mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-12-03 16:31:12 +00:00
!2085 Implementation of Dynamic Import
Merge pull request !2085 from DaiHN/dynamicImport
This commit is contained in:
commit
966983e362
@ -29,7 +29,7 @@
|
||||
|
||||
namespace panda::ecmascript::base {
|
||||
enum class Sign { NONE, NEG, POS };
|
||||
uint64_t* RandomGenerator::randomState {nullptr};
|
||||
uint64_t RandomGenerator::randomState {0};
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define RETURN_IF_CONVERSION_END(p, end, result) \
|
||||
if ((p) == (end)) { \
|
||||
@ -794,7 +794,7 @@ int NumberHelper::GetMinmumDigits(double d, int *decpt, char *buf)
|
||||
|
||||
return digits;
|
||||
}
|
||||
uint64_t* RandomGenerator::GetRandomState()
|
||||
uint64_t& RandomGenerator::GetRandomState()
|
||||
{
|
||||
return randomState;
|
||||
}
|
||||
@ -811,10 +811,9 @@ void RandomGenerator::InitRandom()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
auto val = static_cast<int64_t>((tv.tv_sec * SECONDS_TO_SUBTLE) + tv.tv_usec);
|
||||
randomState = reinterpret_cast<uint64_t *>(&val);
|
||||
randomState = static_cast<uint64_t>((tv.tv_sec * SECONDS_TO_SUBTLE) + tv.tv_usec);
|
||||
// the state must be non zero
|
||||
if (*randomState == 0)
|
||||
*randomState = 1;
|
||||
if (randomState == 0)
|
||||
randomState = 1;
|
||||
}
|
||||
} // namespace panda::ecmascript::base
|
||||
|
@ -116,11 +116,11 @@ private:
|
||||
};
|
||||
class RandomGenerator {
|
||||
public:
|
||||
static uint64_t* GetRandomState();
|
||||
static uint64_t& GetRandomState();
|
||||
static uint64_t XorShift64(uint64_t *pVal);
|
||||
static void InitRandom();
|
||||
private:
|
||||
static uint64_t* randomState;
|
||||
static uint64_t randomState;
|
||||
};
|
||||
} // namespace panda::ecmascript::base
|
||||
#endif // ECMASCRIPT_BASE_NUMBER_HELPER_H
|
||||
|
@ -2552,6 +2552,8 @@ void Builtins::InitializePromiseJob(const JSHandle<GlobalEnv> &env)
|
||||
env->SetPromiseReactionJob(thread_, func);
|
||||
func = NewFunction(env, keyString, BuiltinsPromiseJob::PromiseResolveThenableJob, FunctionLength::THREE);
|
||||
env->SetPromiseResolveThenableJob(thread_, func);
|
||||
func = NewFunction(env, keyString, BuiltinsPromiseJob::DynamicImportJob, FunctionLength::FOUR);
|
||||
env->SetDynamicImportJob(thread_, func);
|
||||
}
|
||||
|
||||
void Builtins::InitializeDataView(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const
|
||||
|
@ -590,8 +590,8 @@ JSTaggedValue BuiltinsMath::Random([[maybe_unused]] EcmaRuntimeCallInfo *argv)
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
Float64Union dataU;
|
||||
uint64_t val;
|
||||
uint64_t* randomState = RandomGenerator::GetRandomState();
|
||||
val = RandomGenerator::XorShift64(randomState);
|
||||
uint64_t &randomState = RandomGenerator::GetRandomState();
|
||||
val = RandomGenerator::XorShift64(&randomState);
|
||||
dataU.u64 = ((uint64_t)base::USE_LEFT << base::LEFT52) | (val >> base::RIGHT12);
|
||||
return GetTaggedDouble(dataU.d - 1.0);
|
||||
}
|
||||
|
@ -20,9 +20,11 @@
|
||||
#include "ecmascript/interpreter/interpreter.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
#include "ecmascript/jspandafile/js_pandafile_executor.h"
|
||||
#include "ecmascript/js_promise.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
|
||||
#include "ecmascript/module/js_module_manager.h"
|
||||
#include "ecmascript/require/js_cjs_module.h"
|
||||
#include "libpandabase/macros.h"
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
@ -119,4 +121,57 @@ JSTaggedValue BuiltinsPromiseJob::PromiseResolveThenableJob(EcmaRuntimeCallInfo
|
||||
// 4. NextJob Completion(thenCallResult).
|
||||
return result;
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsPromiseJob::DynamicImportJob(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), PromiseJob, DynamicImportJob);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
|
||||
JSHandle<JSPromiseReactionsFunction> resolve(GetCallArg(argv, 0));
|
||||
JSHandle<JSPromiseReactionsFunction> reject(GetCallArg(argv, 1)); // 1 : first argument
|
||||
JSHandle<EcmaString> dirPath(GetCallArg(argv, 2)); // 2: second argument
|
||||
JSHandle<EcmaString> specifier(GetCallArg(argv, 3)); // 3 : third argument
|
||||
|
||||
// dirPath + specifier ----> fileName
|
||||
JSHandle<EcmaString> fileName = CjsModule::ResolveFilenameFromNative(thread, dirPath.GetTaggedValue(),
|
||||
specifier.GetTaggedValue());
|
||||
CString moduleName = ConvertToString(fileName.GetTaggedValue());
|
||||
|
||||
// std::string entry = "_GLOBAL::func_main_0";
|
||||
if (!vm->GetModuleManager()->IsImportedModuleLoaded(fileName.GetTaggedValue())) {
|
||||
if (!JSPandaFileExecutor::ExecuteFromFile(thread, moduleName.c_str(), "_GLOBAL::func_main_0")) {
|
||||
LOG_FULL(FATAL) << "Cannot execute dynamic-imported panda file : ";
|
||||
}
|
||||
}
|
||||
|
||||
// b. Let moduleRecord be ! HostResolveImportedModule(referencingScriptOrModule, specifier).
|
||||
JSHandle<SourceTextModule> moduleRecord = vm->GetModuleManager()->HostGetImportedModule(fileName);
|
||||
|
||||
// d. Let namespace be ? GetModuleNamespace(moduleRecord).
|
||||
JSHandle<JSTaggedValue> moduleNamespace = SourceTextModule::GetModuleNamespace(thread, moduleRecord);
|
||||
|
||||
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||
EcmaRuntimeCallInfo *info =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread,
|
||||
JSHandle<JSTaggedValue>(resolve),
|
||||
undefined, undefined, 1);
|
||||
info->SetCallArg(moduleNamespace.GetTaggedValue());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSTaggedValue result = JSFunction::Call(info);
|
||||
|
||||
if (thread->HasPendingException()) {
|
||||
auto thenResult = JSPromise::IfThrowGetThrowValue(thread);
|
||||
thread->ClearException();
|
||||
JSHandle<JSTaggedValue> rejectfun(reject);
|
||||
EcmaRuntimeCallInfo *runtimeInfo =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread, rejectfun, undefined, undefined, 1);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
runtimeInfo->SetCallArg(thenResult.GetTaggedValue());
|
||||
return JSFunction::Call(runtimeInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
@ -23,6 +23,7 @@ class BuiltinsPromiseJob : base::BuiltinsBase {
|
||||
public:
|
||||
static JSTaggedValue PromiseReactionJob(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue PromiseResolveThenableJob(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue DynamicImportJob(EcmaRuntimeCallInfo *argv);
|
||||
};
|
||||
} // namespace panda::ecmascript::builtins
|
||||
#endif // ECMASCRIPT_JS_PROMISE_JOB_H
|
||||
|
@ -163,6 +163,7 @@ namespace panda::ecmascript::kungfu {
|
||||
T(HandleCreateAsyncGeneratorObjPrefV8) \
|
||||
T(HandleAsyncGeneratorResolvePrefV8V8V8) \
|
||||
T(HandleDefineAsyncGeneratorFuncPrefId16Imm16V8) \
|
||||
T(HandleDynamicImportPrefV8) \
|
||||
T(HandleMovDynV8V8) \
|
||||
T(HandleMovDynV16V16) \
|
||||
T(HandleLdaStrId32) \
|
||||
|
@ -1709,6 +1709,13 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::DYNAMICIMPORT_PREF_V8: {
|
||||
uint16_t v0 = READ_INST_8_1();
|
||||
info.accOut = true;
|
||||
info.offset = BytecodeOffset::THREE;
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::SUPERCALL_PREF_IMM16_V8: {
|
||||
uint16_t range = READ_INST_16_1();
|
||||
uint16_t v0 = READ_INST_8_3();
|
||||
|
@ -4144,6 +4144,15 @@ DECLARE_ASM_HANDLER(HandleDefineAsyncGeneratorFuncPrefId16Imm16V8)
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_ASM_HANDLER(HandleDynamicImportPrefV8)
|
||||
{
|
||||
DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc);
|
||||
GateRef v0 = ReadInst8_1(pc);
|
||||
GateRef specifier = GetVregValue(sp, ZExtInt8ToPtr(v0));
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(DynamicImport), { specifier });
|
||||
CHECK_EXCEPTION_WITH_ACC(res, INT_PTR(PREF_V8));
|
||||
}
|
||||
|
||||
DECLARE_ASM_HANDLER(HandleCreateAsyncGeneratorObjPrefV8)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
@ -501,6 +501,9 @@ void SlowPathLowering::Lower(GateRef gate)
|
||||
case TONUMERIC_PREF_V8:
|
||||
LowerToNumeric(gate, glue);
|
||||
break;
|
||||
case DYNAMICIMPORT_PREF_V8:
|
||||
LowerDynamicImport(gate, glue);
|
||||
break;
|
||||
case LDMODULEVAR_PREF_ID32_IMM8:
|
||||
LowerLdModuleVar(gate, glue, jsFunc);
|
||||
break;
|
||||
@ -1618,6 +1621,16 @@ void SlowPathLowering::LowerToNumeric(GateRef gate, GateRef glue)
|
||||
ReplaceHirToCall(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerDynamicImport(GateRef gate, GateRef glue)
|
||||
{
|
||||
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleDynamicImportPrefV8)));
|
||||
const int id = RTSTUB_ID(DynamicImport);
|
||||
// 1: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 1);
|
||||
GateRef newGate = LowerCallRuntime(glue, id, {acc_.GetValueIn(gate, 0)});
|
||||
ReplaceHirToCall(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerLdModuleVar(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
{
|
||||
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleLdModuleVarPrefId32Imm8)));
|
||||
|
@ -220,6 +220,7 @@ private:
|
||||
void LowerSetObjectWithProto(GateRef gate, GateRef glue);
|
||||
void LowerLdBigInt(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerToNumeric(GateRef gate, GateRef glue);
|
||||
void LowerDynamicImport(GateRef gate, GateRef glue);
|
||||
void LowerLdModuleVar(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerGetModuleNamespace(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerGetIteratorNext(GateRef gate, GateRef glue);
|
||||
|
@ -2315,6 +2315,8 @@ void GlobalEnv::Dump(std::ostream &os) const
|
||||
GetPromiseReactionJob().GetTaggedValue().Dump(os);
|
||||
os << " - PromiseResolveThenableJob: ";
|
||||
GetPromiseResolveThenableJob().GetTaggedValue().Dump(os);
|
||||
os << " - DynamicImportJob: ";
|
||||
GetDynamicImportJob().GetTaggedValue().Dump(os);
|
||||
os << " - ScriptJobString: ";
|
||||
globalConst->GetScriptJobString().Dump(os);
|
||||
os << " - PromiseString: ";
|
||||
@ -3254,9 +3256,6 @@ void ResolvedBinding::Dump(std::ostream &os) const
|
||||
|
||||
void ModuleNamespace::Dump(std::ostream &os) const
|
||||
{
|
||||
os << " - Module: ";
|
||||
GetModule().Dump(os);
|
||||
os << "\n";
|
||||
os << " - Exports: ";
|
||||
GetExports().Dump(os);
|
||||
os << "\n";
|
||||
@ -4437,6 +4436,8 @@ void GlobalEnv::DumpForSnapshot(std::vector<std::pair<CString, JSTaggedValue>> &
|
||||
vec.push_back(std::make_pair(CString("PromiseReactionJob"), GetPromiseReactionJob().GetTaggedValue()));
|
||||
vec.push_back(
|
||||
std::make_pair(CString("PromiseResolveThenableJob"), GetPromiseResolveThenableJob().GetTaggedValue()));
|
||||
vec.push_back(
|
||||
std::make_pair(CString("DynamicImportJob"), GetDynamicImportJob().GetTaggedValue()));
|
||||
vec.push_back(std::make_pair(CString("ScriptJobString"), globalConst->GetScriptJobString()));
|
||||
vec.push_back(std::make_pair(CString("PromiseString"), globalConst->GetPromiseString()));
|
||||
vec.push_back(std::make_pair(CString("IdentityString"), globalConst->GetIdentityString()));
|
||||
|
@ -617,3 +617,7 @@ groups:
|
||||
prefix: ecma
|
||||
format: [pref_op_id_16_imm_16_v_8]
|
||||
properties: [method_id]
|
||||
- sig: ecma.dynamicimport v:in:top
|
||||
acc: out:top
|
||||
prefix: ecma
|
||||
format: [pref_op_v_8]
|
||||
|
@ -464,6 +464,30 @@ FileLoader::FileLoader(EcmaVM *vm) : vm_(vm), factory_(vm->GetFactory())
|
||||
arkStackMapParser_ = new kungfu::ArkStackMapParser(enableLog);
|
||||
}
|
||||
|
||||
JSTaggedValue FileLoader::GetAbsolutePath(JSThread *thread, JSTaggedValue relativePathVal)
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
CString relativePath = ConvertToString(relativePathVal);
|
||||
CString absPath;
|
||||
if (!GetAbsolutePath(relativePath, absPath)) {
|
||||
LOG_FULL(FATAL) << "Get Absolute Path failed";
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
JSTaggedValue absPathVal = factory->NewFromUtf8(absPath).GetTaggedValue();
|
||||
return absPathVal;
|
||||
}
|
||||
|
||||
bool FileLoader::GetAbsolutePath(const CString &relativePathCstr, CString &absPathCstr)
|
||||
{
|
||||
std::string relativePath = CstringConvertToStdString(relativePathCstr);
|
||||
std::string absPath = "";
|
||||
if (GetAbsolutePath(relativePath, absPath)) {
|
||||
absPathCstr = ConvertToString(absPath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileLoader::GetAbsolutePath(const std::string &relativePath, std::string &absPath)
|
||||
{
|
||||
if (relativePath.size() >= PATH_MAX) {
|
||||
|
@ -425,7 +425,10 @@ public:
|
||||
void SetAOTFuncEntryForLiteral(const JSPandaFile *jsPandaFile, const JSHandle<TaggedArray> &obj);
|
||||
void LoadSnapshotFile();
|
||||
kungfu::ArkStackMapParser* GetStackMapParser() const;
|
||||
static JSTaggedValue GetAbsolutePath(JSThread *thread, JSTaggedValue relativePathVal);
|
||||
static bool GetAbsolutePath(const std::string &relativePath, std::string &absPath);
|
||||
static bool GetAbsolutePath(const CString &relativePathCstr, CString &absPathCstr);
|
||||
|
||||
bool RewriteDataSection(uintptr_t dataSec, size_t size, uintptr_t newData, size_t newSize);
|
||||
void RuntimeRelocate();
|
||||
private:
|
||||
|
@ -130,6 +130,7 @@ class JSThread;
|
||||
V(JSTaggedValue, PromiseFunction, PROMISE_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, PromiseReactionJob, PROMISE_REACTION_JOB_INDEX) \
|
||||
V(JSTaggedValue, PromiseResolveThenableJob, PROMISE_REACTION_THENABLE_JOB_INDEX) \
|
||||
V(JSTaggedValue, DynamicImportJob, DYNAMIC_IMPORT_JOB_INDEX) \
|
||||
V(JSTaggedValue, TemplateMap, TEMPLATE_MAP_INDEX) \
|
||||
V(JSTaggedValue, FunctionClassWithProto, FUNCTION_CLASS_WITH_PROTO) \
|
||||
V(JSTaggedValue, FunctionClassWithoutProto, FUNCTION_CLASS_WITHOUT_PROTO) \
|
||||
|
@ -3568,6 +3568,18 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
SET_ACC(res);
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8);
|
||||
}
|
||||
HANDLE_OPCODE(HANDLE_DYNAMICIMPORT_PREF_V8) {
|
||||
uint16_t v0 = READ_INST_8_1();
|
||||
|
||||
LOG_INST() << "intrinsics::dynamicimport"
|
||||
<< " v" << v0;
|
||||
JSTaggedValue specifier = GET_VREG_VALUE(v0);
|
||||
SAVE_PC();
|
||||
JSTaggedValue res = SlowRuntimeStub::DynamicImport(thread, specifier);
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
SET_ACC(res);
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_V8);
|
||||
}
|
||||
HANDLE_OPCODE(HANDLE_SUPERCALL_PREF_IMM16_V8) {
|
||||
uint16_t range = READ_INST_16_1();
|
||||
uint16_t v0 = READ_INST_8_3();
|
||||
@ -4168,6 +4180,7 @@ std::string GetEcmaOpcodeStr(EcmaOpcode opcode)
|
||||
{TONUMERIC_PREF_V8, "TONUMERIC"},
|
||||
{CREATEASYNCGENERATOROBJ_PREF_V8, "CREATEASYNCGENERATOROBJ"},
|
||||
{ASYNCGENERATORRESOLVE_PREF_V8_V8_V8, "ASYNCGENERATORRESOLVE"},
|
||||
{DYNAMICIMPORT_PREF_V8, "DYNAMICIMPORT"},
|
||||
{MOV_DYN_V8_V8, "MOV_DYN"},
|
||||
{MOV_DYN_V16_V16, "MOV_DYN"},
|
||||
{LDA_STR_ID32, "LDA_STR"},
|
||||
|
@ -202,6 +202,7 @@ enum EcmaOpcode {
|
||||
CREATEASYNCGENERATOROBJ_PREF_V8,
|
||||
ASYNCGENERATORRESOLVE_PREF_V8_V8_V8,
|
||||
DEFINEASYNCGENERATORFUNC_PREF_ID16_IMM16_V8,
|
||||
DYNAMICIMPORT_PREF_V8,
|
||||
MOV_DYN_V8_V8,
|
||||
MOV_DYN_V16_V16,
|
||||
LDA_STR_ID32,
|
||||
|
@ -3435,6 +3435,21 @@ void InterpreterAssembly::HandleToNumericPrefV8(
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_V8);
|
||||
}
|
||||
|
||||
void InterpreterAssembly::HandleDynamicImportPrefV8(
|
||||
JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo,
|
||||
JSTaggedValue acc, int16_t hotnessCounter)
|
||||
{
|
||||
uint16_t v0 = READ_INST_8_1();
|
||||
|
||||
LOG_INST() << "intrinsics::dynamicimport"
|
||||
<< " v" << v0;
|
||||
JSTaggedValue specifier = GET_VREG_VALUE(v0);
|
||||
JSTaggedValue res = SlowRuntimeStub::DynamicImport(thread, specifier);
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
SET_ACC(res);
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_V8);
|
||||
}
|
||||
|
||||
void InterpreterAssembly::HandleSuperCallPrefImm16V8(
|
||||
JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo,
|
||||
JSTaggedValue acc, int16_t hotnessCounter)
|
||||
|
@ -164,7 +164,6 @@ static std::array<DispatchEntryPoint, BCStubEntries::BC_HANDLER_COUNT> asmDispat
|
||||
InterpreterAssembly::HandleOverflow,
|
||||
InterpreterAssembly::HandleOverflow,
|
||||
InterpreterAssembly::HandleOverflow,
|
||||
InterpreterAssembly::HandleOverflow,
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_INTERPRETER_INTERPRETER_ASSEMBLY_64BIT_H
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "ecmascript/interpreter/frame_handler.h"
|
||||
#include "ecmascript/interpreter/interpreter-inl.h"
|
||||
#include "ecmascript/interpreter/slow_runtime_helper.h"
|
||||
#include "ecmascript/jspandafile/class_info_extractor.h"
|
||||
#include "ecmascript/jobs/micro_job_queue.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/jspandafile/scope_info_extractor.h"
|
||||
#include "ecmascript/js_arguments.h"
|
||||
@ -1036,6 +1036,61 @@ JSTaggedValue SlowRuntimeStub::SuperCall(JSThread *thread, JSTaggedValue func, J
|
||||
return RuntimeStubs::RuntimeSuperCall(thread, funcHandle, newTargetHandle, firstVRegIdx, length);
|
||||
}
|
||||
|
||||
// specifier = "./test.js"
|
||||
JSTaggedValue SlowRuntimeStub::DynamicImport(JSThread *thread, JSTaggedValue specifier)
|
||||
{
|
||||
INTERPRETER_TRACE(thread, DynamicImport);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
EcmaVM *ecmaVm = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVm->GetFactory();
|
||||
|
||||
// 5. Let specifierString be Completion(ToString(specifier))
|
||||
JSHandle<EcmaString> specifierString = JSTaggedValue::ToString(thread, specifier);
|
||||
|
||||
// get current filename
|
||||
std::string filename;
|
||||
JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentInterpretedFrame());
|
||||
if (thread->IsAsmInterpreter()) {
|
||||
AsmInterpretedFrame *state = (reinterpret_cast<AsmInterpretedFrame *>(sp) - 1);
|
||||
Method *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget();
|
||||
filename = method->GetJSPandaFile()->GetPandaFile()->GetFilename();
|
||||
} else {
|
||||
InterpretedFrame *state = (reinterpret_cast<InterpretedFrame *>(sp) - 1);
|
||||
Method *method = JSFunction::Cast(state->function.GetTaggedObject())->GetCallTarget();
|
||||
filename = method->GetJSPandaFile()->GetPandaFile()->GetFilename();
|
||||
}
|
||||
|
||||
// parse dirPath from filename
|
||||
CString fullName = CString(filename);
|
||||
int foundPos = static_cast<int>(fullName.find_last_of("/\\"));
|
||||
if (foundPos == -1) {
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Hole());
|
||||
}
|
||||
CString dirPathStr = fullName.substr(0, foundPos + 1);
|
||||
JSHandle<EcmaString> dirPath = factory->NewFromUtf8(dirPathStr);
|
||||
|
||||
// 4. Let promiseCapability be !NewPromiseCapability(%Promise%).
|
||||
JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction();
|
||||
JSHandle<PromiseCapability> promiseCapability = JSPromise::NewPromiseCapability(thread, promiseFunc);
|
||||
|
||||
// 6. IfAbruptRejectPromise(specifierString, promiseCapability).
|
||||
RETURN_REJECT_PROMISE_IF_ABRUPT(thread, specifierString, promiseCapability);
|
||||
JSHandle<JSTaggedValue> currentModule(thread, thread->GetEcmaVM()->GetModuleManager()->GetCurrentModule());
|
||||
JSHandle<job::MicroJobQueue> job = ecmaVm->GetMicroJobQueue();
|
||||
|
||||
JSHandle<TaggedArray> argv = factory->NewTaggedArray(4); // 4: 4 means two args stored in array
|
||||
argv->Set(thread, 0, promiseCapability->GetResolve());
|
||||
argv->Set(thread, 1, promiseCapability->GetReject()); // 1 : first argument
|
||||
argv->Set(thread, 2, dirPath); // 2: second argument
|
||||
argv->Set(thread, 3, specifierString); // 3 : third argument
|
||||
|
||||
JSHandle<JSFunction> dynamicImportJob(env->GetDynamicImportJob());
|
||||
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, dynamicImportJob, argv);
|
||||
|
||||
return promiseCapability->GetPromise();
|
||||
}
|
||||
|
||||
JSTaggedValue SlowRuntimeStub::SuperCallSpread(JSThread *thread, JSTaggedValue func, JSTaggedValue newTarget,
|
||||
JSTaggedValue array)
|
||||
{
|
||||
|
@ -152,6 +152,7 @@ public:
|
||||
uint16_t length);
|
||||
static JSTaggedValue SuperCallSpread(JSThread *thread, JSTaggedValue func, JSTaggedValue newTarget,
|
||||
JSTaggedValue array);
|
||||
static JSTaggedValue DynamicImport(JSThread *thread, JSTaggedValue specifier);
|
||||
static JSTaggedValue DefineMethod(JSThread *thread, JSFunction *func, JSTaggedValue homeObject);
|
||||
static JSTaggedValue LdSuperByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue thisFunc);
|
||||
static JSTaggedValue StSuperByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue value,
|
||||
|
@ -153,6 +153,7 @@
|
||||
&&DEBUG_HANDLE_CREATEASYNCGENERATOROBJ_PREF_V8,
|
||||
&&DEBUG_HANDLE_ASYNCGENERATORRESOLVE_PREF_V8_V8_V8,
|
||||
&&DEBUG_HANDLE_DEFINEASYNCGENERATORFUNC_PREF_ID16_IMM16_V8,
|
||||
&&DEBUG_HANDLE_DYNAMICIMPORT_PREF_V8,
|
||||
&&DEBUG_HANDLE_MOV_DYN_V8_V8,
|
||||
&&DEBUG_HANDLE_MOV_DYN_V16_V16,
|
||||
&&DEBUG_HANDLE_LDA_STR_ID32,
|
||||
@ -267,5 +268,4 @@
|
||||
&&DEBUG_HANDLE_OVERFLOW,
|
||||
&&DEBUG_HANDLE_OVERFLOW,
|
||||
&&DEBUG_HANDLE_OVERFLOW,
|
||||
&&DEBUG_HANDLE_OVERFLOW,
|
||||
&&DEBUG_HANDLE_OVERFLOW,
|
@ -713,6 +713,11 @@
|
||||
NOTIFY_DEBUGGER_EVENT();
|
||||
REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCGENERATORRESOLVE_PREF_V8_V8_V8);
|
||||
}
|
||||
HANDLE_OPCODE(DEBUG_HANDLE_DYNAMICIMPORT_PREF_V8)
|
||||
{
|
||||
NOTIFY_DEBUGGER_EVENT();
|
||||
REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DYNAMICIMPORT_PREF_V8);
|
||||
}
|
||||
HANDLE_OPCODE(DEBUG_HANDLE_MOV_DYN_V8_V8)
|
||||
{
|
||||
NOTIFY_DEBUGGER_EVENT();
|
||||
|
@ -153,6 +153,7 @@
|
||||
&&HANDLE_CREATEASYNCGENERATOROBJ_PREF_V8,
|
||||
&&HANDLE_ASYNCGENERATORRESOLVE_PREF_V8_V8_V8,
|
||||
&&HANDLE_DEFINEASYNCGENERATORFUNC_PREF_ID16_IMM16_V8,
|
||||
&&HANDLE_DYNAMICIMPORT_PREF_V8,
|
||||
&&HANDLE_MOV_DYN_V8_V8,
|
||||
&&HANDLE_MOV_DYN_V16_V16,
|
||||
&&HANDLE_LDA_STR_ID32,
|
||||
@ -268,4 +269,3 @@
|
||||
&&HANDLE_OVERFLOW,
|
||||
&&HANDLE_OVERFLOW,
|
||||
&&HANDLE_OVERFLOW,
|
||||
&&HANDLE_OVERFLOW,
|
||||
|
@ -388,6 +388,12 @@ JSTaggedValue JSTaggedValue::OrdinaryToPrimitive(JSThread *thread, const JSHandl
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot convert a illegal value to a Primitive", JSTaggedValue::Undefined());
|
||||
}
|
||||
|
||||
JSHandle<EcmaString> JSTaggedValue::ToString(JSThread *thread, JSTaggedValue val)
|
||||
{
|
||||
JSHandle<JSTaggedValue> tagged(thread, val);
|
||||
return ToString(thread, tagged);
|
||||
}
|
||||
|
||||
JSHandle<EcmaString> JSTaggedValue::ToString(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
|
||||
{
|
||||
if (tagged->IsString()) {
|
||||
|
@ -405,6 +405,7 @@ public:
|
||||
static uint8_t ToUint8(JSThread *thread, const JSHandle<JSTaggedValue> &tagged);
|
||||
static uint8_t ToUint8Clamp(JSThread *thread, const JSHandle<JSTaggedValue> &tagged);
|
||||
static JSHandle<EcmaString> ToString(JSThread *thread, const JSHandle<JSTaggedValue> &tagged);
|
||||
static JSHandle<EcmaString> ToString(JSThread *thread, JSTaggedValue val);
|
||||
static JSHandle<JSObject> ToObject(JSThread *thread, const JSHandle<JSTaggedValue> &tagged);
|
||||
static JSHandle<JSTaggedValue> ToPropertyKey(JSThread *thread, const JSHandle<JSTaggedValue> &tagged);
|
||||
static JSTaggedNumber ToLength(JSThread *thread, const JSHandle<JSTaggedValue> &tagged);
|
||||
|
@ -140,21 +140,25 @@ JSHandle<SourceTextModule> ModuleManager::HostGetImportedModule(const CString &r
|
||||
NameDictionary::Cast(resolvedModules_.GetTaggedObject())->GetValue(entry));
|
||||
}
|
||||
|
||||
JSHandle<SourceTextModule> ModuleManager::HostGetImportedModule(JSTaggedValue referencingModule)
|
||||
JSHandle<SourceTextModule> ModuleManager::HostGetImportedModule(JSHandle<EcmaString> &referencingHandle)
|
||||
{
|
||||
return HostGetImportedModule(referencingHandle.GetTaggedValue());
|
||||
}
|
||||
|
||||
JSHandle<SourceTextModule> ModuleManager::HostGetImportedModule(JSTaggedValue referencing)
|
||||
{
|
||||
int entry =
|
||||
NameDictionary::Cast(resolvedModules_.GetTaggedObject())->FindEntry(referencingModule);
|
||||
LOG_ECMA_IF(entry == -1, FATAL) << "cannot get module: " << ConvertToString(referencingModule);
|
||||
|
||||
NameDictionary::Cast(resolvedModules_.GetTaggedObject())->FindEntry(referencing);
|
||||
LOG_ECMA_IF(entry == -1, FATAL) << "cannot get module: ";
|
||||
return JSHandle<SourceTextModule>(vm_->GetJSThread(),
|
||||
NameDictionary::Cast(resolvedModules_.GetTaggedObject())->GetValue(entry));
|
||||
}
|
||||
|
||||
bool ModuleManager::resolveImportedModule(JSTaggedValue referencingModule)
|
||||
bool ModuleManager::IsImportedModuleLoaded(JSTaggedValue referencing)
|
||||
{
|
||||
int entry =
|
||||
NameDictionary::Cast(resolvedModules_.GetTaggedObject())->FindEntry(referencingModule);
|
||||
return entry != -1;
|
||||
NameDictionary::Cast(resolvedModules_.GetTaggedObject())->FindEntry(referencing);
|
||||
return (entry != -1);
|
||||
}
|
||||
|
||||
JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModule(const CString &referencingModule)
|
||||
@ -166,10 +170,7 @@ JSHandle<SourceTextModule> ModuleManager::HostResolveImportedModule(const CStrin
|
||||
JSHandle<JSTaggedValue>::Cast(factory->NewFromUtf8(referencingModule));
|
||||
CString moduleFileName = referencingModule;
|
||||
if (!vm_->GetResolvePathCallback()) {
|
||||
std::string absPath;
|
||||
std::string moduleName = CstringConvertToStdString(moduleFileName);
|
||||
if (FileLoader::GetAbsolutePath(moduleName, absPath)) {
|
||||
moduleFileName = ConvertToString(absPath);
|
||||
if (FileLoader::GetAbsolutePath(referencingModule, moduleFileName)) {
|
||||
referencingHandle = JSHandle<JSTaggedValue>::Cast(factory->NewFromUtf8(moduleFileName));
|
||||
} else {
|
||||
LOG_ECMA(ERROR) << "absolute " << referencingModule << " path error";
|
||||
@ -264,6 +265,10 @@ void ModuleManager::ConcatFileName(std::string &dirPath, std::string &requestPat
|
||||
fileName = dirPath.substr(0, pos + 1) + requestPath.substr(0, suffixEnd) + ".abc";
|
||||
}
|
||||
#else
|
||||
if (requestPath.find("./") == 0) {
|
||||
requestPath = requestPath.substr(2); // 2 : delete './'
|
||||
suffixEnd -=2; // 2 : delete './'
|
||||
}
|
||||
if (requestPath[0] == '/') { // absoluteFilePath
|
||||
fileName = requestPath.substr(0, suffixEnd) + ".abc";
|
||||
} else {
|
||||
|
@ -32,14 +32,18 @@ public:
|
||||
void StoreModuleValue(JSTaggedValue key, JSTaggedValue value);
|
||||
void StoreModuleValue(JSTaggedValue key, JSTaggedValue value, JSTaggedValue jsFunc);
|
||||
JSHandle<SourceTextModule> HostGetImportedModule(const CString &referencingModule);
|
||||
JSHandle<SourceTextModule> HostGetImportedModule(JSTaggedValue referencingModule);
|
||||
JSHandle<SourceTextModule> HostResolveImportedModule(const void *buffer, size_t size, const CString &filename);
|
||||
JSHandle<SourceTextModule> HostResolveImportedModule(std::string &baseFilename, std::string &moduleFilename);
|
||||
JSHandle<SourceTextModule> HostResolveImportedModule(const CString &referencingModule);
|
||||
JSHandle<SourceTextModule> HostGetImportedModule(JSTaggedValue referencing);
|
||||
JSHandle<SourceTextModule> HostGetImportedModule(JSHandle<EcmaString> &referencingHandle);
|
||||
bool IsImportedModuleLoaded(JSTaggedValue referencing);
|
||||
JSTaggedValue GetModuleNamespace(JSTaggedValue localName);
|
||||
JSTaggedValue GetModuleNamespace(JSTaggedValue localName, JSTaggedValue currentFunc);
|
||||
JSTaggedValue GetCurrentModule();
|
||||
JSTaggedValue GetModuleNamespaceInternal(JSTaggedValue localName, JSTaggedValue currentModule);
|
||||
|
||||
void AddResolveImportedModule(const JSPandaFile *jsPandaFile, const CString &referencingModule);
|
||||
bool resolveImportedModule(JSTaggedValue referencingModule);
|
||||
void Iterate(const RootVisitor &v);
|
||||
bool GetCurrentMode() const
|
||||
{
|
||||
@ -58,11 +62,9 @@ private:
|
||||
NO_COPY_SEMANTIC(ModuleManager);
|
||||
NO_MOVE_SEMANTIC(ModuleManager);
|
||||
|
||||
JSTaggedValue GetCurrentModule();
|
||||
JSTaggedValue GetModuleValueOutterInternal(JSTaggedValue key, JSTaggedValue currentModule);
|
||||
void StoreModuleValueInternal(JSHandle<SourceTextModule> ¤tModule,
|
||||
JSTaggedValue key, JSTaggedValue value);
|
||||
JSTaggedValue GetModuleNamespaceInternal(JSTaggedValue localName, JSTaggedValue currentModule);
|
||||
|
||||
static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4;
|
||||
|
||||
|
@ -126,12 +126,38 @@ bool ModuleNamespace::PreventExtensions()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleNamespace::DefineOwnProperty([[maybe_unused]] JSThread *thread,
|
||||
[[maybe_unused]] const JSHandle<JSTaggedValue> &obj,
|
||||
[[maybe_unused]] const JSHandle<JSTaggedValue> &key,
|
||||
[[maybe_unused]] PropertyDescriptor desc)
|
||||
bool ModuleNamespace::DefineOwnProperty(JSThread *thread,
|
||||
const JSHandle<JSTaggedValue> &obj,
|
||||
const JSHandle<JSTaggedValue> &key,
|
||||
PropertyDescriptor desc)
|
||||
{
|
||||
return false;
|
||||
ASSERT(obj->IsModuleNamespace());
|
||||
// 1. If Type(P) is Symbol, return ! OrdinaryDefineOwnProperty(O, P, Desc).
|
||||
if (key->IsSymbol()) {
|
||||
bool res = JSObject::OrdinaryDefineOwnProperty(thread, JSHandle<JSObject>(obj), key, desc);
|
||||
return res;
|
||||
}
|
||||
// 4. If Desc has a [[Configurable]] field and Desc.[[Configurable]] is true, return false.
|
||||
// 5. If Desc has an [[Enumerable]] field and Desc.[[Enumerable]] is false, return false.
|
||||
// 6. If IsAccessorDescriptor(Desc) is true, return false.
|
||||
// 7. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, return false.
|
||||
if (desc.IsConfigurable() || !desc.IsEnumerable() || !desc.IsWritable() || desc.IsAccessorDescriptor()) {
|
||||
return false;
|
||||
}
|
||||
// 2. Let current be ? O.[[GetOwnProperty]](P).
|
||||
PropertyDescriptor current(thread);
|
||||
// 3. If current is undefined, return false.
|
||||
if (!GetOwnProperty(thread, obj, key, current)) {
|
||||
return false;
|
||||
}
|
||||
// 8. If Desc has a [[Value]] field, return SameValue(Desc.[[Value]], current.[[Value]]).
|
||||
if (desc.HasValue()) {
|
||||
JSHandle<JSTaggedValue> descValue = desc.GetValue();
|
||||
JSHandle<JSTaggedValue> currentValue = current.GetValue();
|
||||
return JSTaggedValue::SameValue(descValue, currentValue);
|
||||
}
|
||||
// 9. Return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleNamespace::HasProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
|
||||
|
@ -82,7 +82,7 @@ JSHandle<SourceTextModule> SourceTextModule::HostResolveImportedModule(JSThread
|
||||
const JSHandle<JSTaggedValue> &moduleRequest)
|
||||
{
|
||||
auto moduleManage = thread->GetEcmaVM()->GetModuleManager();
|
||||
if (moduleManage->resolveImportedModule(moduleRequest.GetTaggedValue())) {
|
||||
if (moduleManage->IsImportedModuleLoaded(moduleRequest.GetTaggedValue())) {
|
||||
return moduleManage->HostGetImportedModule(moduleRequest.GetTaggedValue());
|
||||
}
|
||||
std::string baseFilename = base::StringHelper::ToStdString(
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "ecmascript/require/js_cjs_module.h"
|
||||
|
||||
#include "ecmascript/file_loader.h"
|
||||
#include "ecmascript/interpreter/interpreter-inl.h"
|
||||
#include "ecmascript/interpreter/slow_runtime_stub.h"
|
||||
#include "ecmascript/require/js_cjs_module_cache.h"
|
||||
@ -169,6 +170,7 @@ JSHandle<EcmaString> CjsModule::ResolveFilenameFromNative(JSThread *thread, JSTa
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread);
|
||||
}
|
||||
CString fullname;
|
||||
CString res;
|
||||
if (requestStr[0] == '/') { // absolute FilePath
|
||||
fullname = requestStr.substr(0, suffixEnd) + ".abc";
|
||||
} else {
|
||||
@ -178,7 +180,11 @@ JSHandle<EcmaString> CjsModule::ResolveFilenameFromNative(JSThread *thread, JSTa
|
||||
}
|
||||
fullname = dirnameStr.substr(0, pos + 1) + requestStr.substr(0, suffixEnd) + ".abc";
|
||||
}
|
||||
return factory->NewFromUtf8(fullname);
|
||||
|
||||
if (!FileLoader::GetAbsolutePath(fullname, res)) {
|
||||
LOG_FULL(FATAL) << "resolve absolute path fail";
|
||||
}
|
||||
return factory->NewFromUtf8(res);
|
||||
}
|
||||
|
||||
JSTaggedValue CjsModule::Require(JSThread *thread, JSHandle<EcmaString> &request,
|
||||
|
@ -226,7 +226,9 @@ namespace panda::ecmascript {
|
||||
V(DefineAsyncGeneratorFunc) \
|
||||
V(DefineGeneratorFuncWithMethodId) \
|
||||
V(DefineAsyncGeneratorFuncWithMethodId) \
|
||||
V(GetSuperConstructor)
|
||||
V(GetSuperConstructor) \
|
||||
V(DynamicImport)
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define BUILTINS_API_LIST(V) \
|
||||
V(Array, Constructor) \
|
||||
|
@ -641,6 +641,7 @@ static uintptr_t g_nativeTable[] = {
|
||||
reinterpret_cast<uintptr_t>(Promise::GetSpecies),
|
||||
reinterpret_cast<uintptr_t>(BuiltinsPromiseJob::PromiseReactionJob),
|
||||
reinterpret_cast<uintptr_t>(BuiltinsPromiseJob::PromiseResolveThenableJob),
|
||||
reinterpret_cast<uintptr_t>(BuiltinsPromiseJob::DynamicImportJob),
|
||||
reinterpret_cast<uintptr_t>(Intl::GetCanonicalLocales),
|
||||
reinterpret_cast<uintptr_t>(Locale::LocaleConstructor),
|
||||
reinterpret_cast<uintptr_t>(Locale::Maximize),
|
||||
|
@ -1153,6 +1153,11 @@ JSTaggedValue RuntimeStubs::RuntimeToNumeric(JSThread *thread, const JSHandle<JS
|
||||
return JSTaggedValue::ToNumeric(thread, value).GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeDynamicImport(JSThread *thread, JSTaggedValue specifier)
|
||||
{
|
||||
return SlowRuntimeStub::DynamicImport(thread, specifier);
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeEqDyn(JSThread *thread, const JSHandle<JSTaggedValue> &left,
|
||||
const JSHandle<JSTaggedValue> &right)
|
||||
{
|
||||
|
@ -1630,6 +1630,13 @@ DEF_RUNTIME_STUBS(ToNumeric)
|
||||
return RuntimeToNumeric(thread, value).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(DynamicImport)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(DynamicImport);
|
||||
JSTaggedValue specifier = GetArg(argv, argc, 0); // 0: means the zeroth parameter
|
||||
return RuntimeDynamicImport(thread, specifier).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(NewLexicalEnvWithNameDyn)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(NewLexicalEnvWithNameDyn);
|
||||
|
@ -229,6 +229,7 @@ using JSFunctionEntryType = JSTaggedValue (*)(uintptr_t glue, uintptr_t prevFp,
|
||||
V(OptSuperCall) \
|
||||
V(LdBigInt) \
|
||||
V(ToNumeric) \
|
||||
V(DynamicImport) \
|
||||
V(CreateAsyncGeneratorObj) \
|
||||
V(AsyncGeneratorResolve) \
|
||||
V(DefineAsyncGeneratorFunc) \
|
||||
@ -434,6 +435,7 @@ private:
|
||||
static inline JSTaggedValue RuntimeStGlobalVar(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
|
||||
const JSHandle<JSTaggedValue> &value);
|
||||
static inline JSTaggedValue RuntimeToNumber(JSThread *thread, const JSHandle<JSTaggedValue> &value);
|
||||
static inline JSTaggedValue RuntimeDynamicImport(JSThread *thread, JSTaggedValue specifier);
|
||||
static inline JSTaggedValue RuntimeToNumeric(JSThread *thread, const JSHandle<JSTaggedValue> &value);
|
||||
static inline JSTaggedValue RuntimeEqDyn(JSThread *thread, const JSHandle<JSTaggedValue> &left,
|
||||
const JSHandle<JSTaggedValue> &right);
|
||||
|
@ -136,6 +136,8 @@ group("ark_aot_test") {
|
||||
"throwundefindeifhole:throwundefindeifholeAotAction",
|
||||
"tonumber:tonumberAotAction",
|
||||
"tonumeric:tonumericAotAction",
|
||||
|
||||
#"dynamicimport:dynamicimportAotAction",
|
||||
"try_catch_finally:try_catch_finallyAotAction",
|
||||
"trystglobalbynameprefid32:trystglobalbynameprefid32AotAction",
|
||||
"typeadd:typeaddAotAction",
|
||||
|
20
test/aottest/dynamicimport/A.js
Normal file
20
test/aottest/dynamicimport/A.js
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export {name, familyCrets, cognomen};
|
||||
|
||||
const name = 'Tywin';
|
||||
const familyCrets = 'Lion';
|
||||
const cognomen = 'Lannister';
|
23
test/aottest/dynamicimport/B.js
Normal file
23
test/aottest/dynamicimport/B.js
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export {name, familyCrets, cognomen};
|
||||
var cognomen, familyCrets;
|
||||
import('./A.js').then(animalA=> {
|
||||
cognomen = animalA.cognomen;
|
||||
familyCrets = animalA.familyCrets;
|
||||
}).then().catch();
|
||||
|
||||
const name = 'Tyrion';
|
31
test/aottest/dynamicimport/BUILD.gn
Normal file
31
test/aottest/dynamicimport/BUILD.gn
Normal file
@ -0,0 +1,31 @@
|
||||
# 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("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_test_action("B") {
|
||||
deps = []
|
||||
is_module = true
|
||||
}
|
||||
|
||||
host_aot_test_action("A") {
|
||||
deps = []
|
||||
is_module = true
|
||||
}
|
||||
|
||||
host_aot_test_action("dynamicimport") {
|
||||
deps = [
|
||||
":gen_A_abc",
|
||||
":gen_B_abc",
|
||||
]
|
||||
}
|
39
test/aottest/dynamicimport/dynamicimport.js
Normal file
39
test/aottest/dynamicimport/dynamicimport.js
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const objA = {
|
||||
toString() {
|
||||
return './A.js';
|
||||
}
|
||||
};
|
||||
|
||||
const objB = {
|
||||
toString() {
|
||||
return './B.js';
|
||||
}
|
||||
};
|
||||
|
||||
import(objA).then(animalA => {
|
||||
print('full name : ', animalA.name, ' ', animalA.cognomen);
|
||||
print(animalA.familyCrets);
|
||||
}).then().catch();
|
||||
|
||||
async function f() {
|
||||
var animalB = await import(objB);
|
||||
print('full name : ', animalB.name, ' ', animalB.cognomen);
|
||||
print(animalB.familyCrets);
|
||||
}
|
||||
|
||||
f().then().catch();
|
17
test/aottest/dynamicimport/expect_output.txt
Normal file
17
test/aottest/dynamicimport/expect_output.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# 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.
|
||||
|
||||
full name : Tyrion Lannister
|
||||
Lion
|
||||
full name : Tywin Lannister
|
||||
Lion
|
@ -27,6 +27,7 @@ group("ark_js_moduletest") {
|
||||
"class:classAction",
|
||||
"compareobjecthclass:compareobjecthclassAction",
|
||||
"container:containerAction",
|
||||
"dynamicimport:dynamicimportAction",
|
||||
"dyninstruction:dyninstructionAction",
|
||||
"ecmastringtable:ecmastringtableAction",
|
||||
"fortest:fortestAction",
|
||||
@ -84,6 +85,7 @@ group("ark_asm_test") {
|
||||
"class:classAsmAction",
|
||||
"compareobjecthclass:compareobjecthclassAsmAction",
|
||||
"container:containerAsmAction",
|
||||
"dynamicimport:dynamicimportAction",
|
||||
"dyninstruction:dyninstructionAsmAction",
|
||||
"ecmastringtable:ecmastringtableAsmAction",
|
||||
"fortest:fortestAsmAction",
|
||||
@ -136,6 +138,7 @@ group("ark_asm_single_step_test") {
|
||||
"class:classAsmSingleStepAction",
|
||||
"compareobjecthclass:compareobjecthclassAsmSingleStepAction",
|
||||
"container:containerAsmSingleStepAction",
|
||||
"dynamicimport:dynamicimportAction",
|
||||
"dyninstruction:dyninstructionAsmSingleStepAction",
|
||||
"ecmastringtable:ecmastringtableAsmSingleStepAction",
|
||||
"fortest:fortestAsmSingleStepAction",
|
||||
|
20
test/moduletest/dynamicimport/A.js
Normal file
20
test/moduletest/dynamicimport/A.js
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export {name, familyCrets, cognomen};
|
||||
|
||||
const name = 'Tywin';
|
||||
const familyCrets = 'Lion';
|
||||
const cognomen = 'Lannister';
|
23
test/moduletest/dynamicimport/B.js
Normal file
23
test/moduletest/dynamicimport/B.js
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export {name, familyCrets, cognomen};
|
||||
var cognomen, familyCrets;
|
||||
import('./A.js').then(animalA=> {
|
||||
cognomen = animalA.cognomen;
|
||||
familyCrets = animalA.familyCrets;
|
||||
}).then().catch();
|
||||
|
||||
const name = 'Tyrion';
|
31
test/moduletest/dynamicimport/BUILD.gn
Normal file
31
test/moduletest/dynamicimport/BUILD.gn
Normal file
@ -0,0 +1,31 @@
|
||||
# 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("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_moduletest_action("B") {
|
||||
deps = []
|
||||
is_module = true
|
||||
}
|
||||
|
||||
host_moduletest_action("A") {
|
||||
deps = []
|
||||
is_module = true
|
||||
}
|
||||
|
||||
host_moduletest_action("dynamicimport") {
|
||||
deps = [
|
||||
":gen_A_abc",
|
||||
":gen_B_abc",
|
||||
]
|
||||
}
|
39
test/moduletest/dynamicimport/dynamicimport.js
Normal file
39
test/moduletest/dynamicimport/dynamicimport.js
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const objA = {
|
||||
toString() {
|
||||
return './A.js';
|
||||
}
|
||||
};
|
||||
|
||||
const objB = {
|
||||
toString() {
|
||||
return './B.js';
|
||||
}
|
||||
};
|
||||
|
||||
import(objA).then(animalA => {
|
||||
print('full name : ', animalA.name, ' ', animalA.cognomen);
|
||||
print(animalA.familyCrets);
|
||||
}).then().catch();
|
||||
|
||||
async function f() {
|
||||
var animalB = await import(objB);
|
||||
print('full name : ', animalB.name, ' ', animalB.cognomen);
|
||||
print(animalB.familyCrets);
|
||||
}
|
||||
|
||||
f().then().catch();
|
17
test/moduletest/dynamicimport/expect_output.txt
Normal file
17
test/moduletest/dynamicimport/expect_output.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# 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.
|
||||
|
||||
full name : Tyrion Lannister
|
||||
Lion
|
||||
full name : Tywin Lannister
|
||||
Lion
|
Loading…
Reference in New Issue
Block a user