Throw JS error when find abc failed

--------
1. Remove redundant function interface.
2. Throw JS error when find abc failed
issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I67R5D?from=project-issue

Signed-off-by: DaiHN <daihuina1@huawei.com>
Change-Id: I7b8cdc521d660d6651cf9b08863154756bbd0973
This commit is contained in:
DaiHN 2023-01-17 21:01:22 +08:00
parent 0e1f7e7bff
commit 1d676b9df7
37 changed files with 428 additions and 520 deletions

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2023 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.
*/
#ifndef ECMASCRIPT_BASE_PATH_HELPER_H
#define ECMASCRIPT_BASE_PATH_HELPER_H
#include "ecmascript/aot_file_manager.h"
#include "ecmascript/ecma_macros.h"
#include "ecmascript/ecma_string.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/global_env.h"
#include "ecmascript/js_tagged_value-inl.h"
#include "ecmascript/jspandafile/js_pandafile.h"
namespace panda::ecmascript::base {
class PathHelper {
public:
static void ResolveCurrentPath(JSThread *thread,
JSMutableHandle<JSTaggedValue> &dirPath,
JSMutableHandle<JSTaggedValue> &fileName,
const JSPandaFile *jsPandaFile)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
CString fullName = jsPandaFile->GetJSPandaFileDesc();
// find last '/'
int foundPos = static_cast<int>(fullName.find_last_of("/\\"));
if (foundPos == -1) {
RETURN_IF_ABRUPT_COMPLETION(thread);
}
CString dirPathStr = fullName.substr(0, foundPos + 1);
JSHandle<EcmaString> dirPathName = factory->NewFromUtf8(dirPathStr);
dirPath.Update(dirPathName.GetTaggedValue());
// Get filename from JSPandaFile
JSHandle<EcmaString> cbFileName = factory->NewFromUtf8(fullName);
fileName.Update(cbFileName.GetTaggedValue());
}
static JSHandle<EcmaString> ResolveDirPath(JSThread *thread,
JSHandle<JSTaggedValue> fileName)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
CString fullName = ConvertToString(fileName.GetTaggedValue());
// find last '/'
int foundPos = static_cast<int>(fullName.find_last_of("/\\"));
if (foundPos == -1) {
RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread);
}
CString dirPathStr = fullName.substr(0, foundPos + 1);
return factory->NewFromUtf8(dirPathStr);
}
};
} // namespace panda::ecmascript::base
#endif // ECMASCRIPT_BASE_PATH_HELPER_H

View File

@ -16,11 +16,14 @@
#include "ecmascript/builtins/builtins_cjs_module.h"
#include "ecmascript/base/builtins_base.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/interpreter/interpreter-inl.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/require/js_cjs_module.h"
#include "ecmascript/require/js_require_manager.h"
namespace panda::ecmascript::builtins {
using PathHelper = base::PathHelper;
JSTaggedValue BuiltinsCjsModule::CjsModuleConstructor(EcmaRuntimeCallInfo *argv)
{
JSThread *thread = argv->GetThread();
@ -56,15 +59,15 @@ JSTaggedValue BuiltinsCjsModule::ResolveFilename(EcmaRuntimeCallInfo *argv)
JSMutableHandle<JSTaggedValue> parent(thread, JSTaggedValue::Undefined());
JSMutableHandle<JSTaggedValue> dirname(thread, JSTaggedValue::Undefined());
const JSPandaFile *jsPandaFile = EcmaInterpreter::GetNativeCallPandafile(thread);
RequireManager::ResolveCurrentPath(thread, parent, dirname, jsPandaFile);
PathHelper::ResolveCurrentPath(thread, parent, dirname, jsPandaFile);
if (length != 1) { // strange arg's number
LOG_ECMA(FATAL) << "BuiltinsCjsModule::Load : can only accept one argument";
UNREACHABLE();
}
JSHandle<EcmaString> requestName = JSHandle<EcmaString>::Cast(GetCallArg(argv, 0));
JSHandle<EcmaString> filename = CjsModule::ResolveFilename(thread, dirname.GetTaggedValue(),
requestName.GetTaggedValue());
JSHandle<EcmaString> filename = ResolveFilenameFromNative(thread, dirname.GetTaggedValue(),
requestName.GetTaggedValue());
return filename.GetTaggedValue();
}

View File

@ -15,6 +15,7 @@
#include "ecmascript/builtins/builtins_promise_job.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/ecma_macros.h"
#include "ecmascript/global_env.h"
#include "ecmascript/interpreter/interpreter.h"
@ -25,10 +26,12 @@
#include "ecmascript/js_promise.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/module/js_module_manager.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/require/js_cjs_module.h"
#include "libpandabase/macros.h"
namespace panda::ecmascript::builtins {
using PathHelper = base::PathHelper;
JSTaggedValue BuiltinsPromiseJob::PromiseReactionJob(EcmaRuntimeCallInfo *argv)
{
ASSERT(argv);
@ -128,6 +131,7 @@ JSTaggedValue BuiltinsPromiseJob::DynamicImportJob(EcmaRuntimeCallInfo *argv)
ASSERT(argv);
BUILTINS_API_TRACE(argv->GetThread(), PromiseJob, DynamicImportJob);
JSThread *thread = argv->GetThread();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
EcmaVM *vm = thread->GetEcmaVM();
[[maybe_unused]] EcmaHandleScope handleScope(thread);
@ -148,14 +152,22 @@ JSTaggedValue BuiltinsPromiseJob::DynamicImportJob(EcmaRuntimeCallInfo *argv)
CString baseFilename = ConvertToString(dirPath.GetTaggedValue());
CString fileNameStr = "";
if (recordName->IsUndefined()) {
moduleName = CjsModule::ResolveFilenameFromNative(thread, dirPath.GetTaggedValue(),
specifierString.GetTaggedValue());
moduleName = ResolveFilenameFromNative(thread, dirPath.GetTaggedValue(),
specifierString.GetTaggedValue());
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
fileNameStr = ConvertToString(moduleName.GetTaggedValue());
} else {
CString recordNameStr = ConvertToString(recordName.GetTaggedValue());
CString requestModule = ConvertToString(specifierString.GetTaggedValue());
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, baseFilename, recordNameStr.c_str());
if (jsPandaFile == nullptr) {
LOG_ECMA(ERROR) << "Try to load record " << recordNameStr << " in abc : " << baseFilename;
CString msg = "Faild to load file '" + recordNameStr + "', please check the request path.";
JSTaggedValue error = factory->GetJSError(ErrorType::REFERENCE_ERROR, msg.c_str()).GetTaggedValue();
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
}
entryPoint =
ModuleManager::ConcatFileNameWithMerge(jsPandaFile, baseFilename, recordNameStr, requestModule);
@ -164,12 +176,20 @@ JSTaggedValue BuiltinsPromiseJob::DynamicImportJob(EcmaRuntimeCallInfo *argv)
}
const JSPandaFile *jsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, fileNameStr,
entryPoint);
bool isModule = jsPandaFile->IsModule(entryPoint);
if (jsPandaFile == nullptr) {
LOG_ECMA(ERROR) << "Try to load record " << entryPoint << " in abc : " << fileNameStr;
CString msg = "Faild to load file '" + entryPoint + "', please check the request path.";
JSTaggedValue error = factory->GetJSError(ErrorType::REFERENCE_ERROR, msg.c_str()).GetTaggedValue();
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
}
bool isModule = jsPandaFile->IsModule(thread, entryPoint);
JSMutableHandle<JSTaggedValue> moduleNamespace(thread, JSTaggedValue::Undefined());
if (!vm->GetModuleManager()->IsImportedModuleLoaded(moduleName.GetTaggedValue())) {
if (!JSPandaFileExecutor::ExecuteFromFile(thread, fileNameStr.c_str(), entryPoint.c_str(), false, true)) {
LOG_FULL(FATAL) << "Cannot execute dynamic-imported panda file : "<< fileNameStr.c_str()
<< entryPoint.c_str();
LOG_ECMA(ERROR) << "Try to load record " << entryPoint << " in abc : " << fileNameStr;
CString msg = "Cannot execute request dynamic-imported module : " + entryPoint;
JSTaggedValue error = factory->GetJSError(ErrorType::REFERENCE_ERROR, msg.c_str()).GetTaggedValue();
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
}
}
if (thread->HasPendingException()) {

View File

@ -135,9 +135,11 @@ void PassManager::ResolveModule(const JSPandaFile *jsPandaFile, const std::strin
{
const auto &recordInfo = jsPandaFile->GetJSRecordInfo();
ModuleManager *moduleManager = vm_->GetModuleManager();
JSThread *thread = vm_->GetJSThread();
for (auto info: recordInfo) {
auto recordName = info.first;
if (jsPandaFile->IsModule(recordName)) {
if (jsPandaFile->IsModule(thread, recordName)) {
ASSERT(!thread->HasPendingException());
moduleManager->HostResolveImportedModuleWithMerge(fileName.c_str(), recordName);
}
}

View File

@ -310,6 +310,21 @@
return (value); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, errorType, type, message) \
do { \
if ((thread)->HasPendingException()) { \
return JSHandle<type>(thread, JSTaggedValue::Exception()); \
} \
ObjectFactory *_factory = (thread)->GetEcmaVM()->GetFactory(); \
JSHandle<JSObject> _error = _factory->GetJSError(errorType, message); \
(thread)->SetException(_error.GetTaggedValue()); \
if ((thread)->IsPrintBCOffset()) { \
(thread)->CollectBCOffsetInfo(); \
} \
return JSHandle<type>(thread, JSTaggedValue::Exception()); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define THROW_NEW_ERROR_WITH_MSG_AND_RETURN_VALUE(thread, errorType, message, value) \
do { \

View File

@ -15,6 +15,7 @@
#include "ecmascript/ecma_vm.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/base/string_helper.h"
#include "ecmascript/builtins/builtins.h"
#include "ecmascript/builtins/builtins_collator.h"
@ -92,6 +93,7 @@
#endif
namespace panda::ecmascript {
using PathHelper = base::PathHelper;
/* static */
EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options, EcmaParamConfiguration &config)
{
@ -455,7 +457,7 @@ Expected<JSTaggedValue, bool> EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js
JSHandle<JSFunction> func(thread_, program->GetMainFunction());
JSHandle<JSTaggedValue> global = GlobalEnv::Cast(globalEnv_.GetTaggedObject())->GetJSGlobalObject();
JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
if (jsPandaFile->IsModule(entryPoint.data())) {
if (jsPandaFile->IsModule(thread_, entryPoint.data())) {
global = undefined;
CString moduleName = jsPandaFile->GetJSPandaFileDesc();
if (!jsPandaFile->IsBundlePack()) {
@ -476,8 +478,10 @@ Expected<JSTaggedValue, bool> EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js
EcmaRuntimeStatScope runtimeStatScope(this);
result = InvokeEcmaAotEntrypoint(func, global, jsPandaFile, entryPoint);
} else {
if (jsPandaFile->IsCjs(entryPoint.data())) {
CJSExecution(func, global, jsPandaFile);
if (jsPandaFile->IsCjs(thread_, entryPoint.data())) {
if (!thread_->HasPendingException()) {
CJSExecution(func, global, jsPandaFile);
}
} else {
EcmaRuntimeCallInfo *info =
EcmaInterpreter::NewRuntimeCallInfo(thread_, JSHandle<JSTaggedValue>(func), global, undefined, 0);
@ -557,11 +561,11 @@ void EcmaVM::CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &t
JSMutableHandle<JSTaggedValue> filename(thread_, JSTaggedValue::Undefined());
JSMutableHandle<JSTaggedValue> dirname(thread_, JSTaggedValue::Undefined());
if (jsPandaFile->IsBundlePack()) {
RequireManager::ResolveCurrentPath(thread_, dirname, filename, jsPandaFile);
PathHelper::ResolveCurrentPath(thread_, dirname, filename, jsPandaFile);
} else {
filename.Update(func->GetModule());
ASSERT(filename->IsString());
RequireManager::ResolveDirPath(thread_, dirname, filename);
dirname.Update(PathHelper::ResolveDirPath(thread_, filename));
}
CJSInfo cjsInfo(module, require, exports, filename, dirname);
RequireManager::InitializeCommonJS(thread_, cjsInfo);

View File

@ -382,17 +382,6 @@ public:
}
}
// CJS callbacks
void SetResolvePathCallback(ResolvePathCallback cb)
{
resolvePathCallback_ = cb;
}
ResolvePathCallback GetResolvePathCallback() const
{
return resolvePathCallback_;
}
void SetResolveBufferCallback(ResolveBufferCallback cb)
{
resolveBufferCallback_ = cb;
@ -474,6 +463,11 @@ public:
return false;
}
bool IsWorkerThread()
{
return options_.IsWorker();
}
bool IsBundlePack() const
{
return isBundlePack_;
@ -589,10 +583,10 @@ public:
return optCodeProfiler_;
}
protected:
void HandleUncaughtException(JSTaggedValue exception);
protected:
void PrintJSErrorInfo(const JSHandle<JSTaggedValue> &exceptionInfo);
private:

View File

@ -204,7 +204,7 @@ MethodLiteral *JSPandaFile::FindMethodLiteral(uint32_t offset) const
return iter->second;
}
bool JSPandaFile::IsModule(const CString &recordName) const
bool JSPandaFile::IsModule(JSThread *thread, const CString &recordName) const
{
if (IsBundlePack()) {
return jsRecordInfo_.begin()->second.moduleRecordIdx != -1;
@ -213,11 +213,11 @@ bool JSPandaFile::IsModule(const CString &recordName) const
if (info != jsRecordInfo_.end()) {
return info->second.moduleRecordIdx != -1;
}
LOG_FULL(FATAL) << "find entryPoint failed: " << recordName;
UNREACHABLE();
CString msg = "Faild to load file '" + recordName + "', please check the request path.";
THROW_REFERENCE_ERROR_AND_RETURN(thread, msg.c_str(), false);
}
bool JSPandaFile::IsCjs(const CString &recordName) const
bool JSPandaFile::IsCjs(JSThread *thread, const CString &recordName) const
{
if (IsBundlePack()) {
return jsRecordInfo_.begin()->second.isCjs;
@ -226,8 +226,8 @@ bool JSPandaFile::IsCjs(const CString &recordName) const
if (info != jsRecordInfo_.end()) {
return info->second.isCjs;
}
LOG_FULL(FATAL) << "find entryPoint failed: " << recordName;
UNREACHABLE();
CString msg = "Faild to load file '" + recordName + "', please check the request path.";
THROW_REFERENCE_ERROR_AND_RETURN(thread, msg.c_str(), false);
}
bool JSPandaFile::IsJson(JSThread *thread, const CString &recordName) const
@ -239,8 +239,8 @@ bool JSPandaFile::IsJson(JSThread *thread, const CString &recordName) const
if (info != jsRecordInfo_.end()) {
return info->second.isJson;
}
CString message = "find entryPoint failed: " + recordName;
THROW_REFERENCE_ERROR_AND_RETURN(thread, message.c_str(), false);
CString msg = "Faild to load file '" + recordName + "', please check the request path.";
THROW_REFERENCE_ERROR_AND_RETURN(thread, msg.c_str(), false);
}
CString JSPandaFile::GetJsonStringId(JSThread *thread, const CString &recordName) const
@ -255,11 +255,11 @@ CString JSPandaFile::GetJsonStringId(JSThread *thread, const CString &recordName
StringData sd = GetStringData(EntityId(info->second.jsonStringId));
return utf::Mutf8AsCString(sd.data);
}
CString message = "find jsonStringId failed: " + recordName;
THROW_REFERENCE_ERROR_AND_RETURN(thread, message.c_str(), "");
CString msg = "Faild to load file '" + recordName + "', please check the request path.";
THROW_REFERENCE_ERROR_AND_RETURN(thread, msg.c_str(), "");
}
CString JSPandaFile::FindEntryPoint(const CString &recordName) const
CString JSPandaFile::FindNpmEntryPoint(const CString &recordName) const
{
if (HasRecord(recordName)) {
return recordName;

View File

@ -230,9 +230,9 @@ public:
return pf_->GetHeader()->file_size;
}
bool PUBLIC_API IsModule(const CString &recordName = ENTRY_FUNCTION_NAME) const;
bool PUBLIC_API IsModule(JSThread *thread, const CString &recordName = ENTRY_FUNCTION_NAME) const;
bool IsCjs(const CString &recordName = ENTRY_FUNCTION_NAME) const;
bool IsCjs(JSThread *thread, const CString &recordName = ENTRY_FUNCTION_NAME) const;
bool IsJson(JSThread *thread, const CString &recordName = ENTRY_FUNCTION_NAME) const;
@ -298,7 +298,7 @@ public:
void CheckIsBundlePack();
void CheckIsNewRecord(EcmaVM *vm);
CString FindEntryPoint(const CString &record) const;
CString FindNpmEntryPoint(const CString &record) const;
static CString ParseOhmUrl(EcmaVM *vm, const CString &inputFileName, CString &outFileName);
static std::string ParseHapPath(const CString &fileName);

View File

@ -70,11 +70,15 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromFile(JSThread *thr
JSPandaFile::CroppingRecord(entry);
}
}
bool isModule = jsPandaFile->IsModule(entry.c_str());
bool isModule = jsPandaFile->IsModule(thread, entry.c_str());
if (thread->HasPendingException()) {
vm->HandleUncaughtException(thread->GetException());
return JSTaggedValue::Undefined();
}
if (isModule) {
[[maybe_unused]] EcmaHandleScope scope(thread);
ModuleManager *moduleManager = vm->GetModuleManager();
JSHandle<SourceTextModule> moduleRecord(thread->GlobalConstants()->GetHandledUndefined());
JSHandle<JSTaggedValue> moduleRecord(thread->GlobalConstants()->GetHandledUndefined());
if (jsPandaFile->IsBundlePack()) {
moduleRecord = moduleManager->HostResolveImportedModule(name);
} else {
@ -87,9 +91,9 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromFile(JSThread *thr
}
return JSTaggedValue::Undefined();
}
moduleRecord->SetStatus(ModuleStatus::INSTANTIATED);
SourceTextModule::Evaluate(thread, moduleRecord, nullptr, 0, excuteFromJob);
JSHandle<SourceTextModule> module = JSHandle<SourceTextModule>::Cast(moduleRecord);
module->SetStatus(ModuleStatus::INSTANTIATED);
SourceTextModule::Evaluate(thread, module, nullptr, 0, excuteFromJob);
return JSTaggedValue::Undefined();
}
return JSPandaFileExecutor::Execute(thread, jsPandaFile, entry.c_str(), excuteFromJob);
@ -107,7 +111,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromBuffer(JSThread *t
}
CString entry = entryPoint.data();
bool isModule = jsPandaFile->IsModule(entry);
bool isModule = jsPandaFile->IsModule(thread, entry);
bool isBundle = jsPandaFile->IsBundlePack();
if (isModule) {
return CommonExecuteBuffer(thread, isBundle, normalName, entry, buffer, size);
@ -135,8 +139,16 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteModuleBuffer(
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, name, entry.c_str(), buffer, size);
if (jsPandaFile == nullptr) {
return Unexpected(false);
if (thread->GetEcmaVM()->IsWorkerThread()) {
CString mesWorker = "Excute worker's entryPoint failed: " + entry +
". Please check worker's reference path .";
THROW_REFERENCE_ERROR_AND_RETURN(thread, mesWorker.c_str(), Unexpected(false));
}
CString message = "Excute file's entryPoint failed: " + entry +
". Please check the reference path .";
THROW_REFERENCE_ERROR_AND_RETURN(thread, message.c_str(), Unexpected(false));
}
ASSERT(jsPandaFile->IsModule(thread, entry.c_str()));
bool isBundle = jsPandaFile->IsBundlePack();
if (!isBundle) {
const_cast<JSPandaFile *>(jsPandaFile)->CheckIsNewRecord(vm);
@ -144,7 +156,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteModuleBuffer(
JSPandaFile::CroppingRecord(entry);
}
}
ASSERT(jsPandaFile->IsModule(entry.c_str()));
ASSERT(jsPandaFile->IsModule(thread, entry.c_str()));
return CommonExecuteBuffer(thread, isBundle, name, entry, buffer, size);
}
@ -155,7 +167,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::CommonExecuteBuffer(JSThread
EcmaVM *vm = thread->GetEcmaVM();
ModuleManager *moduleManager = vm->GetModuleManager();
moduleManager->SetExecuteMode(true);
JSHandle<SourceTextModule> moduleRecord(thread->GlobalConstants()->GetHandledUndefined());
JSHandle<JSTaggedValue> moduleRecord(thread->GlobalConstants()->GetHandledUndefined());
if (isBundle) {
moduleRecord = moduleManager->HostResolveImportedModule(buffer, size, filename);
} else {
@ -166,8 +178,9 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::CommonExecuteBuffer(JSThread
vm->HandleUncaughtException(thread->GetException());
return JSTaggedValue::Undefined();
}
moduleRecord->SetStatus(ModuleStatus::INSTANTIATED);
SourceTextModule::Evaluate(thread, moduleRecord, buffer, size);
JSHandle<SourceTextModule> module = JSHandle<SourceTextModule>::Cast(moduleRecord);
module->SetStatus(ModuleStatus::INSTANTIATED);
SourceTextModule::Evaluate(thread, module, buffer, size);
return JSTaggedValue::Undefined();
}

View File

@ -267,7 +267,7 @@ JSHandle<JSFunction> LiteralDataExtractor::DefineMethodInLiteral(JSThread *threa
moduleName = entryPoint;
entry = entryPoint;
}
if (jsPandaFile->IsModule(entry)) {
if (jsPandaFile->IsModule(thread, entry)) {
EcmaVM *vm = thread->GetEcmaVM();
JSHandle<SourceTextModule> module = vm->GetModuleManager()->HostGetImportedModule(moduleName);
jsFunc->SetModule(thread, module.GetTaggedValue());

View File

@ -223,11 +223,12 @@ void PandaFileTranslator::ParseFuncAndLiteralConstPool(EcmaVM *vm, const JSPanda
JSHandle<ConstantPool> constpool)
{
auto &recordInfo = const_cast<JSPandaFile *>(jsPandaFile)->FindRecordInfo(entryPoint);
JSThread *thread = vm->GetJSThread();
ASSERT(!thread->HasPendingException());
if (recordInfo.IsParsedConstpoolOfCurrentVM(vm)) {
return;
}
JSThread *thread = vm->GetJSThread();
ObjectFactory *factory = vm->GetFactory();
[[maybe_unused]] EcmaHandleScope handleScope(thread);

View File

@ -271,8 +271,8 @@ HWTEST_F_L0(JSPandaFileTest, IsModule_IsCjs)
)";
const CString fileName1 = "test1.pa";
JSPandaFile *pf1 = CreateJSPandaFile(source1, fileName1);
EXPECT_EQ(pf1->IsModule(), false);
EXPECT_EQ(pf1->IsCjs(), false);
EXPECT_EQ(pf1->IsModule(thread), false);
EXPECT_EQ(pf1->IsCjs(thread), false);
JSPandaFileManager::RemoveJSPandaFile(pf1);
}

View File

@ -279,8 +279,8 @@ bool ModuleManager::IsImportedModuleLoaded(JSTaggedValue referencing)
return (entry != -1);
}
JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModuleWithMerge(const CString &moduleFileName,
const CString &recordName)
JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModuleWithMerge(const CString &moduleFileName,
const CString &recordName)
{
JSThread *thread = vm_->GetJSThread();
ObjectFactory *factory = vm_->GetFactory();
@ -289,7 +289,7 @@ JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModuleWithMerge(con
NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
int entry = dict->FindEntry(recordNameHandle.GetTaggedValue());
if (entry != -1) {
return JSHandle<SourceTextModule>(thread, dict->GetValue(entry));
return JSHandle<JSTaggedValue>(thread, dict->GetValue(entry));
}
const JSPandaFile *jsPandaFile = JSPandaFileManager::GetInstance()->FindJSPandaFile(moduleFileName);
if (jsPandaFile == nullptr) {
@ -312,11 +312,14 @@ JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModuleWithMerge(con
}
}
if (jsPandaFile == nullptr) {
LOG_FULL(FATAL) << "open jsPandaFile " << moduleFileName << " error";
UNREACHABLE();
LOG_ECMA(ERROR) << "Try to load record " << recordName << " in abc : " << moduleFileName;
CString msg = "Faild to load file '" + recordName + "', please check the request path.";
THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
}
JSHandle<SourceTextModule> moduleRecord = ResolveModuleWithMerge(thread, jsPandaFile, recordName);
JSHandle<JSTaggedValue> moduleRecord = ResolveModuleWithMerge(thread, jsPandaFile, recordName);
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
JSHandle<NameDictionary> handleDict(thread, resolvedModules_);
resolvedModules_ = NameDictionary::Put(thread, handleDict, JSHandle<JSTaggedValue>(recordNameHandle),
JSHandle<JSTaggedValue>(moduleRecord), PropertyAttributes::Default())
@ -325,40 +328,42 @@ JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModuleWithMerge(con
return moduleRecord;
}
JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModule(const CString &referencingModule)
JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModule(const CString &referencingModule)
{
JSThread *thread = vm_->GetJSThread();
ObjectFactory *factory = vm_->GetFactory();
JSHandle<EcmaString> referencingHandle = factory->NewFromUtf8(referencingModule);
CString moduleFileName = referencingModule;
if (!vm_->GetResolvePathCallback()) {
if (vm_->IsBundlePack()) {
if (AOTFileManager::GetAbsolutePath(referencingModule, moduleFileName)) {
referencingHandle = factory->NewFromUtf8(moduleFileName);
} else {
LOG_FULL(FATAL) << "absolute " << referencingModule << " path error";
UNREACHABLE();
CString msg = "Parse absolute " + referencingModule + " path failed";
THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
}
}
NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
int entry = dict->FindEntry(referencingHandle.GetTaggedValue());
if (entry != -1) {
return JSHandle<SourceTextModule>(thread, dict->GetValue(entry));
return JSHandle<JSTaggedValue>(thread, dict->GetValue(entry));
}
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, moduleFileName, JSPandaFile::ENTRY_MAIN_FUNCTION);
if (jsPandaFile == nullptr) {
LOG_FULL(FATAL) << "open jsPandaFile " << moduleFileName << " error";
UNREACHABLE();
LOG_ECMA(ERROR) << "Try to load abc : " << moduleFileName;
CString msg = "Faild to load file '" + moduleFileName + "', please check the request path.";
THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
}
return ResolveModule(thread, jsPandaFile);
}
JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModule(const void *buffer, size_t size,
const CString &filename)
JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModule(const void *buffer, size_t size,
const CString &filename)
{
JSThread *thread = vm_->GetJSThread();
ObjectFactory *factory = vm_->GetFactory();
@ -367,34 +372,32 @@ JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModule(const void *
NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
int entry = dict->FindEntry(referencingHandle.GetTaggedValue());
if (entry != -1) {
return JSHandle<SourceTextModule>(thread, dict->GetValue(entry));
return JSHandle<JSTaggedValue>(thread, dict->GetValue(entry));
}
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, filename,
JSPandaFile::ENTRY_MAIN_FUNCTION, buffer, size);
if (jsPandaFile == nullptr) {
LOG_FULL(FATAL) << "open jsPandaFile " << filename << " error";
UNREACHABLE();
CString msg = "Faild to load file '" + filename + "', please check the request path.";
THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
}
return ResolveModule(thread, jsPandaFile);
}
JSHandle<SourceTextModule> ModuleManager::ResolveModule(JSThread *thread, const JSPandaFile *jsPandaFile)
JSHandle<JSTaggedValue> ModuleManager::ResolveModule(JSThread *thread, const JSPandaFile *jsPandaFile)
{
ObjectFactory *factory = vm_->GetFactory();
CString moduleFileName = jsPandaFile->GetJSPandaFileDesc();
JSHandle<JSTaggedValue> moduleRecord = thread->GlobalConstants()->GetHandledUndefined();
if (jsPandaFile->IsCjs()) {
moduleRecord = ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile);
} else if (jsPandaFile->IsModule()) {
if (jsPandaFile->IsModule(thread)) {
moduleRecord = ModuleDataExtractor::ParseModule(thread, jsPandaFile, moduleFileName, moduleFileName);
} else if (jsPandaFile->IsJson(thread)) {
moduleRecord = ModuleDataExtractor::ParseJsonModule(thread, jsPandaFile, moduleFileName);
} else {
LOG_FULL(FATAL) << "jsPandaFile: " << moduleFileName << " is not CjsModule or EcmaModule or JsonModule";
UNREACHABLE();
ASSERT(jsPandaFile->IsCjs(thread));
moduleRecord = ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile);
}
JSHandle<NameDictionary> dict(thread, resolvedModules_);
@ -402,117 +405,29 @@ JSHandle<SourceTextModule> ModuleManager::ResolveModule(JSThread *thread, const
resolvedModules_ =
NameDictionary::Put(thread, dict, referencingHandle, moduleRecord, PropertyAttributes::Default())
.GetTaggedValue();
return JSHandle<SourceTextModule>::Cast(moduleRecord);
return moduleRecord;
}
JSHandle<SourceTextModule> ModuleManager::ResolveModuleWithMerge(
JSHandle<JSTaggedValue> ModuleManager::ResolveModuleWithMerge(
JSThread *thread, const JSPandaFile *jsPandaFile, const CString &recordName)
{
ObjectFactory *factory = vm_->GetFactory();
CString moduleFileName = jsPandaFile->GetJSPandaFileDesc();
JSHandle<JSTaggedValue> moduleRecord = thread->GlobalConstants()->GetHandledUndefined();
if (jsPandaFile->IsCjs(recordName)) {
moduleRecord = ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile);
} else if (jsPandaFile->IsModule(recordName)) {
if (jsPandaFile->IsModule(thread, recordName)) {
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
moduleRecord = ModuleDataExtractor::ParseModule(thread, jsPandaFile, recordName, moduleFileName);
} else if (jsPandaFile->IsJson(thread, recordName)) {
moduleRecord = ModuleDataExtractor::ParseJsonModule(thread, jsPandaFile, moduleFileName, recordName);
} else {
LOG_FULL(FATAL) << "jsPandaFile: " << moduleFileName << " is not CjsModule or EcmaModule or JsonModule";
UNREACHABLE();
ASSERT(jsPandaFile->IsCjs(thread, recordName));
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
moduleRecord = ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile);
}
JSHandle<JSTaggedValue> recordNameHandle = JSHandle<JSTaggedValue>::Cast(factory->NewFromUtf8(recordName));
JSHandle<SourceTextModule>::Cast(moduleRecord)->SetEcmaModuleRecordName(thread, recordNameHandle);
return JSHandle<SourceTextModule>::Cast(moduleRecord);
}
void ModuleManager::ConcatFileName(std::string &dirPath, std::string &requestPath, std::string &fileName)
{
JSThread *thread = vm_->GetJSThread();
int suffixEnd = static_cast<int>(requestPath.find_last_of('.'));
if (suffixEnd == -1) {
RETURN_IF_ABRUPT_COMPLETION(thread);
}
#if defined(PANDA_TARGET_WINDOWS)
if (requestPath[1] == ':') { // absoluteFilePath
fileName = requestPath.substr(0, suffixEnd) + ".abc";
} else {
int pos = static_cast<int>(dirPath.find_last_of('\\'));
if (pos == -1) {
RETURN_IF_ABRUPT_COMPLETION(thread);
}
fileName = dirPath.substr(0, pos + 1) + requestPath.substr(0, suffixEnd) + ".abc";
}
#else
if (requestPath.find("./") == 0) {
requestPath = requestPath.substr(2); // 2 : delete './'
suffixEnd -= 2; // 2 : delete './'
}
if (requestPath[0] == '/') { // absoluteFilePath
fileName = requestPath.substr(0, suffixEnd) + ".abc";
} else {
int pos = static_cast<int>(dirPath.find_last_of('/'));
if (pos == -1) {
RETURN_IF_ABRUPT_COMPLETION(thread);
}
fileName = dirPath.substr(0, pos + 1) + requestPath.substr(0, suffixEnd) + ".abc";
}
#endif
}
JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModule(std::string &baseFilename,
std::string &moduleFilename)
{
JSThread *thread = vm_->GetJSThread();
bool mode = GetCurrentMode();
std::string moduleFullname;
if (!mode) {
ResolvePathCallback resolvePathCallback = thread->GetEcmaVM()->GetResolvePathCallback();
if (resolvePathCallback != nullptr) {
moduleFullname = resolvePathCallback(baseFilename, moduleFilename);
if (moduleFullname == "") {
LOG_FULL(FATAL) << "dirPath: " << baseFilename << "\n" << " requestPath: " << moduleFilename << "\n"
<< " moduleRequest callbackModuleName is hole failed";
UNREACHABLE();
}
return HostResolveImportedModule(moduleFullname.c_str());
}
ConcatFileName(baseFilename, moduleFilename, moduleFullname);
return HostResolveImportedModule(moduleFullname.c_str());
} else {
// mode == true buffer
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
ResolveBufferCallback resolveBufferCallback = thread->GetEcmaVM()->GetResolveBufferCallback();
if (resolveBufferCallback != nullptr) {
std::vector<uint8_t> data = resolveBufferCallback(baseFilename);
size_t size = data.size();
if (data.empty()) {
LOG_FULL(FATAL) << " moduleRequest callbackModuleName " << moduleFullname << "is hole failed";
UNREACHABLE();
}
ConcatFileName(baseFilename, moduleFilename, moduleFullname);
return HostResolveImportedModule(data.data(),
size, moduleFullname.c_str());
}
#else
ResolvePathCallback resolvePathCallback = thread->GetEcmaVM()->GetResolvePathCallback();
std::string modulePath = moduleFilename;
#ifdef PANDA_TARGET_WINDOWS
replace(modulePath.begin(), modulePath.end(), '/', '\\');
#endif
if (resolvePathCallback != nullptr) {
moduleFullname = resolvePathCallback(baseFilename, modulePath);
if (moduleFullname == "") {
LOG_FULL(FATAL) << "dirPath: " << baseFilename << "\n" << " requestPath: " << modulePath << "\n"
<< " moduleRequest callbackModuleName is hole failed";
UNREACHABLE();
}
return HostResolveImportedModule(moduleFullname.c_str());
}
#endif
return JSHandle<SourceTextModule>(thread, JSTaggedValue::Undefined());
}
return moduleRecord;
}
void ModuleManager::AddResolveImportedModule(const JSPandaFile *jsPandaFile, const CString &referencingModule)
@ -557,7 +472,7 @@ JSTaggedValue ModuleManager::GetModuleNamespaceInternal(int32_t index, JSTaggedV
JSTaggedValue requestedModule = module->GetRequestedModules();
JSTaggedValue moduleName = TaggedArray::Cast(requestedModule.GetTaggedObject())->Get(index);
JSTaggedValue moduleRecordName = module->GetEcmaModuleRecordName();
JSHandle<SourceTextModule> requiredModule;
JSHandle<JSTaggedValue> requiredModule;
if (moduleRecordName.IsUndefined()) {
requiredModule = SourceTextModule::HostResolveImportedModule(thread,
JSHandle<SourceTextModule>(thread, module), JSHandle<JSTaggedValue>(thread, moduleName));
@ -566,13 +481,16 @@ JSTaggedValue ModuleManager::GetModuleNamespaceInternal(int32_t index, JSTaggedV
requiredModule = SourceTextModule::HostResolveImportedModuleWithMerge(thread,
JSHandle<SourceTextModule>(thread, module), JSHandle<JSTaggedValue>(thread, moduleName));
}
// if requiredModule is CommonJS
if (requiredModule->GetTypes() == ModuleTypes::CJSMODULE) {
JSHandle<JSTaggedValue> cjsModuleName(thread, GetModuleName(requiredModule.GetTaggedValue()));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
// if requiredModuleST is CommonJS
JSHandle<SourceTextModule> requiredModuleST = JSHandle<SourceTextModule>::Cast(requiredModule);
if (requiredModuleST->GetTypes() == ModuleTypes::CJSMODULE) {
JSHandle<JSTaggedValue> cjsModuleName(thread, GetModuleName(requiredModuleST.GetTaggedValue()));
return CjsModule::SearchFromModuleCache(thread, cjsModuleName).GetTaggedValue();
}
// if requiredModule is ESM
JSHandle<JSTaggedValue> moduleNamespace = SourceTextModule::GetModuleNamespace(thread, requiredModule);
// if requiredModuleST is ESM
JSHandle<JSTaggedValue> moduleNamespace = SourceTextModule::GetModuleNamespace(thread, requiredModuleST);
ASSERT(moduleNamespace->IsModuleNamespace());
return moduleNamespace.GetTaggedValue();
}
@ -691,6 +609,9 @@ CString ModuleManager::ConcatFileNameWithMerge(const JSPandaFile *jsPandaFile, C
while ((pos = PackageName.rfind(JSPandaFile::NODE_MODULES)) != CString::npos) {
key = PackageName + "/" + JSPandaFile::NODE_MODULES + moduleRequestName;
AddIndexToEntryPoint(jsPandaFile, entryPoint, key);
if (entryPoint.empty()) {
break;
}
PackageName = PackageName.substr(0, pos > 0 ? pos - 1 : 0);
}
}
@ -731,10 +652,10 @@ bool ModuleManager::IsImportedPath(const CString &moduleRequestName, size_t &typ
void ModuleManager::AddIndexToEntryPoint(const JSPandaFile *jsPandaFile, CString &entryPoint, CString &key)
{
entryPoint = jsPandaFile->FindEntryPoint(key);
entryPoint = jsPandaFile->FindNpmEntryPoint(key);
if (entryPoint.empty()) {
key += "/index";
entryPoint = jsPandaFile->FindEntryPoint(key);
entryPoint = jsPandaFile->FindNpmEntryPoint(key);
}
}

View File

@ -52,17 +52,20 @@ public:
JSHandle<SourceTextModule> HostGetImportedModule(JSTaggedValue referencing);
bool IsImportedModuleLoaded(JSTaggedValue referencing);
JSHandle<SourceTextModule> HostResolveImportedModule(const void *buffer, size_t size, const CString &filename);
JSHandle<SourceTextModule> HostResolveImportedModule(std::string &baseFilename, std::string &moduleFilename);
JSHandle<SourceTextModule> HostResolveImportedModule(const CString &referencingModule);
JSHandle<SourceTextModule> PUBLIC_API HostResolveImportedModuleWithMerge(const CString &referencingModule,
const CString &recordName);
JSHandle<JSTaggedValue> HostResolveImportedModule(const void *buffer, size_t size, const CString &filename);
JSHandle<JSTaggedValue> HostResolveImportedModule(const CString &referencingModule);
JSHandle<JSTaggedValue> PUBLIC_API HostResolveImportedModuleWithMerge(const CString &referencingModule,
const CString &recordName);
JSTaggedValue GetCurrentModule();
void AddResolveImportedModule(const JSPandaFile *jsPandaFile, const CString &referencingModule);
void AddResolveImportedModule(const CString &referencingModule, JSHandle<JSTaggedValue> moduleRecord);
void Iterate(const RootVisitor &v);
static CString ConcatFileNameWithMerge(const JSPandaFile *jsPandaFile, CString &baseFilename,
CString moduleRecordName, CString moduleRequestName);
bool GetCurrentMode() const
{
return isExecuteBuffer_;
@ -71,9 +74,7 @@ public:
{
isExecuteBuffer_ = mode;
}
void ConcatFileName(std::string &dirPath, std::string &requestPath, std::string &fileName);
static CString ConcatFileNameWithMerge(const JSPandaFile *jsPandaFile, CString &baseFilename,
CString moduleRecordName, CString moduleRequestName);
static CString GetRecordName(JSTaggedValue module);
static int GetExportObjectIndex(EcmaVM *vm, JSHandle<SourceTextModule> ecmaModule, const std::string &key);
static bool IsImportedPath(const CString &moduleRequestName, size_t &typePos);
@ -93,9 +94,9 @@ private:
JSTaggedValue key, JSTaggedValue value);
// deprecated end
JSHandle<SourceTextModule> ResolveModule(JSThread *thread, const JSPandaFile *jsPandaFile);
JSHandle<SourceTextModule> ResolveModuleWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,
const CString &recodeName);
JSHandle<JSTaggedValue> ResolveModule(JSThread *thread, const JSPandaFile *jsPandaFile);
JSHandle<JSTaggedValue> ResolveModuleWithMerge(JSThread *thread, const JSPandaFile *jsPandaFile,
const CString &recodeName);
static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4;

View File

@ -20,8 +20,7 @@ namespace panda::ecmascript {
int32_t ModuleRecord::Instantiate(JSThread *thread, const JSHandle<JSTaggedValue> &module)
{
if (module->IsSourceTextModule()) {
JSHandle<SourceTextModule> moduleRecord = JSHandle<SourceTextModule>::Cast(module);
return SourceTextModule::Instantiate(thread, moduleRecord);
return SourceTextModule::Instantiate(thread, module);
}
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();

View File

@ -16,6 +16,7 @@
#include "ecmascript/module/js_module_source_text.h"
#include "ecmascript/global_env.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/base/string_helper.h"
#include "ecmascript/jspandafile/js_pandafile_executor.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
@ -23,6 +24,7 @@
#include "ecmascript/linked_hash_table.h"
#include "ecmascript/module/js_module_manager.h"
#include "ecmascript/module/js_module_namespace.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/tagged_dictionary.h"
namespace panda::ecmascript {
@ -71,47 +73,49 @@ CVector<std::string> SourceTextModule::GetExportedNames(JSThread *thread, const
}
// new way with module
JSHandle<SourceTextModule> SourceTextModule::HostResolveImportedModuleWithMerge(
JSHandle<JSTaggedValue> SourceTextModule::HostResolveImportedModuleWithMerge(
JSThread *thread, const JSHandle<SourceTextModule> &module, const JSHandle<JSTaggedValue> &moduleRequest)
{
DISALLOW_GARBAGE_COLLECTION;
auto moduleManager = thread->GetEcmaVM()->GetModuleManager();
if (moduleManager->IsImportedModuleLoaded(moduleRequest.GetTaggedValue())) {
return moduleManager->HostGetImportedModule(moduleRequest.GetTaggedValue());
return JSHandle<JSTaggedValue>(moduleManager->HostGetImportedModule(moduleRequest.GetTaggedValue()));
}
ASSERT(module->GetEcmaModuleFilename().IsHeapObject());
CString baseFilename =
ConvertToString(EcmaString::Cast(module->GetEcmaModuleFilename().GetTaggedObject()));
CString baseFilename = ConvertToString(module->GetEcmaModuleFilename());
ASSERT(module->GetEcmaModuleRecordName().IsHeapObject());
CString moduleRecordName =
ConvertToString(EcmaString::Cast(module->GetEcmaModuleRecordName().GetTaggedObject()));
CString moduleRecordName = ConvertToString(module->GetEcmaModuleRecordName());
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, baseFilename, moduleRecordName);
CString moduleRequestName = ConvertToString(EcmaString::Cast(moduleRequest->GetTaggedObject()));
CString moduleRequestName = ConvertToString(moduleRequest.GetTaggedValue());
CString entryPoint =
ModuleManager::ConcatFileNameWithMerge(jsPandaFile, baseFilename, moduleRecordName, moduleRequestName);
#if defined(PANDA_TARGET_WINDOWS) || defined(PANDA_TARGET_MACOS)
if (entryPoint == JSPandaFile::PREVIEW_OF_ACROSS_HAP_FLAG) {
JSHandle<SourceTextModule> throwValue(thread, JSTaggedValue::Undefined());
THROW_SYNTAX_ERROR_AND_RETURN(thread, "", throwValue);
THROW_SYNTAX_ERROR_AND_RETURN(thread, "", thread->GlobalConstants()->GetHandledUndefined());
}
#endif
return moduleManager->HostResolveImportedModuleWithMerge(baseFilename, entryPoint);
}
// old way with bundle
JSHandle<SourceTextModule> SourceTextModule::HostResolveImportedModule(JSThread *thread,
const JSHandle<SourceTextModule> &module,
const JSHandle<JSTaggedValue> &moduleRequest)
JSHandle<JSTaggedValue> SourceTextModule::HostResolveImportedModule(JSThread *thread,
const JSHandle<SourceTextModule> &module,
const JSHandle<JSTaggedValue> &moduleRequest)
{
auto moduleManage = thread->GetEcmaVM()->GetModuleManager();
if (moduleManage->IsImportedModuleLoaded(moduleRequest.GetTaggedValue())) {
return moduleManage->HostGetImportedModule(moduleRequest.GetTaggedValue());
return JSHandle<JSTaggedValue>(moduleManage->HostGetImportedModule(moduleRequest.GetTaggedValue()));
}
std::string baseFilename = EcmaStringAccessor(module->GetEcmaModuleFilename()).ToStdString();
std::string moduleFilename = EcmaStringAccessor(moduleRequest->GetTaggedObject()).ToStdString();
return thread->GetEcmaVM()->GetModuleManager()->HostResolveImportedModule(baseFilename, moduleFilename);
JSHandle<EcmaString> dirname = base::PathHelper::ResolveDirPath(thread,
JSHandle<JSTaggedValue>(thread, module->GetEcmaModuleFilename()));
JSHandle<EcmaString> moduleFilename = ResolveFilenameFromNative(thread, dirname.GetTaggedValue(),
moduleRequest.GetTaggedValue());
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
return thread->GetEcmaVM()->GetModuleManager()->
HostResolveImportedModule(ConvertToString(moduleFilename.GetTaggedValue()));
}
bool SourceTextModule::CheckCircularImport(const JSHandle<SourceTextModule> &module,
@ -285,8 +289,10 @@ void SourceTextModule::CJSInstantiate(JSThread *thread, const JSHandle<SourceTex
}
}
int SourceTextModule::Instantiate(JSThread *thread, const JSHandle<SourceTextModule> &module)
int SourceTextModule::Instantiate(JSThread *thread, const JSHandle<JSTaggedValue> &moduleHdl)
{
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, SourceTextModule::UNDEFINED_INDEX);
JSHandle<SourceTextModule> module = JSHandle<SourceTextModule>::Cast(moduleHdl);
// 1. Let module be this Source Text Module Record.
// 2. Assert: module.[[Status]] is not "instantiating" or "evaluating".
ASSERT(module->GetStatus() != ModuleStatus::INSTANTIATING && module->GetStatus() != ModuleStatus::EVALUATING);
@ -364,12 +370,17 @@ int SourceTextModule::InnerModuleInstantiation(JSThread *thread, const JSHandle<
JSMutableHandle<SourceTextModule> requiredModule(thread, thread->GlobalConstants()->GetUndefined());
JSTaggedValue moduleRecordName = module->GetEcmaModuleRecordName();
if (moduleRecordName.IsUndefined()) {
requiredModule.Update(SourceTextModule::HostResolveImportedModule(thread, module, required));
JSHandle<JSTaggedValue> requiredVal =
SourceTextModule::HostResolveImportedModule(thread, module, required);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, SourceTextModule::UNDEFINED_INDEX);
requiredModule.Update(JSHandle<SourceTextModule>::Cast(requiredVal));
requestedModules->Set(thread, idx, requiredModule->GetEcmaModuleFilename());
} else {
ASSERT(moduleRecordName.IsString());
requiredModule.Update(SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, required));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, index);
JSHandle<JSTaggedValue> requiredVal =
SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, required);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, SourceTextModule::UNDEFINED_INDEX);
requiredModule.Update(JSHandle<SourceTextModule>::Cast(requiredVal));
requestedModules->Set(thread, idx, requiredModule->GetEcmaModuleRecordName());
}
@ -465,10 +476,16 @@ void SourceTextModule::ModuleDeclarationEnvironmentSetup(JSThread *thread,
JSMutableHandle<SourceTextModule> importedModule(thread, thread->GlobalConstants()->GetUndefined());
JSTaggedValue moduleRecordName = module->GetEcmaModuleRecordName();
if (moduleRecordName.IsUndefined()) {
importedModule.Update(SourceTextModule::HostResolveImportedModule(thread, module, moduleRequest));
JSHandle<JSTaggedValue> importedVal =
SourceTextModule::HostResolveImportedModule(thread, module, moduleRequest);
RETURN_IF_ABRUPT_COMPLETION(thread);
importedModule.Update(JSHandle<SourceTextModule>::Cast(importedVal));
} else {
ASSERT(moduleRecordName.IsString());
importedModule.Update(SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, moduleRequest));
JSHandle<JSTaggedValue> importedVal =
SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, moduleRequest);
RETURN_IF_ABRUPT_COMPLETION(thread);
importedModule.Update(JSHandle<SourceTextModule>::Cast(importedVal));
}
// c. If in.[[ImportName]] is "*", then
JSHandle<JSTaggedValue> starString = globalConstants->GetHandledStarString();
@ -539,10 +556,16 @@ void SourceTextModule::ModuleDeclarationArrayEnvironmentSetup(JSThread *thread,
JSMutableHandle<SourceTextModule> importedModule(thread, thread->GlobalConstants()->GetUndefined());
JSTaggedValue moduleRecordName = module->GetEcmaModuleRecordName();
if (moduleRecordName.IsUndefined()) {
importedModule.Update(SourceTextModule::HostResolveImportedModule(thread, module, moduleRequest));
JSHandle<JSTaggedValue> importedVal =
SourceTextModule::HostResolveImportedModule(thread, module, moduleRequest);
RETURN_IF_ABRUPT_COMPLETION(thread);
importedModule.Update(JSHandle<SourceTextModule>::Cast(importedVal));
} else {
ASSERT(moduleRecordName.IsString());
importedModule.Update(SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, moduleRequest));
JSHandle<JSTaggedValue> importedVal =
SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, moduleRequest);
RETURN_IF_ABRUPT_COMPLETION(thread);
importedModule.Update(JSHandle<SourceTextModule>::Cast(importedVal));
}
// c. If in.[[ImportName]] is "*", then
JSHandle<JSTaggedValue> starString = globalConstants->GetHandledStarString();
@ -737,10 +760,16 @@ int SourceTextModule::InnerModuleEvaluation(JSThread *thread, const JSHandle<Mod
JSMutableHandle<SourceTextModule> requiredModule(thread, thread->GlobalConstants()->GetUndefined());
JSTaggedValue moduleRecordName = module->GetEcmaModuleRecordName();
if (moduleRecordName.IsUndefined()) {
requiredModule.Update(SourceTextModule::HostResolveImportedModule(thread, module, required));
JSHandle<JSTaggedValue> requiredVal =
SourceTextModule::HostResolveImportedModule(thread, module, required);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, SourceTextModule::UNDEFINED_INDEX);
requiredModule.Update(JSHandle<SourceTextModule>::Cast(requiredVal));
} else {
ASSERT(moduleRecordName.IsString());
requiredModule.Update(SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, required));
JSHandle<JSTaggedValue> requiredVal =
SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, required);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, SourceTextModule::UNDEFINED_INDEX);
requiredModule.Update(JSHandle<SourceTextModule>::Cast(requiredVal));
}
// c. Set index to ? InnerModuleEvaluation(requiredModule, stack, index).
JSHandle<ModuleRecord> requiredModuleRecord = JSHandle<ModuleRecord>::Cast(requiredModule);
@ -864,8 +893,9 @@ void SourceTextModule::ModuleExecution(JSThread *thread, const JSHandle<SourceTe
}
if (jsPandaFile == nullptr) {
LOG_FULL(FATAL) << "open jsPandaFile " << moduleFilenameStr << " error";
UNREACHABLE();
LOG_ECMA(ERROR) << "Try to load abc " << moduleFilenameStr;
CString msg = "Faild to load file '" + moduleFilenameStr + "', please check the request path.";
THROW_ERROR(thread, ErrorType::REFERENCE_ERROR, msg.c_str());
}
JSPandaFileExecutor::Execute(thread, jsPandaFile, entryPoint, excuteFromJob);
}
@ -1044,10 +1074,16 @@ void SourceTextModule::SetExportName(JSThread *thread, const JSHandle<JSTaggedVa
JSMutableHandle<SourceTextModule> requestedModule(thread, thread->GlobalConstants()->GetUndefined());
JSTaggedValue moduleRecordName = module->GetEcmaModuleRecordName();
if (moduleRecordName.IsUndefined()) {
requestedModule.Update(SourceTextModule::HostResolveImportedModule(thread, module, moduleRequest));
JSHandle<JSTaggedValue> requestedVal =
SourceTextModule::HostResolveImportedModule(thread, module, moduleRequest);
RETURN_IF_ABRUPT_COMPLETION(thread);
requestedModule.Update(JSHandle<SourceTextModule>::Cast(requestedVal));
} else {
ASSERT(moduleRecordName.IsString());
requestedModule.Update(SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, moduleRequest));
JSHandle<JSTaggedValue> requestedVal =
SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, moduleRequest);
RETURN_IF_ABRUPT_COMPLETION(thread);
requestedModule.Update(JSHandle<SourceTextModule>::Cast(requestedVal));
}
// b. Let starNames be ? requestedModule.GetExportedNames(exportStarSet).
CVector<std::string> starNames =
@ -1076,12 +1112,17 @@ JSHandle<JSTaggedValue> SourceTextModule::GetStarResolution(JSThread *thread,
JSMutableHandle<SourceTextModule> importedModule(thread, thread->GlobalConstants()->GetUndefined());
JSTaggedValue moduleRecordName = module->GetEcmaModuleRecordName();
if (moduleRecordName.IsUndefined()) {
importedModule.Update(SourceTextModule::HostResolveImportedModule(thread, module, moduleRequest));
JSHandle<JSTaggedValue> importedVal =
SourceTextModule::HostResolveImportedModule(thread, module, moduleRequest);
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
importedModule.Update(JSHandle<SourceTextModule>::Cast(importedVal));
} else {
ASSERT(moduleRecordName.IsString());
importedModule.Update(SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, moduleRequest));
JSHandle<JSTaggedValue> importedVal =
SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, moduleRequest);
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
importedModule.Update(JSHandle<SourceTextModule>::Cast(importedVal));
}
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
// b. Let resolution be ? importedModule.ResolveExport(exportName, resolveVector).
JSHandle<JSTaggedValue> resolution =
SourceTextModule::ResolveExport(thread, importedModule, exportName, resolveVector);

View File

@ -33,10 +33,10 @@ public:
CAST_CHECK(SourceTextModule, IsSourceTextModule);
// 15.2.1.17 Runtime Semantics: HostResolveImportedModule ( referencingModule, specifier )
static JSHandle<SourceTextModule> HostResolveImportedModule(JSThread *thread,
static JSHandle<JSTaggedValue> HostResolveImportedModule(JSThread *thread,
const JSHandle<SourceTextModule> &module,
const JSHandle<JSTaggedValue> &moduleRequest);
static JSHandle<SourceTextModule> HostResolveImportedModuleWithMerge(
static JSHandle<JSTaggedValue> HostResolveImportedModuleWithMerge(
JSThread *thread, const JSHandle<SourceTextModule> &module, const JSHandle<JSTaggedValue> &moduleRequest);
// 15.2.1.16.2 GetExportedNames(exportStarSet)
@ -117,7 +117,7 @@ public:
// 15.2.1.16.4 Instantiate()
static void CJSInstantiate(JSThread *thread, const JSHandle<SourceTextModule> &module,
const JSHandle<SourceTextModule> &requiredModule);
static int Instantiate(JSThread *thread, const JSHandle<SourceTextModule> &module);
static int Instantiate(JSThread *thread, const JSHandle<JSTaggedValue> &moduleHdl);
JSTaggedValue GetModuleValue(JSThread *thread, int32_t index, bool isThrow);
void StoreModuleValue(JSThread *thread, int32_t index, const JSHandle<JSTaggedValue> &value);

View File

@ -397,7 +397,7 @@ HWTEST_F_L0(EcmaModuleTest, HostResolveImportedModule)
JSHandle<SourceTextModule> module = factory->NewSourceTextModule();
JSHandle<JSTaggedValue> moduleRecord(thread, module.GetTaggedValue());
moduleManager->AddResolveImportedModule(baseFileName.c_str(), moduleRecord);
JSHandle<SourceTextModule> res = moduleManager->HostResolveImportedModule(baseFileName.c_str());
JSHandle<JSTaggedValue> res = moduleManager->HostResolveImportedModule(baseFileName.c_str());
EXPECT_EQ(moduleRecord->GetRawData(), res.GetTaggedValue().GetRawData());
}

View File

@ -1265,8 +1265,6 @@ public:
static Local<JSValueRef> DeserializeValue(const EcmaVM *vm, void *recoder, void *hint);
static void DeleteSerializationData(void *data);
static void SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data);
static void SetHostResolvePathTracker(EcmaVM *vm,
std::function<std::string(std::string dirPath, std::string requestPath)> cb);
static void SetHostResolveBufferTracker(EcmaVM *vm, std::function<std::vector<uint8_t>(std::string dirPath)> cb);
static void SetNativePtrGetter(EcmaVM *vm, void* cb);
static void SetHostEnqueueJob(const EcmaVM* vm, Local<JSValueRef> cb);

View File

@ -583,12 +583,6 @@ void JSNApi::SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data)
vm->SetData(data);
}
void JSNApi::SetHostResolvePathTracker(EcmaVM *vm,
std::function<std::string(std::string dirPath, std::string requestPath)> cb)
{
vm->SetResolvePathCallback(cb);
}
void JSNApi::SetHostResolveBufferTracker(EcmaVM *vm, std::function<std::vector<uint8_t>(std::string dirPath)> cb)
{
vm->SetResolveBufferCallback(cb);
@ -2719,10 +2713,10 @@ bool JSNApi::InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> function)
ecmascript::CString moduleName = jsPandaFile->GetJSPandaFileDesc();
ecmascript::CString recordName = method->GetRecordName();
bool isModule = jsPandaFile->IsModule(recordName);
bool isModule = jsPandaFile->IsModule(thread, recordName);
if (isModule) {
ecmascript::ModuleManager *moduleManager = vm->GetModuleManager();
JSHandle<ecmascript::SourceTextModule> moduleRecord;
JSHandle<ecmascript::JSTaggedValue> moduleRecord;
if (jsPandaFile->IsBundlePack()) {
moduleRecord = moduleManager->HostResolveImportedModule(moduleName);
} else {
@ -2733,9 +2727,10 @@ bool JSNApi::InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> function)
vm->HandleUncaughtException(thread->GetException());
return false;
}
moduleRecord->SetStatus(ecmascript::ModuleStatus::INSTANTIATED);
ecmascript::SourceTextModule::EvaluateForConcurrent(thread, moduleRecord);
transFunc->SetModule(thread, moduleRecord);
JSHandle<ecmascript::SourceTextModule> module = JSHandle<ecmascript::SourceTextModule>::Cast(moduleRecord);
module->SetStatus(ecmascript::ModuleStatus::INSTANTIATED);
ecmascript::SourceTextModule::EvaluateForConcurrent(thread, module);
transFunc->SetModule(thread, module);
return true;
}
return false;

View File

@ -1228,22 +1228,6 @@ HWTEST_F_L0(JSNApiTests, JSNApi_SetHostPromiseRejectionTracker)
ASSERT_EQ(res, reinterpret_cast<ecmascript::PromiseRejectCallback>(data));
}
HWTEST_F_L0(JSNApiTests, JSNApi_SetHostResolvePathTracker)
{
std::string dirPath;
std::string requestPath;
using CallbackType = std::function<std::string(std::string, std::string)>;
CallbackType callback = [dirPath, requestPath](std::string dp, std::string rp) -> std::string {
dp = dirPath;
rp = requestPath;
return dp + rp;
};
JSNApi::SetHostResolvePathTracker(vm_, callback);
ResolvePathCallback res = nullptr;
res = vm_->GetResolvePathCallback();
EXPECT_TRUE(res);
}
HWTEST_F_L0(JSNApiTests, JSNApi_SetNativePtrGetter_SetHostEnqueueJob)
{
void *cb = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);

View File

@ -89,7 +89,7 @@ void PatchLoader::ParseConstpoolWithMerge(JSThread *thread, const JSPandaFile *j
for (const auto &item : patchRecordInfos) {
const CString &recordName = item.first;
vm->GetModuleManager()->HostResolveImportedModuleWithMerge(fileName, recordName);
ASSERT(!thread->HasPendingException());
if (!isNewVersion) {
PandaFileTranslator::ParseFuncAndLiteralConstPool(vm, jsPandaFile, recordName, constpool);
}
@ -357,11 +357,11 @@ bool PatchLoader::CheckIsInvalidPatch(const JSPandaFile *baseFile, const JSPanda
CString baseRecordName = patchRecordName;
ASSERT(baseRecordInfos.find(baseRecordName) != baseRecordInfos.end());
JSHandle<SourceTextModule> patchModule =
JSHandle<JSTaggedValue> patchModule =
moduleManager->ResolveModuleWithMerge(thread, patchFile, patchRecordName);
JSHandle<SourceTextModule> baseModule = moduleManager->HostGetImportedModule(baseRecordName);
if (CheckIsModuleMismatch(thread, patchModule, baseModule)) {
if (CheckIsModuleMismatch(thread, JSHandle<SourceTextModule>(patchModule), baseModule)) {
return true;
}
}

View File

@ -26,6 +26,8 @@
#include <string>
#include "ecmascript/ecma_string.h"
#include "ecmascript/js_tagged_value.h"
namespace panda::ecmascript {
#ifdef PANDA_TARGET_WINDOWS
using fd_t = HANDLE;
@ -53,5 +55,7 @@ fd_t Open(const char *file, int flag);
void Close(fd_t fd);
void *FileMmap(fd_t fd, uint64_t size, uint64_t offset, fd_t *extra);
int FileUnMap(void *addr, uint64_t size, fd_t *extra);
JSHandle<EcmaString> ResolveFilenameFromNative(JSThread *thread, JSTaggedValue dirname,
JSTaggedValue request);
} // namespace panda::ecmascript
#endif // ECMASCRIPT_PLATFORM_FILE_H

View File

@ -19,6 +19,8 @@
#include <sys/mman.h>
#include <unistd.h>
#include "ecmascript/js_tagged_value-inl.h"
#include "ecmascript/ecma_macros.h"
#include "ecmascript/log_wrapper.h"
#include "ecmascript/platform/map.h"
@ -74,4 +76,40 @@ int FileUnMap(void *addr, uint64_t size, [[maybe_unused]] fd_t *extra)
{
return munmap(addr, size);
}
JSHandle<EcmaString> ResolveFilenameFromNative(JSThread *thread, JSTaggedValue dirname,
JSTaggedValue request)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
CString fullname;
CString resolvedFilename;
CString dirnameStr = ConvertToString(EcmaString::Cast(dirname.GetTaggedObject()));
CString requestStr = ConvertToString(EcmaString::Cast(request.GetTaggedObject()));
if (requestStr.find("./") == 0) {
requestStr = requestStr.substr(2); // 2 : delete './'
}
int suffixEnd = static_cast<int>(requestStr.find_last_of('.'));
if (suffixEnd == -1) {
RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread);
}
if (requestStr[0] == '/') { // absolute FilePath
fullname = requestStr.substr(0, suffixEnd) + ".abc";
} else {
int pos = static_cast<int>(dirnameStr.find_last_of('/'));
if (pos == -1) {
RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread);
}
fullname = dirnameStr.substr(0, pos + 1) + requestStr.substr(0, suffixEnd) + ".abc";
}
std::string relativePath = ConvertToStdString(fullname);
std::string absPath = "";
if (RealPath(relativePath, absPath)) {
resolvedFilename = ConvertToString(absPath);
return factory->NewFromUtf8(resolvedFilename);
}
CString msg = "resolve absolute path fail";
THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, EcmaString, msg.c_str());
}
} // namespace panda::ecmascript

View File

@ -23,6 +23,17 @@
#undef ERROR
#endif
#ifdef VOID
#undef VOID
#endif
#ifdef CONST
#undef CONST
#endif
#include "ecmascript/ecma_macros.h"
#include "ecmascript/ecma_string.h"
#include "ecmascript/js_tagged_value-inl.h"
#include "ecmascript/log_wrapper.h"
#include "ecmascript/platform/map.h"
@ -97,4 +108,36 @@ int FileUnMap(void *addr, [[maybe_unused]] uint64_t size, fd_t *extra)
}
return FILE_SUCCESS;
}
JSHandle<EcmaString> ResolveFilenameFromNative(JSThread *thread, JSTaggedValue dirname,
JSTaggedValue request)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
CString fullname;
CString resolvedFilename;
CString dirnameStr = ConvertToString(EcmaString::Cast(dirname.GetTaggedObject()));
CString requestStr = ConvertToString(EcmaString::Cast(request.GetTaggedObject()));
int suffixEnd = static_cast<int>(requestStr.find_last_of('.'));
if (suffixEnd == -1) {
RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread);
}
if (requestStr[1] == ':') { // absoluteFilePath
fullname = requestStr.substr(0, suffixEnd) + ".abc";
} else {
int pos = static_cast<int>(dirnameStr.find_last_of('\\'));
if (pos == -1) {
RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread);
}
fullname = dirnameStr.substr(0, pos + 1) + requestStr.substr(0, suffixEnd) + ".abc";
}
std::string relativePath = ConvertToStdString(fullname);
std::string absPath = "";
if (RealPath(relativePath, absPath)) {
resolvedFilename = ConvertToString(absPath);
return factory->NewFromUtf8(resolvedFilename);
}
CString msg = "resolve absolute path fail";
THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, EcmaString, msg.c_str());
}
} // namespace panda::ecmascript

View File

@ -22,6 +22,14 @@
#undef ERROR
#endif
#ifdef VOID
#undef VOID
#endif
#ifdef CONST
#undef CONST
#endif
#include "ecmascript/log_wrapper.h"
#include "ecmascript/mem/mem.h"

View File

@ -16,9 +16,11 @@
#include "ecmascript/require/js_cjs_module.h"
#include "ecmascript/aot_file_manager.h"
#include "ecmascript/base/path_helper.h"
#include "ecmascript/builtins/builtins_json.h"
#include "ecmascript/interpreter/interpreter-inl.h"
#include "ecmascript/interpreter/slow_runtime_stub.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/require/js_cjs_module_cache.h"
#include "ecmascript/require/js_require_manager.h"
#include "ecmascript/jspandafile/js_pandafile.h"
@ -28,6 +30,7 @@
namespace panda::ecmascript {
using BuiltinsJson = builtins::BuiltinsJson;
using PathHelper = base::PathHelper;
void CjsModule::InitializeModule(JSThread *thread, JSHandle<CjsModule> &module,
JSHandle<JSTaggedValue> &filename, JSHandle<JSTaggedValue> &dirname)
{
@ -102,9 +105,10 @@ JSHandle<JSTaggedValue> CjsModule::Load(JSThread *thread, JSHandle<EcmaString> &
JSMutableHandle<JSTaggedValue> filename(thread, JSTaggedValue::Undefined());
if (jsPandaFile->IsBundlePack()) {
RequireManager::ResolveCurrentPath(thread, parent, dirname, jsPandaFile);
PathHelper::ResolveCurrentPath(thread, parent, dirname, jsPandaFile);
filename.Update(ResolveFilenameFromNative(thread, dirname.GetTaggedValue(),
request.GetTaggedValue()));
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
mergedFilename = ConvertToString(filename.GetTaggedValue());
} else {
CString currentEntryPoint = ConvertToString(entrypointVal.GetTaggedValue());
@ -123,7 +127,7 @@ JSHandle<JSTaggedValue> CjsModule::Load(JSThread *thread, JSHandle<EcmaString> &
// Don't get required exports from cache, execute required JSPandaFile.
// module = new Module(), which belongs to required JSPandaFile.
JSHandle<CjsModule> module = factory->NewCjsModule();
RequireManager::ResolveDirPath(thread, dirname, filename);
dirname.Update(PathHelper::ResolveDirPath(thread, filename));
InitializeModule(thread, module, filename, dirname);
PutIntoCache(thread, module, filename);
@ -138,7 +142,10 @@ JSHandle<JSTaggedValue> CjsModule::Load(JSThread *thread, JSHandle<EcmaString> &
}
// Execute required JSPandaFile
RequireExecution(thread, mergedFilename, requestEntryPoint);
if (thread->HasPendingException()) {
thread->GetEcmaVM()->HandleUncaughtException(thread->GetException());
return thread->GlobalConstants()->GetHandledUndefined();
}
// Search from Module.cache after execution.
JSHandle<JSTaggedValue> cachedExports = SearchFromModuleCache(thread, filename);
if (cachedExports->IsHole()) {
@ -153,61 +160,13 @@ void CjsModule::RequireExecution(JSThread *thread, CString mergedFilename, CStri
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, mergedFilename, requestEntryPoint);
if (jsPandaFile == nullptr) {
LOG_ECMA(FATAL) << "open jsPandaFile : " << mergedFilename <<
" , record name : " << requestEntryPoint << " error";
UNREACHABLE();
LOG_ECMA(ERROR) << "Try to load cjs module " << requestEntryPoint << " in abc : " << mergedFilename;
CString msg = "Faild to load file '" + requestEntryPoint + "', please check the request path.";
THROW_ERROR(thread, ErrorType::REFERENCE_ERROR, msg.c_str());
}
JSPandaFileExecutor::Execute(thread, jsPandaFile, requestEntryPoint);
}
JSHandle<EcmaString> CjsModule::ResolveFilename(JSThread *thread, JSTaggedValue dirname, JSTaggedValue request)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
ResolvePathCallback resolvePathCallback = thread->GetEcmaVM()->GetResolvePathCallback();
if (resolvePathCallback == nullptr) {
JSHandle<EcmaString> nativeRequireName = ResolveFilenameFromNative(thread, dirname, request);
return nativeRequireName;
}
std::string modDirname = std::string(ConvertToString(EcmaString::Cast(dirname.GetTaggedObject())));
std::string modFile = std::string(ConvertToString(EcmaString::Cast(request.GetTaggedObject())));
std::string callbackRequireName = resolvePathCallback(modDirname, modFile);
CString fullname = callbackRequireName.c_str();
return factory->NewFromUtf8(fullname);
}
JSHandle<EcmaString> CjsModule::ResolveFilenameFromNative(JSThread *thread, JSTaggedValue dirname,
JSTaggedValue request)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
CString dirnameStr = ConvertToString(EcmaString::Cast(dirname.GetTaggedObject()));
CString requestStr = ConvertToString(EcmaString::Cast(request.GetTaggedObject()));
if (requestStr.find("./") == 0) {
requestStr = requestStr.substr(2); // 2 : delete './'
}
int suffixEnd = static_cast<int>(requestStr.find_last_of('.'));
if (suffixEnd == -1) {
RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread);
}
CString fullname;
CString res;
if (requestStr[0] == '/') { // absolute FilePath
fullname = requestStr.substr(0, suffixEnd) + ".abc";
} else {
int pos = static_cast<int>(dirnameStr.find_last_of('/'));
if (pos == -1) {
RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread);
}
fullname = dirnameStr.substr(0, pos + 1) + requestStr.substr(0, suffixEnd) + ".abc";
}
if (!AOTFileManager::GetAbsolutePath(fullname, res)) {
LOG_FULL(FATAL) << "resolve absolute path fail";
}
return factory->NewFromUtf8(res);
}
JSTaggedValue CjsModule::Require(JSThread *thread, JSHandle<EcmaString> &request,
[[maybe_unused]] JSHandle<CjsModule> &parent,
[[maybe_unused]] bool isMain)

View File

@ -54,11 +54,6 @@ public:
static JSTaggedValue Require(JSThread *thread, JSHandle<EcmaString> &request, JSHandle<CjsModule> &parent,
bool isMain);
static JSHandle<EcmaString> ResolveFilename(JSThread *thread, JSTaggedValue dirname, JSTaggedValue filename);
static JSHandle<EcmaString> ResolveFilenameFromNative(JSThread *thread, JSTaggedValue dirname,
JSTaggedValue request);
static void RequireExecution(JSThread *thread, CString mergedFilename, CString requestEntryPoint);
};
} // namespace panda::ecmascript

View File

@ -22,42 +22,6 @@
#include "ecmascript/ecma_string.h"
namespace panda::ecmascript {
void RequireManager::ResolveCurrentPath(JSThread *thread,
JSMutableHandle<JSTaggedValue> &dirPath,
JSMutableHandle<JSTaggedValue> &fileName,
const JSPandaFile *jsPandaFile)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
CString fullName = jsPandaFile->GetJSPandaFileDesc();
// find last '/'
int foundPos = static_cast<int>(fullName.find_last_of("/\\"));
if (foundPos == -1) {
RETURN_IF_ABRUPT_COMPLETION(thread);
}
CString dirPathStr = fullName.substr(0, foundPos + 1);
JSHandle<EcmaString> dirPathName = factory->NewFromUtf8(dirPathStr);
dirPath.Update(dirPathName.GetTaggedValue());
// Get filename from JSPandaFile
JSHandle<EcmaString> cbFileName = factory->NewFromUtf8(fullName);
fileName.Update(cbFileName.GetTaggedValue());
}
void RequireManager::ResolveDirPath(JSThread *thread,
JSMutableHandle<JSTaggedValue> &dirPath,
JSHandle<JSTaggedValue> &fileName)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
CString fullName = ConvertToString(fileName.GetTaggedValue());
// find last '/'
int foundPos = static_cast<int>(fullName.find_last_of("/\\"));
if (foundPos == -1) {
RETURN_IF_ABRUPT_COMPLETION(thread);
}
CString dirPathStr = fullName.substr(0, foundPos + 1);
dirPath.Update((factory->NewFromUtf8(dirPathStr)).GetTaggedValue());
}
void RequireManager::InitializeCommonJS(JSThread *thread, CJSInfo cjsInfo)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();

View File

@ -39,13 +39,6 @@ struct CJSInfo {
};
class RequireManager {
public:
static void ResolveCurrentPath(JSThread *thread, JSMutableHandle<JSTaggedValue> &dirPath,
JSMutableHandle<JSTaggedValue> &file,
const JSPandaFile *jsPandaFile);
static void ResolveDirPath(JSThread *thread, JSMutableHandle<JSTaggedValue> &dirPath,
JSHandle<JSTaggedValue> &file);
static void InitializeCommonJS(JSThread *thread, CJSInfo cjsInfo);
static void CollectExecutedExp(JSThread *thread, CJSInfo cjsInfo);

View File

@ -212,7 +212,6 @@ group("fuzztest") {
"jsnapideleteserializationdata_fuzzer:fuzztest",
"jsnapideserializevalue_fuzzer:fuzztest",
"jsnapisethostpromiserejectiontracker_fuzzer:fuzztest",
"jsnapisethostresolvepathtracker_fuzzer:fuzztest",
"jsnapistartdebugger_fuzzer:fuzztest",
"jsonparse_fuzzer:fuzztest",
"jsonstringify_fuzzer:fuzztest",

View File

@ -1,40 +0,0 @@
# Copyright (c) 2022 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.
#####################################hydra-fuzz###############################
import("//arkcompiler/ets_runtime/js_runtime_config.gni")
import("//arkcompiler/ets_runtime/test/test_helper.gni")
import("//build/config/features.gni")
import("//build/ohos.gni")
####################################fuzztest##################################
ohos_fuzztest("JSNApiSetHostResolvePathTrackerFuzzTest") {
module_out_path = "arkcompiler/ets_runtime"
fuzz_config_file = "//arkcompiler/ets_runtime/test/fuzztest/jsnapisethostresolvepathtracker_fuzzer"
sources = [ "jsnapisethostresolvepathtracker_fuzzer.cpp" ]
configs = [ "//arkcompiler/ets_runtime:ecma_test_config" ]
deps = [
"//arkcompiler/ets_runtime:libark_jsruntime",
sdk_libc_secshared_dep,
]
}
group("fuzztest") {
testonly = true
deps = []
deps += [ ":JSNApiSetHostResolvePathTrackerFuzzTest" ]
}

View File

@ -1,14 +0,0 @@
# Copyright (c) 2021 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.
FUZZ

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2022 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 "jsnapisethostresolvepathtracker_fuzzer.h"
#include "ecmascript/napi/include/jsnapi.h"
using namespace panda;
using namespace panda::ecmascript;
namespace OHOS {
void JSNApiSetHostResolvePathTrackerFuzzTest(const uint8_t* data, size_t size)
{
RuntimeOption option;
option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
EcmaVM *vm = JSNApi::CreateJSVM(option);
if (size <= 0) {
return;
}
std::string dirPath(data, data + size);
std::string requestPath(data, data + size);
using CallbackType = std::function<std::string(std::string, std::string)>;
CallbackType callback = [dirPath, requestPath](std::string dp, std::string rp) -> std::string {
dp = dirPath;
rp = requestPath;
return dp + rp;
};
JSNApi::SetHostResolvePathTracker(vm, callback);
JSNApi::DestroyJSVM(vm);
}
}
// Fuzzer entry point.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
// Run your code on data.
OHOS::JSNApiSetHostResolvePathTrackerFuzzTest(data, size);
return 0;
}

View File

@ -1,21 +0,0 @@
/*
* Copyright (c) 2022 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.
*/
#ifndef JSNAPISETHOSTRESOLVEPATHTRACKER_FUZZER_H
#define JSNAPISETHOSTRESOLVEPATHTRACKER_FUZZER_H
#define FUZZ_PROJECT_NAME "jsnapisethostresolvepathtracker_fuzzer.h"
#endif

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2022 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.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>