2021-09-04 08:06:49 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ecmascript/ecma_vm.h"
|
|
|
|
|
|
|
|
#include "ecmascript/base/string_helper.h"
|
|
|
|
#include "ecmascript/builtins.h"
|
|
|
|
#include "ecmascript/builtins/builtins_regexp.h"
|
|
|
|
#include "ecmascript/class_linker/panda_file_translator.h"
|
|
|
|
#include "ecmascript/class_linker/program_object-inl.h"
|
2022-02-26 03:08:37 +00:00
|
|
|
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
2021-12-17 09:18:10 +00:00
|
|
|
#include "ecmascript/cpu_profiler/cpu_profiler.h"
|
2022-02-26 03:08:37 +00:00
|
|
|
#endif
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/ecma_module.h"
|
|
|
|
#include "ecmascript/ecma_string_table.h"
|
2021-10-12 08:57:22 +00:00
|
|
|
#include "ecmascript/global_dictionary.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/global_env.h"
|
|
|
|
#include "ecmascript/global_env_constants-inl.h"
|
|
|
|
#include "ecmascript/global_env_constants.h"
|
2021-09-07 14:24:16 +00:00
|
|
|
#include "ecmascript/internal_call_params.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/jobs/micro_job_queue.h"
|
2022-02-06 15:16:08 +00:00
|
|
|
#include "ecmascript/jspandafile/js_pandafile.h"
|
|
|
|
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/js_arraybuffer.h"
|
|
|
|
#include "ecmascript/js_for_in_iterator.h"
|
|
|
|
#include "ecmascript/js_invoker.h"
|
2021-12-16 03:41:16 +00:00
|
|
|
#include "ecmascript/js_native_pointer.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/js_thread.h"
|
2021-12-17 09:18:10 +00:00
|
|
|
#include "ecmascript/mem/concurrent_marker.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/mem/heap.h"
|
|
|
|
#include "ecmascript/object_factory.h"
|
2021-09-24 06:31:54 +00:00
|
|
|
#include "ecmascript/platform/platform.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/regexp/regexp_parser_cache.h"
|
|
|
|
#include "ecmascript/runtime_call_id.h"
|
2022-02-26 03:08:37 +00:00
|
|
|
#ifndef PANDA_TARGET_WINDOWS
|
2021-09-07 14:24:16 +00:00
|
|
|
#include "ecmascript/runtime_trampolines.h"
|
2022-02-26 03:08:37 +00:00
|
|
|
#endif
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/snapshot/mem/slot_bit.h"
|
|
|
|
#include "ecmascript/snapshot/mem/snapshot.h"
|
|
|
|
#include "ecmascript/snapshot/mem/snapshot_serialize.h"
|
|
|
|
#include "ecmascript/symbol_table.h"
|
|
|
|
#include "ecmascript/tagged_array-inl.h"
|
2021-12-17 09:18:10 +00:00
|
|
|
#include "ecmascript/tagged_dictionary.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/tagged_queue-inl.h"
|
|
|
|
#include "ecmascript/tagged_queue.h"
|
|
|
|
#include "ecmascript/template_map.h"
|
2022-02-22 08:50:20 +00:00
|
|
|
#include "ecmascript/ts_types/ts_loader.h"
|
|
|
|
#include "ecmascript/vmstat/runtime_stat.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "include/runtime_notification.h"
|
|
|
|
#include "libpandafile/file.h"
|
2022-02-26 03:08:37 +00:00
|
|
|
#ifdef PANDA_TARGET_WINDOWS
|
|
|
|
#include <shlwapi.h>
|
|
|
|
#ifdef ERROR
|
|
|
|
#undef ERROR
|
|
|
|
#endif
|
|
|
|
#ifdef GetObject
|
|
|
|
#undef GetObject
|
|
|
|
#endif
|
|
|
|
#endif
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
namespace panda::ecmascript {
|
|
|
|
// NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
|
|
|
|
static const std::string_view ENTRY_POINTER = "_GLOBAL::func_main_0";
|
2021-10-19 03:55:00 +00:00
|
|
|
JSRuntimeOptions EcmaVM::options_; // NOLINT(fuchsia-statically-constructed-objects)
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
/* static */
|
2021-10-19 03:55:00 +00:00
|
|
|
EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
|
|
|
auto runtime = Runtime::GetCurrent();
|
|
|
|
auto vm = runtime->GetInternalAllocator()->New<EcmaVM>(options);
|
|
|
|
if (UNLIKELY(vm == nullptr)) {
|
|
|
|
LOG_ECMA(ERROR) << "Failed to create jsvm";
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
auto jsThread = JSThread::Create(runtime, vm);
|
|
|
|
vm->thread_ = jsThread;
|
|
|
|
vm->Initialize();
|
|
|
|
return vm;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
bool EcmaVM::Destroy(PandaVM *vm)
|
|
|
|
{
|
|
|
|
if (vm != nullptr) {
|
|
|
|
auto runtime = Runtime::GetCurrent();
|
|
|
|
runtime->GetInternalAllocator()->Delete(vm);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
Expected<EcmaVM *, CString> EcmaVM::Create(Runtime *runtime)
|
|
|
|
{
|
|
|
|
EcmaVM *vm = runtime->GetInternalAllocator()->New<EcmaVM>();
|
|
|
|
auto jsThread = ecmascript::JSThread::Create(runtime, vm);
|
|
|
|
vm->thread_ = jsThread;
|
|
|
|
return vm;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
2021-10-19 03:55:00 +00:00
|
|
|
EcmaVM::EcmaVM() : EcmaVM(EcmaVM::GetJSOptions())
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
|
|
|
isTestMode_ = true;
|
|
|
|
}
|
|
|
|
|
2021-10-19 03:55:00 +00:00
|
|
|
EcmaVM::EcmaVM(JSRuntimeOptions options)
|
|
|
|
: stringTable_(new EcmaStringTable(this)),
|
2022-02-17 07:11:23 +00:00
|
|
|
nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()),
|
|
|
|
heapRegionAllocator_(std::make_unique<HeapRegionAllocator>()),
|
|
|
|
chunk_(nativeAreaAllocator_.get()),
|
|
|
|
arrayBufferDataList_(&chunk_),
|
|
|
|
frameworkProgramMethods_(&chunk_),
|
2022-02-28 07:04:37 +00:00
|
|
|
nativeMethods_(&chunk_)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2021-10-19 03:55:00 +00:00
|
|
|
options_ = std::move(options);
|
2021-09-04 08:06:49 +00:00
|
|
|
icEnable_ = options_.IsIcEnable();
|
2022-01-07 09:36:04 +00:00
|
|
|
optionalLogEnabled_ = options_.IsEnableOptionalLog();
|
2021-09-04 08:06:49 +00:00
|
|
|
rendezvous_ = chunk_.New<EmptyRendezvous>();
|
|
|
|
snapshotSerializeEnable_ = options_.IsSnapshotSerializeEnabled();
|
|
|
|
if (!snapshotSerializeEnable_) {
|
|
|
|
snapshotDeserializeEnable_ = options_.IsSnapshotDeserializeEnabled();
|
|
|
|
}
|
2022-01-13 08:26:00 +00:00
|
|
|
snapshotFileName_ = options_.GetSnapshotFile();
|
2021-09-04 08:06:49 +00:00
|
|
|
frameworkAbcFileName_ = options_.GetFrameworkAbcFile();
|
2021-10-18 08:54:11 +00:00
|
|
|
|
|
|
|
auto runtime = Runtime::GetCurrent();
|
|
|
|
notificationManager_ = chunk_.New<RuntimeNotificationManager>(runtime->GetInternalAllocator());
|
|
|
|
notificationManager_->SetRendezvous(rendezvous_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool EcmaVM::Initialize()
|
|
|
|
{
|
2022-01-20 11:11:24 +00:00
|
|
|
ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "EcmaVM::Initialize");
|
2021-09-24 06:31:54 +00:00
|
|
|
Platform::GetCurrentPlatform()->Initialize();
|
2022-02-26 03:08:37 +00:00
|
|
|
#ifndef PANDA_TARGET_WINDOWS
|
2021-10-26 10:52:26 +00:00
|
|
|
RuntimeTrampolines::InitializeRuntimeTrampolines(thread_);
|
2022-02-26 03:08:37 +00:00
|
|
|
#endif
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
auto globalConst = const_cast<GlobalEnvConstants *>(thread_->GlobalConstants());
|
|
|
|
regExpParserCache_ = new RegExpParserCache();
|
|
|
|
heap_ = new Heap(this);
|
2021-09-07 14:24:16 +00:00
|
|
|
heap_->Initialize();
|
|
|
|
gcStats_ = chunk_.New<GCStats>(heap_);
|
2021-09-04 08:06:49 +00:00
|
|
|
factory_ = chunk_.New<ObjectFactory>(thread_, heap_);
|
|
|
|
if (UNLIKELY(factory_ == nullptr)) {
|
|
|
|
LOG_ECMA(FATAL) << "alloc factory_ failed";
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
2021-12-17 09:18:10 +00:00
|
|
|
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
2022-01-13 08:26:00 +00:00
|
|
|
if (!snapshotDeserializeEnable_ || !VerifyFilePath(snapshotFileName_)) {
|
2021-09-04 08:06:49 +00:00
|
|
|
LOG_ECMA(DEBUG) << "EcmaVM::Initialize run builtins";
|
|
|
|
|
2021-12-17 09:18:10 +00:00
|
|
|
JSHandle<JSHClass> dynClassClassHandle =
|
|
|
|
factory_->NewEcmaDynClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS);
|
2021-09-04 08:06:49 +00:00
|
|
|
JSHClass *dynclass = reinterpret_cast<JSHClass *>(dynClassClassHandle.GetTaggedValue().GetTaggedObject());
|
|
|
|
dynclass->SetClass(dynclass);
|
|
|
|
JSHandle<JSHClass> globalEnvClass =
|
|
|
|
factory_->NewEcmaDynClass(*dynClassClassHandle, GlobalEnv::SIZE, JSType::GLOBAL_ENV);
|
|
|
|
|
|
|
|
JSHandle<GlobalEnv> globalEnvHandle = factory_->NewGlobalEnv(*globalEnvClass);
|
|
|
|
globalEnv_ = globalEnvHandle.GetTaggedValue();
|
|
|
|
auto globalEnv = GlobalEnv::Cast(globalEnv_.GetTaggedObject());
|
|
|
|
|
|
|
|
// init global env
|
|
|
|
globalConst->InitRootsClass(thread_, *dynClassClassHandle);
|
|
|
|
globalConst->InitGlobalConstant(thread_);
|
|
|
|
globalEnv->SetEmptyArray(thread_, factory_->NewEmptyArray());
|
|
|
|
globalEnv->SetEmptyLayoutInfo(thread_, factory_->CreateLayoutInfo(0));
|
2021-12-17 09:18:10 +00:00
|
|
|
globalEnv->SetRegisterSymbols(thread_, SymbolTable::Create(thread_));
|
|
|
|
globalEnv->SetGlobalRecord(thread_, GlobalDictionary::Create(thread_));
|
2021-09-04 08:06:49 +00:00
|
|
|
JSTaggedValue emptyStr = thread_->GlobalConstants()->GetEmptyString();
|
|
|
|
stringTable_->InternEmptyString(EcmaString::Cast(emptyStr.GetTaggedObject()));
|
|
|
|
globalEnv->SetEmptyTaggedQueue(thread_, factory_->NewTaggedQueue(0));
|
2021-12-17 09:18:10 +00:00
|
|
|
globalEnv->SetTemplateMap(thread_, TemplateMap::Create(thread_));
|
|
|
|
globalEnv->SetRegisterSymbols(GetJSThread(), SymbolTable::Create(GetJSThread()));
|
2021-10-25 12:50:39 +00:00
|
|
|
#ifdef ECMASCRIPT_ENABLE_STUB_AOT
|
2021-10-16 10:06:22 +00:00
|
|
|
std::string moduleFile = options_.GetStubModuleFile();
|
2022-02-19 02:09:52 +00:00
|
|
|
thread_->LoadStubModule(moduleFile.c_str());
|
2021-10-25 12:50:39 +00:00
|
|
|
#endif
|
2021-09-04 08:06:49 +00:00
|
|
|
SetupRegExpResultCache();
|
|
|
|
microJobQueue_ = factory_->NewMicroJobQueue().GetTaggedValue();
|
|
|
|
{
|
|
|
|
Builtins builtins;
|
|
|
|
builtins.Initialize(globalEnvHandle, thread_);
|
|
|
|
}
|
|
|
|
} else {
|
2022-02-26 03:08:37 +00:00
|
|
|
#if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
|
2021-09-04 08:06:49 +00:00
|
|
|
LOG_ECMA(DEBUG) << "EcmaVM::Initialize run snapshot";
|
|
|
|
SnapShot snapShot(this);
|
2022-01-13 08:26:00 +00:00
|
|
|
std::unique_ptr<const panda_file::File> pf = snapShot.DeserializeGlobalEnvAndProgram(snapshotFileName_);
|
2022-02-28 07:04:37 +00:00
|
|
|
frameworkPandaFile_ = GetJSPandaFileManager()->CreateJSPandaFile(pf.release(), frameworkAbcFileName_);
|
2021-09-04 08:06:49 +00:00
|
|
|
globalConst->InitGlobalUndefined();
|
2022-02-26 03:08:37 +00:00
|
|
|
#endif
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
thread_->SetGlobalObject(GetGlobalEnv()->GetGlobalObject());
|
2021-09-04 08:06:49 +00:00
|
|
|
moduleManager_ = new ModuleManager(this);
|
2022-02-22 08:50:20 +00:00
|
|
|
tsLoader_ = new TSLoader(this);
|
2021-09-04 08:06:49 +00:00
|
|
|
InitializeFinish();
|
2021-10-18 08:54:11 +00:00
|
|
|
notificationManager_->VmStartEvent();
|
2022-01-12 07:43:56 +00:00
|
|
|
notificationManager_->VmInitializationEvent(thread_->GetThreadId());
|
2021-12-17 09:18:10 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-02-28 07:04:37 +00:00
|
|
|
JSPandaFileManager *EcmaVM::GetJSPandaFileManager()
|
|
|
|
{
|
|
|
|
static JSPandaFileManager jsFileManager;
|
|
|
|
return &jsFileManager;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
void EcmaVM::InitializeEcmaScriptRunStat()
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
|
|
|
static const char *runtimeCallerNames[] = {
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
2022-02-09 08:48:39 +00:00
|
|
|
#define INTERPRETER_CALLER_NAME(name) "Interpreter::" #name,
|
|
|
|
INTERPRETER_CALLER_LIST(INTERPRETER_CALLER_NAME) // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
|
2021-09-04 08:06:49 +00:00
|
|
|
#undef INTERPRETER_CALLER_NAME
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
|
|
#define BUILTINS_API_NAME(class, name) "BuiltinsApi::" #class "_" #name,
|
2022-02-09 08:48:39 +00:00
|
|
|
BUITINS_API_LIST(BUILTINS_API_NAME)
|
2021-09-04 08:06:49 +00:00
|
|
|
#undef BUILTINS_API_NAME
|
|
|
|
#define ABSTRACT_OPERATION_NAME(class, name) "AbstractOperation::" #class "_" #name,
|
2022-02-09 08:48:39 +00:00
|
|
|
ABSTRACT_OPERATION_LIST(ABSTRACT_OPERATION_NAME)
|
2021-09-04 08:06:49 +00:00
|
|
|
#undef ABSTRACT_OPERATION_NAME
|
2022-02-09 08:48:39 +00:00
|
|
|
#define MEM_ALLOCATE_AND_GC_NAME(name) "Memory::" #name,
|
|
|
|
MEM_ALLOCATE_AND_GC_LIST(MEM_ALLOCATE_AND_GC_NAME)
|
|
|
|
#undef MEM_ALLOCATE_AND_GC_NAME
|
2021-09-04 08:06:49 +00:00
|
|
|
};
|
2022-01-16 07:30:39 +00:00
|
|
|
static_assert(sizeof(runtimeCallerNames) == sizeof(const char *) * ecmascript::RUNTIME_CALLER_NUMBER,
|
|
|
|
"Invalid runtime caller number");
|
2021-09-04 08:06:49 +00:00
|
|
|
runtimeStat_ = chunk_.New<EcmaRuntimeStat>(runtimeCallerNames, ecmascript::RUNTIME_CALLER_NUMBER);
|
|
|
|
if (UNLIKELY(runtimeStat_ == nullptr)) {
|
|
|
|
LOG_ECMA(FATAL) << "alloc runtimeStat_ failed";
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::SetRuntimeStatEnable(bool flag)
|
|
|
|
{
|
|
|
|
if (flag) {
|
|
|
|
if (runtimeStat_ == nullptr) {
|
|
|
|
InitializeEcmaScriptRunStat();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (runtimeStatEnabled_) {
|
|
|
|
runtimeStat_->Print();
|
|
|
|
runtimeStat_->ResetAllCount();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
runtimeStatEnabled_ = flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EcmaVM::InitializeFinish()
|
|
|
|
{
|
|
|
|
vmInitialized_ = true;
|
|
|
|
return true;
|
|
|
|
}
|
2022-01-12 07:43:56 +00:00
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
EcmaVM::~EcmaVM()
|
|
|
|
{
|
|
|
|
vmInitialized_ = false;
|
2021-12-17 09:18:10 +00:00
|
|
|
Platform::GetCurrentPlatform()->Destroy();
|
2021-09-04 08:06:49 +00:00
|
|
|
ClearNativeMethodsData();
|
|
|
|
|
|
|
|
if (runtimeStat_ != nullptr && runtimeStatEnabled_) {
|
|
|
|
runtimeStat_->Print();
|
|
|
|
}
|
|
|
|
|
|
|
|
// clear c_address: c++ pointer delete
|
|
|
|
ClearBufferData();
|
|
|
|
|
2021-09-07 14:24:16 +00:00
|
|
|
if (gcStats_ != nullptr) {
|
2022-01-07 09:36:04 +00:00
|
|
|
if (options_.IsEnableGCStatsPrint()) {
|
|
|
|
gcStats_->PrintStatisticResult(true);
|
|
|
|
}
|
2021-09-07 14:24:16 +00:00
|
|
|
chunk_.Delete(gcStats_);
|
|
|
|
gcStats_ = nullptr;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
if (heap_ != nullptr) {
|
2021-09-07 14:24:16 +00:00
|
|
|
heap_->Destroy();
|
2021-09-04 08:06:49 +00:00
|
|
|
delete heap_;
|
|
|
|
heap_ = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete regExpParserCache_;
|
|
|
|
regExpParserCache_ = nullptr;
|
|
|
|
|
2021-10-18 08:54:11 +00:00
|
|
|
if (notificationManager_ != nullptr) {
|
|
|
|
chunk_.Delete(notificationManager_);
|
|
|
|
notificationManager_ = nullptr;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
if (factory_ != nullptr) {
|
|
|
|
chunk_.Delete(factory_);
|
|
|
|
factory_ = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stringTable_ != nullptr) {
|
|
|
|
delete stringTable_;
|
|
|
|
stringTable_ = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (runtimeStat_ != nullptr) {
|
|
|
|
chunk_.Delete(runtimeStat_);
|
|
|
|
runtimeStat_ = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (moduleManager_ != nullptr) {
|
|
|
|
delete moduleManager_;
|
|
|
|
moduleManager_ = nullptr;
|
|
|
|
}
|
|
|
|
|
2022-02-22 08:50:20 +00:00
|
|
|
if (tsLoader_ != nullptr) {
|
|
|
|
delete tsLoader_;
|
|
|
|
tsLoader_ = nullptr;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
if (thread_ != nullptr) {
|
|
|
|
delete thread_;
|
|
|
|
thread_ = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
frameworkProgramMethods_.clear();
|
|
|
|
}
|
|
|
|
|
2022-02-06 15:16:08 +00:00
|
|
|
bool EcmaVM::ExecuteFromPf(const std::string &filename, std::string_view entryPoint,
|
|
|
|
const std::vector<std::string> &args, bool isModule)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-02-06 15:16:08 +00:00
|
|
|
const JSPandaFile *jsPandaFile = nullptr;
|
2021-09-04 08:06:49 +00:00
|
|
|
if (frameworkPandaFile_ == nullptr || !IsFrameworkPandaFile(filename)) {
|
2022-02-28 07:04:37 +00:00
|
|
|
jsPandaFile = GetJSPandaFileManager()->LoadPfAbc(filename);
|
2022-02-06 15:16:08 +00:00
|
|
|
if (jsPandaFile == nullptr) {
|
2021-09-04 08:06:49 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
2022-02-06 15:16:08 +00:00
|
|
|
jsPandaFile = frameworkPandaFile_;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2022-02-06 15:16:08 +00:00
|
|
|
return Execute(jsPandaFile, entryPoint, args);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-02-28 07:04:37 +00:00
|
|
|
bool EcmaVM::CollectInfoOfPandaFile(const std::string &filename, std::string_view entryPoint,
|
|
|
|
std::vector<BytecodeTranslationInfo> *infoList, const panda_file::File *&pf)
|
2022-01-22 11:09:02 +00:00
|
|
|
{
|
2022-02-28 07:04:37 +00:00
|
|
|
const JSPandaFile *jsPandaFile;
|
2022-01-22 11:09:02 +00:00
|
|
|
if (frameworkPandaFile_ == nullptr || !IsFrameworkPandaFile(filename)) {
|
2022-02-28 07:04:37 +00:00
|
|
|
jsPandaFile = GetJSPandaFileManager()->LoadPfAbc(filename);
|
|
|
|
if (jsPandaFile == nullptr) {
|
2022-01-22 11:09:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
2022-02-28 07:04:37 +00:00
|
|
|
} else {
|
|
|
|
jsPandaFile = frameworkPandaFile_;
|
2022-01-22 11:09:02 +00:00
|
|
|
}
|
2022-02-28 07:04:37 +00:00
|
|
|
|
2022-01-22 11:09:02 +00:00
|
|
|
// Get ClassName and MethodName
|
|
|
|
size_t pos = entryPoint.find_last_of("::");
|
|
|
|
if (pos == std::string_view::npos) {
|
|
|
|
LOG_ECMA(ERROR) << "EntryPoint:" << entryPoint << " is illegal";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
CString methodName(entryPoint.substr(pos + 1));
|
2022-02-28 07:04:37 +00:00
|
|
|
|
|
|
|
PandaFileTranslator translator(this, jsPandaFile);
|
|
|
|
translator.TranslateAndCollectPandaFile(methodName, infoList);
|
2022-01-22 11:09:02 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
bool EcmaVM::ExecuteFromBuffer(const void *buffer, size_t size, std::string_view entryPoint,
|
2022-02-06 15:16:08 +00:00
|
|
|
const std::vector<std::string> &args, const std::string &filename)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-02-06 15:16:08 +00:00
|
|
|
// Get ClassName and MethodName
|
|
|
|
size_t pos = entryPoint.find_last_of("::");
|
|
|
|
if (pos == std::string_view::npos) {
|
|
|
|
LOG_ECMA(ERROR) << "EntryPoint:" << entryPoint << " is illegal";
|
2021-09-04 08:06:49 +00:00
|
|
|
return false;
|
|
|
|
}
|
2022-02-06 15:16:08 +00:00
|
|
|
CString methodName(entryPoint.substr(pos + 1));
|
2022-02-28 07:04:37 +00:00
|
|
|
const JSPandaFile *jsPandaFile = GetJSPandaFileManager()->LoadBufferAbc(filename, buffer, size);
|
2022-02-06 15:16:08 +00:00
|
|
|
if (jsPandaFile == nullptr) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
InvokeEcmaEntrypoint(jsPandaFile, methodName, args);
|
|
|
|
return true;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tooling::ecmascript::PtJSExtractor *EcmaVM::GetDebugInfoExtractor(const panda_file::File *file)
|
|
|
|
{
|
2022-02-28 07:04:37 +00:00
|
|
|
tooling::ecmascript::PtJSExtractor *res = GetJSPandaFileManager()->GetOrCreatePtJSExtractor(file);
|
2021-09-04 08:06:49 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-02-06 15:16:08 +00:00
|
|
|
bool EcmaVM::Execute(const JSPandaFile *jsPandaFile, std::string_view entryPoint, const std::vector<std::string> &args)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
|
|
|
// Get ClassName and MethodName
|
|
|
|
size_t pos = entryPoint.find_last_of("::");
|
|
|
|
if (pos == std::string_view::npos) {
|
|
|
|
LOG_ECMA(ERROR) << "EntryPoint:" << entryPoint << " is illegal";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
CString methodName(entryPoint.substr(pos + 1));
|
|
|
|
// For Ark application startup
|
2022-02-06 15:16:08 +00:00
|
|
|
InvokeEcmaEntrypoint(jsPandaFile, methodName, args);
|
2021-09-04 08:06:49 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSHandle<GlobalEnv> EcmaVM::GetGlobalEnv() const
|
|
|
|
{
|
|
|
|
return JSHandle<GlobalEnv>(reinterpret_cast<uintptr_t>(&globalEnv_));
|
|
|
|
}
|
|
|
|
|
|
|
|
JSHandle<job::MicroJobQueue> EcmaVM::GetMicroJobQueue() const
|
|
|
|
{
|
|
|
|
return JSHandle<job::MicroJobQueue>(reinterpret_cast<uintptr_t>(µJobQueue_));
|
|
|
|
}
|
|
|
|
|
|
|
|
JSMethod *EcmaVM::GetMethodForNativeFunction(const void *func)
|
|
|
|
{
|
|
|
|
// signature: any foo(any function_obj, any this)
|
|
|
|
uint32_t accessFlags = ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_NATIVE;
|
|
|
|
uint32_t numArgs = 2; // function object and this
|
|
|
|
|
|
|
|
auto method = chunk_.New<JSMethod>(nullptr, nullptr, panda_file::File::EntityId(0), panda_file::File::EntityId(0),
|
|
|
|
accessFlags, numArgs, nullptr);
|
|
|
|
method->SetNativePointer(const_cast<void *>(func));
|
2022-02-22 12:15:46 +00:00
|
|
|
method->SetNativeBit(true);
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
nativeMethods_.push_back(method);
|
|
|
|
return nativeMethods_.back();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::RedirectMethod(const panda_file::File &pf)
|
|
|
|
{
|
|
|
|
for (auto method : frameworkProgramMethods_) {
|
|
|
|
method->SetPandaFile(&pf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Expected<int, Runtime::Error> EcmaVM::InvokeEntrypointImpl(Method *entrypoint, const std::vector<std::string> &args)
|
|
|
|
{
|
|
|
|
// For testcase startup
|
|
|
|
const panda_file::File *file = entrypoint->GetPandaFile();
|
2022-02-28 07:04:37 +00:00
|
|
|
const JSPandaFile *jsPandaFile = GetJSPandaFileManager()->GetJSPandaFile(file);
|
|
|
|
ASSERT(jsPandaFile != nullptr);
|
2022-02-06 15:16:08 +00:00
|
|
|
return InvokeEcmaEntrypoint(jsPandaFile, utf::Mutf8AsCString(entrypoint->GetName().data), args);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-02-28 07:04:37 +00:00
|
|
|
Expected<int, Runtime::Error> EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile,
|
|
|
|
[[maybe_unused]] const CString &methodName,
|
2021-09-04 08:06:49 +00:00
|
|
|
const std::vector<std::string> &args)
|
|
|
|
{
|
|
|
|
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
|
|
|
JSHandle<Program> program;
|
|
|
|
if (snapshotSerializeEnable_) {
|
2022-02-28 07:04:37 +00:00
|
|
|
program = GetJSPandaFileManager()->GenerateProgram(this, jsPandaFile);
|
2021-09-04 08:06:49 +00:00
|
|
|
|
2022-02-06 15:16:08 +00:00
|
|
|
auto index = jsPandaFile->GetJSPandaFileDesc().find(frameworkAbcFileName_);
|
2021-09-04 08:06:49 +00:00
|
|
|
if (index != CString::npos) {
|
2022-02-26 03:08:37 +00:00
|
|
|
#if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
|
2022-02-06 15:16:08 +00:00
|
|
|
LOG_ECMA(DEBUG) << "snapShot MakeSnapShotProgramObject abc " << jsPandaFile->GetJSPandaFileDesc();
|
2021-09-04 08:06:49 +00:00
|
|
|
SnapShot snapShot(this);
|
2022-02-06 15:16:08 +00:00
|
|
|
snapShot.MakeSnapShotProgramObject(*program, jsPandaFile->GetPandaFile(), snapshotFileName_);
|
2022-02-26 03:08:37 +00:00
|
|
|
#endif
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
} else {
|
2022-02-06 15:16:08 +00:00
|
|
|
if (jsPandaFile != frameworkPandaFile_) {
|
2022-02-28 07:04:37 +00:00
|
|
|
program = GetJSPandaFileManager()->GenerateProgram(this, jsPandaFile);
|
2021-09-04 08:06:49 +00:00
|
|
|
} else {
|
|
|
|
program = JSHandle<Program>(thread_, frameworkProgram_);
|
2022-02-06 15:16:08 +00:00
|
|
|
RedirectMethod(*jsPandaFile->GetPandaFile());
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (program.IsEmpty()) {
|
|
|
|
LOG_ECMA(ERROR) << "program is empty, invoke entrypoint failed";
|
|
|
|
return Unexpected(Runtime::Error::PANDA_FILE_LOAD_ERROR);
|
|
|
|
}
|
2022-02-28 07:04:37 +00:00
|
|
|
// for debugger
|
|
|
|
notificationManager_->LoadModuleEvent(jsPandaFile->GetJSPandaFileDesc());
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
JSHandle<JSFunction> func = JSHandle<JSFunction>(thread_, program->GetMainFunction());
|
|
|
|
JSHandle<JSTaggedValue> newTarget(thread_, JSTaggedValue::Undefined());
|
|
|
|
JSHandle<TaggedArray> jsargs = factory_->NewTaggedArray(args.size());
|
2022-01-14 13:50:26 +00:00
|
|
|
uint32_t i = 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
for (const std::string &str : args) {
|
|
|
|
JSHandle<JSTaggedValue> strobj(factory_->NewFromStdString(str));
|
|
|
|
jsargs->Set(thread_, i++, strobj);
|
|
|
|
}
|
|
|
|
|
2021-09-07 14:24:16 +00:00
|
|
|
InternalCallParams *params = thread_->GetInternalCallParams();
|
|
|
|
params->MakeArgList(*jsargs);
|
2021-12-17 09:18:10 +00:00
|
|
|
JSRuntimeOptions options = this->GetJSOptions();
|
2022-02-26 03:08:37 +00:00
|
|
|
JSHandle<JSTaggedValue> global = GlobalEnv::Cast(globalEnv_.GetTaggedObject())->GetJSGlobalObject();
|
2021-12-17 09:18:10 +00:00
|
|
|
if (options.IsEnableCpuProfiler()) {
|
2022-02-26 03:08:37 +00:00
|
|
|
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
2021-12-17 09:18:10 +00:00
|
|
|
CpuProfiler *profiler = CpuProfiler::GetInstance();
|
2022-01-12 07:46:02 +00:00
|
|
|
profiler->CpuProfiler::StartCpuProfiler(this, "");
|
2021-12-17 09:18:10 +00:00
|
|
|
panda::ecmascript::InvokeJsFunction(thread_, func, global, newTarget, params);
|
|
|
|
profiler->CpuProfiler::StopCpuProfiler();
|
2022-02-26 03:08:37 +00:00
|
|
|
#endif
|
2021-12-17 09:18:10 +00:00
|
|
|
} else {
|
|
|
|
panda::ecmascript::InvokeJsFunction(thread_, func, global, newTarget, params);
|
|
|
|
}
|
2021-09-04 08:06:49 +00:00
|
|
|
if (!thread_->HasPendingException()) {
|
2021-10-20 09:35:03 +00:00
|
|
|
job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue());
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// print exception information
|
|
|
|
if (thread_->HasPendingException()) {
|
|
|
|
auto exception = thread_->GetException();
|
|
|
|
HandleUncaughtException(exception.GetTaggedObject());
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EcmaVM::IsFrameworkPandaFile(std::string_view filename) const
|
|
|
|
{
|
|
|
|
return filename.size() >= frameworkAbcFileName_.size() &&
|
|
|
|
filename.substr(filename.size() - frameworkAbcFileName_.size()) == frameworkAbcFileName_;
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:54:49 +00:00
|
|
|
JSHandle<JSTaggedValue> EcmaVM::GetAndClearEcmaUncaughtException() const
|
|
|
|
{
|
|
|
|
JSHandle<JSTaggedValue> exceptionHandle = GetEcmaUncaughtException();
|
|
|
|
thread_->ClearException(); // clear for ohos app
|
|
|
|
return exceptionHandle;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
JSHandle<JSTaggedValue> EcmaVM::GetEcmaUncaughtException() const
|
|
|
|
{
|
|
|
|
if (thread_->GetException().IsHole()) {
|
|
|
|
return JSHandle<JSTaggedValue>();
|
|
|
|
}
|
|
|
|
JSHandle<JSTaggedValue> exceptionHandle(thread_, thread_->GetException());
|
|
|
|
return exceptionHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::EnableUserUncaughtErrorHandler()
|
|
|
|
{
|
|
|
|
isUncaughtExceptionRegistered_ = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::HandleUncaughtException(ObjectHeader *exception)
|
|
|
|
{
|
|
|
|
if (isUncaughtExceptionRegistered_) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
[[maybe_unused]] EcmaHandleScope handle_scope(thread_);
|
|
|
|
JSHandle<JSTaggedValue> exceptionHandle(thread_, JSTaggedValue(exception));
|
|
|
|
// if caught exceptionHandle type is JSError
|
|
|
|
thread_->ClearException();
|
|
|
|
if (exceptionHandle->IsJSError()) {
|
|
|
|
PrintJSErrorInfo(exceptionHandle);
|
|
|
|
return;
|
|
|
|
}
|
2021-09-26 13:23:54 +00:00
|
|
|
JSHandle<EcmaString> result = JSTaggedValue::ToString(thread_, exceptionHandle);
|
|
|
|
CString string = ConvertToString(*result);
|
|
|
|
LOG(ERROR, RUNTIME) << string;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::PrintJSErrorInfo(const JSHandle<JSTaggedValue> &exceptionInfo)
|
|
|
|
{
|
|
|
|
JSHandle<JSTaggedValue> nameKey = thread_->GlobalConstants()->GetHandledNameString();
|
|
|
|
JSHandle<EcmaString> name(JSObject::GetProperty(thread_, exceptionInfo, nameKey).GetValue());
|
|
|
|
JSHandle<JSTaggedValue> msgKey = thread_->GlobalConstants()->GetHandledMessageString();
|
|
|
|
JSHandle<EcmaString> msg(JSObject::GetProperty(thread_, exceptionInfo, msgKey).GetValue());
|
|
|
|
JSHandle<JSTaggedValue> stackKey = thread_->GlobalConstants()->GetHandledStackString();
|
|
|
|
JSHandle<EcmaString> stack(JSObject::GetProperty(thread_, exceptionInfo, stackKey).GetValue());
|
|
|
|
|
|
|
|
CString nameBuffer = ConvertToString(*name);
|
|
|
|
CString msgBuffer = ConvertToString(*msg);
|
|
|
|
CString stackBuffer = ConvertToString(*stack);
|
|
|
|
LOG(ERROR, RUNTIME) << nameBuffer << ": " << msgBuffer << "\n" << stackBuffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::ProcessReferences(const WeakRootVisitor &v0)
|
|
|
|
{
|
|
|
|
if (regExpParserCache_ != nullptr) {
|
|
|
|
regExpParserCache_->Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
// array buffer
|
|
|
|
for (auto iter = arrayBufferDataList_.begin(); iter != arrayBufferDataList_.end();) {
|
|
|
|
JSNativePointer *object = *iter;
|
|
|
|
auto fwd = v0(reinterpret_cast<TaggedObject *>(object));
|
|
|
|
if (fwd == nullptr) {
|
|
|
|
object->Destroy();
|
|
|
|
iter = arrayBufferDataList_.erase(iter);
|
|
|
|
} else if (fwd != reinterpret_cast<TaggedObject *>(object)) {
|
|
|
|
*iter = JSNativePointer::Cast(fwd);
|
|
|
|
++iter;
|
|
|
|
} else {
|
|
|
|
++iter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// framework program
|
|
|
|
if (!frameworkProgram_.IsHole()) {
|
|
|
|
auto fwd = v0(frameworkProgram_.GetTaggedObject());
|
|
|
|
if (fwd == nullptr) {
|
|
|
|
frameworkProgram_ = JSTaggedValue::Undefined();
|
|
|
|
} else if (fwd != frameworkProgram_.GetTaggedObject()) {
|
|
|
|
frameworkProgram_ = JSTaggedValue(fwd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::PushToArrayDataList(JSNativePointer *array)
|
|
|
|
{
|
|
|
|
if (std::find(arrayBufferDataList_.begin(), arrayBufferDataList_.end(), array) != arrayBufferDataList_.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
arrayBufferDataList_.emplace_back(array);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::RemoveArrayDataList(JSNativePointer *array)
|
|
|
|
{
|
|
|
|
auto iter = std::find(arrayBufferDataList_.begin(), arrayBufferDataList_.end(), array);
|
|
|
|
if (iter != arrayBufferDataList_.end()) {
|
|
|
|
arrayBufferDataList_.erase(iter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-26 03:08:37 +00:00
|
|
|
// Do not support snapshot on windows
|
2021-09-04 08:06:49 +00:00
|
|
|
bool EcmaVM::VerifyFilePath(const CString &filePath) const
|
|
|
|
{
|
2022-02-26 03:08:37 +00:00
|
|
|
#ifndef PANDA_TARGET_WINDOWS
|
2021-09-04 08:06:49 +00:00
|
|
|
if (filePath.size() > PATH_MAX) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
CVector<char> resolvedPath(PATH_MAX);
|
|
|
|
auto result = realpath(filePath.c_str(), resolvedPath.data());
|
|
|
|
if (result == nullptr) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
std::ifstream file(resolvedPath.data());
|
|
|
|
if (!file.good()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
file.close();
|
|
|
|
return true;
|
2022-02-26 03:08:37 +00:00
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::ClearBufferData()
|
|
|
|
{
|
|
|
|
for (auto iter : arrayBufferDataList_) {
|
|
|
|
iter->Destroy();
|
|
|
|
}
|
|
|
|
arrayBufferDataList_.clear();
|
|
|
|
|
2022-02-06 15:16:08 +00:00
|
|
|
if (frameworkPandaFile_) {
|
|
|
|
delete frameworkPandaFile_;
|
|
|
|
frameworkPandaFile_ = nullptr;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EcmaVM::ExecutePromisePendingJob() const
|
|
|
|
{
|
|
|
|
if (!thread_->HasPendingException()) {
|
2021-10-20 09:35:03 +00:00
|
|
|
job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue());
|
2021-09-04 08:06:49 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::CollectGarbage(TriggerGCType gcType) const
|
|
|
|
{
|
|
|
|
heap_->CollectGarbage(gcType);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::StartHeapTracking(HeapTracker *tracker)
|
|
|
|
{
|
|
|
|
heap_->StartHeapTracking(tracker);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::StopHeapTracking()
|
|
|
|
{
|
|
|
|
heap_->StopHeapTracking();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::Iterate(const RootVisitor &v)
|
|
|
|
{
|
|
|
|
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&globalEnv_)));
|
|
|
|
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(µJobQueue_)));
|
|
|
|
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(®expCache_)));
|
2022-02-22 08:50:20 +00:00
|
|
|
moduleManager_->Iterate(v);
|
|
|
|
tsLoader_->Iterate(v);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::SetGlobalEnv(GlobalEnv *global)
|
|
|
|
{
|
|
|
|
ASSERT(global != nullptr);
|
|
|
|
globalEnv_ = JSTaggedValue(global);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::SetMicroJobQueue(job::MicroJobQueue *queue)
|
|
|
|
{
|
|
|
|
ASSERT(queue != nullptr);
|
|
|
|
microJobQueue_ = JSTaggedValue(queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
JSHandle<JSTaggedValue> EcmaVM::GetModuleByName(JSHandle<JSTaggedValue> moduleName)
|
|
|
|
{
|
2022-02-06 15:16:08 +00:00
|
|
|
// only used in testcase, pandaFileWithProgram_ only one item. this interface will delete
|
2022-02-28 07:04:37 +00:00
|
|
|
const JSPandaFile *currentJSPandaFile = nullptr;
|
|
|
|
GetJSPandaFileManager()->EnumerateJSPandaFiles([¤tJSPandaFile](const JSPandaFile *jsPandaFile) {
|
|
|
|
currentJSPandaFile = jsPandaFile;
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
ASSERT(currentJSPandaFile != nullptr);
|
|
|
|
CString currentPathFile = currentJSPandaFile->GetJSPandaFileDesc();
|
2021-10-19 06:51:14 +00:00
|
|
|
CString relativeFile = ConvertToString(EcmaString::Cast(moduleName->GetTaggedObject()));
|
|
|
|
|
|
|
|
// generate full path
|
2022-02-22 08:50:20 +00:00
|
|
|
CString abcPath = moduleManager_->GenerateAmiPath(currentPathFile, relativeFile);
|
2021-10-15 09:20:37 +00:00
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
// Uniform module name
|
|
|
|
JSHandle<EcmaString> abcModuleName = factory_->NewFromString(abcPath);
|
|
|
|
|
|
|
|
JSHandle<JSTaggedValue> module = moduleManager_->GetModule(thread_, JSHandle<JSTaggedValue>::Cast(abcModuleName));
|
|
|
|
if (module->IsUndefined()) {
|
2022-02-06 15:16:08 +00:00
|
|
|
std::string file = base::StringHelper::ToStdString(abcModuleName.GetObject<EcmaString>());
|
2021-09-04 08:06:49 +00:00
|
|
|
std::vector<std::string> argv;
|
|
|
|
ExecuteModule(file, ENTRY_POINTER, argv);
|
|
|
|
module = moduleManager_->GetModule(thread_, JSHandle<JSTaggedValue>::Cast(abcModuleName));
|
|
|
|
}
|
|
|
|
return module;
|
|
|
|
}
|
|
|
|
|
2022-02-06 15:16:08 +00:00
|
|
|
void EcmaVM::ExecuteModule(const std::string &moduleFile, std::string_view entryPoint,
|
2021-09-04 08:06:49 +00:00
|
|
|
const std::vector<std::string> &args)
|
|
|
|
{
|
|
|
|
moduleManager_->SetCurrentExportModuleName(moduleFile);
|
|
|
|
// Update Current Module
|
|
|
|
EcmaVM::ExecuteFromPf(moduleFile, entryPoint, args, true);
|
|
|
|
// Restore Current Module
|
|
|
|
moduleManager_->RestoreCurrentExportModuleName();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::ClearNativeMethodsData()
|
|
|
|
{
|
|
|
|
for (auto iter : nativeMethods_) {
|
|
|
|
chunk_.Delete(iter);
|
|
|
|
}
|
|
|
|
nativeMethods_.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::SetupRegExpResultCache()
|
|
|
|
{
|
|
|
|
regexpCache_ = builtins::RegExpExecResultCache::CreateCacheTable(thread_);
|
|
|
|
}
|
|
|
|
} // namespace panda::ecmascript
|