1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/module/napi_module_loader.h" 17#include "ecmascript/module/module_path_helper.h" 18#include "ecmascript/module/js_module_manager.h" 19#include "ecmascript/jspandafile/js_pandafile_manager.h" 20#include "ecmascript/jspandafile/js_pandafile_executor.h" 21 22namespace panda::ecmascript { 23JSHandle<JSTaggedValue> NapiModuleLoader::LoadModuleNameSpaceWithModuleInfo(EcmaVM *vm, CString &requestPath, 24 CString &modulePath) 25{ 26 CString moduleStr = ModulePathHelper::GetModuleNameWithPath(modulePath); 27 CString abcFilePath = ModulePathHelper::ConcatPandaFilePath(moduleStr); 28 JSThread *thread = vm->GetJSThread(); 29 std::shared_ptr<JSPandaFile> curJsPandaFile; 30 if (modulePath.size() != 0) { 31 curJsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, abcFilePath, requestPath); 32 if (curJsPandaFile == nullptr) { 33 CString msg = "Load file with filename '" + abcFilePath + 34 "' failed, module name '" + requestPath + "'" + ", from napi load module"; 35 THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str()); 36 } 37 if (vm->IsNormalizedOhmUrlPack()) { 38 ModulePathHelper::TranslateExpressionToNormalized(thread, curJsPandaFile.get(), abcFilePath, "", 39 requestPath); 40 } else if (ModulePathHelper::NeedTranstale(requestPath)) { 41 ModulePathHelper::TranstaleExpressionInput(curJsPandaFile.get(), requestPath); 42 } 43 } 44 JSHandle<JSTaggedValue> nameSp = LoadModuleNameSpaceWithPath(thread, abcFilePath, requestPath, modulePath, 45 curJsPandaFile.get()); 46 return nameSp; 47} 48 49JSHandle<JSTaggedValue> NapiModuleLoader::LoadModuleNameSpaceWithPath(JSThread *thread, CString &abcFilePath, 50 CString &requestPath, CString &modulePath, const JSPandaFile *pandaFile) 51{ 52 auto [isNative, moduleType] = SourceTextModule::CheckNativeModule(requestPath); 53 ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager(); 54 if (isNative) { 55 JSHandle<JSTaggedValue> moduleHandle = moduleManager->LoadNativeModule(thread, requestPath); 56 return moduleHandle; 57 } 58 CString entryPoint = ModulePathHelper::ConcatFileNameWithMerge(thread, pandaFile, 59 abcFilePath, modulePath, requestPath); 60 RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); 61 62 std::shared_ptr<JSPandaFile> jsPandaFile = 63 JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, abcFilePath, entryPoint); 64 if (jsPandaFile == nullptr) { 65 CString msg = "Load file with filename '" + abcFilePath + 66 "' failed, module name '" + requestPath + "'" + ", from napi load module"; 67 THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str()); 68 } 69 70 JSRecordInfo *recordInfo = nullptr; 71 bool hasRecord = jsPandaFile->CheckAndGetRecordInfo(entryPoint, &recordInfo); 72 if (!hasRecord) { 73 LOG_FULL(ERROR) << "cannot find record '" << entryPoint <<"' in basefileName " << abcFilePath << "," 74 << "from napi load module"; 75 CString msg = "cannot find record '" + entryPoint + "' in basefileName " + abcFilePath + "," + 76 "from napi load module"; 77 THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str()); 78 } 79 // IsInstantiatedModule is for lazy module to execute 80 if (!moduleManager->IsLocalModuleLoaded(entryPoint) || moduleManager->IsLocalModuleInstantiated(entryPoint)) { 81 if (!JSPandaFileExecutor::ExecuteFromAbcFile(thread, abcFilePath, entryPoint.c_str(), false, true)) { 82 CString msg = "Cannot execute request from napi load module : " + entryPoint + 83 ", from napi load module"; 84 THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str()); 85 } 86 } 87 JSHandle<SourceTextModule> moduleRecord = moduleManager->HostGetImportedModule(entryPoint); 88 JSHandle<JSTaggedValue> nameSp = SourceTextModule::GetModuleNamespace(thread, moduleRecord); 89 RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); 90 return nameSp; 91} 92}