2021-09-04 08:06:49 +00:00
|
|
|
/*
|
2022-04-16 07:57:40 +00:00
|
|
|
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
2021-09-04 08:06:49 +00:00
|
|
|
* 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"
|
|
|
|
|
2023-01-17 13:01:22 +00:00
|
|
|
#include "ecmascript/base/path_helper.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/base/string_helper.h"
|
2022-08-25 12:47:18 +00:00
|
|
|
#include "ecmascript/builtins/builtins.h"
|
2023-01-29 03:40:13 +00:00
|
|
|
#include "ecmascript/builtins/builtins_ark_tools.h"
|
2023-03-03 02:59:00 +00:00
|
|
|
#ifdef ARK_SUPPORT_INTL
|
2022-08-16 13:05:02 +00:00
|
|
|
#include "ecmascript/builtins/builtins_collator.h"
|
|
|
|
#include "ecmascript/builtins/builtins_date_time_format.h"
|
|
|
|
#include "ecmascript/builtins/builtins_number_format.h"
|
2023-03-03 02:59:00 +00:00
|
|
|
#endif
|
|
|
|
#include "ecmascript/builtins/builtins_global.h"
|
2022-08-16 13:05:02 +00:00
|
|
|
#include "ecmascript/builtins/builtins_object.h"
|
|
|
|
#include "ecmascript/builtins/builtins_promise.h"
|
|
|
|
#include "ecmascript/builtins/builtins_promise_handler.h"
|
|
|
|
#include "ecmascript/builtins/builtins_proxy.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/builtins/builtins_regexp.h"
|
2022-08-04 06:58:57 +00:00
|
|
|
#include "ecmascript/compiler/builtins/builtins_call_signature.h"
|
2022-05-16 11:38:24 +00:00
|
|
|
#include "ecmascript/compiler/call_signature.h"
|
2022-03-19 01:17:21 +00:00
|
|
|
#include "ecmascript/compiler/common_stubs.h"
|
2022-03-16 10:12:15 +00:00
|
|
|
#include "ecmascript/compiler/interpreter_stub.h"
|
|
|
|
#include "ecmascript/compiler/rt_call_signature.h"
|
2022-02-26 03:08:37 +00:00
|
|
|
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
2022-03-03 14:22:54 +00:00
|
|
|
#include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
|
2022-02-26 03:08:37 +00:00
|
|
|
#endif
|
2022-10-10 02:08:43 +00:00
|
|
|
#if !WIN_OR_MAC_OR_IOS_PLATFORM
|
2022-08-02 08:07:48 +00:00
|
|
|
#include "ecmascript/dfx/hprof/heap_profiler.h"
|
|
|
|
#include "ecmascript/dfx/hprof/heap_profiler_interface.h"
|
|
|
|
#endif
|
2022-09-20 11:25:15 +00:00
|
|
|
#include "ecmascript/debugger/js_debugger_manager.h"
|
2022-12-14 09:07:53 +00:00
|
|
|
#include "ecmascript/dfx/vmstat/opt_code_profiler.h"
|
2022-03-03 14:22:54 +00:00
|
|
|
#include "ecmascript/dfx/vmstat/runtime_stat.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/ecma_string_table.h"
|
2022-10-14 07:01:55 +00:00
|
|
|
#include "ecmascript/aot_file_manager.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"
|
2022-03-24 07:04:57 +00:00
|
|
|
#include "ecmascript/interpreter/interpreter-inl.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/jobs/micro_job_queue.h"
|
2022-05-06 08:34:15 +00:00
|
|
|
#include "ecmascript/jspandafile/constpool_value.h"
|
2022-02-06 15:16:08 +00:00
|
|
|
#include "ecmascript/jspandafile/js_pandafile.h"
|
|
|
|
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
2022-01-30 08:01:33 +00:00
|
|
|
#include "ecmascript/jspandafile/panda_file_translator.h"
|
2022-04-05 13:28:18 +00:00
|
|
|
#include "ecmascript/jspandafile/program_object.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/js_arraybuffer.h"
|
|
|
|
#include "ecmascript/js_for_in_iterator.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"
|
2022-05-11 09:36:28 +00:00
|
|
|
#include "ecmascript/mem/gc_stats.h"
|
|
|
|
#include "ecmascript/mem/mem.h"
|
|
|
|
#include "ecmascript/mem/space.h"
|
|
|
|
#include "ecmascript/mem/visitor.h"
|
2023-01-29 03:40:13 +00:00
|
|
|
#include "ecmascript/napi/include/dfx_jsnapi.h"
|
2022-05-11 09:36:28 +00:00
|
|
|
#include "ecmascript/taskpool/task.h"
|
2022-01-30 08:01:33 +00:00
|
|
|
#include "ecmascript/module/js_module_manager.h"
|
2023-03-05 10:05:15 +00:00
|
|
|
#include "ecmascript/module/module_data_extractor.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/object_factory.h"
|
2022-11-29 06:28:34 +00:00
|
|
|
#include "ecmascript/patch/quick_fix_manager.h"
|
2023-02-09 13:47:15 +00:00
|
|
|
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
|
2022-03-23 07:43:38 +00:00
|
|
|
#include "ecmascript/taskpool/taskpool.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/regexp/regexp_parser_cache.h"
|
|
|
|
#include "ecmascript/runtime_call_id.h"
|
2022-05-11 09:36:28 +00:00
|
|
|
#include "ecmascript/snapshot/mem/snapshot_env.h"
|
|
|
|
#include "ecmascript/snapshot/mem/snapshot.h"
|
2022-03-16 10:12:15 +00:00
|
|
|
#include "ecmascript/stubs/runtime_stubs.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/tagged_array-inl.h"
|
2021-12-17 09:18:10 +00:00
|
|
|
#include "ecmascript/tagged_dictionary.h"
|
2022-04-05 13:28:18 +00:00
|
|
|
#include "ecmascript/tagged_queue.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
#include "ecmascript/tagged_queue.h"
|
2022-07-21 17:37:55 +00:00
|
|
|
#include "ecmascript/ts_types/ts_manager.h"
|
2022-06-08 02:59:06 +00:00
|
|
|
#include "ecmascript/require/js_cjs_module_cache.h"
|
|
|
|
#include "ecmascript/require/js_require_manager.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
namespace panda::ecmascript {
|
2023-01-17 13:01:22 +00:00
|
|
|
using PathHelper = base::PathHelper;
|
2023-02-21 06:20:10 +00:00
|
|
|
using RandomGenerator = base::RandomGenerator;
|
2021-09-04 08:06:49 +00:00
|
|
|
/* static */
|
2022-06-15 03:23:16 +00:00
|
|
|
EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options, EcmaParamConfiguration &config)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-06-20 11:04:49 +00:00
|
|
|
JSRuntimeOptions newOptions = options;
|
2022-07-05 09:18:30 +00:00
|
|
|
// only define SUPPORT_ENABLE_ASM_INTERP can enable asm-interpreter
|
|
|
|
#if !defined(SUPPORT_ENABLE_ASM_INTERP)
|
2022-06-20 11:04:49 +00:00
|
|
|
newOptions.SetEnableAsmInterpreter(false);
|
|
|
|
#endif
|
|
|
|
auto vm = new EcmaVM(newOptions, config);
|
2021-09-04 08:06:49 +00:00
|
|
|
if (UNLIKELY(vm == nullptr)) {
|
|
|
|
LOG_ECMA(ERROR) << "Failed to create jsvm";
|
|
|
|
return nullptr;
|
|
|
|
}
|
2022-04-20 08:27:09 +00:00
|
|
|
auto jsThread = JSThread::Create(vm);
|
2021-09-04 08:06:49 +00:00
|
|
|
vm->thread_ = jsThread;
|
|
|
|
vm->Initialize();
|
|
|
|
return vm;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
2022-04-20 08:27:09 +00:00
|
|
|
bool EcmaVM::Destroy(EcmaVM *vm)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
|
|
|
if (vm != nullptr) {
|
2022-04-20 08:27:09 +00:00
|
|
|
delete vm;
|
|
|
|
vm = nullptr;
|
2021-09-04 08:06:49 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-11-17 08:32:20 +00:00
|
|
|
void EcmaVM::PreFork()
|
2022-07-05 06:15:02 +00:00
|
|
|
{
|
|
|
|
heap_->CompactHeapBeforeFork();
|
2022-08-08 02:31:03 +00:00
|
|
|
heap_->AdjustSpaceSizeForAppSpawn();
|
2022-07-05 06:15:02 +00:00
|
|
|
heap_->GetReadOnlySpace()->SetReadOnly();
|
|
|
|
heap_->DisableParallelGC();
|
|
|
|
}
|
|
|
|
|
2022-11-17 08:32:20 +00:00
|
|
|
void EcmaVM::PostFork()
|
2022-07-05 06:15:02 +00:00
|
|
|
{
|
2023-02-21 06:20:10 +00:00
|
|
|
RandomGenerator::InitRandom();
|
2023-01-10 07:42:27 +00:00
|
|
|
heap_->SetHeapMode(HeapMode::SHARE);
|
2022-07-05 06:15:02 +00:00
|
|
|
GetAssociatedJSThread()->SetThreadId();
|
2022-12-22 07:16:35 +00:00
|
|
|
heap_->EnableParallelGC();
|
2022-07-05 06:15:02 +00:00
|
|
|
}
|
|
|
|
|
2022-06-15 03:23:16 +00:00
|
|
|
EcmaVM::EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config)
|
2021-10-19 03:55:00 +00:00
|
|
|
: 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()),
|
2022-06-15 03:23:16 +00:00
|
|
|
ecmaParamConfiguration_(std::move(config))
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2021-10-19 03:55:00 +00:00
|
|
|
options_ = std::move(options);
|
2022-04-30 12:02:19 +00:00
|
|
|
icEnabled_ = options_.EnableIC();
|
|
|
|
optionalLogEnabled_ = options_.EnableOptionalLog();
|
2022-03-18 07:17:30 +00:00
|
|
|
options_.ParseAsmInterOption();
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2023-03-08 07:05:35 +00:00
|
|
|
void EcmaVM::InitializePGOProfiler()
|
2023-01-30 13:03:02 +00:00
|
|
|
{
|
2023-03-24 10:29:10 +00:00
|
|
|
bool isEnablePGOProfiler = IsEnablePGOProfiler();
|
|
|
|
if (pgoProfiler_ == nullptr) {
|
|
|
|
pgoProfiler_ = PGOProfilerManager::GetInstance()->Build(this, isEnablePGOProfiler);
|
2023-03-22 03:00:58 +00:00
|
|
|
}
|
2023-01-30 13:03:02 +00:00
|
|
|
thread_->SetPGOProfilerEnable(isEnablePGOProfiler);
|
|
|
|
}
|
|
|
|
|
2023-03-08 07:05:35 +00:00
|
|
|
void EcmaVM::ResetPGOProfiler()
|
|
|
|
{
|
|
|
|
if (pgoProfiler_ != nullptr) {
|
|
|
|
bool isEnablePGOProfiler = IsEnablePGOProfiler();
|
|
|
|
PGOProfilerManager::GetInstance()->Reset(pgoProfiler_, isEnablePGOProfiler);
|
|
|
|
thread_->SetPGOProfilerEnable(isEnablePGOProfiler);
|
|
|
|
thread_->CheckOrSwitchPGOStubs();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-30 13:03:02 +00:00
|
|
|
bool EcmaVM::IsEnablePGOProfiler() const
|
|
|
|
{
|
2023-03-08 07:05:35 +00:00
|
|
|
if (options_.IsWorker()) {
|
|
|
|
return PGOProfilerManager::GetInstance()->IsEnable();
|
|
|
|
}
|
2023-01-30 13:03:02 +00:00
|
|
|
return options_.GetEnableAsmInterpreter() && options_.IsEnablePGOProfiler();
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
bool EcmaVM::Initialize()
|
|
|
|
{
|
2022-05-11 08:51:55 +00:00
|
|
|
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "EcmaVM::Initialize");
|
2023-03-08 07:05:35 +00:00
|
|
|
InitializePGOProfiler();
|
2022-03-23 07:43:38 +00:00
|
|
|
Taskpool::GetCurrentTaskpool()->Initialize();
|
2022-02-26 03:08:37 +00:00
|
|
|
#ifndef PANDA_TARGET_WINDOWS
|
2022-03-16 10:12:15 +00:00
|
|
|
RuntimeStubs::Initialize(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();
|
2022-05-27 09:56:07 +00:00
|
|
|
gcStats_ = chunk_.New<GCStats>(heap_, options_.GetLongPauseTime());
|
2022-08-17 02:09:16 +00:00
|
|
|
factory_ = chunk_.New<ObjectFactory>(thread_, heap_);
|
2021-09-04 08:06:49 +00:00
|
|
|
if (UNLIKELY(factory_ == nullptr)) {
|
2022-07-06 06:12:54 +00:00
|
|
|
LOG_FULL(FATAL) << "alloc factory_ failed";
|
2021-09-04 08:06:49 +00:00
|
|
|
UNREACHABLE();
|
|
|
|
}
|
2022-10-18 03:55:00 +00:00
|
|
|
debuggerManager_ = chunk_.New<tooling::JsDebuggerManager>(this);
|
2021-12-17 09:18:10 +00:00
|
|
|
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
2022-03-26 09:00:26 +00:00
|
|
|
|
2022-06-07 08:44:17 +00:00
|
|
|
if (!options_.EnableSnapshotDeserialize()) {
|
|
|
|
LOG_ECMA(DEBUG) << "EcmaVM::Initialize run builtins";
|
2022-08-16 15:48:09 +00:00
|
|
|
JSHandle<JSHClass> hClassHandle = factory_->InitClassClass();
|
|
|
|
JSHandle<JSHClass> globalEnvClass = factory_->NewEcmaHClass(*hClassHandle,
|
|
|
|
GlobalEnv::SIZE,
|
|
|
|
JSType::GLOBAL_ENV);
|
|
|
|
globalConst->Init(thread_, *hClassHandle);
|
2022-06-07 08:44:17 +00:00
|
|
|
globalConstInitialized_ = true;
|
|
|
|
JSHandle<GlobalEnv> globalEnv = factory_->NewGlobalEnv(*globalEnvClass);
|
|
|
|
globalEnv->Init(thread_);
|
|
|
|
globalEnv_ = globalEnv.GetTaggedValue();
|
2022-10-24 11:32:00 +00:00
|
|
|
thread_->SetGlueGlobalEnv(reinterpret_cast<GlobalEnv *>(globalEnv.GetTaggedType()));
|
2022-06-07 08:44:17 +00:00
|
|
|
Builtins builtins;
|
|
|
|
builtins.Initialize(globalEnv, thread_);
|
2022-10-10 02:08:43 +00:00
|
|
|
if (!WIN_OR_MAC_OR_IOS_PLATFORM && options_.EnableSnapshotSerialize()) {
|
2022-06-07 08:44:17 +00:00
|
|
|
const CString fileName = "builtins.snapshot";
|
|
|
|
Snapshot snapshot(this);
|
|
|
|
snapshot.SerializeBuiltins(fileName);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const CString fileName = "builtins.snapshot";
|
|
|
|
Snapshot snapshot(this);
|
2022-10-10 02:08:43 +00:00
|
|
|
if (!WIN_OR_MAC_OR_IOS_PLATFORM) {
|
2022-06-07 08:44:17 +00:00
|
|
|
snapshot.Deserialize(SnapshotType::BUILTINS, fileName, true);
|
|
|
|
}
|
|
|
|
globalConst->InitSpecialForSnapshot();
|
|
|
|
Builtins builtins;
|
|
|
|
builtins.InitializeForSnapshot(thread_);
|
2022-06-27 06:20:29 +00:00
|
|
|
globalConstInitialized_ = true;
|
2022-06-07 08:44:17 +00:00
|
|
|
}
|
|
|
|
|
2022-03-26 09:00:26 +00:00
|
|
|
SetupRegExpResultCache();
|
|
|
|
microJobQueue_ = factory_->NewMicroJobQueue().GetTaggedValue();
|
2022-08-16 13:05:02 +00:00
|
|
|
GenerateInternalNativeMethods();
|
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-07-21 17:37:55 +00:00
|
|
|
tsManager_ = new TSManager(this);
|
2022-09-08 03:46:46 +00:00
|
|
|
quickFixManager_ = new QuickFixManager();
|
2022-05-12 02:23:24 +00:00
|
|
|
snapshotEnv_ = new SnapshotEnv(this);
|
2022-10-10 02:08:43 +00:00
|
|
|
if (!WIN_OR_MAC_OR_IOS_PLATFORM) {
|
2022-06-14 11:18:29 +00:00
|
|
|
snapshotEnv_->Initialize();
|
|
|
|
}
|
2022-10-14 09:13:26 +00:00
|
|
|
aotFileManager_ = new AOTFileManager(this);
|
2022-06-08 06:43:48 +00:00
|
|
|
if (options_.GetEnableAsmInterpreter()) {
|
2022-05-16 11:38:24 +00:00
|
|
|
LoadStubFile();
|
2022-05-12 02:23:24 +00:00
|
|
|
}
|
2022-12-14 09:07:53 +00:00
|
|
|
|
2023-01-31 13:15:39 +00:00
|
|
|
if (options_.GetEnableAsmInterpreter() && options_.WasAOTOutputFileSet()) {
|
|
|
|
AnFileDataManager::GetInstance()->SetEnable(true);
|
|
|
|
std::string aotFilename = options_.GetAOTOutputFile();
|
|
|
|
LoadAOTFiles(aotFilename);
|
|
|
|
}
|
|
|
|
|
2022-12-14 09:07:53 +00:00
|
|
|
optCodeProfiler_ = new OptCodeProfiler();
|
|
|
|
|
2022-07-27 06:09:34 +00:00
|
|
|
initialized_ = true;
|
2021-12-17 09:18:10 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
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-03-21 09:09:19 +00:00
|
|
|
BUILTINS_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
|
2022-04-16 08:20:50 +00:00
|
|
|
#define DEF_RUNTIME_ID(name) "Runtime::" #name,
|
2022-03-16 10:12:15 +00:00
|
|
|
RUNTIME_STUB_WITH_GC_LIST(DEF_RUNTIME_ID)
|
2022-03-11 08:08:16 +00:00
|
|
|
#undef DEF_RUNTIME_ID
|
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)) {
|
2022-07-06 06:12:54 +00:00
|
|
|
LOG_FULL(FATAL) << "alloc runtimeStat_ failed";
|
2021-09-04 08:06:49 +00:00
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::SetRuntimeStatEnable(bool flag)
|
|
|
|
{
|
2022-04-29 08:46:53 +00:00
|
|
|
static uint64_t start = 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
if (flag) {
|
2022-04-29 08:46:53 +00:00
|
|
|
start = PandaRuntimeTimer::Now();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (runtimeStat_ == nullptr) {
|
|
|
|
InitializeEcmaScriptRunStat();
|
|
|
|
}
|
|
|
|
} else {
|
2022-07-06 06:12:54 +00:00
|
|
|
LOG_ECMA(INFO) << "Runtime State duration:" << PandaRuntimeTimer::Now() - start << "(ns)";
|
2022-04-29 08:46:53 +00:00
|
|
|
if (runtimeStat_->IsRuntimeStatEnabled()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
runtimeStat_->Print();
|
|
|
|
runtimeStat_->ResetAllCount();
|
|
|
|
}
|
|
|
|
}
|
2022-04-29 08:46:53 +00:00
|
|
|
runtimeStat_->SetRuntimeStatEnabled(flag);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EcmaVM::~EcmaVM()
|
|
|
|
{
|
2022-07-27 06:09:34 +00:00
|
|
|
initialized_ = false;
|
2023-01-29 03:40:13 +00:00
|
|
|
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
|
|
|
DFXJSNApi::StopCpuProfilerForFile(this);
|
|
|
|
#endif
|
2022-07-18 11:06:58 +00:00
|
|
|
heap_->WaitAllTasksFinished();
|
2022-11-18 03:58:51 +00:00
|
|
|
Taskpool::GetCurrentTaskpool()->Destroy(thread_->GetThreadId());
|
2021-09-04 08:06:49 +00:00
|
|
|
|
2022-04-29 08:46:53 +00:00
|
|
|
if (runtimeStat_ != nullptr && runtimeStat_->IsRuntimeStatEnabled()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
runtimeStat_->Print();
|
|
|
|
}
|
|
|
|
|
2022-12-14 09:07:53 +00:00
|
|
|
if (optCodeProfiler_ != nullptr) {
|
|
|
|
delete optCodeProfiler_;
|
|
|
|
optCodeProfiler_ = nullptr;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
// clear c_address: c++ pointer delete
|
|
|
|
ClearBufferData();
|
2022-11-15 03:05:29 +00:00
|
|
|
if (!isBundlePack_) {
|
2023-03-15 08:25:25 +00:00
|
|
|
std::shared_ptr<JSPandaFile> jsPandaFile = JSPandaFileManager::GetInstance()->FindJSPandaFile(assetPath_);
|
2022-11-15 03:05:29 +00:00
|
|
|
if (jsPandaFile != nullptr) {
|
2023-03-15 08:25:25 +00:00
|
|
|
jsPandaFile->DeleteParsedConstpoolVM(this);
|
2022-11-15 03:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
2022-11-26 07:50:44 +00:00
|
|
|
// clear icu cache
|
|
|
|
ClearIcuCache();
|
2021-09-04 08:06:49 +00:00
|
|
|
|
2021-09-07 14:24:16 +00:00
|
|
|
if (gcStats_ != nullptr) {
|
2022-04-30 12:02:19 +00:00
|
|
|
if (options_.EnableGCStatsPrint()) {
|
2022-01-07 09:36:04 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-07-27 06:09:34 +00:00
|
|
|
if (regExpParserCache_ != nullptr) {
|
|
|
|
delete regExpParserCache_;
|
|
|
|
regExpParserCache_ = nullptr;
|
|
|
|
}
|
2021-09-04 08:06:49 +00:00
|
|
|
|
2022-04-22 07:19:24 +00:00
|
|
|
if (debuggerManager_ != nullptr) {
|
|
|
|
chunk_.Delete(debuggerManager_);
|
|
|
|
debuggerManager_ = nullptr;
|
2021-10-18 08:54:11 +00:00
|
|
|
}
|
|
|
|
|
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-07-21 17:37:55 +00:00
|
|
|
if (tsManager_ != nullptr) {
|
|
|
|
delete tsManager_;
|
|
|
|
tsManager_ = nullptr;
|
2022-02-22 08:50:20 +00:00
|
|
|
}
|
|
|
|
|
2022-09-08 03:46:46 +00:00
|
|
|
if (quickFixManager_ != nullptr) {
|
|
|
|
delete quickFixManager_;
|
|
|
|
quickFixManager_ = nullptr;
|
2022-08-27 03:52:15 +00:00
|
|
|
}
|
|
|
|
|
2022-05-17 06:52:04 +00:00
|
|
|
if (snapshotEnv_ != nullptr) {
|
|
|
|
delete snapshotEnv_;
|
|
|
|
snapshotEnv_ = nullptr;
|
|
|
|
}
|
|
|
|
|
2022-10-14 09:13:26 +00:00
|
|
|
if (aotFileManager_ != nullptr) {
|
|
|
|
delete aotFileManager_;
|
2022-11-29 03:14:12 +00:00
|
|
|
aotFileManager_ = nullptr;
|
2022-02-23 08:50:04 +00:00
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
if (thread_ != nullptr) {
|
|
|
|
delete thread_;
|
|
|
|
thread_ = nullptr;
|
|
|
|
}
|
2022-10-17 09:02:45 +00:00
|
|
|
|
|
|
|
if (pgoProfiler_ != nullptr) {
|
|
|
|
PGOProfilerManager::GetInstance()->Destroy(pgoProfiler_);
|
|
|
|
pgoProfiler_ = nullptr;
|
|
|
|
}
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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_));
|
|
|
|
}
|
|
|
|
|
2022-07-07 11:09:19 +00:00
|
|
|
JSTaggedValue EcmaVM::InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSHandle<JSTaggedValue> &thisArg,
|
2022-10-20 03:08:39 +00:00
|
|
|
const JSPandaFile *jsPandaFile, std::string_view entryPoint)
|
2022-05-06 08:34:15 +00:00
|
|
|
{
|
2022-12-05 14:55:52 +00:00
|
|
|
aotFileManager_->SetAOTMainFuncEntry(mainFunc, jsPandaFile, entryPoint);
|
2022-11-01 06:32:39 +00:00
|
|
|
Method *method = mainFunc->GetCallTarget();
|
|
|
|
size_t actualNumArgs = method->GetNumArgs();
|
|
|
|
size_t argsNum = actualNumArgs + NUM_MANDATORY_JSFUNC_ARGS;
|
2022-10-26 06:14:52 +00:00
|
|
|
std::vector<JSTaggedType> args(argsNum, JSTaggedValue::Undefined().GetRawData());
|
|
|
|
args[0] = mainFunc.GetTaggedValue().GetRawData();
|
|
|
|
args[2] = thisArg.GetTaggedValue().GetRawData(); // 2: this
|
2022-12-02 07:00:28 +00:00
|
|
|
const JSTaggedType *prevFp = thread_->GetLastLeaveFrame();
|
2023-01-31 13:15:39 +00:00
|
|
|
// do not modify this log to INFO, this will call many times
|
|
|
|
LOG_ECMA(DEBUG) << "start to execute aot entry: " << entryPoint;
|
2022-11-01 06:32:39 +00:00
|
|
|
JSTaggedValue res = ExecuteAot(actualNumArgs, args.data(), prevFp, OptimizedEntryFrame::CallType::CALL_FUNC);
|
|
|
|
if (thread_->HasPendingException()) {
|
|
|
|
return thread_->GetException();
|
|
|
|
}
|
2022-10-18 08:16:20 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-11-01 06:32:39 +00:00
|
|
|
JSTaggedValue EcmaVM::ExecuteAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp,
|
|
|
|
OptimizedEntryFrame::CallType callType)
|
2022-10-18 08:16:20 +00:00
|
|
|
{
|
2022-12-02 03:12:46 +00:00
|
|
|
INTERPRETER_TRACE(thread_, ExecuteAot);
|
2022-05-17 02:23:58 +00:00
|
|
|
auto entry = thread_->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
|
2023-01-31 13:15:39 +00:00
|
|
|
// do not modify this log to INFO, this will call many times
|
|
|
|
LOG_ECMA(DEBUG) << "start to execute aot entry: " << (void*)entry;
|
2022-05-17 02:23:58 +00:00
|
|
|
auto res = reinterpret_cast<JSFunctionEntryType>(entry)(thread_->GetGlueAddr(),
|
2022-10-26 06:14:52 +00:00
|
|
|
actualNumArgs,
|
2022-11-01 06:32:39 +00:00
|
|
|
args,
|
|
|
|
reinterpret_cast<uintptr_t>(prevFp),
|
|
|
|
static_cast<size_t>(callType));
|
2022-10-26 06:14:52 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2023-01-29 03:40:13 +00:00
|
|
|
void EcmaVM::CheckStartCpuProfiler()
|
|
|
|
{
|
|
|
|
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
|
|
|
if (profiler_ == nullptr && !options_.IsWorker() &&
|
|
|
|
options_.EnableCpuProfiler() && options_.GetArkBundleName().compare(bundleName_) == 0) {
|
|
|
|
std::string fileName = options_.GetArkBundleName() + ".cpuprofile";
|
|
|
|
if (!builtins::BuiltinsArkTools::CreateFile(fileName)) {
|
|
|
|
LOG_ECMA(ERROR) << "createFile failed " << fileName;
|
|
|
|
} else {
|
|
|
|
DFXJSNApi::StartCpuProfilerForFile(this, fileName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-03-15 08:25:25 +00:00
|
|
|
Expected<JSTaggedValue, bool> EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile,
|
|
|
|
std::string_view entryPoint, bool excuteFromJob)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
|
|
|
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
2023-01-12 02:14:50 +00:00
|
|
|
JSHandle<Program> program = JSPandaFileManager::GetInstance()->GenerateProgram(this, jsPandaFile, entryPoint);
|
2021-09-04 08:06:49 +00:00
|
|
|
if (program.IsEmpty()) {
|
|
|
|
LOG_ECMA(ERROR) << "program is empty, invoke entrypoint failed";
|
2022-04-08 01:23:52 +00:00
|
|
|
return Unexpected(false);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2022-02-28 07:04:37 +00:00
|
|
|
// for debugger
|
2022-08-30 12:52:16 +00:00
|
|
|
debuggerManager_->GetNotificationManager()->LoadModuleEvent(jsPandaFile->GetJSPandaFileDesc(), entryPoint);
|
2021-09-04 08:06:49 +00:00
|
|
|
|
2023-01-14 01:29:02 +00:00
|
|
|
JSHandle<JSFunction> func(thread_, program->GetMainFunction());
|
2022-02-26 03:08:37 +00:00
|
|
|
JSHandle<JSTaggedValue> global = GlobalEnv::Cast(globalEnv_.GetTaggedObject())->GetJSGlobalObject();
|
2023-01-12 02:14:50 +00:00
|
|
|
JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
|
2023-01-17 13:01:22 +00:00
|
|
|
if (jsPandaFile->IsModule(thread_, entryPoint.data())) {
|
2023-01-12 02:14:50 +00:00
|
|
|
global = undefined;
|
2022-08-30 12:52:16 +00:00
|
|
|
CString moduleName = jsPandaFile->GetJSPandaFileDesc();
|
2022-09-09 08:44:33 +00:00
|
|
|
if (!jsPandaFile->IsBundlePack()) {
|
2022-08-30 12:52:16 +00:00
|
|
|
moduleName = entryPoint.data();
|
|
|
|
}
|
|
|
|
JSHandle<SourceTextModule> module = moduleManager_->HostGetImportedModule(moduleName);
|
2022-01-30 08:01:33 +00:00
|
|
|
func->SetModule(thread_, module);
|
2022-09-28 02:49:13 +00:00
|
|
|
} else {
|
2022-10-22 11:01:40 +00:00
|
|
|
// if it is Cjs at present, the module slot of the function is not used. We borrow it to store the recordName,
|
|
|
|
// which can avoid the problem of larger memory caused by the new slot
|
2022-11-28 06:53:17 +00:00
|
|
|
JSHandle<EcmaString> recordName = factory_->NewFromUtf8(entryPoint.data());
|
2022-09-28 02:49:13 +00:00
|
|
|
func->SetModule(thread_, recordName);
|
2022-01-30 08:01:33 +00:00
|
|
|
}
|
2023-01-29 03:40:13 +00:00
|
|
|
CheckStartCpuProfiler();
|
2022-04-06 11:22:08 +00:00
|
|
|
|
2023-01-12 02:14:50 +00:00
|
|
|
JSTaggedValue result;
|
2022-11-14 12:19:17 +00:00
|
|
|
if (aotFileManager_->IsLoadMain(jsPandaFile, entryPoint.data())) {
|
2022-10-17 11:41:53 +00:00
|
|
|
EcmaRuntimeStatScope runtimeStatScope(this);
|
2022-10-20 03:08:39 +00:00
|
|
|
result = InvokeEcmaAotEntrypoint(func, global, jsPandaFile, entryPoint);
|
2021-12-17 09:18:10 +00:00
|
|
|
} else {
|
2023-01-17 13:01:22 +00:00
|
|
|
if (jsPandaFile->IsCjs(thread_, entryPoint.data())) {
|
|
|
|
if (!thread_->HasPendingException()) {
|
|
|
|
CJSExecution(func, global, jsPandaFile);
|
|
|
|
}
|
2022-06-08 02:59:06 +00:00
|
|
|
} else {
|
2022-07-04 02:08:05 +00:00
|
|
|
EcmaRuntimeCallInfo *info =
|
2022-06-08 02:59:06 +00:00
|
|
|
EcmaInterpreter::NewRuntimeCallInfo(thread_, JSHandle<JSTaggedValue>(func), global, undefined, 0);
|
|
|
|
EcmaRuntimeStatScope runtimeStatScope(this);
|
2022-07-04 02:08:05 +00:00
|
|
|
EcmaInterpreter::Execute(info);
|
2022-06-08 06:43:48 +00:00
|
|
|
}
|
2021-12-17 09:18:10 +00:00
|
|
|
}
|
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
|
2022-11-21 12:47:04 +00:00
|
|
|
if (!excuteFromJob && thread_->HasPendingException()) {
|
2023-01-12 02:14:50 +00:00
|
|
|
HandleUncaughtException(thread_->GetException());
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2022-04-08 01:23:52 +00:00
|
|
|
return result;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-12-13 07:01:05 +00:00
|
|
|
bool EcmaVM::HasCachedConstpool(const JSPandaFile *jsPandaFile) const
|
|
|
|
{
|
|
|
|
return cachedConstpools_.find(jsPandaFile) != cachedConstpools_.end();
|
|
|
|
}
|
|
|
|
|
2022-08-26 12:40:41 +00:00
|
|
|
JSTaggedValue EcmaVM::FindConstpool(const JSPandaFile *jsPandaFile, int32_t index)
|
2022-03-21 13:19:10 +00:00
|
|
|
{
|
|
|
|
auto iter = cachedConstpools_.find(jsPandaFile);
|
|
|
|
if (iter == cachedConstpools_.end()) {
|
|
|
|
return JSTaggedValue::Hole();
|
|
|
|
}
|
2022-10-15 10:47:04 +00:00
|
|
|
auto constpoolIter = iter->second.find(index);
|
|
|
|
if (constpoolIter == iter->second.end()) {
|
|
|
|
return JSTaggedValue::Hole();
|
|
|
|
}
|
|
|
|
return constpoolIter->second;
|
|
|
|
}
|
|
|
|
|
2022-11-01 12:34:48 +00:00
|
|
|
std::optional<std::reference_wrapper<CMap<int32_t, JSTaggedValue>>> EcmaVM::FindConstpools(
|
|
|
|
const JSPandaFile *jsPandaFile)
|
|
|
|
{
|
|
|
|
auto iter = cachedConstpools_.find(jsPandaFile);
|
|
|
|
if (iter == cachedConstpools_.end()) {
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
return iter->second;
|
|
|
|
}
|
|
|
|
|
2022-11-29 06:28:34 +00:00
|
|
|
// For new version instruction.
|
|
|
|
JSTaggedValue EcmaVM::FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id)
|
|
|
|
{
|
|
|
|
panda_file::IndexAccessor indexAccessor(*jsPandaFile->GetPandaFile(), id);
|
|
|
|
int32_t index = static_cast<int32_t>(indexAccessor.GetHeaderIndex());
|
|
|
|
return FindConstpool(jsPandaFile, index);
|
|
|
|
}
|
|
|
|
|
2023-03-15 08:25:25 +00:00
|
|
|
JSHandle<ConstantPool> EcmaVM::FindOrCreateConstPool(const JSPandaFile *jsPandaFile, EntityId id)
|
2022-10-15 10:47:04 +00:00
|
|
|
{
|
|
|
|
panda_file::IndexAccessor indexAccessor(*jsPandaFile->GetPandaFile(), id);
|
|
|
|
int32_t index = static_cast<int32_t>(indexAccessor.GetHeaderIndex());
|
|
|
|
JSTaggedValue constpool = FindConstpool(jsPandaFile, index);
|
|
|
|
if (constpool.IsHole()) {
|
|
|
|
JSHandle<ConstantPool> newConstpool = ConstantPool::CreateConstPool(this, jsPandaFile, id);
|
|
|
|
AddConstpool(jsPandaFile, newConstpool.GetTaggedValue(), index);
|
|
|
|
return newConstpool;
|
|
|
|
}
|
|
|
|
|
|
|
|
return JSHandle<ConstantPool>(thread_, constpool);
|
2022-03-21 13:19:10 +00:00
|
|
|
}
|
|
|
|
|
2023-02-16 12:28:51 +00:00
|
|
|
void EcmaVM::CreateAllConstpool(const JSPandaFile *jsPandaFile)
|
|
|
|
{
|
|
|
|
auto headers = jsPandaFile->GetPandaFile()->GetIndexHeaders();
|
|
|
|
uint32_t index = 0;
|
|
|
|
for (const auto &header : headers) {
|
|
|
|
auto constpoolSize = header.method_idx_size;
|
|
|
|
JSHandle<ConstantPool> constpool = factory_->NewConstantPool(constpoolSize);
|
|
|
|
constpool->SetJSPandaFile(jsPandaFile);
|
|
|
|
constpool->SetIndexHeader(&header);
|
|
|
|
AddConstpool(jsPandaFile, constpool.GetTaggedValue(), index++);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-05 02:19:28 +00:00
|
|
|
void EcmaVM::CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
|
|
|
|
const JSPandaFile *jsPandaFile)
|
2022-06-08 02:59:06 +00:00
|
|
|
{
|
|
|
|
// create "module", "exports", "require", "filename", "dirname"
|
2022-09-28 02:49:13 +00:00
|
|
|
JSHandle<CjsModule> module = factory_->NewCjsModule();
|
2022-06-08 02:59:06 +00:00
|
|
|
JSHandle<JSTaggedValue> require = GetGlobalEnv()->GetCjsRequireFunction();
|
2022-09-28 02:49:13 +00:00
|
|
|
JSHandle<CjsExports> exports = factory_->NewCjsExports();
|
2022-07-07 07:20:02 +00:00
|
|
|
JSMutableHandle<JSTaggedValue> filename(thread_, JSTaggedValue::Undefined());
|
|
|
|
JSMutableHandle<JSTaggedValue> dirname(thread_, JSTaggedValue::Undefined());
|
2022-12-05 02:19:28 +00:00
|
|
|
if (jsPandaFile->IsBundlePack()) {
|
2023-01-17 13:01:22 +00:00
|
|
|
PathHelper::ResolveCurrentPath(thread_, dirname, filename, jsPandaFile);
|
2022-12-05 02:19:28 +00:00
|
|
|
} else {
|
2023-01-12 02:14:50 +00:00
|
|
|
filename.Update(func->GetModule());
|
2022-12-05 02:19:28 +00:00
|
|
|
ASSERT(filename->IsString());
|
2023-01-17 13:01:22 +00:00
|
|
|
dirname.Update(PathHelper::ResolveDirPath(thread_, filename));
|
2022-12-05 02:19:28 +00:00
|
|
|
}
|
2022-06-08 02:59:06 +00:00
|
|
|
CJSInfo cjsInfo(module, require, exports, filename, dirname);
|
2022-07-07 09:29:10 +00:00
|
|
|
RequireManager::InitializeCommonJS(thread_, cjsInfo);
|
2022-06-08 02:59:06 +00:00
|
|
|
|
|
|
|
// Execute main function
|
|
|
|
JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
|
2022-07-04 02:08:05 +00:00
|
|
|
EcmaRuntimeCallInfo *info =
|
2022-06-08 02:59:06 +00:00
|
|
|
EcmaInterpreter::NewRuntimeCallInfo(thread_,
|
|
|
|
JSHandle<JSTaggedValue>(func),
|
2022-07-07 11:09:19 +00:00
|
|
|
thisArg, undefined, 5); // 5 : argument numbers
|
2022-12-05 02:19:28 +00:00
|
|
|
RETURN_IF_ABRUPT_COMPLETION(thread_);
|
2022-07-04 02:08:05 +00:00
|
|
|
if (info == nullptr) {
|
2022-07-06 06:12:54 +00:00
|
|
|
LOG_ECMA(ERROR) << "CJSExecution Stack overflow!";
|
2022-07-04 02:08:05 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
info->SetCallArg(cjsInfo.exportsHdl.GetTaggedValue(),
|
|
|
|
cjsInfo.requireHdl.GetTaggedValue(),
|
|
|
|
cjsInfo.moduleHdl.GetTaggedValue(),
|
|
|
|
cjsInfo.filenameHdl.GetTaggedValue(),
|
|
|
|
cjsInfo.dirnameHdl.GetTaggedValue());
|
2022-06-08 02:59:06 +00:00
|
|
|
EcmaRuntimeStatScope runtimeStatScope(this);
|
2022-07-04 02:08:05 +00:00
|
|
|
EcmaInterpreter::Execute(info);
|
2022-12-05 02:19:28 +00:00
|
|
|
if (!thread_->HasPendingException()) {
|
|
|
|
job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue());
|
|
|
|
}
|
2022-06-08 02:59:06 +00:00
|
|
|
|
2023-02-16 07:07:19 +00:00
|
|
|
if (!thread_->HasPendingException()) {
|
|
|
|
// Collecting module.exports : exports ---> module.exports --->Module._cache
|
|
|
|
RequireManager::CollectExecutedExp(thread_, cjsInfo);
|
2022-12-05 02:19:28 +00:00
|
|
|
}
|
2022-06-08 02:59:06 +00:00
|
|
|
}
|
|
|
|
|
2022-10-15 10:47:04 +00:00
|
|
|
void EcmaVM::AddConstpool(const JSPandaFile *jsPandaFile, JSTaggedValue constpool, int32_t index)
|
2022-03-21 13:19:10 +00:00
|
|
|
{
|
2022-09-05 03:38:50 +00:00
|
|
|
ASSERT(constpool.IsConstantPool());
|
2022-08-26 12:40:41 +00:00
|
|
|
if (cachedConstpools_.find(jsPandaFile) == cachedConstpools_.end()) {
|
2022-10-15 10:47:04 +00:00
|
|
|
cachedConstpools_[jsPandaFile] = CMap<int32_t, JSTaggedValue>();
|
2022-08-26 12:40:41 +00:00
|
|
|
}
|
2022-10-15 10:47:04 +00:00
|
|
|
auto &constpoolMap = cachedConstpools_[jsPandaFile];
|
|
|
|
ASSERT(constpoolMap.find(index) == constpoolMap.end());
|
2022-03-21 13:19:10 +00:00
|
|
|
|
2022-10-15 10:47:04 +00:00
|
|
|
constpoolMap.insert({index, constpool});
|
2022-03-21 13:19:10 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
{
|
2022-08-22 06:44:19 +00:00
|
|
|
if (!thread_->HasPendingException()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
return JSHandle<JSTaggedValue>();
|
|
|
|
}
|
|
|
|
JSHandle<JSTaggedValue> exceptionHandle(thread_, thread_->GetException());
|
|
|
|
return exceptionHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::EnableUserUncaughtErrorHandler()
|
|
|
|
{
|
|
|
|
isUncaughtExceptionRegistered_ = true;
|
|
|
|
}
|
|
|
|
|
2023-01-12 02:14:50 +00:00
|
|
|
void EcmaVM::HandleUncaughtException(JSTaggedValue exception)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
|
|
|
if (isUncaughtExceptionRegistered_) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-16 07:57:40 +00:00
|
|
|
[[maybe_unused]] EcmaHandleScope handleScope(thread_);
|
2023-01-12 02:14:50 +00:00
|
|
|
JSHandle<JSTaggedValue> exceptionHandle(thread_, exception);
|
2021-09-04 08:06:49 +00:00
|
|
|
// 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);
|
2022-09-22 13:37:23 +00:00
|
|
|
LOG_NO_TAG(ERROR) << 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);
|
2022-09-22 13:37:23 +00:00
|
|
|
LOG_NO_TAG(ERROR) << nameBuffer << ": " << msgBuffer << "\n" << stackBuffer;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-07-30 08:29:50 +00:00
|
|
|
void EcmaVM::ProcessNativeDelete(const WeakRootVisitor &visitor)
|
2022-03-07 03:58:44 +00:00
|
|
|
{
|
|
|
|
auto iter = nativePointerList_.begin();
|
|
|
|
while (iter != nativePointerList_.end()) {
|
|
|
|
JSNativePointer *object = *iter;
|
2022-07-30 08:29:50 +00:00
|
|
|
auto fwd = visitor(reinterpret_cast<TaggedObject *>(object));
|
2022-03-07 03:58:44 +00:00
|
|
|
if (fwd == nullptr) {
|
|
|
|
object->Destroy();
|
|
|
|
iter = nativePointerList_.erase(iter);
|
|
|
|
} else {
|
|
|
|
++iter;
|
|
|
|
}
|
|
|
|
}
|
2022-08-31 10:21:38 +00:00
|
|
|
|
|
|
|
auto iterator = cachedConstpools_.begin();
|
|
|
|
while (iterator != cachedConstpools_.end()) {
|
2022-09-03 10:40:44 +00:00
|
|
|
auto &constpools = iterator->second;
|
2022-10-15 10:47:04 +00:00
|
|
|
auto constpoolIter = constpools.begin();
|
|
|
|
while (constpoolIter != constpools.end()) {
|
|
|
|
JSTaggedValue constpoolVal = constpoolIter->second;
|
|
|
|
if (constpoolVal.IsHeapObject()) {
|
|
|
|
TaggedObject *obj = constpoolVal.GetTaggedObject();
|
2022-09-03 10:40:44 +00:00
|
|
|
auto fwd = visitor(obj);
|
|
|
|
if (fwd == nullptr) {
|
2022-10-15 10:47:04 +00:00
|
|
|
constpoolIter = constpools.erase(constpoolIter);
|
|
|
|
continue;
|
2022-09-03 10:40:44 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-15 10:47:04 +00:00
|
|
|
++constpoolIter;
|
|
|
|
}
|
|
|
|
if (constpools.size() == 0) {
|
2023-03-15 08:25:25 +00:00
|
|
|
LOG_ECMA(INFO) << "remove js pandafile by gc, file:" << iterator->first->GetJSPandaFileDesc();
|
|
|
|
JSPandaFileManager::GetInstance()->RemoveJSPandaFileVm(this, iterator->first);
|
2022-10-15 10:47:04 +00:00
|
|
|
iterator = cachedConstpools_.erase(iterator);
|
|
|
|
} else {
|
|
|
|
++iterator;
|
2022-08-31 10:21:38 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-07 03:58:44 +00:00
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void EcmaVM::ProcessReferences(const WeakRootVisitor &visitor)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
|
|
|
if (regExpParserCache_ != nullptr) {
|
|
|
|
regExpParserCache_->Clear();
|
|
|
|
}
|
2022-09-09 08:58:03 +00:00
|
|
|
heap_->ResetNativeBindingSize();
|
2021-09-04 08:06:49 +00:00
|
|
|
// array buffer
|
2022-10-15 10:47:04 +00:00
|
|
|
auto iter = nativePointerList_.begin();
|
|
|
|
while (iter != nativePointerList_.end()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
JSNativePointer *object = *iter;
|
2022-07-30 08:29:50 +00:00
|
|
|
auto fwd = visitor(reinterpret_cast<TaggedObject *>(object));
|
2021-09-04 08:06:49 +00:00
|
|
|
if (fwd == nullptr) {
|
|
|
|
object->Destroy();
|
2022-03-04 07:23:09 +00:00
|
|
|
iter = nativePointerList_.erase(iter);
|
2022-03-07 03:58:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2022-09-21 03:30:58 +00:00
|
|
|
heap_->IncreaseNativeBindingSize(JSNativePointer::Cast(fwd));
|
2022-03-07 03:58:44 +00:00
|
|
|
if (fwd != reinterpret_cast<TaggedObject *>(object)) {
|
2021-09-04 08:06:49 +00:00
|
|
|
*iter = JSNativePointer::Cast(fwd);
|
|
|
|
}
|
2022-03-07 03:58:44 +00:00
|
|
|
++iter;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2022-03-21 13:19:10 +00:00
|
|
|
|
|
|
|
// program maps
|
2022-10-15 10:47:04 +00:00
|
|
|
auto iterator = cachedConstpools_.begin();
|
|
|
|
while (iterator != cachedConstpools_.end()) {
|
|
|
|
auto &constpools = iterator->second;
|
|
|
|
auto constpoolIter = constpools.begin();
|
|
|
|
while (constpoolIter != constpools.end()) {
|
|
|
|
JSTaggedValue constpoolVal = constpoolIter->second;
|
|
|
|
if (constpoolVal.IsHeapObject()) {
|
|
|
|
TaggedObject *obj = constpoolVal.GetTaggedObject();
|
2022-08-26 12:40:41 +00:00
|
|
|
auto fwd = visitor(obj);
|
|
|
|
if (fwd == nullptr) {
|
2022-10-15 10:47:04 +00:00
|
|
|
constpoolIter = constpools.erase(constpoolIter);
|
|
|
|
continue;
|
2022-08-26 12:40:41 +00:00
|
|
|
} else if (fwd != obj) {
|
2022-10-15 10:47:04 +00:00
|
|
|
constpoolIter->second = JSTaggedValue(fwd);
|
2022-08-26 12:40:41 +00:00
|
|
|
}
|
2022-03-21 13:19:10 +00:00
|
|
|
}
|
2022-10-15 10:47:04 +00:00
|
|
|
++constpoolIter;
|
|
|
|
}
|
|
|
|
if (constpools.size() == 0) {
|
2023-03-15 08:25:25 +00:00
|
|
|
LOG_ECMA(INFO) << "remove js pandafile by gc, file:" << iterator->first->GetJSPandaFileDesc();
|
|
|
|
JSPandaFileManager::GetInstance()->RemoveJSPandaFileVm(this, iterator->first);
|
2022-10-15 10:47:04 +00:00
|
|
|
iterator = cachedConstpools_.erase(iterator);
|
|
|
|
} else {
|
|
|
|
++iterator;
|
2022-03-21 13:19:10 +00:00
|
|
|
}
|
|
|
|
}
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-03-04 07:23:09 +00:00
|
|
|
void EcmaVM::PushToNativePointerList(JSNativePointer *array)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-03-04 07:23:09 +00:00
|
|
|
nativePointerList_.emplace_back(array);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-03-04 07:23:09 +00:00
|
|
|
void EcmaVM::RemoveFromNativePointerList(JSNativePointer *array)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-03-04 07:23:09 +00:00
|
|
|
auto iter = std::find(nativePointerList_.begin(), nativePointerList_.end(), array);
|
|
|
|
if (iter != nativePointerList_.end()) {
|
2022-05-07 09:21:10 +00:00
|
|
|
JSNativePointer *object = *iter;
|
|
|
|
object->Destroy();
|
2022-03-04 07:23:09 +00:00
|
|
|
nativePointerList_.erase(iter);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EcmaVM::ClearBufferData()
|
|
|
|
{
|
2022-03-04 07:23:09 +00:00
|
|
|
for (auto iter : nativePointerList_) {
|
2021-09-04 08:06:49 +00:00
|
|
|
iter->Destroy();
|
|
|
|
}
|
2022-03-04 07:23:09 +00:00
|
|
|
nativePointerList_.clear();
|
2022-03-21 13:19:10 +00:00
|
|
|
|
2023-03-15 08:25:25 +00:00
|
|
|
auto iter = cachedConstpools_.begin();
|
|
|
|
while (iter != cachedConstpools_.end()) {
|
|
|
|
LOG_ECMA(INFO) << "remove js pandafile by vm destruct, file:" << iter->first->GetJSPandaFileDesc();
|
|
|
|
JSPandaFileManager::GetInstance()->RemoveJSPandaFileVm(this, iter->first);
|
|
|
|
iter++;
|
|
|
|
}
|
2022-03-21 13:19:10 +00:00
|
|
|
cachedConstpools_.clear();
|
2022-08-16 13:05:02 +00:00
|
|
|
internalNativeMethods_.clear();
|
2022-11-29 02:22:20 +00:00
|
|
|
workerList_.clear();
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-05-23 03:16:27 +00:00
|
|
|
bool EcmaVM::ExecutePromisePendingJob()
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-05-23 03:16:27 +00:00
|
|
|
if (isProcessingPendingJob_) {
|
2022-07-05 06:15:02 +00:00
|
|
|
LOG_ECMA(DEBUG) << "EcmaVM::ExecutePromisePendingJob can not reentrant";
|
2022-05-23 03:16:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!thread_->HasPendingException()) {
|
|
|
|
isProcessingPendingJob_ = true;
|
2021-10-20 09:35:03 +00:00
|
|
|
job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue());
|
2022-05-23 03:16:27 +00:00
|
|
|
isProcessingPendingJob_ = false;
|
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();
|
|
|
|
}
|
|
|
|
|
2022-08-16 13:05:02 +00:00
|
|
|
void EcmaVM::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
|
|
|
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-11-28 01:56:43 +00:00
|
|
|
rv(Root::ROOT_VM, ObjectSlot(ToUintPtr(&internalNativeMethods_.front())),
|
|
|
|
ObjectSlot(ToUintPtr(&internalNativeMethods_.back()) + JSTaggedValue::TaggedTypeSize()));
|
2022-02-22 08:50:20 +00:00
|
|
|
moduleManager_->Iterate(v);
|
2022-07-21 17:37:55 +00:00
|
|
|
tsManager_->Iterate(v);
|
2022-10-14 09:13:26 +00:00
|
|
|
aotFileManager_->Iterate(v);
|
2022-10-10 02:08:43 +00:00
|
|
|
if (!WIN_OR_MAC_OR_IOS_PLATFORM) {
|
2022-06-07 08:44:17 +00:00
|
|
|
snapshotEnv_->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);
|
|
|
|
}
|
|
|
|
|
2022-05-16 11:38:24 +00:00
|
|
|
void EcmaVM::SetupRegExpResultCache()
|
2022-03-26 09:00:26 +00:00
|
|
|
{
|
2022-05-16 11:38:24 +00:00
|
|
|
regexpCache_ = builtins::RegExpExecResultCache::CreateCacheTable(thread_);
|
2022-03-26 09:00:26 +00:00
|
|
|
}
|
|
|
|
|
2022-05-16 11:38:24 +00:00
|
|
|
void EcmaVM::LoadStubFile()
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-11-29 06:53:20 +00:00
|
|
|
std::string stubFile = options_.GetStubFile();
|
|
|
|
aotFileManager_->LoadStubFile(stubFile);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2022-02-23 08:50:04 +00:00
|
|
|
|
2023-04-01 10:12:56 +00:00
|
|
|
bool EcmaVM::LoadAOTFiles(const std::string& aotFileName)
|
2022-02-23 08:50:04 +00:00
|
|
|
{
|
2023-01-31 13:15:39 +00:00
|
|
|
std::string anFile = aotFileName + AOTFileManager::FILE_EXTENSION_AN;
|
2023-04-01 10:12:56 +00:00
|
|
|
if (!aotFileManager_->LoadAnFile(anFile)) {
|
|
|
|
LOG_ECMA(ERROR) << "Load " << anFile << " failed. Destroy aot data and rollback to interpreter";
|
|
|
|
ecmascript::AnFileDataManager::GetInstance()->SafeDestroyAnData(anFile);
|
|
|
|
return false;
|
|
|
|
}
|
2022-09-06 12:26:10 +00:00
|
|
|
|
2023-01-31 13:15:39 +00:00
|
|
|
std::string aiFile = aotFileName + AOTFileManager::FILE_EXTENSION_AI;
|
2023-04-01 10:12:56 +00:00
|
|
|
if (!aotFileManager_->LoadAiFile(aiFile)) {
|
|
|
|
LOG_ECMA(ERROR) << "Load " << aiFile << " failed. Destroy aot data and rollback to interpreter";
|
|
|
|
ecmascript::AnFileDataManager::GetInstance()->SafeDestroyAnData(anFile);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2022-02-23 08:50:04 +00:00
|
|
|
}
|
2022-08-02 08:07:48 +00:00
|
|
|
|
2023-03-08 01:32:05 +00:00
|
|
|
void EcmaVM::DumpAOTInfo() const
|
|
|
|
{
|
|
|
|
aotFileManager_->DumpAOTInfo();
|
|
|
|
}
|
|
|
|
|
2023-02-15 09:17:18 +00:00
|
|
|
#if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
|
2022-08-02 08:07:48 +00:00
|
|
|
void EcmaVM::DeleteHeapProfile()
|
|
|
|
{
|
|
|
|
if (heapProfile_ == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const_cast<NativeAreaAllocator *>(GetNativeAreaAllocator())->Delete(heapProfile_);
|
|
|
|
heapProfile_ = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
HeapProfilerInterface *EcmaVM::GetOrNewHeapProfile()
|
|
|
|
{
|
|
|
|
if (heapProfile_ != nullptr) {
|
|
|
|
return heapProfile_;
|
|
|
|
}
|
|
|
|
heapProfile_ = const_cast<NativeAreaAllocator *>(GetNativeAreaAllocator())->New<HeapProfiler>(this);
|
|
|
|
ASSERT(heapProfile_ != nullptr);
|
|
|
|
return heapProfile_;
|
|
|
|
}
|
|
|
|
#endif
|
2022-08-16 13:05:02 +00:00
|
|
|
|
|
|
|
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
|
|
|
void *EcmaVM::InternalMethodTable[] = {
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsGlobal::CallJsBoundFunction),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsGlobal::CallJsProxy),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsObject::CreateDataPropertyOnObjectFunctions),
|
2023-03-03 02:59:00 +00:00
|
|
|
#ifdef ARK_SUPPORT_INTL
|
2022-08-16 13:05:02 +00:00
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsCollator::AnonymousCollator),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsDateTimeFormat::AnonymousDateTimeFormat),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsNumberFormat::NumberFormatInternalFormatNumber),
|
2023-03-03 02:59:00 +00:00
|
|
|
#endif
|
2022-08-16 13:05:02 +00:00
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsProxy::InvalidateProxyFunction),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AsyncAwaitFulfilled),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AsyncAwaitRejected),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::ResolveElementFunction),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::Resolve),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::Reject),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::Executor),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AnyRejectElementFunction),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AllSettledResolveElementFunction),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::AllSettledRejectElementFunction),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::ThenFinally),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::CatchFinally),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::valueThunkFunction),
|
|
|
|
reinterpret_cast<void *>(builtins::BuiltinsPromiseHandler::throwerFunction),
|
|
|
|
reinterpret_cast<void *>(JSAsyncGeneratorObject::ProcessorFulfilledFunc),
|
2023-01-12 10:49:18 +00:00
|
|
|
reinterpret_cast<void *>(JSAsyncGeneratorObject::ProcessorRejectedFunc),
|
|
|
|
reinterpret_cast<void *>(JSAsyncFromSyncIterator::AsyncFromSyncIterUnwarpFunction)
|
2022-08-16 13:05:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void EcmaVM::GenerateInternalNativeMethods()
|
|
|
|
{
|
|
|
|
size_t length = static_cast<size_t>(MethodIndex::METHOD_END);
|
|
|
|
for (size_t i = 0; i < length; i++) {
|
|
|
|
uint32_t numArgs = 2; // function object and this
|
2023-04-12 07:26:21 +00:00
|
|
|
auto method = factory_->NewMethod(nullptr, MemSpaceType::NON_MOVABLE);
|
2022-08-16 13:05:02 +00:00
|
|
|
method->SetNativePointer(InternalMethodTable[i]);
|
|
|
|
method->SetNativeBit(true);
|
|
|
|
method->SetNumArgsWithCallField(numArgs);
|
2022-09-08 15:22:35 +00:00
|
|
|
method->SetFunctionKind(FunctionKind::NORMAL_FUNCTION);
|
2022-08-16 13:05:02 +00:00
|
|
|
internalNativeMethods_.emplace_back(method.GetTaggedValue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
JSTaggedValue EcmaVM::GetMethodByIndex(MethodIndex idx)
|
|
|
|
{
|
|
|
|
auto index = static_cast<uint8_t>(idx);
|
|
|
|
ASSERT(index < internalNativeMethods_.size());
|
|
|
|
return internalNativeMethods_[index];
|
|
|
|
}
|
2023-02-07 10:36:08 +00:00
|
|
|
|
|
|
|
void EcmaVM::TriggerConcurrentCallback(JSTaggedValue result, JSTaggedValue hint)
|
|
|
|
{
|
|
|
|
if (concurrentCallback_ == nullptr) {
|
|
|
|
LOG_ECMA(INFO) << "Only trigger concurrent callback in taskpool thread";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-03-07 01:52:05 +00:00
|
|
|
bool success = true;
|
2023-02-07 10:36:08 +00:00
|
|
|
if (result.IsJSPromise()) {
|
|
|
|
// Async concurrent will return Promise
|
|
|
|
auto promise = JSPromise::Cast(result.GetTaggedObject());
|
2023-03-07 01:52:05 +00:00
|
|
|
auto status = promise->GetPromiseState();
|
|
|
|
if (status == PromiseState::PENDING) {
|
|
|
|
result = JSHandle<JSTaggedValue>::Cast(factory_->GetJSError(
|
|
|
|
ErrorType::ERROR, "Can't return Promise in pending state")).GetTaggedValue();
|
|
|
|
} else {
|
|
|
|
result = promise->GetPromiseResult();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status != PromiseState::FULFILLED) {
|
|
|
|
success = false;
|
2023-02-07 10:36:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-07 01:52:05 +00:00
|
|
|
concurrentCallback_(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread_, result)), success,
|
|
|
|
JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread_, hint)), concurrentData_);
|
2023-02-07 10:36:08 +00:00
|
|
|
}
|
2022-08-17 02:09:16 +00:00
|
|
|
} // namespace panda::ecmascript
|