From a8ad8ca60f73aa4af6665c904412d5d20f834aa1 Mon Sep 17 00:00:00 2001 From: wengchangcheng Date: Fri, 8 Apr 2022 09:23:52 +0800 Subject: [PATCH] [part-1] support watch expression 1. delete unused execute arguments 2. support select execute entry 3. support get execute return value issue: https://gitee.com/openharmony/ark_js_runtime/issues/I51MKR Signed-off-by: wengchangcheng Change-Id: I40139e2f4afa36ad7d169d7f6c367a62a40bf476 --- ecmascript/compiler/pass_manager.cpp | 8 ++-- ecmascript/compiler/pass_manager.h | 3 +- ecmascript/ecma_language_context.cpp | 6 +-- ecmascript/ecma_vm.cpp | 26 ++++------- ecmascript/ecma_vm.h | 7 ++- ecmascript/jspandafile/js_pandafile.h | 2 +- .../jspandafile/js_pandafile_executor.cpp | 40 +++++++---------- .../jspandafile/js_pandafile_executor.h | 14 +++--- .../jspandafile/js_pandafile_manager.cpp | 43 +++++++++++++++---- ecmascript/jspandafile/js_pandafile_manager.h | 20 ++++----- .../jspandafile/panda_file_translator.cpp | 7 --- ecmascript/module/js_module_manager.cpp | 3 +- ecmascript/module/js_module_source_text.cpp | 6 +-- ecmascript/napi/jsnapi.cpp | 13 +++--- ecmascript/tooling/interface/debugger_api.cpp | 21 ++++++++- ecmascript/tooling/interface/debugger_api.h | 4 ++ test/moduletest/BUILD.gn | 1 + test/moduletest/watch/BUILD.gn | 19 ++++++++ test/moduletest/watch/expect_output.txt | 14 ++++++ test/moduletest/watch/watch.js | 18 ++++++++ test/test_helper.gni | 9 ++-- 21 files changed, 176 insertions(+), 108 deletions(-) create mode 100644 test/moduletest/watch/BUILD.gn create mode 100644 test/moduletest/watch/expect_output.txt create mode 100644 test/moduletest/watch/watch.js diff --git a/ecmascript/compiler/pass_manager.cpp b/ecmascript/compiler/pass_manager.cpp index 048334467e..0122c40fcc 100644 --- a/ecmascript/compiler/pass_manager.cpp +++ b/ecmascript/compiler/pass_manager.cpp @@ -28,7 +28,7 @@ bool PassManager::Compile(const std::string &fileName, const std::string &triple { BytecodeTranslationInfo translationInfo; [[maybe_unused]] EcmaHandleScope handleScope(vm_->GetJSThread()); - bool res = CollectInfoOfPandaFile(fileName, &translationInfo); + bool res = CollectInfoOfPandaFile(fileName, entry_, &translationInfo); if (!res) { std::cerr << "Cannot execute panda file '" << fileName << "'" << std::endl; return false; @@ -51,13 +51,15 @@ bool PassManager::Compile(const std::string &fileName, const std::string &triple return true; } -bool PassManager::CollectInfoOfPandaFile(const std::string &fileName, BytecodeTranslationInfo *translateInfo) +bool PassManager::CollectInfoOfPandaFile(const std::string &fileName, std::string_view entryPoint, + BytecodeTranslationInfo *translateInfo) { if (translateInfo == nullptr) { return false; } const JSPandaFile *jsPandaFile = - JSPandaFileManager::GetInstance()->LoadAotInfoFromPf(fileName.c_str(), &(translateInfo->methodPcInfos)); + JSPandaFileManager::GetInstance()->LoadAotInfoFromPf(fileName.c_str(), entryPoint, + &(translateInfo->methodPcInfos)); if (jsPandaFile == nullptr) { return false; } diff --git a/ecmascript/compiler/pass_manager.h b/ecmascript/compiler/pass_manager.h index 36cfa1c984..f0d9a7e91c 100644 --- a/ecmascript/compiler/pass_manager.h +++ b/ecmascript/compiler/pass_manager.h @@ -24,7 +24,8 @@ class PassManager { public: PassManager(EcmaVM* vm, std::string entry) : vm_(vm), entry_(entry) {} PassManager() = default; - bool CollectInfoOfPandaFile(const std::string &filename, BytecodeTranslationInfo *translateInfo); + bool CollectInfoOfPandaFile(const std::string &filename, std::string_view entryPoint, + BytecodeTranslationInfo *translateInfo); bool Compile(const std::string &fileName, const std::string &triple, const std::string &outputFileName); private: diff --git a/ecmascript/ecma_language_context.cpp b/ecmascript/ecma_language_context.cpp index 8f44eadf2e..4816c4b0db 100644 --- a/ecmascript/ecma_language_context.cpp +++ b/ecmascript/ecma_language_context.cpp @@ -59,11 +59,7 @@ std::pair EcmaLanguageContext::GetCatchMethodAndOffset(Metho PandaVM *EcmaLanguageContext::CreateVM(Runtime *runtime, [[maybe_unused]] const RuntimeOptions &options) const { - auto ret = EcmaVM::Create(runtime); - if (ret) { - return ret.Value(); - } - return nullptr; + return EcmaVM::Create(runtime); } std::unique_ptr EcmaLanguageContext::CreateClassLinkerExtension() const diff --git a/ecmascript/ecma_vm.cpp b/ecmascript/ecma_vm.cpp index fdf7eb36db..61b6430042 100644 --- a/ecmascript/ecma_vm.cpp +++ b/ecmascript/ecma_vm.cpp @@ -106,7 +106,7 @@ bool EcmaVM::Destroy(PandaVM *vm) } // static -Expected EcmaVM::Create(Runtime *runtime) +EcmaVM *EcmaVM::Create(Runtime *runtime) { EcmaVM *vm = runtime->GetInternalAllocator()->New(); auto jsThread = ecmascript::JSThread::Create(runtime, vm); @@ -367,10 +367,9 @@ JSMethod *EcmaVM::GetMethodForNativeFunction(const void *func) return nativeMethods_.back(); } -Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, - [[maybe_unused]] const CString &methodName, - const std::vector &args) +Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile) { + JSTaggedValue result; [[maybe_unused]] EcmaHandleScope scope(thread_); JSHandle program; if (snapshotSerializeEnable_) { @@ -396,20 +395,12 @@ Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js } if (program.IsEmpty()) { LOG_ECMA(ERROR) << "program is empty, invoke entrypoint failed"; - return Unexpected(Runtime::Error::PANDA_FILE_LOAD_ERROR); + return Unexpected(false); } // for debugger notificationManager_->LoadModuleEvent(jsPandaFile->GetJSPandaFileDesc()); JSHandle func = JSHandle(thread_, program->GetMainFunction()); - const size_t argsLength = args.size(); - JSHandle jsargs = factory_->NewTaggedArray(argsLength); - uint32_t i = 0; - for (const std::string &str : args) { - JSHandle strobj(factory_->NewFromStdString(str)); - jsargs->Set(thread_, i++, strobj); - } - JSHandle global = GlobalEnv::Cast(globalEnv_.GetTaggedObject())->GetJSGlobalObject(); if (jsPandaFile->IsModule()) { global = JSHandle(thread_, JSTaggedValue::Undefined()); @@ -419,19 +410,18 @@ Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js JSHandle undefined = thread_->GlobalConstants()->GetHandledUndefined(); EcmaRuntimeCallInfo info = - EcmaInterpreter::NewRuntimeCallInfo(thread_, JSHandle(func), global, undefined, argsLength); - info.SetCallArg(argsLength, jsargs); + EcmaInterpreter::NewRuntimeCallInfo(thread_, JSHandle(func), global, undefined, 0); JSRuntimeOptions options = this->GetJSOptions(); if (options.IsEnableCpuProfiler()) { #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER) CpuProfiler *profiler = CpuProfiler::GetInstance(); profiler->CpuProfiler::StartCpuProfiler(this, ""); - EcmaInterpreter::Execute(&info); + result = EcmaInterpreter::Execute(&info); profiler->CpuProfiler::StopCpuProfiler(); #endif } else { - EcmaInterpreter::Execute(&info); + result = EcmaInterpreter::Execute(&info); } if (!thread_->HasPendingException()) { job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue()); @@ -442,7 +432,7 @@ Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js auto exception = thread_->GetException(); HandleUncaughtException(exception.GetTaggedObject()); } - return 0; + return result; } JSTaggedValue EcmaVM::FindConstpool(const JSPandaFile *jsPandaFile) diff --git a/ecmascript/ecma_vm.h b/ecmascript/ecma_vm.h index 2c01f021e8..dcd440f0c3 100644 --- a/ecmascript/ecma_vm.h +++ b/ecmascript/ecma_vm.h @@ -87,12 +87,12 @@ public: static EcmaVM *Create(const JSRuntimeOptions &options); + static EcmaVM *Create(Runtime *runtime); + static bool Destroy(PandaVM *vm); explicit EcmaVM(JSRuntimeOptions options); - static Expected Create([[maybe_unused]] Runtime *runtime); - EcmaVM(); ~EcmaVM() override; @@ -407,8 +407,7 @@ private: void SetMicroJobQueue(job::MicroJobQueue *queue); - Expected InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, const CString &methodName, - const std::vector &args); + Expected InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile); void InitializeEcmaScriptRunStat(); diff --git a/ecmascript/jspandafile/js_pandafile.h b/ecmascript/jspandafile/js_pandafile.h index 6f9c7ab3fa..1657ee77dd 100644 --- a/ecmascript/jspandafile/js_pandafile.h +++ b/ecmascript/jspandafile/js_pandafile.h @@ -30,7 +30,7 @@ class File; namespace ecmascript { #define ENTRY_FUNCTION_NAME "func_main_0" #define MODULE_CLASS "L_ESModuleRecord;" -#define ENTRY_MAIN_FUNCTION "_GLOBAL::func_main_0" +#define ENTRY_MAIN_FUNCTION "_GLOBAL::" ENTRY_FUNCTION_NAME class JSPandaFile { public: diff --git a/ecmascript/jspandafile/js_pandafile_executor.cpp b/ecmascript/jspandafile/js_pandafile_executor.cpp index 0ca0026c50..8582d147f9 100644 --- a/ecmascript/jspandafile/js_pandafile_executor.cpp +++ b/ecmascript/jspandafile/js_pandafile_executor.cpp @@ -20,12 +20,12 @@ #include "ecmascript/module/js_module_manager.h" namespace panda::ecmascript { -bool JSPandaFileExecutor::ExecuteFromFile(JSThread *thread, const CString &filename, std::string_view entryPoint, - const std::vector &args) +Expected JSPandaFileExecutor::ExecuteFromFile(JSThread *thread, const CString &filename, + std::string_view entryPoint) { - const JSPandaFile *jsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(filename); + const JSPandaFile *jsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(filename, entryPoint); if (jsPandaFile == nullptr) { - return false; + return Unexpected(false); } bool isModule = jsPandaFile->IsModule(); @@ -38,43 +38,35 @@ bool JSPandaFileExecutor::ExecuteFromFile(JSThread *thread, const CString &filen if (thread->HasPendingException()) { auto exception = thread->GetException(); vm->HandleUncaughtException(exception.GetTaggedObject()); - return false; + return JSTaggedValue::Undefined(); } SourceTextModule::Evaluate(thread, moduleRecord); - return true; + return JSTaggedValue::Undefined(); } - return JSPandaFileExecutor::Execute(thread, jsPandaFile, entryPoint, args); + return JSPandaFileExecutor::Execute(thread, jsPandaFile); } -bool JSPandaFileExecutor::ExecuteFromBuffer(JSThread *thread, const void *buffer, size_t size, - std::string_view entryPoint, const std::vector &args, - const CString &filename) +Expected JSPandaFileExecutor::ExecuteFromBuffer( + JSThread *thread, const void *buffer, size_t size, std::string_view entryPoint, const CString &filename) { - const JSPandaFile *jsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(filename, buffer, size); + const JSPandaFile *jsPandaFile = + JSPandaFileManager::GetInstance()->LoadJSPandaFile(filename, entryPoint, buffer, size); if (jsPandaFile == nullptr) { - return false; + return Unexpected(false); } bool isModule = jsPandaFile->IsModule(); if (isModule) { ModuleManager *moduleManager = thread->GetEcmaVM()->GetModuleManager(); moduleManager->AddResolveImportedModule(jsPandaFile, filename); } - return JSPandaFileExecutor::Execute(thread, jsPandaFile, entryPoint, args); + return JSPandaFileExecutor::Execute(thread, jsPandaFile); } -bool JSPandaFileExecutor::Execute(JSThread *thread, const JSPandaFile *jsPandaFile, std::string_view entryPoint, - const std::vector &args) +Expected JSPandaFileExecutor::Execute(JSThread *thread, const JSPandaFile *jsPandaFile) { - // 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 EcmaVM *vm = thread->GetEcmaVM(); - vm->InvokeEcmaEntrypoint(jsPandaFile, methodName, args); - return true; + Expected result = vm->InvokeEcmaEntrypoint(jsPandaFile); + return result; } } // namespace panda::ecmascript diff --git a/ecmascript/jspandafile/js_pandafile_executor.h b/ecmascript/jspandafile/js_pandafile_executor.h index c9b734cf53..e21260cd35 100644 --- a/ecmascript/jspandafile/js_pandafile_executor.h +++ b/ecmascript/jspandafile/js_pandafile_executor.h @@ -25,15 +25,11 @@ namespace panda::ecmascript { class JSPandaFileExecutor { public: - static bool ExecuteFromFile(JSThread *thread, const CString &filename, std::string_view entryPoint, - const std::vector &args); - static bool ExecuteFromBuffer(JSThread *thread, const void *buffer, size_t size, std::string_view entryPoint, - const std::vector &args, const CString &filename = ""); -private: - static bool Execute(JSThread *thread, const JSPandaFile *jsPandaFile, std::string_view entryPoint, - const std::vector &args); - -friend class SourceTextModule; + static Expected ExecuteFromFile(JSThread *thread, const CString &filename, + std::string_view entryPoint); + static Expected ExecuteFromBuffer(JSThread *thread, const void *buffer, size_t size, + std::string_view entryPoint, const CString &filename = ""); + static Expected Execute(JSThread *thread, const JSPandaFile *jsPandaFile); }; } // namespace panda::ecmascript #endif // ECMASCRIPT_JSPANDAFILE_JS_PANDAFILE_EXECUTOR_H diff --git a/ecmascript/jspandafile/js_pandafile_manager.cpp b/ecmascript/jspandafile/js_pandafile_manager.cpp index 4fc4876344..a9c3a1f454 100644 --- a/ecmascript/jspandafile/js_pandafile_manager.cpp +++ b/ecmascript/jspandafile/js_pandafile_manager.cpp @@ -20,6 +20,12 @@ namespace panda::ecmascript { static const size_t MALLOC_SIZE_LIMIT = 2147483648; // Max internal memory used by the VM declared in options +JSPandaFileManager *JSPandaFileManager::GetInstance() +{ + static JSPandaFileManager jsFileManager; + return &jsFileManager; +} + JSPandaFileManager::~JSPandaFileManager() { os::memory::LockHolder lock(jsPandaFileLock_); @@ -32,7 +38,7 @@ JSPandaFileManager::~JSPandaFileManager() } // generate aot info on host -const JSPandaFile *JSPandaFileManager::LoadAotInfoFromPf(const CString &filename, +const JSPandaFile *JSPandaFileManager::LoadAotInfoFromPf(const CString &filename, std::string_view entryPoint, std::vector *methodPcInfos) { JSPandaFile *jsPandaFile = OpenJSPandaFile(filename); @@ -41,11 +47,20 @@ const JSPandaFile *JSPandaFileManager::LoadAotInfoFromPf(const CString &filename return nullptr; } - PandaFileTranslator::TranslateClasses(jsPandaFile, ENTRY_FUNCTION_NAME, methodPcInfos); + CString methodName; + auto pos = entryPoint.find_last_of("::"); + if (pos != std::string_view::npos) { + methodName = entryPoint.substr(pos + 1); + } else { + // default use func_main_0 as entryPoint + methodName = ENTRY_FUNCTION_NAME; + } + + PandaFileTranslator::TranslateClasses(jsPandaFile, methodName, methodPcInfos); return jsPandaFile; } -const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(const CString &filename) +const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(const CString &filename, std::string_view entryPoint) { ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "JSPandaFileManager::LoadJSPandaFile"); const JSPandaFile *jsPandaFile = FindJSPandaFile(filename); @@ -60,11 +75,12 @@ const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(const CString &filename) return nullptr; } - jsPandaFile = GenerateJSPandaFile(pf.release(), filename); + jsPandaFile = GenerateJSPandaFile(pf.release(), filename, entryPoint); return jsPandaFile; } -const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(const CString &filename, const void *buffer, size_t size) +const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(const CString &filename, std::string_view entryPoint, + const void *buffer, size_t size) { if (buffer == nullptr || size == 0) { return nullptr; @@ -81,7 +97,7 @@ const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(const CString &filename, LOG_ECMA(ERROR) << "open file " << filename << " error"; return nullptr; } - jsPandaFile = GenerateJSPandaFile(pf.release(), filename); + jsPandaFile = GenerateJSPandaFile(pf.release(), filename, entryPoint); return jsPandaFile; } @@ -200,13 +216,22 @@ tooling::ecmascript::JSPtExtractor *JSPandaFileManager::GetJSPtExtractor(const J return iter->second.get(); } -const JSPandaFile *JSPandaFileManager::GenerateJSPandaFile(const panda_file::File *pf, const CString &desc) +const JSPandaFile *JSPandaFileManager::GenerateJSPandaFile(const panda_file::File *pf, const CString &desc, + std::string_view entryPoint) { ASSERT(GetJSPandaFile(pf) == nullptr); - JSPandaFile *newJsPandaFile = NewJSPandaFile(pf, desc); - PandaFileTranslator::TranslateClasses(newJsPandaFile, ENTRY_FUNCTION_NAME); + CString methodName; + auto pos = entryPoint.find_last_of("::"); + if (pos != std::string_view::npos) { + methodName = entryPoint.substr(pos + 1); + } else { + // default use func_main_0 as entryPoint + methodName = ENTRY_FUNCTION_NAME; + } + + PandaFileTranslator::TranslateClasses(newJsPandaFile, methodName); { os::memory::LockHolder lock(jsPandaFileLock_); const JSPandaFile *jsPandaFile = FindJSPandaFile(desc); diff --git a/ecmascript/jspandafile/js_pandafile_manager.h b/ecmascript/jspandafile/js_pandafile_manager.h index d1969ec7e2..819f8853fb 100644 --- a/ecmascript/jspandafile/js_pandafile_manager.h +++ b/ecmascript/jspandafile/js_pandafile_manager.h @@ -34,22 +34,19 @@ class Program; class PUBLIC_API JSPandaFileManager { public: - ~JSPandaFileManager(); + static JSPandaFileManager *GetInstance(); - static JSPandaFileManager *GetInstance() - { - static JSPandaFileManager jsFileManager; - return &jsFileManager; - } + ~JSPandaFileManager(); JSHandle GenerateProgram(EcmaVM *vm, const JSPandaFile *jsPandaFile); - const JSPandaFile* LoadAotInfoFromPf(const CString &filename, - std::vector *methodPcInfos); + const JSPandaFile* LoadAotInfoFromPf(const CString &filename, std::string_view entryPoint, + std::vector *methodPcInfos); - const JSPandaFile *LoadJSPandaFile(const CString &filename); + const JSPandaFile *LoadJSPandaFile(const CString &filename, std::string_view entryPoint); - const JSPandaFile *LoadJSPandaFile(const CString &filename, const void *buffer, size_t size); + const JSPandaFile *LoadJSPandaFile(const CString &filename, std::string_view entryPoint, + const void *buffer, size_t size); JSPandaFile *OpenJSPandaFile(const CString &filename); @@ -81,7 +78,8 @@ private: static void FreeBuffer(void *mem); }; - const JSPandaFile *GenerateJSPandaFile(const panda_file::File *pf, const CString &desc); + const JSPandaFile *GenerateJSPandaFile(const panda_file::File *pf, const CString &desc, + std::string_view entryPoint); void ReleaseJSPandaFile(const JSPandaFile *jsPandaFile); const JSPandaFile *GetJSPandaFile(const panda_file::File *pf); const JSPandaFile *FindJSPandaFile(const CString &filename); diff --git a/ecmascript/jspandafile/panda_file_translator.cpp b/ecmascript/jspandafile/panda_file_translator.cpp index 31f3b089fc..903cc68864 100644 --- a/ecmascript/jspandafile/panda_file_translator.cpp +++ b/ecmascript/jspandafile/panda_file_translator.cpp @@ -133,7 +133,6 @@ JSTaggedValue PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSPandaFile JSHandle generatorDynclass = JSHandle::Cast(env->GetGeneratorFunctionClass()); const CUnorderedMap &constpoolMap = jsPandaFile->GetConstpoolMap(); - [[maybe_unused]] uint32_t mainMethodIndex = jsPandaFile->GetMainMethodIndex(); for (const auto &it : constpoolMap) { ConstPoolValue value(it.second); if (value.GetConstpoolType() == ConstPoolType::STRING) { @@ -143,7 +142,6 @@ JSTaggedValue PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSPandaFile foundStr.utf16_length, foundStr.is_ascii); constpool->Set(thread, value.GetConstpoolIndex(), JSTaggedValue(string)); } else if (value.GetConstpoolType() == ConstPoolType::BASE_FUNCTION) { - ASSERT(mainMethodIndex != it.first); panda_file::File::EntityId id(it.first); auto method = jsPandaFile->FindMethods(it.first); ASSERT(method != nullptr); @@ -153,7 +151,6 @@ JSTaggedValue PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSPandaFile constpool->Set(thread, value.GetConstpoolIndex(), jsFunc.GetTaggedValue()); jsFunc->SetConstantPool(thread, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::NC_FUNCTION) { - ASSERT(mainMethodIndex != it.first); panda_file::File::EntityId id(it.first); auto method = jsPandaFile->FindMethods(it.first); ASSERT(method != nullptr); @@ -163,7 +160,6 @@ JSTaggedValue PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSPandaFile constpool->Set(thread, value.GetConstpoolIndex(), jsFunc.GetTaggedValue()); jsFunc->SetConstantPool(thread, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::GENERATOR_FUNCTION) { - ASSERT(mainMethodIndex != it.first); panda_file::File::EntityId id(it.first); auto method = jsPandaFile->FindMethods(it.first); ASSERT(method != nullptr); @@ -182,7 +178,6 @@ JSTaggedValue PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSPandaFile constpool->Set(thread, value.GetConstpoolIndex(), jsFunc.GetTaggedValue()); jsFunc->SetConstantPool(thread, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::ASYNC_FUNCTION) { - ASSERT(mainMethodIndex != it.first); panda_file::File::EntityId id(it.first); auto method = jsPandaFile->FindMethods(it.first); ASSERT(method != nullptr); @@ -192,14 +187,12 @@ JSTaggedValue PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSPandaFile constpool->Set(thread, value.GetConstpoolIndex(), jsFunc.GetTaggedValue()); jsFunc->SetConstantPool(thread, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::CLASS_FUNCTION) { - ASSERT(mainMethodIndex != it.first); panda_file::File::EntityId id(it.first); auto method = jsPandaFile->FindMethods(it.first); ASSERT(method != nullptr); JSHandle classInfoExtractor = factory->NewClassInfoExtractor(method); constpool->Set(thread, value.GetConstpoolIndex(), classInfoExtractor.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::METHOD) { - ASSERT(mainMethodIndex != it.first); panda_file::File::EntityId id(it.first); auto method = jsPandaFile->FindMethods(it.first); ASSERT(method != nullptr); diff --git a/ecmascript/module/js_module_manager.cpp b/ecmascript/module/js_module_manager.cpp index 47ee5c62c6..1be02a5404 100644 --- a/ecmascript/module/js_module_manager.cpp +++ b/ecmascript/module/js_module_manager.cpp @@ -106,7 +106,8 @@ JSHandle ModuleManager::HostResolveImportedModule(const CStrin thread, NameDictionary::Cast(resolvedModules_.GetTaggedObject())->GetValue(entry)); } - const JSPandaFile *jsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(referencingModule); + const JSPandaFile *jsPandaFile = + JSPandaFileManager::GetInstance()->LoadJSPandaFile(referencingModule, ENTRY_MAIN_FUNCTION); if (jsPandaFile == nullptr) { LOG_ECMA(ERROR) << "open jsPandaFile " << referencingModule << " error"; UNREACHABLE(); diff --git a/ecmascript/module/js_module_source_text.cpp b/ecmascript/module/js_module_source_text.cpp index 4ea943b803..e73ec3e165 100644 --- a/ecmascript/module/js_module_source_text.cpp +++ b/ecmascript/module/js_module_source_text.cpp @@ -658,13 +658,13 @@ void SourceTextModule::ModuleExecution(JSThread *thread, const JSHandleGetEcmaModuleFilename(); ASSERT(moduleFileName.IsString()); CString moduleFilenameStr = ConvertToString(EcmaString::Cast(moduleFileName.GetHeapObject())); - const JSPandaFile *jsPandaFile = JSPandaFileManager::GetInstance()->LoadJSPandaFile(moduleFilenameStr); + const JSPandaFile *jsPandaFile = + JSPandaFileManager::GetInstance()->LoadJSPandaFile(moduleFilenameStr, ENTRY_MAIN_FUNCTION); if (jsPandaFile == nullptr) { LOG_ECMA(ERROR) << "open jsPandaFile " << moduleFilenameStr << " error"; UNREACHABLE(); } - std::vector argv; - JSPandaFileExecutor::Execute(thread, jsPandaFile, ENTRY_MAIN_FUNCTION, argv); + JSPandaFileExecutor::Execute(thread, jsPandaFile); } void SourceTextModule::AddImportEntry(JSThread *thread, const JSHandle &module, diff --git a/ecmascript/napi/jsnapi.cpp b/ecmascript/napi/jsnapi.cpp index 39fdca459d..704f8fd0ef 100644 --- a/ecmascript/napi/jsnapi.cpp +++ b/ecmascript/napi/jsnapi.cpp @@ -287,10 +287,9 @@ bool JSNApi::StopDebugger(const char *library_path) bool JSNApi::Execute(EcmaVM *vm, const std::string &fileName, const std::string &entry) { - std::vector argv; LOG_ECMA(DEBUG) << "start to execute ark file" << fileName; JSThread *thread = vm->GetAssociatedJSThread(); - if (!ecmascript::JSPandaFileExecutor::ExecuteFromFile(thread, fileName.c_str(), entry, argv)) { + if (!ecmascript::JSPandaFileExecutor::ExecuteFromFile(thread, fileName.c_str(), entry)) { LOG_ECMA(ERROR) << "Cannot execute ark file '" << fileName << "' with entry '" << entry << "'" << std::endl; return false; @@ -301,9 +300,8 @@ bool JSNApi::Execute(EcmaVM *vm, const std::string &fileName, const std::string bool JSNApi::Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry, const std::string &filename) { - std::vector argv; JSThread *thread = vm->GetAssociatedJSThread(); - if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, entry, argv, filename.c_str())) { + if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, entry, filename.c_str())) { LOG_ECMA(ERROR) << "Cannot execute ark buffer file '" << filename << "' with entry '" << entry << "'" << std::endl; return false; @@ -481,9 +479,8 @@ void* PromiseRejectInfo::GetData() const bool JSNApi::ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file) { - std::vector argv; JSThread *thread = vm->GetAssociatedJSThread(); - if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, ENTRY_POINTER, argv, file.c_str())) { + if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, ENTRY_POINTER, file.c_str())) { std::cerr << "Cannot execute panda file from memory" << std::endl; return false; } @@ -1505,7 +1502,9 @@ JSExecutionScope::~JSExecutionScope() // ----------------------------------- JSValueRef -------------------------------------- Local JSValueRef::Undefined(const EcmaVM *vm) { - return JSNApiHelper::ToLocal(JSHandle(vm->GetJSThread(), JSTaggedValue::Undefined())); + JSThread *thread = vm->GetJSThread(); + const GlobalEnvConstants *constants = thread->GlobalConstants(); + return JSNApiHelper::ToLocal(constants->GetHandledUndefined()); } Local JSValueRef::Null(const EcmaVM *vm) diff --git a/ecmascript/tooling/interface/debugger_api.cpp b/ecmascript/tooling/interface/debugger_api.cpp index 7967126fd7..ad879bcc28 100644 --- a/ecmascript/tooling/interface/debugger_api.cpp +++ b/ecmascript/tooling/interface/debugger_api.cpp @@ -17,6 +17,7 @@ #include "ecmascript/base/number_helper.h" #include "ecmascript/interpreter/frame_handler.h" +#include "ecmascript/jspandafile/js_pandafile_executor.h" #include "ecmascript/jspandafile/program_object.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_method.h" @@ -29,16 +30,32 @@ namespace panda::tooling::ecmascript { using panda::ecmascript::CStringToL; using panda::ecmascript::EcmaString; using panda::ecmascript::JSHandle; -using panda::ecmascript::JSTaggedValue; +using panda::ecmascript::JSPandaFileExecutor; using panda::ecmascript::JSNativePointer; +using panda::ecmascript::JSTaggedValue; using panda::ecmascript::LexicalEnv; -using panda::ecmascript::ScopeDebugInfo; using panda::ecmascript::Program; +using panda::ecmascript::ScopeDebugInfo; +using panda::ecmascript::TaggedArray; +using panda::ecmascript::JSThread; using panda::ecmascript::base::ALLOW_BINARY; using panda::ecmascript::base::ALLOW_HEX; using panda::ecmascript::base::ALLOW_OCTAL; using panda::ecmascript::base::NumberHelper; +// JSPandaFileExecutor +Local DebuggerApi::Execute(const EcmaVM *ecmaVm, const void *buffer, size_t size, + std::string_view entryPoint) +{ + JSThread *thread = ecmaVm->GetJSThread(); + auto result = JSPandaFileExecutor::ExecuteFromBuffer(thread, buffer, size, entryPoint); + if (!result) { + return JSValueRef::Undefined(ecmaVm); + } + + return JSNApiHelper::ToLocal(JSHandle(thread, result.Value())); +} + // InterpretedFrameHandler uint32_t DebuggerApi::GetStackDepth(const EcmaVM *ecmaVm) { diff --git a/ecmascript/tooling/interface/debugger_api.h b/ecmascript/tooling/interface/debugger_api.h index ab675eb10a..beb456d49a 100644 --- a/ecmascript/tooling/interface/debugger_api.h +++ b/ecmascript/tooling/interface/debugger_api.h @@ -56,6 +56,10 @@ enum StackState { class PUBLIC_API DebuggerApi { public: + // JSPandaFileExecutor + Local Execute(const EcmaVM *ecmaVm, const void *buffer, size_t size, + std::string_view entryPoint); + // InterpretedFrameHandler static uint32_t GetStackDepth(const EcmaVM *ecmaVm); static bool StackWalker(const EcmaVM *ecmaVm, std::function func); diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn index 8b1efea876..82a39b107c 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -38,6 +38,7 @@ group("ark_js_moduletest") { "promise:promiseAction", "spreadoperator:spreadoperatorAction", "throwdyn:throwdynAction", + "watch:watchAction", "yieldstar:yieldstarAction", ] if (!is_debug) { diff --git a/test/moduletest/watch/BUILD.gn b/test/moduletest/watch/BUILD.gn new file mode 100644 index 0000000000..917931d45d --- /dev/null +++ b/test/moduletest/watch/BUILD.gn @@ -0,0 +1,19 @@ +# 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. + +import("//ark/js_runtime/test/test_helper.gni") + +host_moduletest_action("watch") { + entry_point = "_GLOBAL::func_main_watch" + deps = [] +} diff --git a/test/moduletest/watch/expect_output.txt b/test/moduletest/watch/expect_output.txt new file mode 100644 index 0000000000..104c40660d --- /dev/null +++ b/test/moduletest/watch/expect_output.txt @@ -0,0 +1,14 @@ +# 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. + +watch function success! diff --git a/test/moduletest/watch/watch.js b/test/moduletest/watch/watch.js new file mode 100644 index 0000000000..9a3622296b --- /dev/null +++ b/test/moduletest/watch/watch.js @@ -0,0 +1,18 @@ +/* + * 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. + */ + +function func_main_watch() { + print("watch function success!") +} diff --git a/test/test_helper.gni b/test/test_helper.gni index 29451e458f..4af826c1fd 100644 --- a/test/test_helper.gni +++ b/test/test_helper.gni @@ -101,9 +101,12 @@ template("host_moduletest_action") { _extra_modules_ += [ "$target_out_dir/${module}.abc" ] } } - _test_abc_paths_ = rebase_path(_test_abc_path_) + _script_args_ = rebase_path(_test_abc_path_) foreach(extra_module, _extra_modules_) { - _test_abc_paths_ += ":" + rebase_path(extra_module) + _script_args_ += ":" + rebase_path(extra_module) + } + if (defined(invoker.entry_point)) { + _script_args_ += " " + invoker.entry_point } action("${_target_name_}Action") { @@ -132,7 +135,7 @@ template("host_moduletest_action") { "--script-options", js_vm_options, "--script-args", - _test_abc_paths_, + _script_args_, "--expect-file", rebase_path(_test_expect_path_), "--env-path", -- Gitee