/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ecmascript/module/napi_module_loader.h" #include "ecmascript/module/module_path_helper.h" #include "ecmascript/module/js_module_manager.h" #include "ecmascript/jspandafile/js_pandafile_manager.h" #include "ecmascript/jspandafile/js_pandafile_executor.h" namespace panda::ecmascript { JSHandle NapiModuleLoader::LoadModuleNameSpaceWithModuleInfo(EcmaVM *vm, CString &requestPath, CString &modulePath) { LOG_ECMA(DEBUG) << "NapiModuleLoader::LoadModuleNameSpaceWithModuleInfo requestPath:" << requestPath << "," << "modulePath:" << modulePath; CString moduleStr = ModulePathHelper::GetModuleNameWithPath(modulePath); CString abcFilePath = ModulePathHelper::ConcatPandaFilePath(moduleStr); JSThread *thread = vm->GetJSThread(); std::shared_ptr curJsPandaFile; if (modulePath.size() != 0) { bool isValid = JSPandaFileManager::GetInstance()->CheckFilePath(thread, abcFilePath); if (!isValid) { CString msg = "Load file with filename '" + abcFilePath + "' failed, module name '" + requestPath + "'" + ", from napi load module"; THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str()); } curJsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, abcFilePath, requestPath); if (vm->IsNormalizedOhmUrlPack()) { ModulePathHelper::TranslateExpressionToNormalized(thread, curJsPandaFile.get(), abcFilePath, "", requestPath); } else if (ModulePathHelper::NeedTranstale(requestPath)) { ModulePathHelper::TranstaleExpressionInput(curJsPandaFile.get(), requestPath); } } JSHandle nameSp = LoadModuleNameSpaceWithPath(thread, abcFilePath, requestPath, modulePath, curJsPandaFile.get()); return nameSp; } JSHandle NapiModuleLoader::LoadModuleNameSpaceWithPath(JSThread *thread, CString &abcFilePath, CString &requestPath, CString &modulePath, const JSPandaFile *pandaFile) { auto [isNative, moduleType] = SourceTextModule::CheckNativeModule(requestPath); ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager(); if (isNative) { JSHandle moduleHandle = moduleManager->LoadNativeModule(thread, requestPath); return moduleHandle; } CString entryPoint = ModulePathHelper::ConcatFileNameWithMerge(thread, pandaFile, abcFilePath, modulePath, requestPath); RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); bool isValid = JSPandaFileManager::GetInstance()->CheckFilePath(thread, abcFilePath); if (!isValid) { CString msg = "Load file with filename '" + abcFilePath + "' failed, module name '" + requestPath + "'" + ", from napi load module"; THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str()); } std::shared_ptr jsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, abcFilePath, entryPoint); JSRecordInfo *recordInfo = nullptr; bool hasRecord = jsPandaFile->CheckAndGetRecordInfo(entryPoint, &recordInfo); if (!hasRecord) { LOG_FULL(ERROR) << "cannot find record '" << entryPoint <<"' in basefileName " << abcFilePath << "," << "from napi load module"; CString msg = "cannot find record '" + entryPoint + "' in basefileName " + abcFilePath + "," + "from napi load module"; THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str()); } // IsInstantiatedModule is for lazy module to execute if (!moduleManager->IsLocalModuleLoaded(entryPoint) || moduleManager->IsLocalModuleInstantiated(entryPoint)) { if (!JSPandaFileExecutor::ExecuteFromAbcFile(thread, abcFilePath, entryPoint.c_str(), false, true)) { CString msg = "Cannot execute request from napi load module : " + entryPoint + ", from napi load module"; THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str()); } } JSHandle moduleRecord = moduleManager->HostGetImportedModule(entryPoint); JSHandle nameSp = SourceTextModule::GetModuleNamespace(thread, moduleRecord); RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); return nameSp; } }