14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/module/napi_module_loader.h"
174514f5e3Sopenharmony_ci#include "ecmascript/module/module_path_helper.h"
184514f5e3Sopenharmony_ci#include "ecmascript/module/js_module_manager.h"
194514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/js_pandafile_manager.h"
204514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/js_pandafile_executor.h"
214514f5e3Sopenharmony_ci
224514f5e3Sopenharmony_cinamespace panda::ecmascript {
234514f5e3Sopenharmony_ciJSHandle<JSTaggedValue> NapiModuleLoader::LoadModuleNameSpaceWithModuleInfo(EcmaVM *vm, CString &requestPath,
244514f5e3Sopenharmony_ci    CString &modulePath)
254514f5e3Sopenharmony_ci{
264514f5e3Sopenharmony_ci    CString moduleStr = ModulePathHelper::GetModuleNameWithPath(modulePath);
274514f5e3Sopenharmony_ci    CString abcFilePath = ModulePathHelper::ConcatPandaFilePath(moduleStr);
284514f5e3Sopenharmony_ci    JSThread *thread = vm->GetJSThread();
294514f5e3Sopenharmony_ci    std::shared_ptr<JSPandaFile> curJsPandaFile;
304514f5e3Sopenharmony_ci    if (modulePath.size() != 0) {
314514f5e3Sopenharmony_ci        curJsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, abcFilePath, requestPath);
324514f5e3Sopenharmony_ci        if (curJsPandaFile == nullptr) {
334514f5e3Sopenharmony_ci            CString msg = "Load file with filename '" + abcFilePath +
344514f5e3Sopenharmony_ci                "' failed, module name '" + requestPath + "'" + ", from napi load module";
354514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
364514f5e3Sopenharmony_ci        }
374514f5e3Sopenharmony_ci        if (vm->IsNormalizedOhmUrlPack()) {
384514f5e3Sopenharmony_ci            ModulePathHelper::TranslateExpressionToNormalized(thread, curJsPandaFile.get(), abcFilePath, "",
394514f5e3Sopenharmony_ci                requestPath);
404514f5e3Sopenharmony_ci        } else if (ModulePathHelper::NeedTranstale(requestPath)) {
414514f5e3Sopenharmony_ci            ModulePathHelper::TranstaleExpressionInput(curJsPandaFile.get(), requestPath);
424514f5e3Sopenharmony_ci        }
434514f5e3Sopenharmony_ci    }
444514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> nameSp = LoadModuleNameSpaceWithPath(thread, abcFilePath, requestPath, modulePath,
454514f5e3Sopenharmony_ci        curJsPandaFile.get());
464514f5e3Sopenharmony_ci    return nameSp;
474514f5e3Sopenharmony_ci}
484514f5e3Sopenharmony_ci
494514f5e3Sopenharmony_ciJSHandle<JSTaggedValue> NapiModuleLoader::LoadModuleNameSpaceWithPath(JSThread *thread, CString &abcFilePath,
504514f5e3Sopenharmony_ci    CString &requestPath, CString &modulePath, const JSPandaFile *pandaFile)
514514f5e3Sopenharmony_ci{
524514f5e3Sopenharmony_ci    auto [isNative, moduleType] = SourceTextModule::CheckNativeModule(requestPath);
534514f5e3Sopenharmony_ci    ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
544514f5e3Sopenharmony_ci    if (isNative) {
554514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> moduleHandle = moduleManager->LoadNativeModule(thread, requestPath);
564514f5e3Sopenharmony_ci        return moduleHandle;
574514f5e3Sopenharmony_ci    }
584514f5e3Sopenharmony_ci    CString entryPoint = ModulePathHelper::ConcatFileNameWithMerge(thread, pandaFile,
594514f5e3Sopenharmony_ci        abcFilePath, modulePath, requestPath);
604514f5e3Sopenharmony_ci    RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
614514f5e3Sopenharmony_ci
624514f5e3Sopenharmony_ci    std::shared_ptr<JSPandaFile> jsPandaFile =
634514f5e3Sopenharmony_ci        JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, abcFilePath, entryPoint);
644514f5e3Sopenharmony_ci    if (jsPandaFile == nullptr) {
654514f5e3Sopenharmony_ci        CString msg = "Load file with filename '" + abcFilePath +
664514f5e3Sopenharmony_ci            "' failed, module name '" + requestPath + "'" + ", from napi load module";
674514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
684514f5e3Sopenharmony_ci    }
694514f5e3Sopenharmony_ci
704514f5e3Sopenharmony_ci    JSRecordInfo *recordInfo = nullptr;
714514f5e3Sopenharmony_ci    bool hasRecord = jsPandaFile->CheckAndGetRecordInfo(entryPoint, &recordInfo);
724514f5e3Sopenharmony_ci    if (!hasRecord) {
734514f5e3Sopenharmony_ci        LOG_FULL(ERROR) << "cannot find record '" << entryPoint <<"' in basefileName " << abcFilePath << ","
744514f5e3Sopenharmony_ci            << "from napi load module";
754514f5e3Sopenharmony_ci        CString msg = "cannot find record '" + entryPoint + "' in basefileName " + abcFilePath + "," +
764514f5e3Sopenharmony_ci            "from napi load module";
774514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
784514f5e3Sopenharmony_ci    }
794514f5e3Sopenharmony_ci    // IsInstantiatedModule is for lazy module to execute
804514f5e3Sopenharmony_ci    if (!moduleManager->IsLocalModuleLoaded(entryPoint) || moduleManager->IsLocalModuleInstantiated(entryPoint)) {
814514f5e3Sopenharmony_ci        if (!JSPandaFileExecutor::ExecuteFromAbcFile(thread, abcFilePath, entryPoint.c_str(), false, true)) {
824514f5e3Sopenharmony_ci            CString msg = "Cannot execute request from napi load module : " + entryPoint +
834514f5e3Sopenharmony_ci                ", from napi load module";
844514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
854514f5e3Sopenharmony_ci        }
864514f5e3Sopenharmony_ci    }
874514f5e3Sopenharmony_ci    JSHandle<SourceTextModule> moduleRecord = moduleManager->HostGetImportedModule(entryPoint);
884514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> nameSp = SourceTextModule::GetModuleNamespace(thread, moduleRecord);
894514f5e3Sopenharmony_ci    RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
904514f5e3Sopenharmony_ci    return nameSp;
914514f5e3Sopenharmony_ci}
924514f5e3Sopenharmony_ci}