mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 20:20:52 +00:00
commit
88e4f5ae42
2
BUILD.gn
2
BUILD.gn
@ -860,8 +860,10 @@ ecma_source = [
|
||||
"ecmascript/module/js_shared_module.cpp",
|
||||
"ecmascript/module/js_shared_module_manager.cpp",
|
||||
"ecmascript/module/module_data_extractor.cpp",
|
||||
"ecmascript/module/module_logger.cpp",
|
||||
"ecmascript/module/module_manager_helper.cpp",
|
||||
"ecmascript/module/module_path_helper.cpp",
|
||||
"ecmascript/module/module_tools.cpp",
|
||||
"ecmascript/module/napi_module_loader.cpp",
|
||||
"ecmascript/mutator_lock.cpp",
|
||||
"ecmascript/napi/jsnapi.cpp",
|
||||
|
@ -1254,4 +1254,4 @@ JSTaggedValue BuiltinsArkTools::StopRuntimeStat(EcmaRuntimeCallInfo *msg)
|
||||
thread->GetCurrentEcmaContext()->SetRuntimeStatEnable(false);
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
} // namespace panda::ecmascript::builtins
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
@ -40,8 +40,9 @@
|
||||
#include "ecmascript/linked_hash_table.h"
|
||||
#include "ecmascript/log.h"
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/module/js_shared_module.h"
|
||||
#include "ecmascript/module/module_logger.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/patch/patch_loader.h"
|
||||
#include "ecmascript/platform/aot_crash_info.h"
|
||||
@ -129,6 +130,9 @@ bool EcmaContext::Initialize()
|
||||
if (vm_->GetJSOptions().GetTypedOpProfiler()) {
|
||||
typedOpProfiler_ = new TypedOpProfiler();
|
||||
}
|
||||
if (vm_->GetJSOptions().EnableModuleLog() && !vm_->GetJSOptions().IsWorker()) {
|
||||
moduleLogger_ = new ModuleLogger(vm_);
|
||||
}
|
||||
functionProtoTransitionTable_ = new FunctionProtoTransitionTable(thread_);
|
||||
sustainingJSHandleList_ = new SustainingJSHandleList();
|
||||
initialized_ = true;
|
||||
@ -244,6 +248,10 @@ EcmaContext::~EcmaContext()
|
||||
delete moduleManager_;
|
||||
moduleManager_ = nullptr;
|
||||
}
|
||||
if (moduleLogger_ != nullptr) {
|
||||
delete moduleLogger_;
|
||||
moduleLogger_ = nullptr;
|
||||
}
|
||||
if (ptManager_ != nullptr) {
|
||||
delete ptManager_;
|
||||
ptManager_ = nullptr;
|
||||
@ -383,6 +391,10 @@ Expected<JSTaggedValue, bool> EcmaContext::InvokeEcmaEntrypoint(const JSPandaFil
|
||||
if (options.EnableModuleLog()) {
|
||||
LOG_FULL(INFO) << "current executing file's name " << entryPoint.data();
|
||||
}
|
||||
ModuleLogger *moduleLogger = GetModuleLogger();
|
||||
if (moduleLogger != nullptr) {
|
||||
moduleLogger->SetStartTime(CString(entryPoint));
|
||||
}
|
||||
JSHandle<Program> program = JSPandaFileManager::GetInstance()->GenerateProgram(vm_, jsPandaFile, entryPoint);
|
||||
if (program.IsEmpty()) {
|
||||
LOG_ECMA(ERROR) << "program is empty, invoke entrypoint failed";
|
||||
@ -401,6 +413,9 @@ Expected<JSTaggedValue, bool> EcmaContext::InvokeEcmaEntrypoint(const JSPandaFil
|
||||
}
|
||||
#endif
|
||||
|
||||
if (moduleLogger != nullptr) {
|
||||
moduleLogger->SetEndTime(CString(entryPoint));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,7 @@ class QuickFixManager;
|
||||
class OptCodeProfiler;
|
||||
struct CJSInfo;
|
||||
class FunctionProtoTransitionTable;
|
||||
class ModuleLogger;
|
||||
|
||||
namespace job {
|
||||
class MicroJobQueue;
|
||||
@ -312,6 +313,11 @@ public:
|
||||
return typedOpProfiler_;
|
||||
}
|
||||
|
||||
ModuleLogger *GetModuleLogger() const
|
||||
{
|
||||
return moduleLogger_;
|
||||
}
|
||||
|
||||
void SetDefaultLocale(const std::string& locale)
|
||||
{
|
||||
defaultLocale_ = locale;
|
||||
@ -708,6 +714,8 @@ private:
|
||||
// opt code loop hoist
|
||||
TypedOpProfiler *typedOpProfiler_ {nullptr};
|
||||
|
||||
ModuleLogger *moduleLogger_ {nullptr};
|
||||
|
||||
std::string defaultLocale_;
|
||||
std::optional<CompareStringsOption> defaultComapreStringsOption_;
|
||||
|
||||
|
@ -77,6 +77,7 @@
|
||||
#include "ecmascript/module/js_module_manager.h"
|
||||
#include "ecmascript/module/module_data_extractor.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/module/module_logger.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/patch/quick_fix_manager.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
|
||||
@ -184,6 +185,10 @@ void EcmaVM::PostFork()
|
||||
heap_->NotifyPostFork();
|
||||
heap_->NotifyFinishColdStartSoon();
|
||||
#endif
|
||||
ModuleLogger *moduleLogger = thread_->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
if (moduleLogger != nullptr) {
|
||||
moduleLogger->PostModuleLoggerTask(thread_->GetThreadId(), this);
|
||||
}
|
||||
#if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
|
||||
int arkProperties = OHOS::system::GetIntParameter<int>("persist.ark.properties", -1);
|
||||
GetJSOptions().SetArkProperties(arkProperties);
|
||||
|
@ -29,8 +29,10 @@
|
||||
#include "ecmascript/module/js_shared_module.h"
|
||||
#include "ecmascript/module/js_shared_module_manager.h"
|
||||
#include "ecmascript/module/module_data_extractor.h"
|
||||
#include "ecmascript/module/module_logger.h"
|
||||
#include "ecmascript/module/module_manager_helper.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/module/module_tools.h"
|
||||
#include "ecmascript/require/js_cjs_module.h"
|
||||
#include "ecmascript/tagged_dictionary.h"
|
||||
#ifdef PANDA_TARGET_WINDOWS
|
||||
@ -119,6 +121,10 @@ JSTaggedValue ModuleManager::GetModuleValueOutterInternal(int32_t index, JSTagge
|
||||
}
|
||||
ASSERT(moduleEnvironment.IsTaggedArray());
|
||||
JSTaggedValue resolvedBinding = TaggedArray::Cast(moduleEnvironment.GetTaggedObject())->Get(index);
|
||||
ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
if (moduleLogger != nullptr) {
|
||||
return ModuleTools::ProcessModuleLoadInfo(thread, currentModuleHdl, resolvedBinding, index);
|
||||
}
|
||||
if (resolvedBinding.IsResolvedIndexBinding()) {
|
||||
ResolvedIndexBinding *binding = ResolvedIndexBinding::Cast(resolvedBinding.GetTaggedObject());
|
||||
JSTaggedValue resolvedModule = binding->GetModule();
|
||||
@ -613,6 +619,11 @@ JSTaggedValue ModuleManager::GetModuleNamespaceInternal(int32_t index, JSTaggedV
|
||||
}
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
|
||||
JSHandle<SourceTextModule> requiredModuleST = JSHandle<SourceTextModule>::Cast(requiredModule);
|
||||
ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
if (moduleLogger != nullptr) {
|
||||
return ModuleTools::ProcessModuleNameSpaceLoadInfo(thread,
|
||||
JSHandle<SourceTextModule>(thread, module), requiredModuleST);
|
||||
}
|
||||
ModuleTypes moduleType = requiredModuleST->GetTypes();
|
||||
// if requiredModuleST is Native module
|
||||
if (SourceTextModule::IsNativeModule(moduleType)) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
||||
#include "ecmascript/js_promise.h"
|
||||
#include "ecmascript/linked_hash_table.h"
|
||||
#include "ecmascript/module/module_logger.h"
|
||||
#include "ecmascript/module/js_module_deregister.h"
|
||||
#include "ecmascript/module/js_module_manager.h"
|
||||
#include "ecmascript/module/js_module_namespace.h"
|
||||
@ -388,6 +389,10 @@ Local<JSValueRef> SourceTextModule::LoadNativeModuleImpl(EcmaVM *vm, JSThread *t
|
||||
CString traceInfo = "LoadNativeModule: " + moduleRequestName;
|
||||
ECMA_BYTRACE_START_TRACE(HITRACE_TAG_ARK, traceInfo.c_str());
|
||||
}
|
||||
ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
if (moduleLogger != nullptr) {
|
||||
moduleLogger->SetStartTime(moduleRequestName);
|
||||
}
|
||||
CString soName = PathHelper::GetStrippedModuleName(moduleRequestName);
|
||||
|
||||
CString fileName = requiredModule->GetEcmaModuleFilenameString();
|
||||
@ -405,11 +410,23 @@ Local<JSValueRef> SourceTextModule::LoadNativeModuleImpl(EcmaVM *vm, JSThread *t
|
||||
// some function(s) may not registered in global object for non-main thread
|
||||
if (!maybeFuncRef->IsFunction(vm)) {
|
||||
LOG_FULL(WARN) << "Not found require func";
|
||||
if (enableESMTrace) {
|
||||
ECMA_BYTRACE_FINISH_TRACE(HITRACE_TAG_ARK);
|
||||
}
|
||||
if (moduleLogger != nullptr) {
|
||||
moduleLogger->SetEndTime(moduleRequestName);
|
||||
}
|
||||
return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
|
||||
}
|
||||
|
||||
Local<FunctionRef> funcRef = maybeFuncRef;
|
||||
auto exportObject = funcRef->Call(vm, JSValueRef::Undefined(vm), arguments.data(), arguments.size());
|
||||
if (enableESMTrace) {
|
||||
ECMA_BYTRACE_FINISH_TRACE(HITRACE_TAG_ARK);
|
||||
}
|
||||
if (moduleLogger != nullptr) {
|
||||
moduleLogger->SetEndTime(moduleRequestName);
|
||||
}
|
||||
return exportObject;
|
||||
}
|
||||
|
||||
@ -962,6 +979,10 @@ JSTaggedValue SourceTextModule::Evaluate(JSThread *thread, const JSHandle<Source
|
||||
if (!thread->HasPendingException() && !executeFromJob) {
|
||||
job::MicroJobQueue::ExecutePendingJob(thread, thread->GetCurrentEcmaContext()->GetMicroJobQueue());
|
||||
}
|
||||
ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
if ((moduleLogger != nullptr) && !executeFromJob) {
|
||||
moduleLogger->InsertEntryPointModule(module);
|
||||
}
|
||||
// Return capability.[[Promise]].
|
||||
return capability->GetPromise();
|
||||
}
|
||||
@ -1023,6 +1044,7 @@ int SourceTextModule::InnerModuleEvaluationUnsafe(JSThread *thread, const JSHand
|
||||
module->SetPendingAsyncDependencies(0);
|
||||
index++;
|
||||
stack.emplace_back(module);
|
||||
ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
if (!module->GetRequestedModules().IsUndefined()) {
|
||||
JSHandle<TaggedArray> requestedModules(thread, module->GetRequestedModules());
|
||||
size_t requestedModulesLen = requestedModules->GetLength();
|
||||
@ -1043,6 +1065,9 @@ int SourceTextModule::InnerModuleEvaluationUnsafe(JSThread *thread, const JSHand
|
||||
SourceTextModule::HostResolveImportedModuleWithMerge(thread, module, required));
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, index);
|
||||
}
|
||||
if (moduleLogger != nullptr) {
|
||||
moduleLogger->InsertParentModule(module, requiredModule);
|
||||
}
|
||||
ModuleTypes moduleType = requiredModule->GetTypes();
|
||||
if (SourceTextModule::IsNativeModule(moduleType)) {
|
||||
EvaluateNativeModule(thread, requiredModule, moduleType);
|
||||
|
275
ecmascript/module/module_logger.cpp
Normal file
275
ecmascript/module/module_logger.cpp
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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/module/module_logger.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/runtime_lock.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
ModuleLogger::ModuleLogger(EcmaVM *vm) : vm_(vm) {}
|
||||
|
||||
void ModuleLogger::PrintModuleLoadInfo()
|
||||
{
|
||||
ProcessModuleExecuteTime();
|
||||
PrintSummary();
|
||||
PrintUsedFileInfo();
|
||||
PrintUnusedFileInfo();
|
||||
}
|
||||
|
||||
bool ModuleLogger::CreateResultFile(std::string &path) const
|
||||
{
|
||||
path = FILEDIR + std::string(vm_->GetBundleName().c_str()) + SUFFIX;
|
||||
const mode_t defaultMode = S_IRUSR | S_IWUSR | S_IRGRP; // -rw-r--
|
||||
int fd = creat(path.c_str(), defaultMode);
|
||||
if (fd == -1) {
|
||||
LOG_ECMA(ERROR) << "file create failed, errno = "<< errno;
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleLogger::OpenResultFile(std::string &path) const
|
||||
{
|
||||
path = FILEDIR + std::string(vm_->GetBundleName().c_str()) + SUFFIX;
|
||||
if (access(path.c_str(), F_OK) == 0) {
|
||||
if (access(path.c_str(), W_OK) == 0) {
|
||||
LOG_ECMA(DEBUG) << "file open success";
|
||||
return true;
|
||||
}
|
||||
LOG_ECMA(ERROR) << "file create failed, W_OK false";
|
||||
return false;
|
||||
}
|
||||
return CreateResultFile(path);
|
||||
}
|
||||
|
||||
void ModuleLogger::InsertModuleLoadInfo(JSHandle<SourceTextModule> currentModule,
|
||||
JSHandle<SourceTextModule> exportModule, int32_t index)
|
||||
{
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
RuntimeLockHolder locker(thread, mutex_);
|
||||
CString curName = SourceTextModule::GetModuleName(currentModule.GetTaggedValue());
|
||||
CString sonName = SourceTextModule::GetModuleName(exportModule.GetTaggedValue());
|
||||
ModuleLoadInfo *sonModule = GetModuleLoadInfo(sonName);
|
||||
sonModule->isUsed = true;
|
||||
// get importName
|
||||
CString exportNameStr;
|
||||
if (index < 0) {
|
||||
exportNameStr = "*";
|
||||
} else {
|
||||
JSHandle<TaggedArray> importArray(thread, currentModule->GetImportEntries());
|
||||
JSHandle<ImportEntry> importEntry(thread, importArray->Get(index));
|
||||
JSHandle<JSTaggedValue> importName(thread, importEntry->GetImportName());
|
||||
exportNameStr = ModulePathHelper::Utf8ConvertToString(importName.GetTaggedValue());
|
||||
}
|
||||
auto &upLevelInfo = sonModule->upLevel;
|
||||
auto ulModule = upLevelInfo.find(curName);
|
||||
if (ulModule == upLevelInfo.end()) {
|
||||
CSet<CString> tmp;
|
||||
tmp.insert(exportNameStr);
|
||||
upLevelInfo.emplace(curName, std::move(tmp));
|
||||
return;
|
||||
}
|
||||
ulModule->second.insert(exportNameStr);
|
||||
}
|
||||
|
||||
void ModuleLogger::InsertParentModule(JSHandle<SourceTextModule> currentModule,
|
||||
JSHandle<SourceTextModule> requiredModule)
|
||||
{
|
||||
RuntimeLockHolder locker(vm_->GetJSThread(), mutex_);
|
||||
CString curName = currentModule->GetEcmaModuleRecordNameString();
|
||||
CString sonName = requiredModule->GetEcmaModuleRecordNameString();
|
||||
ModuleLoadInfo *sonModule = GetModuleLoadInfo(sonName);
|
||||
sonModule->parentModules.insert(std::move(curName));
|
||||
}
|
||||
|
||||
void ModuleLogger::InsertEntryPointModule(JSHandle<SourceTextModule> currentModule)
|
||||
{
|
||||
RuntimeLockHolder locker(vm_->GetJSThread(), mutex_);
|
||||
CString curName = currentModule->GetEcmaModuleRecordNameString();
|
||||
ModuleLoadInfo *curModule = GetModuleLoadInfo(curName);
|
||||
curModule->isUsed = true;
|
||||
auto &upLevelInfo = curModule->upLevel;
|
||||
CSet<CString> tmp;
|
||||
upLevelInfo.emplace("EntryPoint", tmp);
|
||||
}
|
||||
|
||||
void ModuleLogger::PrintSummary() const
|
||||
{
|
||||
std::string path;
|
||||
if (!CreateResultFile(path)) {
|
||||
LOG_ECMA(ERROR) << "open file fail, no log anymore";
|
||||
}
|
||||
std::ofstream fileHandle;
|
||||
fileHandle.open(path, std::ios_base::app);
|
||||
std::string start = "<----Summary----> Total file number: " + std::to_string(totalFileNumber_) + ", total time: " +
|
||||
std::to_string(totalTime_) + "ms, including used file:" + std::to_string(usedFileNumber_) +
|
||||
", cost time: " + std::to_string(usedFileTime_) + "ms, and unused file: " +
|
||||
std::to_string(unusedFileNumber_) +", cost time: " + std::to_string(unusedFileTime_) + "ms\n";
|
||||
fileHandle << start;
|
||||
fileHandle.close();
|
||||
}
|
||||
|
||||
void ModuleLogger::PrintUsedFileInfo() const
|
||||
{
|
||||
std::string path;
|
||||
if (!OpenResultFile(path)) {
|
||||
LOG_ECMA(ERROR) << "open file fail, no log anymore";
|
||||
}
|
||||
std::ofstream fileHandle;
|
||||
fileHandle.open(path, std::ios_base::app);
|
||||
std::string start = "<----used file start----> used file: " + std::to_string(usedFileNumber_) + ", cost time: "
|
||||
+ std::to_string(usedFileTime_) + "ms\n";
|
||||
fileHandle << start;
|
||||
int32_t fileNumber = 1;
|
||||
for (auto &i : jsModuleLoadInfo_) {
|
||||
ModuleLoadInfo *info = i.second;
|
||||
if (info->isUsed) {
|
||||
std::string content = "used file " + std::to_string(fileNumber++) + ": " + i.first.c_str() +
|
||||
", cost time: " + ToStringWithPrecision(info->time, THREE) + "ms\n";
|
||||
fileHandle << content;
|
||||
auto &upInfo = info->upLevel;
|
||||
int32_t parentModuleCount = 1;
|
||||
for (auto &k : upInfo) {
|
||||
std::string parentInfoStr = " parentModule " + std::to_string(parentModuleCount++) +
|
||||
": " + k.first.c_str() + " ";
|
||||
for (auto &exportN : k.second) {
|
||||
parentInfoStr += exportN + " ";
|
||||
}
|
||||
parentInfoStr += "\n";
|
||||
fileHandle << parentInfoStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string end = "<----------used file end----------> \n";
|
||||
fileHandle << end;
|
||||
fileHandle.close();
|
||||
}
|
||||
|
||||
void ModuleLogger::PrintUnusedFileInfo() const
|
||||
{
|
||||
std::string path;
|
||||
if (!OpenResultFile(path)) {
|
||||
LOG_ECMA(ERROR) << "open file fail, no log anymore";
|
||||
}
|
||||
std::ofstream fileHandle;
|
||||
fileHandle.open(path, std::ios_base::app);
|
||||
std::string start = "<----unused file start----> unused file: " + std::to_string(unusedFileNumber_) +
|
||||
", cost time: " + std::to_string(unusedFileTime_) + "ms\n";
|
||||
fileHandle << start;
|
||||
int32_t fileNumber = 1;
|
||||
for (auto &i : jsModuleLoadInfo_) {
|
||||
ModuleLoadInfo *info = i.second;
|
||||
if (!info->isUsed) {
|
||||
std::string content = "unused file " + std::to_string(fileNumber++) + ": " + i.first.c_str() +
|
||||
", cost time: " + ToStringWithPrecision(info->time, THREE) + "ms\n";
|
||||
fileHandle << content;
|
||||
int32_t parentNumber = 1;
|
||||
CSet<CString> parents = info->parentModules;
|
||||
for (auto &k : parents) {
|
||||
std::string parent = " parentModule " + std::to_string(parentNumber++) +
|
||||
": " + k.c_str() + "\n";
|
||||
fileHandle << parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string end = "<----------unused file end----------> \n";
|
||||
fileHandle << end;
|
||||
fileHandle.close();
|
||||
}
|
||||
|
||||
void ModuleLogger::ProcessModuleExecuteTime()
|
||||
{
|
||||
RuntimeLockHolder locker(vm_->GetJSThread(), mutex_);
|
||||
totalFileNumber_ = jsModuleLoadInfo_.size();
|
||||
double totalTime = 0;
|
||||
double usedFileTime = 0;
|
||||
double unusedFileTime = 0;
|
||||
for (auto &i : jsModuleLoadInfo_) {
|
||||
ModuleLoadInfo *info = i.second;
|
||||
double time = info->time;
|
||||
if (time > TWO_SECONDS) {
|
||||
time = 0;
|
||||
}
|
||||
if (info->isUsed) {
|
||||
usedFileNumber_++;
|
||||
usedFileTime += time;
|
||||
} else {
|
||||
unusedFileNumber_++;
|
||||
unusedFileTime += time;
|
||||
}
|
||||
totalTime += time;
|
||||
}
|
||||
totalTime_ = static_cast<int64_t>(totalTime);
|
||||
usedFileTime_ = static_cast<int64_t>(usedFileTime);
|
||||
unusedFileTime_ = static_cast<int64_t>(unusedFileTime);
|
||||
}
|
||||
|
||||
ModuleLoadInfo *ModuleLogger::GetModuleLoadInfo(const CString &recordName)
|
||||
{
|
||||
auto info = jsModuleLoadInfo_.find(recordName);
|
||||
if (info != jsModuleLoadInfo_.end()) {
|
||||
return info->second;
|
||||
}
|
||||
ModuleLoadInfo *newInfo = new ModuleLoadInfo();
|
||||
jsModuleLoadInfo_.emplace(recordName, newInfo);
|
||||
return newInfo;
|
||||
}
|
||||
|
||||
void ModuleLogger::SetStartTime(const CString &recordName)
|
||||
{
|
||||
RuntimeLockHolder locker(vm_->GetJSThread(), mutex_);
|
||||
ModuleLoadInfo *info = GetModuleLoadInfo(recordName);
|
||||
info->time = std::chrono::duration_cast<std::chrono::microseconds>
|
||||
(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
void ModuleLogger::SetEndTime(const CString &recordName)
|
||||
{
|
||||
RuntimeLockHolder locker(vm_->GetJSThread(), mutex_);
|
||||
ModuleLoadInfo *info = GetModuleLoadInfo(recordName);
|
||||
double time = info->time;
|
||||
info->time = (std::chrono::duration_cast<std::chrono::microseconds>
|
||||
(std::chrono::high_resolution_clock::now().time_since_epoch())
|
||||
.count() - time) / DOUBLE_MILLISECONDS_PER_SEC;
|
||||
}
|
||||
|
||||
std::string ModuleLogger::ToStringWithPrecision(const double num, const uint8_t n)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << std::setprecision(n) << num;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void ModuleLogger::PostModuleLoggerTask(int32_t id, EcmaVM *vm)
|
||||
{
|
||||
Taskpool::GetCurrentTaskpool()->PostTask(
|
||||
std::make_unique<ModuleLoggerTask>(id, vm));
|
||||
}
|
||||
|
||||
bool ModuleLogger::ModuleLoggerTask::Run([[maybe_unused]]uint32_t threadIndex)
|
||||
{
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "ModuleLoggerTask::Run");
|
||||
std::this_thread::sleep_for(
|
||||
std::chrono::microseconds(static_cast<int64_t>(TWO_SECONDS))); // 2s
|
||||
ModuleLogger *moduleLogger =
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
moduleLogger->PrintModuleLoadInfo();
|
||||
return true;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
96
ecmascript/module/module_logger.h
Normal file
96
ecmascript/module/module_logger.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_MODULE_MODULE_LOGGER_H
|
||||
#define ECMASCRIPT_MODULE_MODULE_LOGGER_H
|
||||
|
||||
#include "ecmascript/module/js_module_source_text.h"
|
||||
|
||||
#include <fstream>
|
||||
namespace panda::ecmascript {
|
||||
|
||||
struct ModuleLoadInfo {
|
||||
bool isUsed {false};
|
||||
CSet<CString> parentModules {};
|
||||
CMap<CString, CSet<CString>> upLevel {}; // parent module and importName
|
||||
double time {0};
|
||||
};
|
||||
|
||||
class ModuleLogger {
|
||||
public:
|
||||
explicit ModuleLogger(EcmaVM *vm);
|
||||
~ModuleLogger()
|
||||
{
|
||||
for (auto &info : jsModuleLoadInfo_) {
|
||||
delete info.second;
|
||||
}
|
||||
jsModuleLoadInfo_.clear();
|
||||
}
|
||||
void SetStartTime(const CString &recordName);
|
||||
void SetEndTime(const CString &recordName);
|
||||
void PostModuleLoggerTask(int32_t id, EcmaVM *vm);
|
||||
void InsertModuleLoadInfo(JSHandle<SourceTextModule> currentModule,
|
||||
JSHandle<SourceTextModule> exportModule,
|
||||
int32_t index);
|
||||
void InsertParentModule(JSHandle<SourceTextModule> currentModule, JSHandle<SourceTextModule> requiredModule);
|
||||
void InsertEntryPointModule(JSHandle<SourceTextModule> currentModule);
|
||||
|
||||
private:
|
||||
static constexpr const int MILLISECONDS_PER_SEC = 1000;
|
||||
static constexpr const double DOUBLE_MILLISECONDS_PER_SEC = 1000.0;
|
||||
static constexpr const int TWO = 2;
|
||||
static constexpr const int THREE = 3;
|
||||
static constexpr const double TWO_SECONDS = TWO * MILLISECONDS_PER_SEC * MILLISECONDS_PER_SEC;
|
||||
static constexpr const char FILEDIR[] = "/data/storage/el2/base/files/";
|
||||
static constexpr const char SUFFIX[] = "_redundant_file.txt";
|
||||
|
||||
NO_COPY_SEMANTIC(ModuleLogger);
|
||||
NO_MOVE_SEMANTIC(ModuleLogger);
|
||||
|
||||
bool CreateResultFile(std::string &path) const; // first time
|
||||
bool OpenResultFile(std::string &path) const;
|
||||
ModuleLoadInfo *GetModuleLoadInfo(const CString &recordName);
|
||||
void PrintModuleLoadInfo();
|
||||
void PrintSummary() const;
|
||||
void PrintUsedFileInfo() const;
|
||||
void PrintUnusedFileInfo() const;
|
||||
void ProcessModuleExecuteTime();
|
||||
static std::string ToStringWithPrecision(const double num, const uint8_t n);
|
||||
|
||||
EcmaVM *vm_ {nullptr};
|
||||
CUnorderedMap<CString, ModuleLoadInfo*> jsModuleLoadInfo_ {};
|
||||
uint32_t totalFileNumber_ {0};
|
||||
uint32_t unusedFileNumber_ {0};
|
||||
uint32_t usedFileNumber_ {0};
|
||||
int64_t totalTime_ {0};
|
||||
int64_t usedFileTime_ {0};
|
||||
int64_t unusedFileTime_ {0};
|
||||
Mutex mutex_;
|
||||
|
||||
class ModuleLoggerTask : public Task {
|
||||
public:
|
||||
ModuleLoggerTask(int32_t id, EcmaVM *vm)
|
||||
: Task(id), vm_(vm) {}
|
||||
~ModuleLoggerTask() override = default;
|
||||
bool Run([[maybe_unused]]uint32_t threadIndex) override;
|
||||
|
||||
NO_COPY_SEMANTIC(ModuleLoggerTask);
|
||||
NO_MOVE_SEMANTIC(ModuleLoggerTask);
|
||||
private:
|
||||
EcmaVM *vm_ {nullptr};
|
||||
};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_MODULE_MODULE_LOGGER_H
|
@ -18,6 +18,7 @@
|
||||
#include "ecmascript/jspandafile/js_pandafile_executor.h"
|
||||
#include "ecmascript/module/js_module_source_text.h"
|
||||
#include "ecmascript/module/js_shared_module.h"
|
||||
#include "ecmascript/module/module_logger.h"
|
||||
#include "ecmascript/require/js_cjs_module.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/tagged_array-inl.h"
|
||||
@ -87,50 +88,59 @@ JSTaggedValue ModuleManagerHelper::GetModuleValue(JSThread *thread, JSHandle<Sou
|
||||
JSTaggedValue::Undefined())).GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue ModuleManagerHelper::GetModuleValueFromIndexBinding(JSThread *thread, JSHandle<SourceTextModule> module,
|
||||
JSTaggedValue ModuleManagerHelper::GetModuleValueFromIndexBinding(JSThread *thread,
|
||||
JSHandle<SourceTextModule> module,
|
||||
JSTaggedValue resolvedBinding)
|
||||
{
|
||||
JSHandle<ResolvedRecordIndexBinding> binding(thread, resolvedBinding);
|
||||
JSHandle<SourceTextModule> resolvedModule = GetResolvedRecordIndexBindingModule(thread, module, binding);
|
||||
return GetModuleValue(thread, resolvedModule, binding->GetIndex());
|
||||
}
|
||||
|
||||
JSHandle<SourceTextModule> ModuleManagerHelper::GetResolvedRecordIndexBindingModule(
|
||||
JSThread *thread, JSHandle<SourceTextModule> module, JSHandle<ResolvedRecordIndexBinding> binding)
|
||||
{
|
||||
JSHandle<JSTaggedValue> recordName(thread, binding->GetModuleRecord());
|
||||
ASSERT(recordName->IsString());
|
||||
// recordName is string, find at current vm
|
||||
ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
|
||||
CString recordNameStr = ModulePathHelper::Utf8ConvertToString(recordName.GetTaggedValue());
|
||||
JSHandle<SourceTextModule> resolvedModule;
|
||||
if (moduleManager->IsEvaluatedModule(recordNameStr)) {
|
||||
resolvedModule = moduleManager->HostGetImportedModule(recordNameStr);
|
||||
} else {
|
||||
if (!moduleManager->IsEvaluatedModule(recordNameStr)) {
|
||||
auto isMergedAbc = !module->GetEcmaModuleRecordNameString().empty();
|
||||
CString fileName = ModulePathHelper::Utf8ConvertToString((binding->GetAbcFileName()));
|
||||
if (!JSPandaFileExecutor::LazyExecuteModule(thread, recordNameStr, fileName, isMergedAbc)) {
|
||||
LOG_ECMA(FATAL) << "LazyExecuteModule failed";
|
||||
}
|
||||
resolvedModule = moduleManager->HostGetImportedModule(recordNameStr);
|
||||
}
|
||||
return GetModuleValue(thread, resolvedModule, binding->GetIndex());
|
||||
return moduleManager->HostGetImportedModule(recordNameStr);
|
||||
}
|
||||
|
||||
JSTaggedValue ModuleManagerHelper::GetModuleValueFromRecordBinding(JSThread *thread, JSHandle<SourceTextModule> module,
|
||||
JSTaggedValue ModuleManagerHelper::GetModuleValueFromRecordBinding(JSThread *thread,
|
||||
JSHandle<SourceTextModule> module,
|
||||
JSTaggedValue resolvedBinding)
|
||||
{
|
||||
JSHandle<ResolvedRecordBinding> binding(thread, resolvedBinding);
|
||||
JSHandle<SourceTextModule> resolvedModule = GetResolvedRecordBindingModule(thread, module, binding);
|
||||
return GetModuleValue(thread, resolvedModule, binding->GetBindingName());
|
||||
}
|
||||
|
||||
JSHandle<SourceTextModule> ModuleManagerHelper::GetResolvedRecordBindingModule(JSThread *thread,
|
||||
JSHandle<SourceTextModule> module,
|
||||
JSHandle<ResolvedRecordBinding> binding)
|
||||
{
|
||||
JSHandle<JSTaggedValue> recordName(thread, binding->GetModuleRecord());
|
||||
ASSERT(recordName->IsString());
|
||||
CString recordNameStr = ModulePathHelper::Utf8ConvertToString(recordName.GetTaggedValue());
|
||||
// moduleRecord is string, find at current vm
|
||||
ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
|
||||
JSHandle<SourceTextModule> resolvedModule;
|
||||
if (moduleManager->IsEvaluatedModule(recordNameStr)) {
|
||||
resolvedModule = moduleManager->HostGetImportedModule(recordNameStr);
|
||||
} else {
|
||||
if (!moduleManager->IsEvaluatedModule(recordNameStr)) {
|
||||
auto isMergedAbc = !module->GetEcmaModuleRecordNameString().empty();
|
||||
CString fileName = module->GetEcmaModuleFilenameString();
|
||||
if (!JSPandaFileExecutor::LazyExecuteModule(thread, recordNameStr, fileName, isMergedAbc)) {
|
||||
LOG_ECMA(FATAL) << "LazyExecuteModule failed";
|
||||
}
|
||||
resolvedModule = moduleManager->HostGetImportedModule(recordNameStr);
|
||||
}
|
||||
return GetModuleValue(thread, resolvedModule, binding->GetBindingName());
|
||||
return moduleManager->HostGetImportedModule(recordNameStr);
|
||||
}
|
||||
|
||||
JSTaggedValue ModuleManagerHelper::GetLazyModuleValueFromIndexBinding(JSThread *thread,
|
||||
|
@ -42,6 +42,12 @@ public:
|
||||
static JSTaggedValue PUBLIC_API GetModuleValueFromRecordBinding(JSThread *thread,
|
||||
JSHandle<SourceTextModule> module,
|
||||
JSTaggedValue resolvedBinding);
|
||||
|
||||
static JSHandle<SourceTextModule> GetResolvedRecordIndexBindingModule(
|
||||
JSThread *thread, JSHandle<SourceTextModule> module, JSHandle<ResolvedRecordIndexBinding> binding);
|
||||
|
||||
static JSHandle<SourceTextModule> GetResolvedRecordBindingModule(
|
||||
JSThread *thread, JSHandle<SourceTextModule> module, JSHandle<ResolvedRecordBinding> binding);
|
||||
|
||||
static JSTaggedValue GetLazyModuleValueFromIndexBinding(JSThread *thread,
|
||||
JSHandle<SourceTextModule> module,
|
||||
|
128
ecmascript/module/module_tools.cpp
Normal file
128
ecmascript/module/module_tools.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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/module/module_tools.h"
|
||||
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/module/js_shared_module.h"
|
||||
#include "ecmascript/module/module_logger.h"
|
||||
#include "ecmascript/module/module_manager_helper.h"
|
||||
#include "ecmascript/require/js_cjs_module.h"
|
||||
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
JSTaggedValue ModuleTools::GetModuleValueFromIndexBindingForLog(
|
||||
JSThread *thread, JSHandle<SourceTextModule> module, JSTaggedValue resolvedBinding, int32_t index)
|
||||
{
|
||||
JSHandle<ResolvedRecordIndexBinding> binding(thread, resolvedBinding);
|
||||
JSHandle<SourceTextModule> resolvedModule =
|
||||
ModuleManagerHelper::GetResolvedRecordIndexBindingModule(thread, module, binding);
|
||||
ModuleLogger *moduleLogger =
|
||||
thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
moduleLogger->InsertModuleLoadInfo(module, resolvedModule, index);
|
||||
return ModuleManagerHelper::GetModuleValue(thread, resolvedModule, binding->GetIndex());
|
||||
}
|
||||
|
||||
// use for moduleLogger is not nullptr
|
||||
JSTaggedValue ModuleTools::GetModuleValueFromRecordBindingForLog(
|
||||
JSThread *thread, JSHandle<SourceTextModule> module, JSTaggedValue resolvedBinding, int32_t index)
|
||||
{
|
||||
JSHandle<ResolvedRecordBinding> binding(thread, resolvedBinding);
|
||||
JSHandle<SourceTextModule> resolvedModule =
|
||||
ModuleManagerHelper::GetResolvedRecordBindingModule(thread, module, binding);
|
||||
ModuleLogger *moduleLogger =
|
||||
thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
moduleLogger->InsertModuleLoadInfo(module, resolvedModule, index);
|
||||
return ModuleManagerHelper::GetModuleValue(thread, resolvedModule, binding->GetBindingName());
|
||||
}
|
||||
|
||||
// use for moduleLogger is not nullptr
|
||||
JSTaggedValue ModuleTools::ProcessModuleLoadInfo(JSThread *thread, JSHandle<SourceTextModule> currentModule,
|
||||
JSTaggedValue resolvedBinding, int32_t index)
|
||||
{
|
||||
ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
JSMutableHandle<JSTaggedValue> res(thread, thread->GlobalConstants()->GetUndefined());
|
||||
if (resolvedBinding.IsResolvedIndexBinding()) {
|
||||
ResolvedIndexBinding *binding = ResolvedIndexBinding::Cast(resolvedBinding.GetTaggedObject());
|
||||
JSTaggedValue resolvedModule = binding->GetModule();
|
||||
JSHandle<SourceTextModule> module(thread, resolvedModule);
|
||||
ASSERT(resolvedModule.IsSourceTextModule());
|
||||
|
||||
// Support for only modifying var value of HotReload.
|
||||
// Cause patchFile exclude the record of importing modifying var. Can't reresolve moduleRecord.
|
||||
EcmaContext *context = thread->GetCurrentEcmaContext();
|
||||
if (context->GetStageOfHotReload() == StageOfHotReload::LOAD_END_EXECUTE_PATCHMAIN) {
|
||||
const JSHandle<JSTaggedValue> resolvedModuleOfHotReload =
|
||||
context->FindPatchModule(module->GetEcmaModuleRecordNameString());
|
||||
if (!resolvedModuleOfHotReload->IsHole()) {
|
||||
resolvedModule = resolvedModuleOfHotReload.GetTaggedValue();
|
||||
JSHandle<SourceTextModule> moduleOfHotReload(thread, resolvedModule);
|
||||
moduleLogger->InsertModuleLoadInfo(currentModule, module, index);
|
||||
return ModuleManagerHelper::GetModuleValue(thread, moduleOfHotReload, binding->GetIndex());
|
||||
}
|
||||
}
|
||||
moduleLogger->InsertModuleLoadInfo(currentModule, module, index);
|
||||
return ModuleManagerHelper::GetModuleValue(thread, module, binding->GetIndex());
|
||||
}
|
||||
if (resolvedBinding.IsResolvedBinding()) {
|
||||
ResolvedBinding *binding = ResolvedBinding::Cast(resolvedBinding.GetTaggedObject());
|
||||
JSTaggedValue resolvedModule = binding->GetModule();
|
||||
JSHandle<SourceTextModule> module(thread, resolvedModule);
|
||||
if (SourceTextModule::IsNativeModule(module->GetTypes())) {
|
||||
moduleLogger->InsertModuleLoadInfo(currentModule, module, index);
|
||||
return ModuleManagerHelper::UpdateBindingAndGetModuleValue(
|
||||
thread, currentModule, module, index, binding->GetBindingName());
|
||||
}
|
||||
if (module->GetTypes() == ModuleTypes::CJS_MODULE) {
|
||||
moduleLogger->InsertModuleLoadInfo(currentModule, module, index);
|
||||
return ModuleManagerHelper::UpdateBindingAndGetModuleValue(
|
||||
thread, currentModule, module, index, binding->GetBindingName());
|
||||
}
|
||||
}
|
||||
if (resolvedBinding.IsResolvedRecordIndexBinding()) {
|
||||
return GetModuleValueFromIndexBindingForLog(thread, currentModule, resolvedBinding, index);
|
||||
}
|
||||
if (resolvedBinding.IsResolvedRecordBinding()) {
|
||||
return GetModuleValueFromRecordBindingForLog(thread, currentModule, resolvedBinding, index);
|
||||
}
|
||||
LOG_ECMA(FATAL) << "Get module value failed, mistaken ResolvedBinding";
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
JSTaggedValue ModuleTools::ProcessModuleNameSpaceLoadInfo(
|
||||
JSThread *thread, JSHandle<SourceTextModule> currentModule, JSHandle<SourceTextModule> requiredModule)
|
||||
{
|
||||
ModuleTypes moduleType = requiredModule->GetTypes();
|
||||
ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
|
||||
// if requiredModule is Native module
|
||||
if (SourceTextModule::IsNativeModule(moduleType)) {
|
||||
moduleLogger->InsertModuleLoadInfo(currentModule, requiredModule, -1);
|
||||
return SourceTextModule::Cast(requiredModule.GetTaggedValue())->GetModuleValue(thread, 0, false);
|
||||
}
|
||||
// if requiredModule is CommonJS
|
||||
if (moduleType == ModuleTypes::CJS_MODULE) {
|
||||
moduleLogger->InsertModuleLoadInfo(currentModule, requiredModule, -1);
|
||||
CString cjsModuleName = SourceTextModule::GetModuleName(requiredModule.GetTaggedValue());
|
||||
JSHandle<JSTaggedValue> moduleNameHandle(thread->GetEcmaVM()->GetFactory()->NewFromUtf8(cjsModuleName));
|
||||
return CjsModule::SearchFromModuleCache(thread, moduleNameHandle).GetTaggedValue();
|
||||
}
|
||||
// if requiredModule is ESM
|
||||
moduleLogger->InsertModuleLoadInfo(currentModule, requiredModule, -1);
|
||||
JSHandle<JSTaggedValue> moduleNamespace = SourceTextModule::GetModuleNamespace(thread, requiredModule);
|
||||
ASSERT(moduleNamespace->IsModuleNamespace());
|
||||
return moduleNamespace.GetTaggedValue();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
39
ecmascript/module/module_tools.h
Normal file
39
ecmascript/module/module_tools.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_MODULE_TOOLS_H
|
||||
#define ECMASCRIPT_MODULE_TOOLS_H
|
||||
|
||||
#include "ecmascript/module/js_module_source_text.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
class ModuleTools {
|
||||
public:
|
||||
static JSTaggedValue GetModuleValueFromIndexBindingForLog(JSThread *thread,
|
||||
JSHandle<SourceTextModule> module, JSTaggedValue resolvedBinding, int32_t index);
|
||||
|
||||
static JSTaggedValue GetModuleValueFromRecordBindingForLog(JSThread *thread,
|
||||
JSHandle<SourceTextModule> module, JSTaggedValue resolvedBinding, int32_t index);
|
||||
|
||||
static JSTaggedValue ProcessModuleLoadInfo(JSThread *thread, JSHandle<SourceTextModule> currentModule,
|
||||
JSTaggedValue resolvedBinding, int32_t index);
|
||||
|
||||
static JSTaggedValue ProcessModuleNameSpaceLoadInfo(JSThread *thread,
|
||||
JSHandle<SourceTextModule> currentModule,
|
||||
JSHandle<SourceTextModule> requiredModule);
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_MODULE_MODULE_TOOLS_H
|
Loading…
Reference in New Issue
Block a user