!2085 Implementation of Dynamic Import

Merge pull request !2085 from DaiHN/dynamicImport
This commit is contained in:
openharmony_ci 2022-08-30 07:39:22 +00:00 committed by Gitee
commit 966983e362
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
49 changed files with 579 additions and 41 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -163,6 +163,7 @@ namespace panda::ecmascript::kungfu {
T(HandleCreateAsyncGeneratorObjPrefV8) \
T(HandleAsyncGeneratorResolvePrefV8V8V8) \
T(HandleDefineAsyncGeneratorFuncPrefId16Imm16V8) \
T(HandleDynamicImportPrefV8) \
T(HandleMovDynV8V8) \
T(HandleMovDynV16V16) \
T(HandleLdaStrId32) \

View File

@ -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();

View File

@ -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();

View File

@ -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)));

View File

@ -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);

View File

@ -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()));

View File

@ -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]

View File

@ -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) {

View File

@ -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:

View File

@ -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) \

View File

@ -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"},

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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)
{

View File

@ -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,

View File

@ -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,

View File

@ -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();

View File

@ -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,

View File

@ -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()) {

View File

@ -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);

View File

@ -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 {

View File

@ -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> &currentModule,
JSTaggedValue key, JSTaggedValue value);
JSTaggedValue GetModuleNamespaceInternal(JSTaggedValue localName, JSTaggedValue currentModule);
static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4;

View File

@ -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,

View File

@ -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(

View File

@ -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,

View File

@ -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) \

View File

@ -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),

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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",

View 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';

View 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';

View 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",
]
}

View 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();

View 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

View File

@ -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",

View 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';

View 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';

View 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",
]
}

View 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();

View 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