From cf646dca97e1d216d497a30ebdd828e366cf03c3 Mon Sep 17 00:00:00 2001 From: schernykh Date: Tue, 20 Dec 2022 05:13:18 +0300 Subject: [PATCH] Remove JS environment from thread and cframe. Details: * Removed prev from environment. * Removed env from thread. * Supported building env in compiler as IR instructions: - this function - 1st arg - constant pool read from this_func - lexical environment initially read from this_func, and update in dataflow * Implemented passing env as intrinsic's parameters in cpp/irtoc interpreter and compiler. * Added env vregs in codeinfo for correct restoring in deoptimization. * Splitted LoadString to LoadString and LoadStringDynamic Signed-off-by: Sergey Chernykh --- compiler/codegen_intrinsics_ecmascript.cpp | 63 +--- .../ecmascript_codegen_extensions.cpp | 73 +---- .../ecmascript_codegen_extensions.h | 3 - .../ecmascript_environment.h | 20 +- .../thread_environment_api.h | 26 -- .../code_generator/compiler_base_types.cpp | 31 ++ .../code_generator/compiler_base_types.h | 4 + compiler/optimizer/ecma_pipeline.cpp | 1 - .../ir_builder/ecmascript_inst_builder.cpp | 6 +- .../optimizations/expand_intrinsics.cpp | 53 +--- .../optimizations/expand_intrinsics.h | 1 - .../ecmascript_inst_builder_gen.cpp.erb | 46 +++ ecmascript_plugin_options.yaml | 3 + ecmastdlib/ecmastdlib.pa | 96 +++--- irtoc_scripts/common.irt | 33 +- irtoc_scripts/interpreter_handlers.irt | 289 ++++++++++------- irtoc_scripts/interpreter_main_loop.irt | 114 +++---- irtoc_scripts/object.irt | 16 +- isa/isa.yaml | 108 ++++--- runtime/asm_defines/asm_defines.def | 17 +- runtime/class_linker/program_object.h | 6 + runtime/ecma_compiler.cpp | 17 +- runtime/ecma_entrypoints.cpp | 11 +- runtime/ecma_entrypoints.yaml | 16 + runtime/ecma_language_context.cpp | 69 ++-- runtime/ecma_language_context.h | 9 +- runtime/ecma_runtime.yaml | 125 +++----- runtime/ecma_vm.cpp | 21 +- runtime/ecma_vm.h | 7 +- runtime/ic/ic_runtime_stub-inl.h | 69 ++-- runtime/ic/ic_runtime_stub.h | 34 +- runtime/interpreter/ecma-interpreter-inl.h | 268 ++++++++++------ runtime/interpreter/interpreter-inl.h | 27 +- runtime/interpreter/js_frame.h | 2 +- runtime/interpreter/slow_runtime_helper.cpp | 2 +- runtime/intrinsics-inl.h | 297 +++++++++--------- runtime/js_thread.cpp | 19 +- runtime/js_thread.h | 12 - runtime/lexical_env.h | 6 + tests/checked/try_load_global_by_name.js | 4 +- tests/compiler/codegen_ecma_test.cpp | 3 + .../compiler/expand_intrinsics_ecma_test.cpp | 75 ++--- 42 files changed, 1097 insertions(+), 1005 deletions(-) diff --git a/compiler/codegen_intrinsics_ecmascript.cpp b/compiler/codegen_intrinsics_ecmascript.cpp index 0031d8b55..30534d737 100644 --- a/compiler/codegen_intrinsics_ecmascript.cpp +++ b/compiler/codegen_intrinsics_ecmascript.cpp @@ -33,49 +33,22 @@ static MemRef IFrameAccMemRef(Encoder *enc, Reg iframe_reg) return MemRef(iframe_reg, cross_values::GetFrameAccOffset(enc->GetArch())); } -static void ReadExtensionData(Codegen *cg, Reg dst, uint16_t env_offs, uint32_t depth) +MemRef AccMemRef(Encoder *enc, Reg thread, Reg acc_reg) { - auto enc = cg->GetEncoder(); - auto arch = enc->GetArch(); - - if (cg->GetGraph()->SupportManagedCode()) { - enc->EncodeLdr(dst, false, MemRef(cg->SpReg(), cg->GetLanguageExtensionOffsetFromSpInBytes(depth) + env_offs)); - } else { - auto dst_ptr = dst.As(TypeInfo::FromDataType(DataType::POINTER, arch)); - enc->EncodeLdr(dst_ptr, false, - MemRef(cg->ThreadReg(), cross_values::GetManagedThreadLanguageExtensionDataOffset(arch))); - enc->EncodeLdr(dst, false, MemRef(dst_ptr, env_offs)); - } + enc->EncodeAdd(acc_reg, thread, Imm(ManagedThread::GetFrameOffset())); + auto acc_ptr = MemRef(acc_reg); + enc->EncodeLdr(acc_reg, false, MemRef(acc_ptr)); + return MemRef(acc_reg, cross_values::GetFrameAccOffset(enc->GetArch())); } void Codegen::LdlexenvDyn([[maybe_unused]] IntrinsicInst *inst, [[maybe_unused]] Reg dst, [[maybe_unused]] SRCREGS src) { - auto enc = GetEncoder(); - auto arch = enc->GetArch(); - - auto constexpr LE_OFFS = panda::ecmascript::EcmascriptEnvironment::GetLexicalEnvOffset(); - - ASSERT(GetGraph()->SupportManagedCode() == (inst->GetSaveState() == nullptr)); - if (GetGraph()->SupportManagedCode()) { - ReadExtensionData(this, dst, LE_OFFS, inst->GetImms().back()); - } else if (!GetGraph()->GetMode().IsInterpreter()) { - ReadExtensionData(this, dst, LE_OFFS, inst->GetInliningDepth()); - } else { - auto tmp1 = ConvertInstTmpReg(inst); - ScopedTmpReg tmp2(enc); - - Reg le_reg(tmp1.GetId(), Codegen::ConvertDataType(DataType::ANY, arch)); - Reg iframe_reg(tmp2.GetReg().GetId(), Codegen::ConvertDataType(DataType::POINTER, arch)); - - ReadExtensionData(this, le_reg, LE_OFFS, inst->GetInliningDepth()); - LoadIFramePtr(this, iframe_reg); - enc->EncodeStr(le_reg, IFrameAccMemRef(enc, iframe_reg)); - } + GetEncoder()->EncodeLdr(dst, false, MemRef(src[0], cross_values::GetJsfunctionLexicalEnvOffset(GetArch()))); } void Codegen::LdLexVarDyn(IntrinsicInst *inst, Reg dst, SRCREGS src) { - ASSERT(inst->HasImms() == (inst->GetInputsCount() == 0U)); + ASSERT(inst->HasImms() == (inst->GetInputsCount() == 1U)); ASSERT(GetGraph()->GetMode().IsInterpreter() != inst->HasImms()); auto *enc = GetEncoder(); @@ -88,8 +61,7 @@ void Codegen::LdLexVarDyn(IntrinsicInst *inst, Reg dst, SRCREGS src) ASSERT(lex_env.GetSize() >= lex_env_ptr.GetSize()); ASSERT(GetGraph()->SupportManagedCode() == (inst->GetSaveState() == nullptr)); - auto inline_depth = GetGraph()->SupportManagedCode() ? inst->GetImms().back() : inst->GetInliningDepth(); - ReadExtensionData(this, lex_env, panda::ecmascript::EcmascriptEnvironment::GetLexicalEnvOffset(), inline_depth); + enc->EncodeMov(tmp, src[0]); constexpr size_t LEVEL_INDEX = 0U; auto data = runtime->GetArrayDataOffset(arch); @@ -144,20 +116,6 @@ void Codegen::GetObjectClassTypeIntrinsic([[maybe_unused]] IntrinsicInst *inst, GetEncoder()->EncodeMov(dst, tmp_reg); } -void Codegen::GetEcmaConstantPool([[maybe_unused]] IntrinsicInst *inst, [[maybe_unused]] Reg dst, - [[maybe_unused]] SRCREGS src) -{ - ReadExtensionData(this, dst, panda::ecmascript::EcmascriptEnvironment::GetConstantPoolOffset(), - inst->GetInliningDepth()); -} - -void Codegen::GetEcmaThisFunc([[maybe_unused]] IntrinsicInst *inst, [[maybe_unused]] Reg dst, - [[maybe_unused]] SRCREGS src) -{ - ReadExtensionData(this, dst, panda::ecmascript::EcmascriptEnvironment::GetThisFuncOffset(), - inst->GetInliningDepth()); -} - void Codegen::GetWeakReferent([[maybe_unused]] IntrinsicInst *inst, [[maybe_unused]] Reg dst, [[maybe_unused]] SRCREGS src) { @@ -218,12 +176,13 @@ void Codegen::CreateDynClassGetHash([[maybe_unused]] IntrinsicInst *inst, Reg ds void Codegen::CreateLdObjDynByName([[maybe_unused]] IntrinsicInst *inst, Reg dst, SRCREGS src) { - CallFastPath(inst, EntrypointId::LOAD_OBJECT_DYNAMIC_BY_NAME, dst, {}, src[0], src[1U], src[2U]); + CallFastPath(inst, EntrypointId::LOAD_OBJECT_DYNAMIC_BY_NAME, dst, {}, src[0], src[1U], src[2U], src[3U], src[4U]); } void Codegen::CreateStObjDynByName([[maybe_unused]] IntrinsicInst *inst, Reg dst, SRCREGS src) { - CallFastPath(inst, EntrypointId::STORE_OBJECT_DYNAMIC_BY_NAME, dst, {}, src[0], src[1U], src[2U], src[3U]); + CallFastPath(inst, EntrypointId::STORE_OBJECT_DYNAMIC_BY_NAME, dst, {}, src[0], src[1U], src[2U], src[3U], src[4U], + src[5U]); } void Codegen::CreateAllocDynObject([[maybe_unused]] IntrinsicInst *inst, Reg dst, SRCREGS src) diff --git a/compiler/ecmascript_extensions/ecmascript_codegen_extensions.cpp b/compiler/ecmascript_extensions/ecmascript_codegen_extensions.cpp index 3fa409ee9..a54856f6f 100644 --- a/compiler/ecmascript_extensions/ecmascript_codegen_extensions.cpp +++ b/compiler/ecmascript_extensions/ecmascript_codegen_extensions.cpp @@ -19,70 +19,12 @@ namespace panda::compiler { -void Codegen::GenerateEcmascriptEnvInPrologue(Reg jsfunc_reg, uint32_t depth) -{ - SCOPED_DISASM_STR(this, "Create EcmascriptEnvironment in method prologue"); - auto enc = GetEncoder(); - auto arch = GetArch(); - - auto env_sp_offset = GetLanguageExtensionOffsetFromSpInBytes(depth); - auto env_ptr_tls_offset = cross_values::GetManagedThreadLanguageExtensionDataOffset(arch); - auto prev_env_sp_offset = env_sp_offset + cross_values::GetEcmascriptEnvironmentPrevEnvironmentOffset(arch); - - // Initialize EcmascriptEnv fields - { - ScopedTmpRegLazy jsfunc_reg_tmp(enc); - if (!jsfunc_reg.IsValid()) { - ASSERT(depth == 0); - jsfunc_reg_tmp.Acquire(); - auto args_jsfunc_offset = - GetStackOffset(Location::MakeStackParameter(ecmascript_call_params::SLOT_FUNCTION)); - enc->EncodeLdr(jsfunc_reg_tmp, false, MemRef(SpReg(), args_jsfunc_offset)); - jsfunc_reg = jsfunc_reg_tmp.GetReg(); - } - auto cp_jsf_offset = cross_values::GetJsfunctionConstantPoolOffset(GetArch()); - auto le_jsf_offset = cross_values::GetJsfunctionLexicalEnvOffset(GetArch()); - - auto cp_sp_offset = env_sp_offset + cross_values::GetEcmascriptEnvironmentConstantPoolOffset(arch); - auto le_sp_offset = env_sp_offset + cross_values::GetEcmascriptEnvironmentLexicalEnvOffset(arch); - auto fn_sp_offset = env_sp_offset + cross_values::GetEcmascriptEnvironmentThisFuncOffset(arch); - - enc->EncodeMemCopy(MemRef(jsfunc_reg, cp_jsf_offset), MemRef(SpReg(), cp_sp_offset), - DataType::GetTypeSize(DataType::ANY, arch)); - enc->EncodeMemCopy(MemRef(jsfunc_reg, le_jsf_offset), MemRef(SpReg(), le_sp_offset), - DataType::GetTypeSize(DataType::ANY, arch)); - enc->EncodeStr(jsfunc_reg, MemRef(SpReg(), fn_sp_offset)); - } - - // Update current env TLS pointer and link with previous - { - ScopedTmpReg tmp_reg(enc, ConvertDataType(DataType::POINTER, GetArch())); - enc->EncodeLdr(tmp_reg, false, MemRef(ThreadReg(), env_ptr_tls_offset)); - enc->EncodeStr(tmp_reg, MemRef(SpReg(), prev_env_sp_offset)); - enc->EncodeAdd(tmp_reg, SpReg(), Imm(env_sp_offset)); - enc->EncodeStr(tmp_reg, MemRef(ThreadReg(), env_ptr_tls_offset)); - } -} - -void Codegen::GenerateEcmascriptEnvInEpilogue() -{ - SCOPED_DISASM_STR(this, "Destroy EcmascriptEnvironment in method epilogue"); - auto enc = GetEncoder(); - - auto env_ptr_tls_offset = cross_values::GetManagedThreadLanguageExtensionDataOffset(GetArch()); - auto prev_env_env_offset = panda::ecmascript::EcmascriptEnvironment::GetPrevEnvironmentOffset(); - - ScopedTmpReg env_reg(enc, ConvertDataType(DataType::POINTER, GetArch())); - enc->EncodeLdr(env_reg, false, MemRef(ThreadReg(), env_ptr_tls_offset)); - enc->EncodeMemCopy(MemRef(env_reg, prev_env_env_offset), MemRef(ThreadReg(), env_ptr_tls_offset), - env_reg.GetReg().GetSize()); -} - bool Codegen::GenerateLoadObjectDynamic(Inst *inst) { auto dst_reg = ConvertRegister(inst->GetDstReg(), inst->GetType()); auto obj_reg = ConvertRegister(inst->GetSrcReg(0), inst->GetInputType(0)); auto key_reg = ConvertRegister(inst->GetSrcReg(1U), inst->GetInputType(1U)); + auto this_func = ConvertRegister(inst->GetSrcReg(2U), inst->GetInputType(2U)); auto type = inst->CastToLoadObjectDynamic()->GetAccessType(); auto mode = inst->CastToLoadObjectDynamic()->GetAccessMode(); @@ -101,7 +43,11 @@ bool Codegen::GenerateLoadObjectDynamic(Inst *inst) if (use_ic) { CallFastPath(inst, id, dst_reg, {}, obj_reg, key_reg, TypedImm(inst->GetPc())); } else { - CallFastPath(inst, id, dst_reg, {}, obj_reg, key_reg); + if (type != DynObjectAccessType::BY_INDEX) { + CallFastPath(inst, id, dst_reg, {}, obj_reg, key_reg, this_func); + } else { + CallFastPath(inst, id, dst_reg, {}, obj_reg, key_reg); + } } return true; @@ -113,6 +59,7 @@ bool Codegen::GenerateStoreObjectDynamic(Inst *inst) auto obj_reg = ConvertRegister(inst->GetSrcReg(0), inst->GetInputType(0)); auto key_reg = ConvertRegister(inst->GetSrcReg(1U), inst->GetInputType(1U)); auto val_reg = ConvertRegister(inst->GetSrcReg(2U), inst->GetInputType(2U)); + auto this_func = ConvertRegister(inst->GetSrcReg(3U), inst->GetInputType(3U)); auto type = inst->CastToStoreObjectDynamic()->GetAccessType(); auto mode = inst->CastToStoreObjectDynamic()->GetAccessMode(); @@ -131,7 +78,11 @@ bool Codegen::GenerateStoreObjectDynamic(Inst *inst) if (use_ic) { CallFastPath(inst, id, dst_reg, {}, obj_reg, key_reg, val_reg, TypedImm(inst->GetPc())); } else { - CallFastPath(inst, id, dst_reg, {}, obj_reg, key_reg, val_reg); + if (type != DynObjectAccessType::BY_INDEX) { + CallFastPath(inst, id, dst_reg, {}, obj_reg, key_reg, val_reg, this_func); + } else { + CallFastPath(inst, id, dst_reg, {}, obj_reg, key_reg, val_reg); + } } return true; diff --git a/compiler/ecmascript_extensions/ecmascript_codegen_extensions.h b/compiler/ecmascript_extensions/ecmascript_codegen_extensions.h index a407f9d85..0a9683ec7 100644 --- a/compiler/ecmascript_extensions/ecmascript_codegen_extensions.h +++ b/compiler/ecmascript_extensions/ecmascript_codegen_extensions.h @@ -16,9 +16,6 @@ #ifndef PANDA_COMPILER_ECMASCRIPT_CODEGEN_EXTENSIONS_H #define PANDA_COMPILER_ECMASCRIPT_CODEGEN_EXTENSIONS_H -void GenerateEcmascriptEnvInPrologue(Reg jsfunc_reg, uint32_t depth); -void GenerateEcmascriptEnvInEpilogue(); - bool GenerateLoadObjectDynamic(Inst *inst); bool GenerateStoreObjectDynamic(Inst *inst); diff --git a/compiler/ecmascript_extensions/ecmascript_environment.h b/compiler/ecmascript_extensions/ecmascript_environment.h index 5facccee7..23b4429a0 100644 --- a/compiler/ecmascript_extensions/ecmascript_environment.h +++ b/compiler/ecmascript_extensions/ecmascript_environment.h @@ -33,8 +33,8 @@ class JSHandle; class EcmascriptEnvironment { public: - EcmascriptEnvironment(EcmascriptEnvironment *prev, ObjectHeader *cp, ObjectHeader *le, ObjectHeader *tf) - : prev_env_(prev), constant_pool_(cp), lexical_env_(le), this_func_(tf) + EcmascriptEnvironment(ObjectHeader *cp, ObjectHeader *le, ObjectHeader *tf) + : constant_pool_(cp), lexical_env_(le), this_func_(tf) { } @@ -53,11 +53,6 @@ public: return MEMBER_OFFSET(EcmascriptEnvironment, lexical_env_); } - static constexpr size_t GetPrevEnvironmentOffset() - { - return MEMBER_OFFSET(EcmascriptEnvironment, prev_env_); - } - static constexpr size_t GetThisFuncOffset() { return MEMBER_OFFSET(EcmascriptEnvironment, this_func_); @@ -93,23 +88,12 @@ public: this_func_ = panda::coretypes::TaggedValue(this_func); } - EcmascriptEnvironment *GetPrevEnvironment() const - { - return prev_env_; - } - - void SetPrevEnvironment(EcmascriptEnvironment *prev_env) - { - prev_env_ = prev_env; - } - static constexpr size_t GetSize() { return AlignUp(sizeof(EcmascriptEnvironment), GetAlignmentInBytes(DEFAULT_FRAME_ALIGNMENT)); } private: - EcmascriptEnvironment *prev_env_; panda::coretypes::TaggedValue constant_pool_; panda::coretypes::TaggedValue lexical_env_; panda::coretypes::TaggedValue this_func_; diff --git a/compiler/ecmascript_extensions/thread_environment_api.h b/compiler/ecmascript_extensions/thread_environment_api.h index 84673c1b6..d8cb2bbee 100644 --- a/compiler/ecmascript_extensions/thread_environment_api.h +++ b/compiler/ecmascript_extensions/thread_environment_api.h @@ -25,32 +25,6 @@ namespace panda::ecmascript { -inline EcmascriptEnvironment *GetEcmascriptEnvironment(JSThread *thread) -{ - auto lang_ext = thread->GetLanguageExtensionsData(); - return EcmascriptEnvironment::Cast(lang_ext); -} - -inline ConstantPool *GetConstantPool(JSThread *thread) -{ - return ConstantPool::Cast(GetEcmascriptEnvironment(thread)->GetConstantPool()); -} - -inline LexicalEnv *GetLexicalEnv(JSThread *thread) -{ - return LexicalEnv::Cast(GetEcmascriptEnvironment(thread)->GetLexicalEnv()); -} - -inline void SetLexicalEnv(JSThread *thread, JSTaggedValue env) -{ - GetEcmascriptEnvironment(thread)->SetLexicalEnv(env.GetHeapObject()); -} - -inline JSTaggedValue GetThisFunc(JSThread *thread) -{ - return JSTaggedValue(GetEcmascriptEnvironment(thread)->GetThisFunc()); -} - #ifdef PANDA_QEMU_AARCH64_GCC_8 // Build PANDA_QEMU_AARCH64_GCC_8 hangs without this workaround. Please check issue #8094. JSTaggedValue GetGlobalObject(JSThread *thread); diff --git a/compiler/optimizer/code_generator/compiler_base_types.cpp b/compiler/optimizer/code_generator/compiler_base_types.cpp index 4820fdfda..ace74e71c 100644 --- a/compiler/optimizer/code_generator/compiler_base_types.cpp +++ b/compiler/optimizer/code_generator/compiler_base_types.cpp @@ -515,4 +515,35 @@ bool ecmascript::DynamicCallCheckGen(FixedInputsInst2 *check_inst, EncodeVisitor return true; } +bool ecmascript::LoadConstantPoolGen(const Inst *inst, EncodeVisitor *enc_v) +{ + auto *codegen = enc_v->GetCodegen(); + auto src = codegen->ConvertRegister(inst->GetSrcReg(0), inst->GetType()); + auto dst = codegen->ConvertRegister(inst->GetDstReg(), inst->GetType()); + codegen->GetEncoder()->EncodeLdr(dst, false, + MemRef(src, cross_values::GetJsfunctionConstantPoolOffset(codegen->GetArch()))); + return true; +} + +bool ecmascript::LoadLexicalEnvGen(const Inst *inst, EncodeVisitor *enc_v) +{ + auto *codegen = enc_v->GetCodegen(); + auto src = codegen->ConvertRegister(inst->GetSrcReg(0), inst->GetType()); + auto dst = codegen->ConvertRegister(inst->GetDstReg(), inst->GetType()); + codegen->GetEncoder()->EncodeLdr(dst, false, + MemRef(src, cross_values::GetJsfunctionLexicalEnvOffset(codegen->GetArch()))); + return true; +} + +bool ecmascript::LoadStringDynamicGen(Inst *inst, EncodeVisitor *enc_v) +{ + auto codegen = enc_v->GetCodegen(); + auto src = codegen->ConvertRegister(inst->GetSrcReg(0), DataType::ANY); + auto dst = codegen->ConvertRegister(inst->GetDstReg(), inst->GetType()); + auto string_type = inst->CastToLoadStringDynamic()->GetTypeId(); + ASSERT(inst->IsRuntimeCall()); + codegen->CallRuntime(inst, ::panda::compiler::RuntimeInterface::EntrypointId::RESOLVE_STRING_DYNAMIC, dst, + RegMask::GetZeroMask(), src, TypedImm(string_type)); + return true; +} } // namespace panda::compiler diff --git a/compiler/optimizer/code_generator/compiler_base_types.h b/compiler/optimizer/code_generator/compiler_base_types.h index b228e37c4..114ac3c2e 100644 --- a/compiler/optimizer/code_generator/compiler_base_types.h +++ b/compiler/optimizer/code_generator/compiler_base_types.h @@ -19,6 +19,7 @@ namespace panda::compiler { +class Inst; class CompareAnyTypeInst; class CastAnyTypeValueInst; class CastValueToAnyTypeInst; @@ -34,6 +35,9 @@ bool CastValueToAnyTypeGen(const CastValueToAnyTypeInst *cvai, EncodeVisitor *en bool AnyTypeCheckGen(AnyTypeCheckInst *check_inst, EncodeVisitor *enc_v); bool ObjByIndexCheckGen(const FixedInputsInst2 *check_inst, EncodeVisitor *enc_v, LabelHolder::LabelId id); bool DynamicCallCheckGen(FixedInputsInst2 *check_inst, EncodeVisitor *enc_v); +bool LoadConstantPoolGen(const Inst *inst, EncodeVisitor *enc_v); +bool LoadLexicalEnvGen(const Inst *inst, EncodeVisitor *enc_v); +bool LoadStringDynamicGen(Inst *inst, EncodeVisitor *enc_v); } // namespace ecmascript } // namespace panda::compiler diff --git a/compiler/optimizer/ecma_pipeline.cpp b/compiler/optimizer/ecma_pipeline.cpp index 1ea70fc6e..76dddcf69 100644 --- a/compiler/optimizer/ecma_pipeline.cpp +++ b/compiler/optimizer/ecma_pipeline.cpp @@ -54,7 +54,6 @@ namespace panda::compiler::ecmascript { bool EcmaPipeline::RunOptimizations() { auto graph = GetGraph(); - graph->RunPass(); // TODO(schernykh): Find way to inline in AOT and OSR mode if (!graph->IsAotMode() && !graph->IsOsrMode()) { diff --git a/compiler/optimizer/ir_builder/ecmascript_inst_builder.cpp b/compiler/optimizer/ir_builder/ecmascript_inst_builder.cpp index 4920f1970..e6e7b9177 100644 --- a/compiler/optimizer/ir_builder/ecmascript_inst_builder.cpp +++ b/compiler/optimizer/ir_builder/ecmascript_inst_builder.cpp @@ -169,7 +169,8 @@ void InstBuilder::BuildStGlobalVar(const BytecodeInstruction *bc_inst, size_t ty get_address->SetTypeId(type_id); get_address->SetMethod(GetGraph()->GetMethod()); - get_address->SetInput(0, save_state); + get_address->SetInput(0, GetEnvDefinition(CONST_POOL_IDX)); + get_address->SetInput(1, save_state); auto store_object = graph_->CreateInstStoreObject(DataType::ANY, pc); store_object->SetTypeId(TypeIdMixin::MEM_DYN_GLOBAL_ID); @@ -200,7 +201,8 @@ void InstBuilder::BuildLdGlobalVar(const BytecodeInstruction *bc_inst, size_t ty get_address->SetTypeId(type_id); get_address->SetMethod(GetGraph()->GetMethod()); - get_address->SetInput(0, save_state); + get_address->SetInput(0, GetEnvDefinition(CONST_POOL_IDX)); + get_address->SetInput(1, save_state); auto load_object = graph_->CreateInstLoadObject(DataType::ANY, pc); load_object->SetTypeId(TypeIdMixin::MEM_DYN_GLOBAL_ID); diff --git a/compiler/optimizer/optimizations/expand_intrinsics.cpp b/compiler/optimizer/optimizations/expand_intrinsics.cpp index 674d6e4b8..f8a5e4e0d 100644 --- a/compiler/optimizer/optimizations/expand_intrinsics.cpp +++ b/compiler/optimizer/optimizations/expand_intrinsics.cpp @@ -52,8 +52,6 @@ bool ExpandIntrinsics::Expand(IntrinsicInst *inst) return ExpandLdLexDyn(inst); case RuntimeInterface::IntrinsicId::INTRINSIC_LD_LEX_VAR_DYN: return ExpandLdLexVarDyn(inst); - case RuntimeInterface::IntrinsicId::INTRINSIC_LDLEXENV_DYN: - return ExpandLdlexenvDyn(inst); case RuntimeInterface::IntrinsicId::INTRINSIC_TRY_LD_GLOBAL_BY_NAME: return ExpandTryLdGlobalByName(inst); default: @@ -149,7 +147,7 @@ Inst *ExpandIntrinsics::NewObjFillCallConstructorBlock(InstAppender *appender, I ss_copy->SetVirtualRegister(input_idx, ss->GetVirtualRegister(input_idx)); } ss_copy->AppendInput(alloc_obj); - VirtualRegister vreg {VirtualRegister::BRIDGE, false}; + VirtualRegister vreg {VirtualRegister::BRIDGE, VRegType::VREG}; ss_copy->SetVirtualRegister(ss->GetInputsCount(), vreg); auto call_ctor = NewObjCreateConstructorCall(orig_alloc, alloc_obj, ss_copy, pc); @@ -168,7 +166,7 @@ Inst *ExpandIntrinsics::NewObjResolveCtorResult(InstAppender *appender, Inst *or ss_copy_2->SetVirtualRegister(input_idx, ss->GetVirtualRegister(input_idx)); } ss_copy_2->AppendInput(call_ctor); - VirtualRegister vreg {VirtualRegister::BRIDGE, false}; + VirtualRegister vreg {VirtualRegister::BRIDGE, VRegType::VREG}; ss_copy_2->SetVirtualRegister(ss->GetInputsCount(), vreg); auto resolve_result = GetGraph()->CreateInstIntrinsic( @@ -350,12 +348,17 @@ bool ExpandIntrinsics::ExpandLdLexDyn(IntrinsicInst *intrinsic) ASSERT(save_state != nullptr); ASSERT(intrinsic->GetImms().size() == 3U); + // ConstPool, LexEnv, SaveState + ASSERT(intrinsic->GetInputsCount() == 3U); auto *load_lex_var = intrinsic; load_lex_var->SetIntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LD_LEX_VAR_DYN); load_lex_var->SetImm(0U, load_lex_var->GetImm(1U)); // level load_lex_var->SetImm(1U, load_lex_var->GetImm(2U)); // slot load_lex_var->GetImms().pop_back(); // the last is not needed - + ASSERT(load_lex_var->GetInput(2U).GetInst()->GetOpcode() == Opcode::SaveState); + load_lex_var->RemoveInput(2U); + load_lex_var->RemoveInput(0U); + load_lex_var->ClearFlag(inst_flags::REQUIRE_STATE); InstAppender appender(load_lex_var->GetBasicBlock(), load_lex_var); auto pc = intrinsic->GetPc(); @@ -376,44 +379,22 @@ bool ExpandIntrinsics::ExpandLdLexDyn(IntrinsicInst *intrinsic) return true; } -static bool MoveInliningDepthToImms(IntrinsicInst *intrinsic) -{ - if (intrinsic->GetSaveState() == nullptr) { - return false; - } - - CHECK_GT(intrinsic->GetInputsCount(), 0U); - auto save_state_index = intrinsic->GetInputsCount() - 1U; - auto *save_state = intrinsic->GetInput(save_state_index).GetInst(); - ASSERT(save_state->IsSaveState()); - - auto *graph = intrinsic->GetBasicBlock()->GetGraph(); - intrinsic->AddImm(graph->GetAllocator(), save_state->GetInliningDepth()); - intrinsic->RemoveInput(save_state_index); - intrinsic->ClearFlag(inst_flags::Flags::REQUIRE_STATE); - intrinsic->ClearFlag(inst_flags::Flags::RUNTIME_CALL); - return true; -} - bool ExpandIntrinsics::ExpandLdLexVarDyn(IntrinsicInst *intrinsic) { auto level = intrinsic->GetImms()[0U]; if (level > GetLdLexVarDynLevelThreshold()) { - return MoveInliningDepthToImms(intrinsic); + return false; } auto slot = intrinsic->GetImms()[1U]; - auto *load_lex_env = intrinsic; - load_lex_env->SetIntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LDLEXENV_DYN); - load_lex_env->GetImms().clear(); - MoveInliningDepthToImms(load_lex_env); + auto *load_lex_env = intrinsic->GetInput(0U).GetInst(); - InstAppender appender(load_lex_env->GetBasicBlock(), load_lex_env); + InstAppender appender(intrinsic->GetBasicBlock(), intrinsic); auto pc = intrinsic->GetPc(); auto *env_ref = GetGraph()->CreateInstCastAnyTypeValue(pc, AnyBaseType::ECMASCRIPT_ARRAY_TYPE); - // set input load_lex_env later + env_ref->SetInput(0U, load_lex_env); env_ref->SetFlag(inst_flags::NO_HOIST); appender.Append(env_ref); @@ -440,15 +421,10 @@ bool ExpandIntrinsics::ExpandLdLexVarDyn(IntrinsicInst *intrinsic) appender.Append(load_lex_var); intrinsic->ReplaceUsers(load_lex_var); - env_ref->SetInput(0U, load_lex_env); // set input here because of replacing users + intrinsic->GetBasicBlock()->RemoveInst(intrinsic); return true; } -bool ExpandIntrinsics::ExpandLdlexenvDyn(IntrinsicInst *intrinsic) -{ - return MoveInliningDepthToImms(intrinsic); -} - bool ExpandIntrinsics::ExpandTryLdGlobalByName(IntrinsicInst *inst) { if (GetGraph()->IsAotMode()) { @@ -487,7 +463,8 @@ void ExpandIntrinsics::ExpandTryLdGlobalField(IntrinsicInst *inst, uintptr_t add auto get_address = GetGraph()->CreateInstGetGlobalVarAddress(DataType::REFERENCE, pc, address); get_address->SetTypeId(type_id); get_address->SetMethod(GetGraph()->GetMethod()); - get_address->SetInput(0, save_state); + get_address->SetInput(0, inst->GetInput(2).GetInst()); + get_address->SetInput(1, save_state); inst->InsertBefore(get_address); auto load_object = GetGraph()->CreateInstLoadObject(DataType::ANY, pc); diff --git a/compiler/optimizer/optimizations/expand_intrinsics.h b/compiler/optimizer/optimizations/expand_intrinsics.h index 93ee637f7..4866eb5e5 100644 --- a/compiler/optimizer/optimizations/expand_intrinsics.h +++ b/compiler/optimizer/optimizations/expand_intrinsics.h @@ -75,7 +75,6 @@ private: void BuildGuard(Inst *inst, uintptr_t target); bool ExpandLdLexDyn(IntrinsicInst *intrinsic); bool ExpandLdLexVarDyn(IntrinsicInst *intrinsic); - bool ExpandLdlexenvDyn(IntrinsicInst *intrinsic); bool ExpandTryLdGlobalByName(IntrinsicInst *inst); template diff --git a/compiler/templates/ecmascript_inst_builder_gen.cpp.erb b/compiler/templates/ecmascript_inst_builder_gen.cpp.erb index 3cd5dcca3..698f2712f 100644 --- a/compiler/templates/ecmascript_inst_builder_gen.cpp.erb +++ b/compiler/templates/ecmascript_inst_builder_gen.cpp.erb @@ -109,7 +109,16 @@ void InstBuilder::BuildEcmaAsIntrinsics(const BytecodeInstruction* bc_inst) // N % num_vregs = params_arr.select{|b| b.reg?}.length % num_imms = params_arr.select{|b| b.imm?}.length % num_ids = params_arr.select{|b| b.id?}.length +% +% use_this_func = inst.properties.include? 'func' +% use_cp = inst.properties.include? 'cp' +% use_lex_env = inst.properties.include? 'lex_env' +% write_lex_env = inst.properties.include? 'write_lex_env' +% % num_inputs = acc_read ? num_vregs + 2 : num_vregs + 1 +% num_inputs += use_this_func ? 1 : 0 +% num_inputs += use_cp ? 1 : 0 +% num_inputs += use_lex_env ? 1 : 0 % use_ic = inst.properties.include? 'use_ic' % if range_should_exclude_last % num_inputs = num_inputs - 1 @@ -239,11 +248,38 @@ void InstBuilder::BuildEcmaAsIntrinsics(const BytecodeInstruction* bc_inst) // N inst->AppendInput(FindOrCreate32BitConstant(GetPc(bc_inst->GetAddress()))); inst->AddInputType(DataType::UINT16); } +% end +% if use_this_func + if (!GetGraph()->IsBytecodeOptimizer()) + { + inst->AppendInput(GetDefinition(vregs_and_args_count_ + 1 + THIS_FUNC_IDX)); + inst->AddInputType(DataType::ANY); + } +% end +% if use_cp + if (!GetGraph()->IsBytecodeOptimizer()) + { + inst->AppendInput(GetEnvDefinition(CONST_POOL_IDX)); + inst->AddInputType(DataType::ANY); + } +% end +% if use_lex_env + if (!GetGraph()->IsBytecodeOptimizer()) + { + inst->AppendInput(GetEnvDefinition(LEX_ENV_IDX)); + inst->AddInputType(DataType::ANY); + } % end if (inst->RequireState()) { inst->AppendInput(inst_save_state); inst->AddInputType(DataType::NO_TYPE); } +% if write_lex_env + if (!GetGraph()->IsBytecodeOptimizer()) + { + UpdateDefinitionLexEnv(inst); + } +% end AddInstruction(inst); % if acc_write UpdateDefinitionAcc(inst); @@ -311,6 +347,16 @@ void InstBuilder::BuildEcmaFromIrtoc([[maybe_unused]] const BytecodeInstruction* % if inst.properties.include?('use_ic') % inputs.push('GetGraph()->FindOrCreateConstant(GetPc(bc_inst->GetAddress()))') % end +% if inst.properties.include?('func') +% inputs.push('GetEnvDefinition(THIS_FUNC_IDX)') +% end +% if inst.properties.include?('cp') +% inputs.push('GetEnvDefinition(CONST_POOL_IDX)') +% end +% if inst.properties.include?('lex_env') +% inputs.push('GetEnvDefinition(LEX_ENV_IDX)') +% end + % builder = 'Build' + inst.opcode.split('_')[0..1].map do |_| _.capitalize end.join() [[maybe_unused]] auto inst = <%= builder %>(GetGraph(), this, ¤t_bb_, <%= inputs.empty? ? '' : inputs.join(', ') + ', ' %>GetPc(bc_inst->GetAddress()), visited_block_marker_); % if inst.acc.include?('out') diff --git a/ecmascript_plugin_options.yaml b/ecmascript_plugin_options.yaml index c11fc3339..104f39aef 100644 --- a/ecmascript_plugin_options.yaml +++ b/ecmascript_plugin_options.yaml @@ -46,6 +46,9 @@ func_resolve_numeric_type: panda::compiler::ecmascript::NumericDataTypeToAnyType func_resolve_string_type: panda::compiler::ecmascript::GetAnyStringType func_is_any_type_can_be_subtype_of: panda::compiler::ecmascript::IsAnyTypeCanBeSubtypeOf + func_load_constant_pool: panda::compiler::ecmascript::LoadConstantPoolGen + func_load_lexical_env: panda::compiler::ecmascript::LoadLexicalEnvGen + func_load_string_dyn: panda::compiler::ecmascript::LoadStringDynamicGen list_types: HOLE_TYPE: panda::compiler::DataType::Type::ANY NULL_TYPE: panda::compiler::DataType::Type::ANY diff --git a/ecmastdlib/ecmastdlib.pa b/ecmastdlib/ecmastdlib.pa index 8a73062ff..4b1fd16b4 100644 --- a/ecmastdlib/ecmastdlib.pa +++ b/ecmastdlib/ecmastdlib.pa @@ -22,7 +22,7 @@ .function any Ecmascript.Intrinsics.ldboolean(any a0) .function any Ecmascript.Intrinsics.ldnumber(any a0) .function any Ecmascript.Intrinsics.ldstring(any a0) -.function any Ecmascript.Intrinsics.ldbigint(u32 a0) +.function any Ecmascript.Intrinsics.ldbigint(u32 a0, any a1) .function any Ecmascript.Intrinsics.ldnull() .function any Ecmascript.Intrinsics.ldsymbol() .function any Ecmascript.Intrinsics.ldobject(any a0, any a1) @@ -41,9 +41,9 @@ .function any Ecmascript.Intrinsics.lesseqDyn(any a0, any a1) .function any Ecmascript.Intrinsics.greaterDyn(any a0, any a1) .function any Ecmascript.Intrinsics.greatereqDyn(any a0, any a1) -.function any Ecmascript.Intrinsics.ldObjByValue(any a0, any a1, u16 a2) +.function any Ecmascript.Intrinsics.ldObjByValue(any a0, any a1, u16 a2, any a3) .function any Ecmascript.Intrinsics.tryLdGlobalByValue(u16 a0, any a1) -.function any Ecmascript.Intrinsics.stObjByValue(any a0, any a1, any a2, u16 a3) +.function any Ecmascript.Intrinsics.stObjByValue(any a0, any a1, any a2, u16 a3, any a4) .function void Ecmascript.Intrinsics.tryStGlobalByValue(u16 a0, any a1, any a2) .function any Ecmascript.Intrinsics.shl2Dyn(any a0, any a1) .function any Ecmascript.Intrinsics.shr2Dyn(any a0, any a1) @@ -62,8 +62,8 @@ .function any Ecmascript.Intrinsics.defineglobalvar(any a0, any a1) .function any Ecmascript.Intrinsics.definelocalvar(any a0, any a1) .function any Ecmascript.Intrinsics.definefuncexpr(any a0, any a1) -.function any Ecmascript.Intrinsics.definefuncDyn(u32 a0, any a1) -.function any Ecmascript.Intrinsics.defineNCFuncDyn(u32 a0, any a1, any a2) +.function any Ecmascript.Intrinsics.definefuncDyn(u32 a0, any a1, any a2) +.function any Ecmascript.Intrinsics.defineNCFuncDyn(u32 a0, any a1, any a2, any a3) .function any Ecmascript.Intrinsics.refeqDyn(any a0, any a1) .function any Ecmascript.Intrinsics.expDyn(any a0, any a1) .function any Ecmascript.Intrinsics.typeofDyn(any a0) @@ -76,14 +76,14 @@ .function any Ecmascript.Intrinsics.callspreadDyn(any a0, any a1, any a2) .function void Ecmascript.Intrinsics.jtrueDyn(u16 a0, any a1) .function void Ecmascript.Intrinsics.jfalseDyn(u16 a0, any a1) -.function any Ecmascript.Intrinsics.newlexenvDyn(u16 a0) -.function any Ecmascript.Intrinsics.copylexenvDyn() -.function void Ecmascript.Intrinsics.StLexVarDyn(u16 a0, u16 a1, any a2) -.function any Ecmascript.Intrinsics.StLexDyn(u32 a0, u16 a1, u16 a2, any a3) -.function any Ecmascript.Intrinsics.LdLexVarDyn(u16 a0, u16 a1) -.function any Ecmascript.Intrinsics.LdLexDyn(u32 a0, u16 a1, u16 a2) +.function any Ecmascript.Intrinsics.newlexenvDyn(u16 a0, any a1) +.function any Ecmascript.Intrinsics.copylexenvDyn(any a0) +.function void Ecmascript.Intrinsics.StLexVarDyn(u16 a0, u16 a1, any a2, any a3) +.function any Ecmascript.Intrinsics.StLexDyn(u32 a0, u16 a1, u16 a2, any a3, any a4, any a5) +.function any Ecmascript.Intrinsics.LdLexVarDyn(u16 a0, u16 a1, any a2) +.function any Ecmascript.Intrinsics.LdLexDyn(u32 a0, u16 a1, u16 a2, any a3, any a4) .function any Ecmascript.Intrinsics.ldlexenvDyn() -.function void Ecmascript.Intrinsics.popLexenvDyn() +.function any Ecmascript.Intrinsics.popLexenvDyn(any a0) .function any Ecmascript.Intrinsics.getUnmappedArgs() .function any Ecmascript.Intrinsics.getUnmappedArgsInterp() .function any Ecmascript.Intrinsics.toboolean(any a0) @@ -93,7 +93,7 @@ .function any Ecmascript.Intrinsics.isFalse(any a0) .function any Ecmascript.Intrinsics.isCoercible(any a0) .function any Ecmascript.Intrinsics.getPropIterator(any a0) -.function any Ecmascript.Intrinsics.defineGeneratorFunc(u32 a0, any a1) +.function any Ecmascript.Intrinsics.defineGeneratorFunc(u32 a0, any a1, any a2) .function any Ecmascript.Intrinsics.createIterResultObj(any a0, u8 a1) .function any Ecmascript.Intrinsics.setGeneratorState(any a0, u8 a1) .function any Ecmascript.Intrinsics.suspendGenerator(any a0, any a1) @@ -104,8 +104,8 @@ .function any Ecmascript.Intrinsics.getResumeMode(any a0) .function any Ecmascript.Intrinsics.createGeneratorObj(any a0) .function any Ecmascript.Intrinsics.createAsyncGeneratorObj(any a0) -.function any Ecmascript.Intrinsics.defineAsyncFunc(u32 a0, any a1) -.function any Ecmascript.Intrinsics.defineAsyncGeneratorFunc(u32 a0, any a1) +.function any Ecmascript.Intrinsics.defineAsyncFunc(u32 a0, any a1, any a2) +.function any Ecmascript.Intrinsics.defineAsyncGeneratorFunc(u32 a0, any a1, any a2) .function any Ecmascript.Intrinsics.asyncFunctionEnter() .function any Ecmascript.Intrinsics.asyncFunctionAwait(any a0, any a1) .function any Ecmascript.Intrinsics.asyncFunctionResolve(any a0, any a1) @@ -113,19 +113,19 @@ .function any Ecmascript.Intrinsics.asyncGeneratorResolve(any a0, any a1) .function any Ecmascript.Intrinsics.asyncGeneratorReject(any a0, any a1) .function void Ecmascript.Intrinsics.throwUndefined(any a0) -.function void Ecmascript.Intrinsics.throwConstAssignment(u32 a0) -.function void Ecmascript.Intrinsics.throwTdz(u32 a0) +.function void Ecmascript.Intrinsics.throwConstAssignment(u32 a0, any a1) +.function void Ecmascript.Intrinsics.throwTdz(u32 a0, any a1) .function any Ecmascript.Intrinsics.copyrestargs(u16 a0) .function any Ecmascript.Intrinsics.copyrestargsInterp(u16 a0) .function any Ecmascript.Intrinsics.ldHole() -.function any Ecmascript.Intrinsics.getMethod(u32 a0, any a1) +.function any Ecmascript.Intrinsics.getMethod(u32 a0, any a1, any a2) .function any Ecmascript.Intrinsics.getTemplateObject(any a0) -.function any Ecmascript.Intrinsics.TryLdGlobalByName(u32 a0, u16 a1) -.function any Ecmascript.Intrinsics.TryStGlobalByName(u32 a0, any a1, u16 a2) -.function any Ecmascript.Intrinsics.LdGlobalVar(u32 a0, u16 a1) -.function any Ecmascript.Intrinsics.StGlobalVar(u32 a0, any a1, u16 a2) -.function any Ecmascript.Intrinsics.LdObjByName(u32 a0, any a1, u16 a2) -.function any Ecmascript.Intrinsics.StObjByName(u32 a0, any a1, any a2, u16 a3) +.function any Ecmascript.Intrinsics.TryLdGlobalByName(u32 a0, u16 a1, any a2, any a3) +.function any Ecmascript.Intrinsics.TryStGlobalByName(u32 a0, any a1, u16 a2, any a3, any a4) +.function any Ecmascript.Intrinsics.LdGlobalVar(u32 a0, u16 a1, any a2, any a3) +.function any Ecmascript.Intrinsics.StGlobalVar(u32 a0, any a1, u16 a2, any a3, any a4) +.function any Ecmascript.Intrinsics.LdObjByName(u32 a0, any a1, u16 a2, any a3, any a4) +.function any Ecmascript.Intrinsics.StObjByName(u32 a0, any a1, any a2, u16 a3, any a4, any a5) .function any Ecmascript.Intrinsics.LdObjByIndex(u32 a0, any a1) .function any Ecmascript.Intrinsics.StObjByIndex(u32 a0, any a1, any a2) .function any Ecmascript.Intrinsics.getnextpropname(any a0) @@ -143,14 +143,14 @@ .function any Ecmascript.Intrinsics.Call3ThisDyn(any a0, any a1, any a2, any a3, any a4) .function any Ecmascript.Intrinsics.CalliThisRangeDyn(u16 a0, any a1) .function any Ecmascript.Intrinsics.createemptyobject() -.function any Ecmascript.Intrinsics.createobjectwithbuffer(u16 a0) +.function any Ecmascript.Intrinsics.createobjectwithbuffer(u16 a0, any a1) .function any Ecmascript.Intrinsics.setobjectwithproto(any a0, any a1) .function any Ecmascript.Intrinsics.copydataproperties(any a0, any a1) .function any Ecmascript.Intrinsics.definegettersetterbyvalue(any a0, any a1, any a2, any a3, any a4) .function any Ecmascript.Intrinsics.createemptyarray() -.function any Ecmascript.Intrinsics.createarraywithbuffer(u16 a0) -.function any Ecmascript.Intrinsics.createregexpwithliteral(u32 a0, u8 a1) -.function any Ecmascript.Intrinsics.StOwnByName(u32 a0, any a1, any a2) +.function any Ecmascript.Intrinsics.createarraywithbuffer(u16 a0, any a1) +.function any Ecmascript.Intrinsics.createregexpwithliteral(u32 a0, u8 a1, any a2) +.function any Ecmascript.Intrinsics.StOwnByName(u32 a0, any a1, any a2, any a3) .function any Ecmascript.Intrinsics.StOwnByIndex(u32 a0, any a1, any a2) .function any Ecmascript.Intrinsics.StOwnByValue(any a0, any a1, any a2) .function any Ecmascript.Intrinsics.starrayspread(any a0, any a1, any a2) @@ -161,42 +161,40 @@ .function any Ecmascript.Intrinsics.CreateObjectWithExcludedKeys(u16 a0, any a1, any a2) .function void Ecmascript.Intrinsics.ThrowPatternNonCoercible() .function any Ecmascript.Intrinsics.CloseIterator(any a0, any a1) -.function any Ecmascript.Intrinsics.ImportModule(u32 a0) -.function void Ecmascript.Intrinsics.StModuleVar(u32 a0, any a1) +.function any Ecmascript.Intrinsics.ImportModule(u32 a0, any a1) +.function void Ecmascript.Intrinsics.StModuleVar(u32 a0, any a1, any a2) .function void Ecmascript.Intrinsics.CopyModule(any a0) -.function any Ecmascript.Intrinsics.LdModvarByName(u32 a0, any a1) +.function any Ecmascript.Intrinsics.LdModvarByName(u32 a0, any a1, any a2) .function any Ecmascript.Intrinsics.LoadClassComputedInstanceFields(any a0) .function void Ecmascript.Intrinsics.SetClassComputedFields(any a0, any a1) -.function any Ecmascript.Intrinsics.DefineClassWithBuffer(u32 a0, u16 a1, any a2, any a3) +.function any Ecmascript.Intrinsics.DefineClassWithBuffer(u32 a0, u16 a1, any a2, any a3, any a4) .function any Ecmascript.Intrinsics.ClassFieldAdd(any a0, any a1, any a2) -.function void Ecmascript.Intrinsics.DefineClassPrivateFields(u16 a0, any a1, any a2) +.function void Ecmascript.Intrinsics.DefineClassPrivateFields(u16 a0, any a1, any a2, any a3) .function any Ecmascript.Intrinsics.ClassPrivateMethodOrAccessorAdd(any a0, any a1) -.function any Ecmascript.Intrinsics.ClassPrivateFieldAdd(u32 a0, any a1, any a2, any a3) -.function any Ecmascript.Intrinsics.ClassPrivateFieldGet(u32 a0, any a1, any a2) -.function any Ecmascript.Intrinsics.ClassPrivateFieldSet(u32 a0, any a1, any a2, any a3) -.function any Ecmascript.Intrinsics.ClassPrivateFieldIn(u32 a0, any a1, any a2) +.function any Ecmascript.Intrinsics.ClassPrivateFieldAdd(u32 a0, any a1, any a2, any a3, any a4) +.function any Ecmascript.Intrinsics.ClassPrivateFieldGet(u32 a0, any a1, any a2, any a3) +.function any Ecmascript.Intrinsics.ClassPrivateFieldSet(u32 a0, any a1, any a2, any a3, any a4) +.function any Ecmascript.Intrinsics.ClassPrivateFieldIn(u32 a0, any a1, any a2, any a3) .function any Ecmascript.Intrinsics.SuperCall(u16 a0, any a1, any a2, any a3) .function any Ecmascript.Intrinsics.SuperCallSpread(any a0, any a1, any a2) -.function any Ecmascript.Intrinsics.defineMethod(u32 a0, any a1, any a2) -.function any Ecmascript.Intrinsics.LdSuperByName(u32 a0, any a1) -.function any Ecmascript.Intrinsics.StSuperByName(u32 a0, any a1, any a2) -.function any Ecmascript.Intrinsics.StSuperByValue(any a0, any a1, any a2) -.function any Ecmascript.Intrinsics.LdSuperByValue(any a0, any a1) -.function any Ecmascript.Intrinsics.createobjecthavingmethod(u16 a0, any a1) +.function any Ecmascript.Intrinsics.defineMethod(u32 a0, any a1, any a2, any a3) +.function any Ecmascript.Intrinsics.LdSuperByName(u32 a0, any a1, any a2, any a3) +.function any Ecmascript.Intrinsics.StSuperByName(u32 a0, any a1, any a2, any a3, any a4) +.function any Ecmascript.Intrinsics.StSuperByValue(any a0, any a1, any a2, any a3) +.function any Ecmascript.Intrinsics.LdSuperByValue(any a0, any a1, any a2) +.function any Ecmascript.Intrinsics.createobjecthavingmethod(u16 a0, any a1, any a2) .function any Ecmascript.Intrinsics.ThrowIfSuperNotCorrectCall(u16 a0, any a1) -.function any Ecmascript.Intrinsics.LdHomeObject() +.function any Ecmascript.Intrinsics.LdHomeObject(any a0) .function void Ecmascript.Intrinsics.ThrowDeleteSuperProperty() -.function any Ecmascript.Intrinsics.LdEvalBindings(u16 a0) +.function any Ecmascript.Intrinsics.LdEvalBindings(u16 a0, any a1) .function any Ecmascript.Intrinsics.DirectEval(u32 a0, any a1, any a2) -.function any Ecmascript.Intrinsics.LdEvalVar(u32 a0, any a1) -.function any Ecmascript.Intrinsics.StEvalVar(u32 a0, any a1, any a2) +.function any Ecmascript.Intrinsics.LdEvalVar(u32 a0, any a1, any a2) +.function any Ecmascript.Intrinsics.StEvalVar(u32 a0, any a1, any a2, any a3) .function void Ecmascript.Intrinsics.debugger() .function void Ecmascript.Intrinsics.NativeMethodWrapper(any a0) .function u8 Ecmascript.Intrinsics.GetObjectClassType(any a0) .function any Ecmascript.Intrinsics.IsNan(f64 a0) -.function any Ecmascript.Intrinsics.GetEcmaConstantPool() -.function any Ecmascript.Intrinsics.GetEcmaThisFunc() .function any Ecmascript.Intrinsics.GetWeakReferent(any a0) .function u1 Ecmascript.Intrinsics.DynClassIsDictionaryElement(any a0) diff --git a/irtoc_scripts/common.irt b/irtoc_scripts/common.irt index 3c19ce0fa..9c02ac2ea 100644 --- a/irtoc_scripts/common.irt +++ b/irtoc_scripts/common.irt @@ -14,8 +14,14 @@ module Constants verbose, $VERBOSE = $VERBOSE, nil + EXTFRAME_EXT_DATA_OFFSET = "EXTFRAME_EXT_DATA_OFFSET" + EXTFRAME_FRAME_OFFSET = "EXTFRAME_FRAME_OFFSET" + + ECMASCRIPT_THIS_FUNC_OFFSET = "ECMASCRIPT_ENVIRONMENT_THIS_FUNC_OFFSET" + ECMASCRIPT_CONSTANT_POOL_OFFSET = "ECMASCRIPT_ENVIRONMENT_CONSTANT_POOL_OFFSET" ECMASCRIPT_LEXICAL_ENV_OFFSET = "ECMASCRIPT_ENVIRONMENT_LEXICAL_ENV_OFFSET" LANGUAGE_EXTENSION_DATA_OFFSET = "MANAGED_THREAD_LANGUAGE_EXTENSION_DATA_OFFSET" + VALUE_TRUE = "coretypes::TaggedValue::VALUE_TRUE" VALUE_FALSE = "coretypes::TaggedValue::VALUE_FALSE" VALUE_HOLE = "coretypes::TaggedValue::VALUE_HOLE" @@ -179,16 +185,33 @@ macro(:f64toany) do |arg| CastValueToAnyType(arg).AnyType("AnyBaseType::ECMASCRIPT_DOUBLE_TYPE").any end +macro(:get_current_env) do || + ext_frame := Sub(%frame, Constants::EXTFRAME_FRAME_OFFSET).ptr + Add(ext_frame, Constants::EXTFRAME_EXT_DATA_OFFSET).ptr +end + macro(:get_this_func) do || - Intrinsic(:GET_ECMA_THIS_FUNC).ref + LoadI(get_current_env).Imm(Constants::ECMASCRIPT_THIS_FUNC_OFFSET).any +end + +macro(:get_cp) do || + LoadI(get_current_env).Imm(Constants::ECMASCRIPT_CONSTANT_POOL_OFFSET).any +end + +macro(:get_lex_env) do || + LoadI(get_current_env).Imm(Constants::ECMASCRIPT_LEXICAL_ENV_OFFSET).any +end + +macro(:set_lex_env) do |lex_env| + StoreI(get_current_env, lex_env).Imm(Constants::ECMASCRIPT_LEXICAL_ENV_OFFSET).any end -macro(:get_ic) do || - LoadObject(get_this_func()).ObjField(Constants::JS_FUNCTION_PROFILE_TYPE_INFO_FIELD).any +macro(:get_ic) do |this_func| + LoadObject(this_func).ObjField(Constants::JS_FUNCTION_PROFILE_TYPE_INFO_FIELD).any end -scoped_macro(:map_ic_slot) do |ic_slot| - method_ptr := LoadObject(get_this_func()).ObjField(Constants::JS_FUNCTION_METHOD_FIELD).ptr +scoped_macro(:map_ic_slot) do |this_func, ic_slot| + method_ptr := LoadObject(this_func).ObjField(Constants::JS_FUNCTION_METHOD_FIELD).ptr mapping := Load(method_ptr, "JSMETHOD_IC_MAPPING_OFFSET").ptr Load(mapping, ic_slot).u8 end diff --git a/irtoc_scripts/interpreter_handlers.irt b/irtoc_scripts/interpreter_handlers.irt index 02ed39d21..7653d023b 100644 --- a/irtoc_scripts/interpreter_handlers.irt +++ b/irtoc_scripts/interpreter_handlers.irt @@ -109,6 +109,10 @@ macro(:cmpanyhole) do |arg| CompareAnyType(arg).AnyType("AnyBaseType::ECMASCRIPT_HOLE_TYPE").b end +macro(:cmpanyhole) do |arg| + CompareAnyType(arg).AnyType("AnyBaseType::ECMASCRIPT_HOLE_TYPE").b +end + macro(:cmpanyobj) do |arg| CompareAnyType(arg).AnyType("AnyBaseType::ECMASCRIPT_OBJECT_TYPE").b end @@ -1025,9 +1029,7 @@ function(:EcmaNoteqdyn, params: {'a'=>'any', 'b'=>'any'}, mode: [:Interpreter, : end macro(:handle_ecma_ldlexenvdyn) do || - ecmascript_env_ptr := LoadI(%tr).Imm(Constants::LANGUAGE_EXTENSION_DATA_OFFSET).ptr - lexical_env := LoadI(ecmascript_env_ptr).Imm(Constants::ECMASCRIPT_LEXICAL_ENV_OFFSET) - lexical_env.any + get_lex_env end #function(:EcmaLdlexenvdyn, params: {}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do @@ -1177,10 +1179,10 @@ macro(:set_class) do |obj, cls| Intrinsic(:DYN_OBJECT_SET_CLASS, obj, cls).void end -macro(:access_global_var_ic) do |key, value, ic_slot, access| - ic := get_ic() +macro(:access_global_var_ic) do |this_func, key, value, ic_slot, access| + ic := get_ic(this_func) IfImm(cmpanyundefined(ic)).Imm(0).CC(:CC_EQ).b { - ic_idx := map_ic_slot(ic_slot) + ic_idx := map_ic_slot(this_func, ic_slot) handler := LoadArray(anytoheapobj(ic), ic_idx).any IfImm(cmpanyheapobj(handler)).Imm(0).CC(:CC_NE).b { r = access.call(anytoheapobj(handler), value) @@ -1195,14 +1197,14 @@ macro(:access_global_var_ic) do |key, value, ic_slot, access| Phi(r0, r1).any end -macro(:load_global_var_ic) do |key, ic_slot| - access_global_var_ic(key, nil, ic_slot, lambda do |box, _| +macro(:load_global_var_ic) do |this_func, key, ic_slot| + access_global_var_ic(this_func, key, nil, ic_slot, lambda do |box, _| LoadObject(box).ObjField(Constants::JS_PROPERTY_BOX_VALUE_FIELD).any end) end -macro(:store_global_var_ic) do |key, value, ic_slot| - access_global_var_ic(key, value, ic_slot, lambda do |box, value| +macro(:store_global_var_ic) do |this_func, key, value, ic_slot| + access_global_var_ic(this_func, key, value, ic_slot, lambda do |box, value| StoreObject(box, value).ObjField(Constants::JS_PROPERTY_BOX_VALUE_FIELD).SetNeedBarrier(true).any NOP() Constants::TAGGED_UNDEFINED @@ -1342,17 +1344,17 @@ Label(:ExitStore) Phi(res0, res1, res2).any end -macro(:access_obj_ic) do |obj, value, ic_slot, access| +macro(:access_obj_ic) do |this_func, obj, value, ic_slot, access| IfImm(cmpanyheapobj(obj)).Imm(0).CC(:CC_EQ).b { Goto(:Miss) } - ic := get_ic() + ic := get_ic(this_func) IfImm(cmpanyundefined(ic)).Imm(0).CC(:CC_NE).b { Goto(:Miss) } - ic_slot_mapped := map_ic_slot(ic_slot) + ic_slot_mapped := map_ic_slot(this_func, ic_slot) ic_cls := LoadArray(anytoheapobj(ic), ic_slot_mapped).any IfImm(cmpanyheapobj(ic_cls)).Imm(0).CC(:CC_EQ).b { Goto(:Miss) @@ -1375,14 +1377,14 @@ Label(:Exit) Phi(res, miss_res).any end -scoped_macro(:try_load_obj_ic) do |obj, ic_slot| - access_obj_ic(obj, nil, ic_slot, lambda do |obj, handler, _| +scoped_macro(:try_load_obj_ic) do |this_func, obj, ic_slot| + access_obj_ic(this_func, obj, nil, ic_slot, lambda do |obj, handler, _| load_obj_ic_with_handler(obj, handler) end) end -scoped_macro(:try_store_obj_ic) do |obj, value, ic_slot| - access_obj_ic(obj, value, ic_slot, lambda do |obj, handler, value| +scoped_macro(:try_store_obj_ic) do |this_func, obj, value, ic_slot| + access_obj_ic(this_func, obj, value, ic_slot, lambda do |obj, handler, value| store_obj_ic_with_handler(obj, handler, value) end) end @@ -1404,42 +1406,61 @@ macro(:ic_handler_get_offset) do |handler| get_bits(handler, Constants::IC_HANDLER_OFFSET_BIT, Constants::IC_HANDLER_OFFSET_MASK) end -macro(:load_object_dynamic) do |obj, key, ic_slot, props| - if props.type == :by_name && (!ic_slot.is_a? Integer) - Intrinsic(:LD_OBJ_DYN_BY_NAME, obj, key, ic_slot).any - else - LoadObjectDynamic(obj, key) - .set_access_type(props.type) - .set_access_mode(props.mode) - .any - end +macro(:load_object_dynamic_by_name) do |obj, key, ic_slot, props, this_func, cp| + Intrinsic(:LD_OBJ_DYN_BY_NAME, obj, key, ic_slot, this_func, cp).any end -macro(:store_object_dynamic) do |obj, key, value, ic_slot, props| - if props.type == :by_name && (!ic_slot.is_a? Integer) - Intrinsic(:ST_OBJ_DYN_BY_NAME, obj, key, value, ic_slot).any - else - StoreObjectDynamic(obj, key, value) - .set_access_type(props.type) - .set_access_mode(props.mode) - .any - end +macro(:load_object_dynamic_by_value) do |obj, key, ic_slot, props, this_func| + LoadObjectDynamic(obj, key, this_func) + .set_access_type(props.type) + .set_access_mode(props.mode) + .any +end + +macro(:store_object_dynamic_by_name) do |obj, key, value, ic_slot, props, this_func, cp| + Intrinsic(:ST_OBJ_DYN_BY_NAME, obj, key, value, ic_slot, this_func, cp).any +end + +macro(:store_object_dynamic_by_value) do |obj, key, value, ic_slot, props, this_func| + StoreObjectDynamic(obj, key, value, this_func) + .set_access_type(props.type) + .set_access_mode(props.mode) + .any end -macro(:handle_load_object_dynamic) do |obj, key, ic_slot, props| +macro(:handle_load_object_dynamic_by_name) do |obj, key, ic_slot, props, this_func, cp| handle_access_object_dynamic(obj, key, nil, lambda do |obj, index, _| handle_load_object_dynamic_by_index(obj, index, props) end, lambda do |obj, key, _| unless ic_slot.nil? - r0 := try_load_obj_ic(obj, ic_slot) + r0 := try_load_obj_ic(this_func, obj, ic_slot) IfImm(cmpanyhole(r0)).Imm(0).CC(:CC_NE).b { - r1 := load_object_dynamic(obj, key, ic_slot, props) + r1 := load_object_dynamic_by_name(obj, key, ic_slot, props, this_func, cp) } Phi(r0, r1).any else - load_object_dynamic(obj, key, ic_slot, props) + load_object_dynamic_by_name(obj, key, ic_slot, props, this_func, cp) + end + end, + props) +end + +macro(:handle_load_object_dynamic_by_value) do |obj, key, ic_slot, props, this_func| + handle_access_object_dynamic(obj, key, nil, + lambda do |obj, index, _| + handle_load_object_dynamic_by_index(obj, index, props) + end, + lambda do |obj, key, _| + unless ic_slot.nil? + r0 := try_load_obj_ic(this_func, obj, ic_slot) + IfImm(cmpanyhole(r0)).Imm(0).CC(:CC_NE).b { + r1 := load_object_dynamic_by_value(obj, key, ic_slot, props, this_func) + } + Phi(r0, r1).any + else + load_object_dynamic_by_value(obj, key, ic_slot, props, this_func) end end, props) @@ -1451,7 +1472,8 @@ macro(:handle_load_object_dynamic_by_index) do |obj, key, props| LoadArray(elements, index).any end, lambda do |obj, index, _| - LoadObjectDynamic(obj, i32toanychecked(u32toi32(key))) + undefined := Constants::TAGGED_UNDEFINED + LoadObjectDynamic(obj, i32toanychecked(u32toi32(key)), undefined.any) .set_access_type(:by_index) .set_access_mode(:dictionary) .any @@ -1459,20 +1481,40 @@ macro(:handle_load_object_dynamic_by_index) do |obj, key, props| props) end -macro(:handle_store_object_dynamic) do |obj, key, value, ic_slot, props| +macro(:handle_store_object_dynamic_by_name) do |obj, key, value, ic_slot, props, this_func, cp| + handle_access_object_dynamic(obj, key, value, + lambda do |obj, index, value| + handle_store_object_dynamic_by_index(obj, index, value, props) + end, + lambda do |obj, _, value| + unless ic_slot.nil? + r0 := try_store_obj_ic(this_func, obj, value, ic_slot) + IfImm(cmpanyhole(r0)).Imm(0).CC(:CC_NE).b { + r1 := store_object_dynamic_by_name(obj, key, value, ic_slot, props, this_func, cp) + } + Phi(r0, r1).any + else + store_object_dynamic_by_name(obj, key, value, ic_slot, props, this_func, cp) + end + end, + props) +end + + +macro(:handle_store_object_dynamic_by_value) do |obj, key, value, ic_slot, props, this_func| handle_access_object_dynamic(obj, key, value, lambda do |obj, index, value| handle_store_object_dynamic_by_index(obj, index, value, props) end, lambda do |obj, _, value| unless ic_slot.nil? - r0 := try_store_obj_ic(obj, value, ic_slot) + r0 := try_store_obj_ic(this_func, obj, value, ic_slot) IfImm(cmpanyhole(r0)).Imm(0).CC(:CC_NE).b { - r1 := store_object_dynamic(obj, key, value, ic_slot, props) + r1 := store_object_dynamic_by_value(obj, key, value, ic_slot, props, this_func) } Phi(r0, r1).any else - store_object_dynamic(obj, key, value, ic_slot, props) + store_object_dynamic_by_value(obj, key, value, ic_slot, props, this_func) end end, props) @@ -1484,8 +1526,8 @@ macro(:handle_store_object_dynamic_by_index) do |obj, key, value, props| store_value_to_elements(obj, elements, index, value) end, lambda do |obj, index, value| - Constants::TAGGED_HOLE - StoreObjectDynamic(obj, i32toanychecked(u32toi32(key)), value) + undefined := Constants::TAGGED_UNDEFINED + StoreObjectDynamic(obj, i32toanychecked(u32toi32(key)), value, undefined.any) .set_access_type(:by_index) .set_access_mode(:dictionary) .any @@ -1548,26 +1590,28 @@ end #################################################################################### # LD_OBJECT_BY_VALUE # -macro(:handle_ecma_ldobjbyvalue) do |obj, key, ic_slot| +macro(:handle_ecma_ldobjbyvalue) do |obj, key, ic_slot, this_func| props = ObjectAccessProperties.new(:unknown, :unknown, false) IfImm(cmpanyheapobj(obj)).Imm(0).CC(:CC_NE).b { - load_res := handle_load_object_dynamic(obj, key, ic_slot, props) + load_res := handle_load_object_dynamic_by_value(obj, key, ic_slot, props, this_func) IfImm(cmpanyhole(load_res)).Imm(0).CC(:CC_NE) { - slow_res := ecma_intrinsic_invoke("LdObjByValueSlow", obj, key, ic_slot).any + slow_res := ecma_intrinsic_invoke("LdObjByValueSlow", obj, key, ic_slot, this_func).any } res := Phi(load_res, slow_res).any } Else { - slow_res_exception := ecma_intrinsic_invoke("LdObjByValueSlow", obj, key, ic_slot).any + slow_res_exception := ecma_intrinsic_invoke("LdObjByValueSlow", obj, key, ic_slot, this_func).any } Phi(res, slow_res_exception).any end -function(:EcmaLdobjbyvalue, params: {'obj'=>'any', 'key'=>'any', 'ic_slot'=>'i32'}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do - Return(handle_ecma_ldobjbyvalue(obj, key, ic_slot)) +function(:EcmaLdobjbyvalue, + params: {'obj'=>'any', 'key'=>'any', 'ic_slot'=>'i32', 'this_func'=>'any'}, + mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do + Return(handle_ecma_ldobjbyvalue(obj, key, ic_slot, this_func)) end function(:FastPathLdObjByValue, - params: {obj: 'any', key: 'any', ic_slot: 'i32'}, + params: {obj: 'any', key: 'any', ic_slot: 'i32', this_func: 'any'}, mode: [:FastPath, :DynamicMethod, :DynamicStub], regmap: $full_regmap, regalloc_set: RegMask.new($full_regmap, :arg0, :arg1) + $panda_callees_mask - $panda_regmap) do @@ -1579,38 +1623,38 @@ function(:FastPathLdObjByValue, props = ObjectAccessProperties.new(:unknown, :unknown, false) IfImm(cmpanyheapobj(obj)).Imm(0).NE.b { - load_res := handle_load_object_dynamic(obj, key, ic_slot, props).any + load_res := handle_load_object_dynamic_by_value(obj, key, ic_slot, props, this_func).any IfImm(cmpanyhole(load_res)).Imm(0).NE { - Intrinsic(:SLOW_PATH_ENTRY, obj, key, ic_slot).Method("LdObjByValueBridge", :AddImm).Relocate.Terminator.any + Intrinsic(:SLOW_PATH_ENTRY, obj, key, ic_slot, this_func).Method("LdObjByValueBridge", :AddImm).Relocate.Terminator.any } Return(load_res).any } Else { - Intrinsic(:SLOW_PATH_ENTRY, obj, key, ic_slot).Method("LdObjByValueBridge", :AddImm).Relocate.Terminator.any + Intrinsic(:SLOW_PATH_ENTRY, obj, key, ic_slot, this_func).Method("LdObjByValueBridge", :AddImm).Relocate.Terminator.any } end #################################################################################### # ST_OBJECT_BY_VALUE # -macro(:handle_ecma_stobjbyvalue) do |obj, key, value, ic_slot| +macro(:handle_ecma_stobjbyvalue) do |obj, key, value, ic_slot, this_func| props = ObjectAccessProperties.new(:unknown, :unknown, false) IfImm(cmpanyheapobj(obj)).Imm(0).CC(:CC_NE).b { - store_res := handle_store_object_dynamic(obj, key, value, ic_slot, props) + store_res := handle_store_object_dynamic_by_value(obj, key, value, ic_slot, props, this_func) IfImm(cmpanyhole(store_res)).Imm(0).CC(:CC_NE) { - ecma_intrinsic_invoke("StObjByValueSlow", obj, key, value, ic_slot).any + ecma_intrinsic_invoke("StObjByValueSlow", obj, key, value, ic_slot, this_func).any } } Else { - ecma_intrinsic_invoke("StObjByValueSlow", obj, key, value, ic_slot).any + ecma_intrinsic_invoke("StObjByValueSlow", obj, key, value, ic_slot, this_func).any } end -function(:EcmaStobjbyvalue, params: {'obj'=>'any', 'key'=>'any', 'value'=>'any', 'ic_slot'=>'i32'}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do - handle_ecma_stobjbyvalue(obj, key, value, ic_slot) +function(:EcmaStobjbyvalue, params: {'obj'=>'any', 'key'=>'any', 'value'=>'any', 'ic_slot'=>'i32', 'this_func'=>'any'}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do + handle_ecma_stobjbyvalue(obj, key, value, ic_slot, this_func) ReturnVoid() end function(:FastPathStObjByValue, - params: {obj: 'any', key: 'any', value: 'any', ic_slot: 'i32'}, + params: {obj: 'any', key: 'any', value: 'any', ic_slot: 'i32', this_func: 'any'}, mode: [:FastPath, :DynamicMethod, :DynamicStub], regmap: $full_regmap, regalloc_set: RegMask.new($full_regmap, :arg0, :arg1) + $panda_callees_mask - $panda_regmap, @@ -1623,12 +1667,12 @@ function(:FastPathStObjByValue, props = ObjectAccessProperties.new(:unknown, :unknown, false) IfImm(cmpanyheapobj(obj)).Imm(0).CC(:CC_NE).b { - store_res := handle_store_object_dynamic(obj, key, value, ic_slot, props) + store_res := handle_store_object_dynamic_by_value(obj, key, value, ic_slot, props, this_func) IfImm(cmpanyhole(store_res)).Imm(0).CC(:CC_NE) { - Intrinsic(:SLOW_PATH_ENTRY, obj, key, value, ic_slot).Method("StObjByValueBridge", :AddImm).Relocate.Terminator.void + Intrinsic(:SLOW_PATH_ENTRY, obj, key, value, ic_slot, this_func).Method("StObjByValueBridge", :AddImm).Relocate.Terminator.void } } Else { - Intrinsic(:SLOW_PATH_ENTRY, obj, key, value, ic_slot).Method("StObjByValueBridge", :AddImm).Relocate.Terminator.void + Intrinsic(:SLOW_PATH_ENTRY, obj, key, value, ic_slot, this_func).Method("StObjByValueBridge", :AddImm).Relocate.Terminator.void } ReturnVoid() end @@ -1637,32 +1681,33 @@ end # LD_OBJECT_BY_NAME # -macro(:resolve_id) do |id| - cp := Intrinsic(:GET_ECMA_CONSTANT_POOL).ref +macro(:resolve_id) do |cp, id| LoadArray(cp, id).any end -macro(:handle_ecma_ldobjbyname) do |obj, id, ic_slot| +macro(:handle_ecma_ldobjbyname) do |obj, id, ic_slot, this_func, cp| props = ObjectAccessProperties.new(:by_name, :unknown, false) - key := resolve_id(id) + key := resolve_id(cp, id) IfImm(cmpanyheapobj(obj)).Imm(0).CC(:CC_NE).b { - load_res := handle_load_object_dynamic(obj, key, ic_slot, props) + load_res := handle_load_object_dynamic_by_name(obj, key, ic_slot, props, this_func, cp) IfImm(cmpanyhole(load_res)).Imm(0).CC(:CC_NE).b { - slow_res := ecma_intrinsic_invoke("LdObjByNameSlow", id, obj, ic_slot).any + slow_res := ecma_intrinsic_invoke("LdObjByNameSlow", id, obj, ic_slot, this_func, cp).any } res := Phi(load_res, slow_res).any } Else { - slow_res_exception := ecma_intrinsic_invoke("LdObjByNameSlow", id, obj, ic_slot).any + slow_res_exception := ecma_intrinsic_invoke("LdObjByNameSlow", id, obj, ic_slot, this_func, cp).any } Phi(res, slow_res_exception).any end -function(:EcmaLdobjbyname, params: {'id'=>'i32', 'obj'=>'any','ic_slot'=>'i32'}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do - Return(handle_ecma_ldobjbyname(obj, id, ic_slot)) +function(:EcmaLdobjbyname, + params: {'id'=>'i32', 'obj'=>'any','ic_slot'=>'i32', 'this_func'=>'any', 'cp'=>'any'}, + mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do + Return(handle_ecma_ldobjbyname(obj, id, ic_slot, this_func, cp)) end function(:FastPathLdObjByName, - params: {id: 'i32', obj: 'any', ic_slot: 'i32'}, + params: {id: 'i32', obj: 'any', ic_slot: 'i32', this_func: 'any', cp: 'any'}, mode: [:FastPath, :DynamicMethod, :DynamicStub], regmap: $full_regmap, regalloc_set: RegMask.new($full_regmap, :arg0, :arg1) + $panda_callees_mask - $panda_regmap) do @@ -1673,41 +1718,43 @@ function(:FastPathLdObjByName, end props = ObjectAccessProperties.new(:by_name, :unknown, false) - key := resolve_id(id) + key := resolve_id(cp, id) IfImm(cmpanyheapobj(obj)).Imm(0).CC(:CC_NE).b { - load_res := handle_load_object_dynamic(obj, key, ic_slot, props) + load_res := handle_load_object_dynamic_by_name(obj, key, ic_slot, props, this_func, cp) IfImm(cmpanyhole(load_res)).Imm(0).CC(:CC_NE).b { - Intrinsic(:SLOW_PATH_ENTRY, id, obj, ic_slot).Method("LdObjByNameBridge", :AddImm).Relocate.Terminator.ptr + Intrinsic(:SLOW_PATH_ENTRY, id, obj, ic_slot, this_func, cp).Method("LdObjByNameBridge", :AddImm).Relocate.Terminator.ptr } Return(load_res).any } Else { - Intrinsic(:SLOW_PATH_ENTRY, id, obj, ic_slot).Method("LdObjByNameBridge", :AddImm).Relocate.Terminator.ptr + Intrinsic(:SLOW_PATH_ENTRY, id, obj, ic_slot, this_func, cp).Method("LdObjByNameBridge", :AddImm).Relocate.Terminator.ptr } end #################################################################################### # ST_OBJECT_BY_NAME # -macro(:handle_ecma_stobjbyname) do |obj, id, value, ic_slot| +macro(:handle_ecma_stobjbyname) do |obj, id, value, ic_slot, this_func, cp| props = ObjectAccessProperties.new(:by_name, :unknown, false) - key := resolve_id(id) + key := resolve_id(cp, id) IfImm(cmpanyheapobj(obj)).Imm(0).CC(:CC_NE).b { - store_res := handle_store_object_dynamic(obj, key, value, ic_slot, props) + store_res := handle_store_object_dynamic_by_name(obj, key, value, ic_slot, props, this_func, cp) IfImm(cmpanyhole(store_res)).Imm(0).CC(:CC_NE).b { - ecma_intrinsic_invoke("StObjByNameSlow", id, obj, value, ic_slot).any + ecma_intrinsic_invoke("StObjByNameSlow", id, obj, value, ic_slot, this_func, cp).any } } Else { - ecma_intrinsic_invoke("StObjByNameSlow", id, obj, value, ic_slot).any + ecma_intrinsic_invoke("StObjByNameSlow", id, obj, value, ic_slot, this_func, cp).any } end -function(:EcmaStobjbyname, params: {'id'=>'i32', 'obj'=>'any', 'value'=>'any', 'ic_slot'=>'i32'}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do - handle_ecma_stobjbyname(obj, id, value, ic_slot) +function(:EcmaStobjbyname, + params: {'id'=>'i32', 'obj'=>'any', 'value'=>'any', 'ic_slot'=>'i32', 'this_func'=>'any', 'cp'=>'any'}, + mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do + handle_ecma_stobjbyname(obj, id, value, ic_slot, this_func, cp) ReturnVoid() end function(:FastPathStObjByName, - params: {id: 'i32', obj: 'any', value: 'any', ic_slot: 'i32'}, + params: {id: 'i32', obj: 'any', value: 'any', ic_slot: 'i32', this_func: 'any', cp: 'any'}, mode: [:FastPath, :DynamicMethod, :DynamicStub], regmap: $full_regmap, regalloc_set: RegMask.new($full_regmap, :arg0, :arg1) + $panda_callees_mask - $panda_regmap, @@ -1719,14 +1766,14 @@ function(:FastPathStObjByName, end props = ObjectAccessProperties.new(:by_name, :unknown, false) - key := resolve_id(id) + key := resolve_id(cp, id) IfImm(cmpanyheapobj(obj)).Imm(0).NE.b { - res := handle_store_object_dynamic(obj, key, value, ic_slot, props) + res := handle_store_object_dynamic_by_name(obj, key, value, ic_slot, props, this_func, cp) IfImm(cmpanyhole(res)).Imm(0).NE.b { - Intrinsic(:SLOW_PATH_ENTRY, id, obj, value, ic_slot).Method("StObjByNameBridge", :AddImm).Relocate.Terminator.ptr + Intrinsic(:SLOW_PATH_ENTRY, id, obj, value, ic_slot, this_func, cp).Method("StObjByNameBridge", :AddImm).Relocate.Terminator.ptr } } Else { - Intrinsic(:SLOW_PATH_ENTRY, id, obj, value, ic_slot).Method("StObjByNameBridge", :AddImm).Relocate.Terminator.ptr + Intrinsic(:SLOW_PATH_ENTRY, id, obj, value, ic_slot, this_func, cp).Method("StObjByNameBridge", :AddImm).Relocate.Terminator.ptr } ReturnVoid() end @@ -1734,41 +1781,45 @@ end #################################################################################### # TRY_LD_GLOBAL_BY_NAME # -macro(:handle_ecma_tryldglobalbyname) do |id, ic_slot| - key := resolve_id(id) - ic_res := load_global_var_ic(key, ic_slot) +macro(:handle_ecma_tryldglobalbyname) do |id, ic_slot, this_func, cp| + key := resolve_id(cp, id) + ic_res := load_global_var_ic(this_func, key, ic_slot) IfImm(cmpanyhole(ic_res)).Imm(0).CC(:CC_EQ).b { res0 := ic_res } Else { - res1 := ecma_intrinsic_invoke("TryLdGlobalByNameSlow", id, ic_slot).any + res1 := ecma_intrinsic_invoke("TryLdGlobalByNameSlow", id, ic_slot, this_func, cp).any } Phi(res0, res1).any end -function(:EcmaTryldglobalbyname, params: {'id'=>'i32', 'ic_slot'=>'i32'}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do - Return(handle_ecma_tryldglobalbyname(id, ic_slot)) +function(:EcmaTryldglobalbyname, + params: {'id'=>'i32', 'ic_slot'=>'i32', 'this_func'=>'any', 'cp'=>'any'}, + mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do + Return(handle_ecma_tryldglobalbyname(id, ic_slot, this_func, cp)) end #################################################################################### # LD_GLOBAL_VAR # -macro(:handle_ecma_ldglobalvar) do |id, ic_slot| - key := resolve_id(id) - ic_res := load_global_var_ic(key, ic_slot) +macro(:handle_ecma_ldglobalvar) do |id, ic_slot, this_func, cp| + key := resolve_id(cp, id) + ic_res := load_global_var_ic(this_func, key, ic_slot) IfImm(cmpanyhole(ic_res)).Imm(0).CC(:CC_EQ).b { res0 := ic_res } Else { - res1 := ecma_intrinsic_invoke("LdGlobalVarSlow", id, ic_slot).any + res1 := ecma_intrinsic_invoke("LdGlobalVarSlow", id, ic_slot, this_func, cp).any } Phi(res0, res1).any end -function(:EcmaLdglobalvar, params: {'id'=>'i32', 'ic_slot'=>'i32'}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do - Return(handle_ecma_ldglobalvar(id, ic_slot)) +function(:EcmaLdglobalvar, + params: {'id'=>'i32', 'ic_slot'=>'i32', 'this_func'=>'any', 'cp'=>'any'}, + mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do + Return(handle_ecma_ldglobalvar(id, ic_slot, this_func, cp)) end function(:FastPathLdGlobalVar, - params: {id: 'i32', ic_slot: 'i32'}, + params: {id: 'i32', ic_slot: 'i32', this_func: 'any', cp: 'any'}, mode: [:FastPath, :DynamicMethod, :DynamicStub], regmap: $full_regmap, regalloc_set: RegMask.new($full_regmap, :arg0, :arg1) + $panda_callees_mask - $panda_regmap) do @@ -1778,10 +1829,10 @@ function(:FastPathLdGlobalVar, next end - key := resolve_id(id) - ic_res := load_global_var_ic(key, ic_slot).any + key := resolve_id(cp, id) + ic_res := load_global_var_ic(this_func, key, ic_slot).any IfImm(cmpanyhole(ic_res)).Imm(0).CC(:CC_NE).b { - Intrinsic(:SLOW_PATH_ENTRY, id, ic_slot).Method("LdGlobalVarBridge", :AddImm).Relocate.Terminator.ptr + Intrinsic(:SLOW_PATH_ENTRY, id, ic_slot, this_func, cp).Method("LdGlobalVarBridge", :AddImm).Relocate.Terminator.ptr } Return(ic_res).any end @@ -1789,21 +1840,23 @@ end #################################################################################### # ST_GLOBAL_VAR # -macro(:handle_ecma_stglobalvar) do |id, value, ic_slot| - key := resolve_id(id) - ic_res := store_global_var_ic(key, value, ic_slot) +macro(:handle_ecma_stglobalvar) do |id, value, ic_slot, this_func, cp| + key := resolve_id(cp, id) + ic_res := store_global_var_ic(this_func, key, value, ic_slot) IfImm(cmpanyhole(ic_res)).Imm(0).CC(:CC_NE).b { - ecma_intrinsic_invoke("StGlobalVarSlow", id, value, ic_slot).any + ecma_intrinsic_invoke("StGlobalVarSlow", id, value, ic_slot, this_func, cp).any } end -function(:EcmaStglobalvar, params: {'id'=>'i32', 'value'=>'any', 'ic_slot'=>'i32'}, mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do - handle_ecma_stglobalvar(id, value, ic_slot) +function(:EcmaStglobalvar, + params: {'id'=>'i32', 'value'=>'any', 'ic_slot'=>'i32', 'this_func'=>'any', 'cp'=>'any'}, + mode: [:Interpreter, :DynamicMethod, :DynamicStub], enable_builder: true) do + handle_ecma_stglobalvar(id, value, ic_slot, this_func, cp) ReturnVoid() end function(:FastPathStGlobalVar, - params: {id: 'i32', value: 'any', ic_slot: 'i32'}, + params: {id: 'i32', value: 'any', ic_slot: 'i32', this_func: 'any', cp: 'any'}, mode: [:FastPath, :DynamicMethod, :DynamicStub], regmap: $full_regmap, regalloc_set: RegMask.new($full_regmap, :arg0, :arg1) + $panda_callees_mask - $panda_regmap) do @@ -1813,10 +1866,10 @@ function(:FastPathStGlobalVar, next end - key := resolve_id(id) - ic_res := store_global_var_ic(key, value, ic_slot) + key := resolve_id(cp, id) + ic_res := store_global_var_ic(this_func, key, value, ic_slot) IfImm(cmpanyhole(ic_res)).Imm(0).CC(:CC_NE).b { - Intrinsic(:SLOW_PATH_ENTRY, id, value, ic_slot).Method("StGlobalVarBridge", :AddImm).Relocate.Terminator.ptr + Intrinsic(:SLOW_PATH_ENTRY, id, value, ic_slot, this_func, cp).Method("StGlobalVarBridge", :AddImm).Relocate.Terminator.ptr } ReturnVoid() end diff --git a/irtoc_scripts/interpreter_main_loop.irt b/irtoc_scripts/interpreter_main_loop.irt index 0d3b956e3..9e50ebb88 100644 --- a/irtoc_scripts/interpreter_main_loop.irt +++ b/irtoc_scripts/interpreter_main_loop.irt @@ -93,7 +93,7 @@ when "ECMA_LDINFINITY_PREF_NONE" ecma_intrinsic_setacc("Ldinfinity") when "ECMA_LDBIGINT_PREF_ID32" - ecma_intrinsic_setacc("Ldbigint", as_id(op[0])) + ecma_intrinsic_setacc("Ldbigint", as_id(op[0]), get_cp) when "ECMA_LDNULL_PREF_NONE" handle_ecma_ldconst(Constants::VALUE_NULL) when "ECMA_LDHOLE_PREF_NONE" @@ -125,9 +125,9 @@ when "ECMA_ISCOERCIBLE_PREF_NONE" ecma_intrinsic_setacc("IsCoercible", acc.any) when "ECMA_CREATEOBJECTWITHBUFFER_PREF_ID16" - ecma_intrinsic_setacc("CreateObjectWithBuffer", as_id(op[0])) + ecma_intrinsic_setacc("CreateObjectWithBuffer", as_id(op[0]), get_cp) when "ECMA_CREATEOBJECTHAVINGMETHOD_PREF_ID16" - ecma_intrinsic_setacc("CreateObjectHavingMethod", as_id(op[0]), acc.any) + ecma_intrinsic_setacc("CreateObjectHavingMethod", as_id(op[0]), acc.any, get_cp) when "ECMA_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8" ecma_intrinsic_setacc("CreateObjectWithExcludedKeys", as_imm(op[0]), vreg_value(op[1]).any, vreg_ptr(op[2])) when "ECMA_CREATEEMPTYOBJECT_PREF_NONE" @@ -145,13 +145,13 @@ # ecma runtime when "ECMA_DEFINEFUNCDYN_PREF_ID16_V8" - ecma_intrinsic_setacc("DefinefuncDyn", as_id(op[0]), vreg_value(op[1]).u64) + ecma_intrinsic_setacc("DefinefuncDyn", as_id(op[0]), vreg_value(op[1]).u64, get_cp) when "ECMA_DEFINEGENERATORFUNC_PREF_ID16_V8" - ecma_intrinsic_setacc("DefineGeneratorFunc", as_id(op[0]), vreg_value(op[1]).any) + ecma_intrinsic_setacc("DefineGeneratorFunc", as_id(op[0]), vreg_value(op[1]).any, get_cp) when "ECMA_DEFINENCFUNCDYN_PREF_ID16_V8" - ecma_intrinsic_setacc("DefineNCFuncDyn", as_id(op[0]), vreg_value(op[1]).any, acc.any) + ecma_intrinsic_setacc("DefineNCFuncDyn", as_id(op[0]), vreg_value(op[1]).any, acc.any, get_cp) when "ECMA_DEFINEASYNCFUNC_PREF_ID16_V8" - ecma_intrinsic_setacc("DefineAsyncFunc", as_id(op[0]), vreg_value(op[1]).any) + ecma_intrinsic_setacc("DefineAsyncFunc", as_id(op[0]), vreg_value(op[1]).any, get_cp) when "ECMA_ASYNCFUNCTIONENTER_PREF_NONE" ecma_intrinsic_setacc("AsyncFunctionEnter") when "ECMA_ASYNCFUNCTIONRESOLVE_PREF_V8" @@ -161,11 +161,11 @@ when "ECMA_ASYNCFUNCTIONREJECT_PREF_V8" ecma_intrinsic_setacc("AsyncFunctionReject", vreg_value(op[0]).any, acc.any) when "ECMA_DEFINEMETHOD_PREF_ID16_V8" - ecma_intrinsic_setacc("DefineMethod", as_id(op[0]), vreg_value(op[1]).any, acc.any) + ecma_intrinsic_setacc("DefineMethod", as_id(op[0]), vreg_value(op[1]).any, acc.any, get_cp) when "ECMA_IMPORTMODULE_PREF_ID32" - ecma_intrinsic_setacc("ImportModule", as_id(op[0])) + ecma_intrinsic_setacc("ImportModule", as_id(op[0]), get_cp) when "ECMA_STMODULEVAR_PREF_ID32" - ecma_intrinsic_setacc("StModuleVar", as_id(op[0]), acc.any) + ecma_intrinsic_setacc("StModuleVar", as_id(op[0]), acc.any, get_cp) when "ECMA_DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8" ecma_intrinsic_setacc("DefineGetterSetterByValue", vreg_value(op[0]).any, vreg_value(op[1]).any, vreg_value(op[2]).any, vreg_value(op[3]).any, acc.any) when "ECMA_TYPEOFDYN_PREF_NONE" @@ -175,7 +175,7 @@ when "ECMA_DELOBJPROP_PREF_V8_V8" ecma_intrinsic_setacc("Delobjprop", vreg_value(op[0]).any, vreg_value(op[1]).any) when "ECMA_GETMETHOD_PREF_ID32_V8" - ecma_intrinsic_setacc("GetMethod", as_id(op[0]), vreg_value(op[1]).any) + ecma_intrinsic_setacc("GetMethod", as_id(op[0]), vreg_value(op[1]).any, get_cp) when "ECMA_GETRESUMEMODE_PREF_V8" ecma_intrinsic_setacc("GetResumeMode", vreg_value(op[0]).any) when "ECMA_GETUNMAPPEDARGS_PREF_NONE" @@ -185,7 +185,7 @@ #class when "ECMA_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_V8_V8" - ecma_intrinsic_setacc("DefineClassWithBuffer", as_id(op[0]), as_imm(op[1]), vreg_value(op[2]).any, vreg_value(op[3]).any) + ecma_intrinsic_setacc("DefineClassWithBuffer", as_id(op[0]), as_imm(op[1]), vreg_value(op[2]).any, vreg_value(op[3]).any, get_cp) when "ECMA_LOADCLASSCOMPUTEDINSTANCEFIELDS_PREF_V8" ecma_intrinsic_setacc("LoadClassComputedInstanceFields", vreg_value(op[0]).any) when "ECMA_SETCLASSCOMPUTEDFIELDS_PREF_V8_V8" @@ -193,27 +193,27 @@ when "ECMA_CLASSFIELDADD_PREF_V8_V8" ecma_intrinsic_setacc("ClassFieldAdd", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any) when "ECMA_DEFINECLASSPRIVATEFIELDS_PREF_ID16_V8" - ecma_intrinsic_invoke("DefineClassPrivateFields", as_id(op[0]), vreg_value(op[1]).any, acc.any) + ecma_intrinsic_invoke("DefineClassPrivateFields", as_id(op[0]), vreg_value(op[1]).any, acc.any, get_cp) when "ECMA_CLASSPRIVATEMETHODORACCESSORADD_PREF_V8_V8" ecma_intrinsic_setacc("ClassPrivateMethodOrAccessorAdd", vreg_value(op[0]).any, vreg_value(op[1]).any) when "ECMA_CLASSPRIVATEFIELDADD_PREF_ID32_V8_V8" - ecma_intrinsic_setacc("ClassPrivateFieldAdd", as_id(op[0]), vreg_value(op[1]).any, vreg_value(op[2]).any, acc.any) + ecma_intrinsic_setacc("ClassPrivateFieldAdd", as_id(op[0]), vreg_value(op[1]).any, vreg_value(op[2]).any, acc.any, get_cp) when "ECMA_CLASSPRIVATEFIELDGET_PREF_ID32_V8_V8" - ecma_intrinsic_setacc("ClassPrivateFieldGet", as_id(op[0]), vreg_value(op[1]).any, vreg_value(op[2]).any) + ecma_intrinsic_setacc("ClassPrivateFieldGet", as_id(op[0]), vreg_value(op[1]).any, vreg_value(op[2]).any, get_cp) when "ECMA_CLASSPRIVATEFIELDSET_PREF_ID32_V8_V8" - ecma_intrinsic_setacc("ClassPrivateFieldSet", as_id(op[0]), vreg_value(op[1]).any, vreg_value(op[2]).any, acc.any) + ecma_intrinsic_setacc("ClassPrivateFieldSet", as_id(op[0]), vreg_value(op[1]).any, vreg_value(op[2]).any, acc.any, get_cp) when "ECMA_CLASSPRIVATEFIELDIN_PREF_ID32_V8" - ecma_intrinsic_setacc("ClassPrivateFieldIn", as_id(op[0]), vreg_value(op[1]).any, acc.any) + ecma_intrinsic_setacc("ClassPrivateFieldIn", as_id(op[0]), vreg_value(op[1]).any, acc.any, get_cp) #eval when "ECMA_LDEVALBINDINGS_PREF_ID16" - ecma_intrinsic_setacc("LdEvalBindings", as_id(op[0])) + ecma_intrinsic_setacc("LdEvalBindings", as_id(op[0]), get_cp) when "ECMA_DIRECTEVAL_PREF_IMM32_V8_V8" ecma_intrinsic_setacc("DirectEval", as_imm(op[0]), vreg_value(op[1]).any, vreg_value(op[2]).any) when "ECMA_LDEVALVAR_PREF_ID32" - ecma_intrinsic_setacc("LdEvalVar", as_id(op[0]), acc.any) + ecma_intrinsic_setacc("LdEvalVar", as_id(op[0]), acc.any, get_cp) when "ECMA_STEVALVAR_PREF_ID32_V8" - ecma_intrinsic_setacc("StEvalVar", as_id(op[0]), vreg_value(op[1]).any, acc.any) + ecma_intrinsic_setacc("StEvalVar", as_id(op[0]), vreg_value(op[1]).any, acc.any, get_cp) # ecma frames when "ECMA_CALL0DYN_PREF_NONE" @@ -245,37 +245,43 @@ when "ECMA_LDLEXENVDYN_PREF_NONE" acc := handle_ecma_ldlexenvdyn() when "ECMA_POPLEXENVDYN_PREF_NONE" - ecma_intrinsic_invoke("PopLexenvDyn") + set_lex_env(ecma_intrinsic_invoke("PopLexenvDyn", get_lex_env)) when "ECMA_NEWLEXENVDYN_PREF_IMM16" - ecma_intrinsic_setacc("NewlexenvDyn", as_imm(op[0])) + lex_env := ecma_intrinsic_setacc("NewlexenvDyn", as_imm(op[0]), get_lex_env) + If(exception_val(), 0).CC(:CC_EQ).b { + set_lex_env(lex_env) + } when "ECMA_COPYLEXENVDYN_PREF_NONE" - ecma_intrinsic_setacc("CopylexenvDyn") + lex_env := ecma_intrinsic_setacc("CopylexenvDyn", get_lex_env) + If(exception_val(), 0).CC(:CC_EQ).b { + set_lex_env(lex_env) + } when "ECMA_STLEXVARDYN_PREF_IMM4_IMM4" - ecma_intrinsic_invoke("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64) + ecma_intrinsic_invoke("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64, get_lex_env) when "ECMA_STLEXVARDYN_PREF_IMM8_IMM8" - ecma_intrinsic_invoke("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64) + ecma_intrinsic_invoke("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64, get_lex_env) when "ECMA_STLEXVARDYN_PREF_IMM16_IMM16" - ecma_intrinsic_invoke("StLexVarDyn", as_imm(op[0]), as_imm(op[1]), acc.u64) + ecma_intrinsic_invoke("StLexVarDyn", as_imm(op[0]), as_imm(op[1]), acc.u64, get_lex_env) when "ECMA_STLEXDYN_PREF_ID32_IMM4_IMM4" - ecma_intrinsic_setacc("StLexDyn", as_id(op[0]), i8tou16(as_imm(op[1])), i8tou16(as_imm(op[2])), acc.u64) + ecma_intrinsic_setacc("StLexDyn", as_id(op[0]), i8tou16(as_imm(op[1])), i8tou16(as_imm(op[2])), acc.u64, get_cp, get_lex_env) when "ECMA_STLEXDYN_PREF_ID32_IMM8_IMM8" - ecma_intrinsic_setacc("StLexDyn", as_id(op[0]), i8tou16(as_imm(op[1])), i8tou16(as_imm(op[2])), acc.u64) + ecma_intrinsic_setacc("StLexDyn", as_id(op[0]), i8tou16(as_imm(op[1])), i8tou16(as_imm(op[2])), acc.u64, get_cp, get_lex_env) when "ECMA_STLEXDYN_PREF_ID32_IMM16_IMM16" - ecma_intrinsic_setacc("StLexDyn", as_id(op[0]), as_imm(op[1]), as_imm(op[2]), acc.u64) + ecma_intrinsic_setacc("StLexDyn", as_id(op[0]), as_imm(op[1]), as_imm(op[2]), acc.u64, get_cp, get_lex_env) when "ECMA_LDLEXVARDYN_PREF_IMM4_IMM4" - ecma_intrinsic_setacc("LdLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1]))) + ecma_intrinsic_setacc("LdLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), get_lex_env) when "ECMA_LDLEXVARDYN_PREF_IMM8_IMM8" - ecma_intrinsic_setacc("LdLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1]))) + ecma_intrinsic_setacc("LdLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), get_lex_env) when "ECMA_LDLEXVARDYN_PREF_IMM16_IMM16" - ecma_intrinsic_setacc("LdLexVarDyn", as_imm(op[0]), as_imm(op[1])) + ecma_intrinsic_setacc("LdLexVarDyn", as_imm(op[0]), as_imm(op[1]), get_lex_env) when "ECMA_LDHOMEOBJECT_PREF_NONE" - ecma_intrinsic_setacc("LdHomeObject") + ecma_intrinsic_setacc("LdHomeObject", get_this_func) when "ECMA_LDLEXDYN_PREF_ID32_IMM4_IMM4" - ecma_intrinsic_setacc("LdLexDyn", as_id(op[0]), i8tou16(as_imm(op[1])), i8tou16(as_imm(op[2]))) + ecma_intrinsic_setacc("LdLexDyn", as_id(op[0]), i8tou16(as_imm(op[1])), i8tou16(as_imm(op[2])), get_cp, get_lex_env) when "ECMA_LDLEXDYN_PREF_ID32_IMM8_IMM8" - ecma_intrinsic_setacc("LdLexDyn", as_id(op[0]), i8tou16(as_imm(op[1])), i8tou16(as_imm(op[2]))) + ecma_intrinsic_setacc("LdLexDyn", as_id(op[0]), i8tou16(as_imm(op[1])), i8tou16(as_imm(op[2])), get_cp, get_lex_env) when "ECMA_LDLEXDYN_PREF_ID32_IMM16_IMM16" - ecma_intrinsic_setacc("LdLexDyn", as_id(op[0]), as_imm(op[1]), as_imm(op[2])) + ecma_intrinsic_setacc("LdLexDyn", as_id(op[0]), as_imm(op[1]), as_imm(op[2]), get_cp, get_lex_env) when "ECMA_CREATEEMPTYOBJECT_PREF_NONE" ecma_intrinsic_setacc("CreateEmptyObject") when "ECMA_RETURNUNDEFINED_PREF_NONE" @@ -285,9 +291,9 @@ when "ECMA_RETURN_DYN_PREF_NONE" Intrinsic(:INTERPRETER_RETURN).ptr when "ECMA_CREATEARRAYWITHBUFFER_PREF_ID16" - ecma_intrinsic_setacc("CreateArrayWithBuffer", as_id(op[0])) + ecma_intrinsic_setacc("CreateArrayWithBuffer", as_id(op[0]), get_cp) when "ECMA_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8" - ecma_intrinsic_setacc("CreateRegExpWithLiteral", as_id(op[0]), as_imm(op[1])) + ecma_intrinsic_setacc("CreateRegExpWithLiteral", as_id(op[0]), as_imm(op[1]), get_cp) when "ECMA_CREATEEMPTYARRAY_PREF_NONE" ecma_intrinsic_setacc("CreateEmptyArray") when "ECMA_STARRAYSPREAD_PREF_V8_V8" @@ -336,39 +342,39 @@ # ecma load/stores by value when "ECMA_STOBJBYVALUE_PREF_V8_V8" - handle_ecma_stobjbyvalue(vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any, ins_offset) + handle_ecma_stobjbyvalue(vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any, ins_offset, get_this_func) when "ECMA_LDOBJBYVALUE_PREF_V8" - acc := handle_ecma_ldobjbyvalue(vreg_value(op[0]).any, acc.any, ins_offset) + acc := handle_ecma_ldobjbyvalue(vreg_value(op[0]).any, acc.any, ins_offset, get_this_func) when "ECMA_LDSUPERBYVALUE_PREF_V8" - ecma_intrinsic_setacc("LdSuperByValue", vreg_value(op[0]).any, acc.any) + ecma_intrinsic_setacc("LdSuperByValue", vreg_value(op[0]).any, acc.any, get_this_func) when "ECMA_STSUPERBYVALUE_PREF_V8_V8" - ecma_intrinsic_setacc("StSuperByValue", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any) + ecma_intrinsic_setacc("StSuperByValue", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any, get_this_func) when "ECMA_STOWNBYVALUE_PREF_V8_V8" ecma_intrinsic_invoke("StOwnByValue", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any) # ecma load/stores by name when "ECMA_STOBJBYNAME_PREF_ID32_V8" - handle_ecma_stobjbyname(vreg_value(op[1]).any, as_id(op[0]), acc.any, ins_offset) + handle_ecma_stobjbyname(vreg_value(op[1]).any, as_id(op[0]), acc.any, ins_offset, get_this_func, get_cp) when "ECMA_LDOBJBYNAME_PREF_ID32" - acc := handle_ecma_ldobjbyname(acc.any, as_id(op[0]), ins_offset) + acc := handle_ecma_ldobjbyname(acc.any, as_id(op[0]), ins_offset, get_this_func, get_cp) when "ECMA_LDSUPERBYNAME_PREF_ID32" - ecma_intrinsic_setacc("LdSuperByName", as_id(op[0]), acc.any) + ecma_intrinsic_setacc("LdSuperByName", as_id(op[0]), acc.any, get_this_func, get_cp) when "ECMA_STSUPERBYNAME_PREF_ID32_V8" - ecma_intrinsic_invoke("StSuperByName", as_id(op[0]), vreg_value(op[1]).any, acc.any) + ecma_intrinsic_invoke("StSuperByName", as_id(op[0]), vreg_value(op[1]).any, acc.any, get_this_func, get_cp) when "ECMA_STOWNBYNAME_PREF_ID32_V8" - ecma_intrinsic_invoke("StOwnByName", as_id(op[0]), vreg_value(op[1]).any, acc.any) + ecma_intrinsic_invoke("StOwnByName", as_id(op[0]), vreg_value(op[1]).any, acc.any, get_cp) # load/stores from global object when "ECMA_LDGLOBAL_PREF_NONE" ecma_intrinsic_setacc("Ldglobal") when "ECMA_TRYLDGLOBALBYNAME_PREF_ID32" - acc := handle_ecma_tryldglobalbyname(as_id(op[0]), ins_offset) + acc := handle_ecma_tryldglobalbyname(as_id(op[0]), ins_offset, get_this_func, get_cp) when "ECMA_TRYSTGLOBALBYNAME_PREF_ID32" - ecma_intrinsic_invoke("TryStGlobalByName", as_id(op[0]), acc.any, ins_offset) + ecma_intrinsic_invoke("TryStGlobalByName", as_id(op[0]), acc.any, ins_offset, get_this_func, get_cp) when "ECMA_LDGLOBALVAR_PREF_ID32" - acc := handle_ecma_ldglobalvar(as_id(op[0]), ins_offset) + acc := handle_ecma_ldglobalvar(as_id(op[0]), ins_offset, get_this_func, get_cp) when "ECMA_STGLOBALVAR_PREF_ID32" - handle_ecma_stglobalvar(as_id(op[0]), acc.any, ins_offset) + handle_ecma_stglobalvar(as_id(op[0]), acc.any, ins_offset, get_this_func, get_cp) # ecma generators when "ECMA_CREATEGENERATOROBJ_PREF_V8" @@ -386,7 +392,7 @@ when "ECMA_CREATEASYNCGENERATOROBJ_PREF_V8" ecma_intrinsic_setacc("CreateAsyncGeneratorObj", vreg_value(op[0]).any) when "ECMA_DEFINEASYNCGENERATORFUNC_PREF_ID16_V8" - ecma_intrinsic_setacc("DefineAsyncGeneratorFunc", as_id(op[0]), vreg_value(op[1]).any) + ecma_intrinsic_setacc("DefineAsyncGeneratorFunc", as_id(op[0]), vreg_value(op[1]).any, get_cp) when "ECMA_GETASYNCITERATOR_PREF_NONE" ecma_intrinsic_setacc("GetAsyncIterator", acc.u64) when "ECMA_ASYNCGENERATORRESOLVE_PREF_V8" @@ -413,7 +419,7 @@ end acc := acc_eh when "ECMA_THROWCONSTASSIGNMENT_PREF_ID32" - ecma_intrinsic_invoke("ThrowConstAssignment", as_id(op[0])) + ecma_intrinsic_invoke("ThrowConstAssignment", as_id(op[0]), get_cp) pc := find_catch_block() frame := frame_eh if Options.arm64? @@ -440,7 +446,7 @@ end acc := acc_eh when "ECMA_THROWTDZ_PREF_ID32" - ecma_intrinsic_invoke("ThrowTdz", as_id(op[0])) + ecma_intrinsic_invoke("ThrowTdz", as_id(op[0]), get_cp) pc := find_catch_block() frame := frame_eh if Options.arm64? diff --git a/irtoc_scripts/object.irt b/irtoc_scripts/object.irt index 2ec92d391..fe7943aa0 100644 --- a/irtoc_scripts/object.irt +++ b/irtoc_scripts/object.irt @@ -534,14 +534,14 @@ scoped_macro(:obj_set_property) do |obj, attributes, value, update_ic| } end -scoped_macro(:update_ic) do |hclass, offset, is_inlined, ic_slot| +scoped_macro(:update_ic) do |this_func, hclass, offset, is_inlined, ic_slot| d0 := 0 d1 := set_bits(d0, Constants::IC_HANDLER_KIND_BIT, Constants::IC_HANDLER_KIND_MASK, Constants::IC_HANDLER_KIND_FIELD) d2 := set_bits(d1, Constants::IC_HANDLER_OFFSET_BIT, Constants::IC_HANDLER_OFFSET_MASK, offset) handler := set_bits(d2, Constants::IC_HANDLER_INLINE_BIT, Constants::IC_HANDLER_INLINE_MASK, is_inlined) - ic := get_ic() - idx := map_ic_slot(ic_slot) + ic := get_ic(this_func) + idx := map_ic_slot(this_func, ic_slot) IfImm(cmpanyundefined(ic)).Imm(0).CC(:CC_EQ).b { StoreArray(anytoheapobj(ic), idx, heapobjtoany(hclass)).SetNeedBarrier(true).any StoreArray(anytoheapobj(ic), AddI(idx).Imm(1).i32, i32toany(handler)).SetNeedBarrier(true).any @@ -560,7 +560,7 @@ end end function("LoadObjectDynamic#{postfix}", - params: {obj: 'ref', key: 'any'}.merge(extra_params), + params: {obj: 'ref', key: 'any'}.merge(extra_params).merge({this_func: 'any'}), regmap: $full_regmap, mode: [:FastPath, :DynamicMethod, :DynamicStub], regalloc_set: $panda_mask, @@ -589,7 +589,8 @@ end lambda do |hclass, offset, is_inlined| if access_props.type == :by_name global :ic_slot - update_ic(hclass, offset, is_inlined, ic_slot) + global :this_func + update_ic(this_func, hclass, offset, is_inlined, ic_slot) end end) end, @@ -602,7 +603,7 @@ end } function("StoreObjectDynamic#{postfix}", - params: {obj: 'ref', key: 'any', value: 'any'}.merge(extra_params), + params: {obj: 'ref', key: 'any', value: 'any'}.merge(extra_params).merge({this_func: 'any'}), regmap: $full_regmap, mode: [:FastPath, :DynamicMethod, :DynamicStub], regalloc_set: $panda_mask, @@ -633,7 +634,8 @@ end lambda do |hclass, offset, is_inlined| if access_props.type == :by_name global :ic_slot - update_ic(hclass, offset, is_inlined, ic_slot) + global :this_func + update_ic(this_func, hclass, offset, is_inlined, ic_slot) end end) NOP() diff --git a/isa/isa.yaml b/isa/isa.yaml index a6064ba5a..86d9712f5 100644 --- a/isa/isa.yaml +++ b/isa/isa.yaml @@ -28,6 +28,15 @@ properties: description: Instruction uses inline cache - tag: skip_literal_id_patch description: Do not patch literal array id + - tag: cp + description: Instruction use constant pool from environment + - tag: func + description: Instruction use this func from environment + - tag: lex_env + description: Instruction use lexical environment from environment + - tag: write_lex_env + description: Instruction write lexical environment to environment + namespaces: - namespace: ecmascript @@ -131,7 +140,7 @@ groups: prefix: ecma format: [pref_op_id_32] intrinsic_name: INTRINSIC_LDBIGINT - properties: [string_id] + properties: [cp, string_id] - sig: ecma.throwdyn acc: in:top @@ -157,12 +166,14 @@ groups: prefix: ecma format: [pref_op_none] exceptions: [x_none] + properties: [write_lex_env, func] intrinsic_name: INTRINSIC_LDLEXENV_DYN - sig: ecma.poplexenvdyn acc: out:top prefix: ecma format: [pref_op_none] + properties: [lex_env, write_lex_env] intrinsic_name: INTRINSIC_POP_LEXENV_DYN - sig: ecma.getunmappedargs @@ -240,6 +251,7 @@ groups: acc: out:top prefix: ecma format: [pref_op_none] + properties: [func] intrinsic_name: INTRINSIC_LD_HOME_OBJECT - sig: ecma.throwdeletesuperproperty @@ -498,14 +510,14 @@ groups: prefix: ecma format: [pref_op_id_32] exceptions: [x_throw] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_THROW_CONST_ASSIGNMENT - sig: ecma.getmethod string_id, v:in:top acc: out:top prefix: ecma format: [pref_op_id_32_v_8] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_GET_METHOD - sig: ecma.gettemplateobject v:in:top @@ -587,7 +599,7 @@ groups: acc: none prefix: ecma format: [pref_op_id_32] - properties: [string_id] + properties: [string_id, cp] exceptions: [x_throw] intrinsic_name: INTRINSIC_THROW_TDZ @@ -613,14 +625,14 @@ groups: acc: inout:top prefix: ecma format: [pref_op_v_8] - properties: [use_ic, inlinable] + properties: [use_ic, inlinable, func] intrinsic_name: INTRINSIC_LD_OBJ_BY_VALUE - sig: ecma.stobjbyvalue v1:in:top, v2:in:top acc: in:top prefix: ecma format: [pref_op_v1_8_v2_8] - properties: [use_ic, inlinable] + properties: [use_ic, inlinable, func] intrinsic_name: INTRINSIC_ST_OBJ_BY_VALUE - sig: ecma.stownbyvalue v1:in:top, v2:in:top @@ -633,12 +645,14 @@ groups: acc: inout:top prefix: ecma format: [pref_op_v_8] + properties: [func] intrinsic_name: INTRINSIC_LD_SUPER_BY_VALUE - sig: ecma.stsuperbyvalue v1:in:top, v2:in:top acc: in:top prefix: ecma format: [pref_op_v1_8_v2_8] + properties: [func] intrinsic_name: INTRINSIC_ST_SUPER_BY_VALUE - sig: ecma.ldobjbyindex imm @@ -852,54 +866,56 @@ groups: acc: out:top prefix: ecma format: [pref_op_id_16_v_8] - properties: [method_id] + properties: [method_id, cp] intrinsic_name: INTRINSIC_DEFINEFUNC_DYN - sig: ecma.definencfuncdyn method_id, v:in:top acc: inout:top prefix: ecma format: [pref_op_id_16_v_8] - properties: [method_id] + properties: [method_id, cp] intrinsic_name: INTRINSIC_DEFINE_NC_FUNC_DYN - sig: ecma.definegeneratorfunc method_id, v:in:top acc: out:top prefix: ecma format: [pref_op_id_16_v_8] - properties: [method_id] + properties: [method_id, cp] intrinsic_name: INTRINSIC_DEFINE_GENERATOR_FUNC - sig: ecma.defineasyncfunc method_id, v:in:top acc: out:top prefix: ecma format: [pref_op_id_16_v_8] - properties: [method_id] + properties: [method_id, cp] intrinsic_name: INTRINSIC_DEFINE_ASYNC_FUNC - sig: ecma.defineasyncgeneratorfunc method_id, v:in:top acc: out:top prefix: ecma format: [pref_op_id_16_v_8] - properties: [method_id] + properties: [method_id, cp] intrinsic_name: INTRINSIC_DEFINE_ASYNC_GENERATOR_FUNC - sig: ecma.definemethod method_id, v:in:top acc: inout:top prefix: ecma format: [pref_op_id_16_v_8] - properties: [method_id] + properties: [method_id, cp] intrinsic_name: INTRINSIC_DEFINE_METHOD - sig: ecma.newlexenvdyn imm acc: out:top prefix: ecma format: [pref_op_imm_16] + properties: [lex_env, write_lex_env] intrinsic_name: INTRINSIC_NEWLEXENV_DYN - sig: ecma.copylexenvdyn acc: out:top prefix: ecma format: [pref_op_none] + properties: [lex_env, write_lex_env] intrinsic_name: INTRINSIC_COPYLEXENV_DYN - sig: ecma.copyrestargs imm @@ -913,21 +929,21 @@ groups: acc: out:top prefix: ecma format: [pref_op_id_32_imm_8] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_CREATE_REG_EXP_WITH_LITERAL - sig: ecma.createarraywithbuffer literalarray_id acc: out:top prefix: ecma format: [pref_op_id_16] - properties: [literalarray_id] + properties: [literalarray_id, cp] intrinsic_name: INTRINSIC_CREATE_ARRAY_WITH_BUFFER - sig: ecma.createobjecthavingmethod literalarray_id acc: inout:top prefix: ecma format: [pref_op_id_16] - properties: [literalarray_id] + properties: [literalarray_id, cp] intrinsic_name: INTRINSIC_CREATE_OBJECT_HAVING_METHOD - sig: ecma.throwifsupernotcorrectcall imm @@ -940,7 +956,7 @@ groups: acc: out:top prefix: ecma format: [pref_op_id_16] - properties: [literalarray_id] + properties: [literalarray_id, cp] intrinsic_name: INTRINSIC_CREATE_OBJECT_WITH_BUFFER - sig: ecma.ldlexvardyn imm1, imm2 @@ -948,6 +964,7 @@ groups: prefix: ecma format: [pref_op_imm1_4_imm2_4] exceptions: [x_none] + properties: [lex_env] intrinsic_name: INTRINSIC_LD_LEX_VAR_DYN - sig: ecma.ldlexvardyn imm1, imm2 @@ -955,6 +972,7 @@ groups: prefix: ecma format: [pref_op_imm1_8_imm2_8] exceptions: [x_none] + properties: [lex_env] intrinsic_name: INTRINSIC_LD_LEX_VAR_DYN - sig: ecma.ldlexvardyn imm1, imm2 @@ -962,6 +980,7 @@ groups: prefix: ecma format: [pref_op_imm1_16_imm2_16] exceptions: [x_none] + properties: [lex_env] intrinsic_name: INTRINSIC_LD_LEX_VAR_DYN - sig: ecma.ldlexdyn string_id, imm1, imm2 @@ -969,26 +988,27 @@ groups: prefix: ecma format: [pref_op_id_32_imm1_4_imm2_4] intrinsic_name: INTRINSIC_LD_LEX_DYN - properties: [string_id] + properties: [string_id, cp, lex_env] - sig: ecma.ldlexdyn string_id, imm1, imm2 acc: out:top prefix: ecma format: [pref_op_id_32_imm1_8_imm2_8] - properties: [string_id] + properties: [string_id, cp, lex_env] intrinsic_name: INTRINSIC_LD_LEX_DYN - sig: ecma.ldlexdyn string_id, imm1, imm2 acc: out:top prefix: ecma format: [pref_op_id_32_imm1_16_imm2_16] - properties: [string_id] + properties: [string_id, cp, lex_env] intrinsic_name: INTRINSIC_LD_LEX_DYN - sig: ecma.stlexvardyn imm1, imm2 acc: in:top prefix: ecma format: [pref_op_imm1_4_imm2_4] + properties: [lex_env] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN - sig: ecma.loadclasscomputedinstancefields v:in:top @@ -1007,33 +1027,35 @@ groups: acc: in:top prefix: ecma format: [pref_op_imm1_8_imm2_8] + properties: [lex_env] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN - sig: ecma.stlexvardyn imm1, imm2 acc: in:top prefix: ecma format: [pref_op_imm1_16_imm2_16] + properties: [lex_env] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN - sig: ecma.stlexdyn string_id, imm1, imm2 acc: inout:top prefix: ecma format: [pref_op_id_32_imm1_4_imm2_4] - properties: [string_id] + properties: [string_id, cp, lex_env] intrinsic_name: INTRINSIC_ST_LEX_DYN - sig: ecma.stlexdyn string_id, imm1, imm2 acc: inout:top prefix: ecma format: [pref_op_id_32_imm1_8_imm2_8] - properties: [string_id] + properties: [string_id, cp, lex_env] intrinsic_name: INTRINSIC_ST_LEX_DYN - sig: ecma.stlexdyn string_id, imm1, imm2 acc: inout:top prefix: ecma format: [pref_op_id_32_imm1_16_imm2_16] - properties: [string_id] + properties: [string_id, cp, lex_env] intrinsic_name: INTRINSIC_ST_LEX_DYN - sig: ecma.defineclasswithbuffer method_id, imm, v1:in:top, v2:in:top @@ -1041,7 +1063,7 @@ groups: prefix: ecma format: [pref_op_id_16_imm_16_v1_8_v2_8] intrinsic_name: INTRINSIC_DEFINE_CLASS_WITH_BUFFER - properties: [method_id, literalarray_id] + properties: [method_id, literalarray_id, cp] - sig: ecma.classfieldadd v1:in:top, v2:in:top acc: in:top @@ -1054,7 +1076,7 @@ groups: prefix: ecma format: [pref_op_id_16_v_8] intrinsic_name: INTRINSIC_DEFINE_CLASS_PRIVATE_FIELDS - properties: [literalarray_id] + properties: [literalarray_id, cp] - sig: ecma.classprivatemethodoraccessoradd v1:in:top, v2:in:top acc: none @@ -1067,112 +1089,112 @@ groups: prefix: ecma format: [pref_op_id_32_v1_8_v2_8] intrinsic_name: INTRINSIC_CLASS_PRIVATE_FIELD_ADD - properties: [string_id] + properties: [string_id, cp] - sig: ecma.classprivatefieldget string_id, v1:in:top, v2:in:top acc: out:top prefix: ecma format: [pref_op_id_32_v1_8_v2_8] intrinsic_name: INTRINSIC_CLASS_PRIVATE_FIELD_GET - properties: [string_id] + properties: [string_id, cp] - sig: ecma.classprivatefieldset string_id, v1:in:top, v2:in:top acc: in:top prefix: ecma format: [pref_op_id_32_v1_8_v2_8] intrinsic_name: INTRINSIC_CLASS_PRIVATE_FIELD_SET - properties: [string_id] + properties: [string_id, cp] - sig: ecma.classprivatefieldin string_id, v:in:top acc: inout:top prefix: ecma format: [pref_op_id_32_v_8] intrinsic_name: INTRINSIC_CLASS_PRIVATE_FIELD_IN - properties: [string_id] + properties: [string_id, cp] - sig: ecma.importmodule string_id acc: out:top prefix: ecma format: [pref_op_id_32] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_IMPORT_MODULE - sig: ecma.stmodulevar string_id acc: in:top prefix: ecma format: [pref_op_id_32] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_ST_MODULE_VAR - sig: ecma.tryldglobalbyname string_id acc: out:top prefix: ecma format: [pref_op_id_32] - properties: [string_id, use_ic, inlinable] + properties: [string_id, use_ic, inlinable, cp, func] intrinsic_name: INTRINSIC_TRY_LD_GLOBAL_BY_NAME - sig: ecma.trystglobalbyname string_id acc: in:top prefix: ecma format: [pref_op_id_32] - properties: [string_id, use_ic] + properties: [string_id, use_ic, cp, func] intrinsic_name: INTRINSIC_TRY_ST_GLOBAL_BY_NAME - sig: ecma.ldglobalvar string_id acc: out:top prefix: ecma format: [pref_op_id_32] - properties: [string_id, use_ic, inlinable] + properties: [string_id, use_ic, inlinable, cp, func] intrinsic_name: INTRINSIC_LD_GLOBAL_VAR - sig: ecma.stglobalvar string_id acc: in:top prefix: ecma format: [pref_op_id_32] - properties: [string_id, use_ic, inlinable] + properties: [string_id, use_ic, inlinable, cp, func] intrinsic_name: INTRINSIC_ST_GLOBAL_VAR - sig: ecma.ldobjbyname string_id acc: inout:top prefix: ecma format: [pref_op_id_32] - properties: [string_id, use_ic, inlinable] + properties: [string_id, use_ic, inlinable, cp, func] intrinsic_name: INTRINSIC_LD_OBJ_BY_NAME - sig: ecma.stobjbyname string_id, v:in:top acc: in:top prefix: ecma format: [pref_op_id_32_v_8] - properties: [string_id, use_ic, inlinable] + properties: [string_id, use_ic, inlinable, cp, func] intrinsic_name: INTRINSIC_ST_OBJ_BY_NAME - sig: ecma.stownbyname string_id, v:in:top acc: in:top prefix: ecma format: [pref_op_id_32_v_8] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_ST_OWN_BY_NAME - sig: ecma.ldsuperbyname string_id acc: inout:top prefix: ecma format: [pref_op_id_32] - properties: [string_id] + properties: [string_id, cp, func] intrinsic_name: INTRINSIC_LD_SUPER_BY_NAME - sig: ecma.stsuperbyname string_id, v:in:top acc: in:top prefix: ecma format: [pref_op_id_32_v_8] - properties: [string_id] + properties: [string_id, cp, func] intrinsic_name: INTRINSIC_ST_SUPER_BY_NAME - sig: ecma.ldmodvarbyname string_id, v:in:top acc: out:top prefix: ecma format: [pref_op_id_32_v_8] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_LD_MODVAR_BY_NAME - sig: ecma.toboolean @@ -1244,7 +1266,7 @@ groups: prefix: ecma format: [pref_op_id_16] intrinsic_name: INTRINSIC_LD_EVAL_BINDINGS - properties: [literalarray_id, skip_literal_id_patch] + properties: [literalarray_id, skip_literal_id_patch, cp] - sig: ecma.directeval imm, v1:in:top, v2:in:top acc: out:top @@ -1256,12 +1278,12 @@ groups: acc: inout:top prefix: ecma format: [pref_op_id_32] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_LD_EVAL_VAR - sig: ecma.stevalvar string_id, v:in:top acc: inout:top prefix: ecma format: [pref_op_id_32_v_8] - properties: [string_id] + properties: [string_id, cp] intrinsic_name: INTRINSIC_ST_EVAL_VAR diff --git a/runtime/asm_defines/asm_defines.def b/runtime/asm_defines/asm_defines.def index c1093baf8..72588841c 100644 --- a/runtime/asm_defines/asm_defines.def +++ b/runtime/asm_defines/asm_defines.def @@ -1,13 +1,24 @@ /** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. + * Copyright (c) 2021-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. */ -DEFINE_VALUE(ECMA_IFRAME_EXT_SIZE, panda::ecmascript::JSExtFrame::GetExtSize()) DEFINE_VALUE(ECMASCRIPT_ENVIRONMENT_SIZE, panda::ecmascript::EcmascriptEnvironment::GetSize()) -DEFINE_VALUE(ECMASCRIPT_ENVIRONMENT_PREV_ENVIRONMENT_OFFSET, panda::ecmascript::EcmascriptEnvironment::GetPrevEnvironmentOffset()) DEFINE_VALUE(ECMASCRIPT_ENVIRONMENT_CONSTANT_POOL_OFFSET, panda::ecmascript::EcmascriptEnvironment::GetConstantPoolOffset()) DEFINE_VALUE(ECMASCRIPT_ENVIRONMENT_LEXICAL_ENV_OFFSET, panda::ecmascript::EcmascriptEnvironment::GetLexicalEnvOffset()) DEFINE_VALUE(ECMASCRIPT_ENVIRONMENT_THIS_FUNC_OFFSET, panda::ecmascript::EcmascriptEnvironment::GetThisFuncOffset()) +DEFINE_VALUE(EXTFRAME_EXT_DATA_OFFSET, panda::ecmascript::JSExtFrame::GetExtDataOffset()) +DEFINE_VALUE(EXTFRAME_FRAME_OFFSET, panda::ecmascript::JSExtFrame::GetFrameOffset()) DEFINE_VALUE(JSTYPE_JS_OBJECT_BEGIN, static_cast(panda::ecmascript::JSType::JS_OBJECT_BEGIN)) DEFINE_VALUE(JSTYPE_JS_OBJECT_END, static_cast(panda::ecmascript::JSType::JS_OBJECT_END)) DEFINE_VALUE(JSTYPE_STRING, static_cast(panda::ecmascript::JSType::STRING)) diff --git a/runtime/class_linker/program_object.h b/runtime/class_linker/program_object.h index 56b389e6e..19bb57592 100644 --- a/runtime/class_linker/program_object.h +++ b/runtime/class_linker/program_object.h @@ -73,6 +73,12 @@ public: return static_cast(object); } + static ConstantPool *Cast(JSTaggedType cp) + { + ASSERT(JSTaggedValue(cp).IsTaggedArray()); + return static_cast(JSTaggedValue(cp).GetHeapObject()); + } + inline JSTaggedValue GetObjectFromCache(uint32_t index) const; DECL_DUMP() }; diff --git a/runtime/ecma_compiler.cpp b/runtime/ecma_compiler.cpp index d6785f163..1f65697ba 100644 --- a/runtime/ecma_compiler.cpp +++ b/runtime/ecma_compiler.cpp @@ -16,6 +16,7 @@ #include "plugins/ecmascript/runtime/ecma_compiler.h" #include "plugins/ecmascript/runtime/compiler/ecmascript_runtime_interface.h" #include "plugins/ecmascript/runtime/js_function.h" +#include "plugins/ecmascript/runtime/interpreter/js_frame.h" #include "plugins/ecmascript/compiler/ecmascript_extensions/ecmascript_environment.h" #include "plugins/ecmascript/runtime/global_handle_collection.h" #include "plugins/ecmascript/runtime/ecma_global_storage-inl.h" @@ -26,19 +27,19 @@ namespace panda::ecmascript { void EcmaCompiler::AddTask(CompilerTask &&task, TaggedValue func) { - auto vm = task.GetVM(); if (func.IsHole()) { - auto thread = static_cast(vm)->GetJSThread(); - auto env = thread->GetEcmascriptEnv(); - if (env != nullptr) { - auto curr_func = JSFunction::Cast(env->GetThisFunc()); - if (curr_func->GetMethod() == task.GetMethod()) { - func = TaggedValue(curr_func); + if (auto stack = StackWalker::Create(GetJSThread()); !stack.IsCFrame()) { + auto frame = stack.GetIFrame(); + if (frame != nullptr && !frame->GetMethod()->IsNative()) { + auto curr_func = JSFunction::Cast(JSFrame::GetJSEnv(frame)->GetThisFunc()); + if (curr_func->GetMethod() == task.GetMethod()) { + func = TaggedValue(curr_func); + } } } } if (!func.IsHole()) { - auto gos = vm->GetGlobalObjectStorage(); + auto gos = task.GetVM()->GetGlobalObjectStorage(); auto func_ref = gos->Add(func.GetHeapObject(), panda::mem::Reference::ObjectType::GLOBAL); static_cast(GetRuntimeInterface())->AddFunctionInMap(task.GetMethod(), func_ref); } diff --git a/runtime/ecma_entrypoints.cpp b/runtime/ecma_entrypoints.cpp index 73245ee68..8cefcfc14 100644 --- a/runtime/ecma_entrypoints.cpp +++ b/runtime/ecma_entrypoints.cpp @@ -21,10 +21,10 @@ #include "plugins/ecmascript/runtime/interpreter/slow_runtime_stub.h" namespace panda::ecmascript { -extern "C" uintptr_t JSGetGlobalVarAddress(uint32_t id) +extern "C" uintptr_t JSGetGlobalVarAddress(uint64_t cp, uint32_t id) { auto thread = JSThread::GetCurrent(); - JSTaggedValue key = GetConstantPool(thread)->GetObjectFromCache(id); + JSTaggedValue key = ConstantPool::Cast(cp)->GetObjectFromCache(id); auto global_obj = thread->GetGlobalObject(); [[maybe_unused]] EcmaHandleScope scope(thread); JSHandle global_handle(thread, global_obj); @@ -33,7 +33,7 @@ extern "C" uintptr_t JSGetGlobalVarAddress(uint32_t id) if (res.IsUndefined() || !res.IsPropertyBox()) { PropertyAttributes attributes = PropertyAttributes::Default(true, true, false); // Reread key because GC can move it in ctor of ObjectOperator - JSHandle key_handle(thread, GetConstantPool(thread)->GetObjectFromCache(id)); + JSHandle key_handle(thread, ConstantPool::Cast(cp)->GetObjectFromCache(id)); op.AddProperty(global_handle, key_handle, attributes); res = op.GetValue(); } @@ -57,4 +57,9 @@ extern "C" uint64_t AllocDynObjectSlowPath(uint64_t ctor_raw) return thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(ctor, new_tgt).GetTaggedValue().GetRawData(); } +extern "C" coretypes::String *ResolveStringDynamicEntrypoint(uint64_t cp, FileEntityId id) +{ + return JSThread::GetCurrent()->GetEcmaVM()->ResolveString(ConstantPool::Cast(cp), panda_file::File::EntityId(id)); +} + } // namespace panda::ecmascript diff --git a/runtime/ecma_entrypoints.yaml b/runtime/ecma_entrypoints.yaml index b25067f2c..b7ec883db 100644 --- a/runtime/ecma_entrypoints.yaml +++ b/runtime/ecma_entrypoints.yaml @@ -27,6 +27,7 @@ properties: [] signature: - uintptr_t + - uint64_t - uint32_t - name: StoreObjectDynamic @@ -38,6 +39,7 @@ - panda::ObjectHeader* - uint64_t - uint64_t + - uint64_t - name: LoadObjectDynamic entrypoint: LoadObjectDynamic @@ -47,6 +49,7 @@ - uint64_t - panda::ObjectHeader* - uint64_t + - uint64_t - name: StoreObjectDynamicByName entrypoint: StoreObjectDynamicByName @@ -58,6 +61,8 @@ - uint64_t - uint64_t - uint16_t + - uint64_t + - uint64_t - name: LoadObjectDynamicByName entrypoint: LoadObjectDynamicByName @@ -68,6 +73,8 @@ - panda::ObjectHeader* - uint64_t - uint16_t + - uint64_t + - uint64_t - name: StoreObjectDynamicByIndexDictionary entrypoint: StoreObjectDynamicByIndexDictionary @@ -120,3 +127,12 @@ properties: [] signature: - void + +- name: ResolveStringDynamic + entrypoint: ResolveStringDynamicEntrypoint + bridge: entrypoint + properties: [] + signature: + - panda::coretypes::String* + - uint64_t + - panda::FileEntityId diff --git a/runtime/ecma_language_context.cpp b/runtime/ecma_language_context.cpp index 6c2db5b40..b962ae834 100644 --- a/runtime/ecma_language_context.cpp +++ b/runtime/ecma_language_context.cpp @@ -18,13 +18,17 @@ #include "plugins/ecmascript/compiler/ecmascript_extensions/ecmascript_environment.h" #include "plugins/ecmascript/runtime/ecma_class_linker_extension.h" +#include "plugins/ecmascript/runtime/class_linker/program_object.h" #include "plugins/ecmascript/runtime/ecma_exceptions.h" #include "plugins/ecmascript/runtime/base/error_type.h" #include "plugins/ecmascript/runtime/js_method.h" #include "plugins/ecmascript/runtime/js_object.h" +#include "plugins/ecmascript/runtime/js_function.h" #include "plugins/ecmascript/runtime/js_tagged_value.h" #include "plugins/ecmascript/runtime/js_thread.h" #include "plugins/ecmascript/runtime/object_factory.h" +#include "plugins/ecmascript/runtime/lexical_env.h" +#include "plugins/ecmascript/runtime/interpreter/js_frame.h" #include "include/method.h" #include "runtime/core/core_itable_builder.h" #include "runtime/core/core_vtable_builder.h" @@ -101,56 +105,35 @@ size_t EcmaLanguageContext::GetStringSize(const ObjectHeader *string_object) con return string->ObjectSize(); } -void EcmaLanguageContext::RestoreEnv(Frame *current_iframe, int inlining_depth) const +using VRegType = panda::compiler::VRegInfo::VRegType; +void EcmaLanguageContext::RestoreEnv(Frame *current_iframe, const StackWalker::EnvData &env_data) const { - JSThread *js_thread = JSThread::GetCurrentRaw(); - auto current_env = js_thread->GetEcmascriptEnv(); - ecmascript::EcmascriptEnvironment *prev_env = nullptr; - - while (inlining_depth >= 0) { - auto *iframe_env = ecmascript::JSExtFrame::FromFrame(current_iframe)->GetExtData(); - iframe_env->SetConstantPool(current_env->GetConstantPool()); - iframe_env->SetLexicalEnv(current_env->GetLexicalEnv()); - iframe_env->SetThisFunc(current_env->GetThisFunc()); - iframe_env->SetPrevEnvironment(current_env->GetPrevEnvironment()); - if (prev_env != nullptr) { - prev_env->SetPrevEnvironment(iframe_env); - } else { - js_thread->SetEcmascriptEnv(iframe_env); - } - prev_env = iframe_env; - current_iframe = current_iframe->GetPrevFrame(); - current_env = current_env->GetPrevEnvironment(); - inlining_depth--; - } + auto *iframe_env = ecmascript::JSExtFrame::FromFrame(current_iframe)->GetExtData(); + iframe_env->SetThisFunc( + ecmascript::JSFunction::Cast(ecmascript::JSTaggedValue(env_data[VRegType::THIS_FUNC]).GetHeapObject())); + iframe_env->SetConstantPool(ecmascript::ConstantPool::Cast(env_data[VRegType::CONST_POOL])); + iframe_env->SetLexicalEnv(ecmascript::LexicalEnv::Cast(env_data[VRegType::LEX_ENV])); } -void EcmaLanguageContext::RestorePrevEnv() const +void EcmaLanguageContext::InitializeOsrCframeSlots(Span param_slots) const { - JSThread *js_thread = JSThread::GetCurrentRaw(); - ecmascript::EcmascriptEnvironment *current_env = js_thread->GetEcmascriptEnv(); - ecmascript::EcmascriptEnvironment *prev_env = current_env->GetPrevEnvironment(); - - // Update EcmascriptEnv - js_thread->SetEcmascriptEnv(prev_env); + std::fill(param_slots.begin(), param_slots.end(), TaggedValue::VALUE_UNDEFINED); } -void EcmaLanguageContext::InitializeOsrCframeSlots(ManagedThread *thread, Span param_slots, - Span lang_ext_slots) const +uint64_t EcmaLanguageContext::GetOsrEnv(const Frame *iframe, compiler::VRegInfo vreg_info) const { - auto *cframe_js_env {reinterpret_cast(lang_ext_slots.Data())}; - CHECK_GE(lang_ext_slots.SizeBytes(), sizeof(ecmascript::EcmascriptEnvironment)); - - auto *js_thread {JSThread::Cast(thread)}; - auto *js_env {ecmascript::JSFrame::GetJSEnv(js_thread->GetCurrentFrame())}; - cframe_js_env->SetConstantPool(js_env->GetConstantPool()); - cframe_js_env->SetLexicalEnv(js_env->GetLexicalEnv()); - cframe_js_env->SetThisFunc(js_env->GetThisFunc()); - cframe_js_env->SetPrevEnvironment(js_env->GetPrevEnvironment()); - - std::fill(param_slots.begin(), param_slots.end(), TaggedValue::VALUE_UNDEFINED); - - js_thread->SetEcmascriptEnv(cframe_js_env); + auto env = ecmascript::JSFrame::GetJSEnv(iframe); + switch (vreg_info.GetVRegType()) { + case compiler::VRegInfo::VRegType::THIS_FUNC: + return TaggedValue(env->GetThisFunc()).GetRawData(); + case compiler::VRegInfo::VRegType::CONST_POOL: + return TaggedValue(env->GetConstantPool()).GetRawData(); + case compiler::VRegInfo::VRegType::LEX_ENV: + return TaggedValue(env->GetLexicalEnv()).GetRawData(); + default: + UNREACHABLE(); + return 0; + } } } // namespace panda diff --git a/runtime/ecma_language_context.h b/runtime/ecma_language_context.h index df57a0c21..79013806b 100644 --- a/runtime/ecma_language_context.h +++ b/runtime/ecma_language_context.h @@ -302,17 +302,16 @@ public: size_t GetStringSize(const ObjectHeader *string_object) const override; - void RestoreEnv(Frame *current_iframe, int inlining_depth) const override; - - void RestorePrevEnv() const override; + void RestoreEnv(Frame *current_iframe, const StackWalker::EnvData &env_data) const override; bool IsEnabledCHA() const override { return false; } - void InitializeOsrCframeSlots(ManagedThread *thread, Span param_slots, - Span lang_ext_slots) const override; + void InitializeOsrCframeSlots(Span param_slots) const override; + + uint64_t GetOsrEnv(const Frame *iframe, compiler::VRegInfo vreg_info) const override; }; } // namespace panda diff --git a/runtime/ecma_runtime.yaml b/runtime/ecma_runtime.yaml index 2764c9182..8e7d4fd49 100644 --- a/runtime/ecma_runtime.yaml +++ b/runtime/ecma_runtime.yaml @@ -98,7 +98,7 @@ intrinsics: static: true signature: ret: any - args: [string_id] + args: [string_id, any] impl: panda::ecmascript::intrinsics::Ldbigint - name: Ldnull @@ -323,7 +323,7 @@ intrinsics: exception: true signature: ret: any - args: [any, acc, u16] + args: [any, acc, u16, any] impl: panda::ecmascript::intrinsics::LdObjByValue fast_path: FastPathLdObjByValue set_flags: [heap_inv] @@ -348,7 +348,7 @@ intrinsics: exception: true signature: ret: any - args: [any, any, acc, u16] + args: [any, any, acc, u16, any] impl: panda::ecmascript::intrinsics::StObjByValue fast_path: FastPathStObjByValue set_flags: [heap_inv] @@ -567,7 +567,7 @@ intrinsics: exception: true signature: ret: any - args: [method_id, any] + args: [method_id, any, any] impl: panda::ecmascript::intrinsics::DefinefuncDyn - name: DefineNCFuncDyn @@ -578,7 +578,7 @@ intrinsics: exception: true signature: ret: any - args: [method_id, any, acc] + args: [method_id, any, acc, any] impl: panda::ecmascript::intrinsics::DefineNCFuncDyn - name: NewobjDynrange @@ -771,7 +771,7 @@ intrinsics: exception: true signature: ret: any - args: [u16] + args: [u16, any] impl: panda::ecmascript::intrinsics::NewlexenvDyn - name: CopylexenvDyn @@ -781,7 +781,7 @@ intrinsics: static: true signature: ret: any - args: [] + args: [any] impl: panda::ecmascript::intrinsics::CopylexenvDyn - name: StLexVarDyn @@ -792,8 +792,9 @@ intrinsics: exception: true signature: ret: void - args: [u16, u16, acc] + args: [u16, u16, acc, any] impl: panda::ecmascript::intrinsics::StLexVarDyn + set_flags: [heap_inv] - name: StLexDyn space: ecmascript @@ -803,8 +804,9 @@ intrinsics: exception: true signature: ret: any - args: [string_id, u16, u16, acc] + args: [string_id, u16, u16, acc, any, any] impl: panda::ecmascript::intrinsics::StLexDyn + set_flags: [heap_inv] - name: LdLexVarDyn space: ecmascript @@ -813,9 +815,9 @@ intrinsics: static: true signature: ret: any - args: [u16, u16] + args: [u16, u16, any] impl: panda::ecmascript::intrinsics::LdLexVarDyn - clear_flags: [no_dce, runtime_call] + clear_flags: [no_dce, runtime_call, require_state] codegen_func: LdLexVarDyn - name: LdLexDyn @@ -826,7 +828,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, u16, u16] + args: [string_id, u16, u16, any, any] impl: panda::ecmascript::intrinsics::LdLexDyn - name: LdlexenvDyn @@ -847,8 +849,8 @@ intrinsics: method_name: popLexenvDyn static: true signature: - ret: void - args: [] + ret: any + args: [any] impl: panda::ecmascript::intrinsics::PopLexenvDyn - name: GetUnmappedArgs @@ -970,7 +972,7 @@ intrinsics: exception: true signature: ret: any - args: [method_id, any] + args: [method_id, any, any] impl: panda::ecmascript::intrinsics::DefineGeneratorFunc - name: CreateIterResultObj @@ -1095,7 +1097,7 @@ intrinsics: exception: true signature: ret: any - args: [method_id, any] + args: [method_id, any, any] impl: panda::ecmascript::intrinsics::DefineAsyncGeneratorFunc - name: DefineAsyncFunc @@ -1106,7 +1108,7 @@ intrinsics: exception: true signature: ret: any - args: [method_id, any] + args: [method_id, any, any] impl: panda::ecmascript::intrinsics::DefineAsyncFunc - name: AsyncFunctionEnter @@ -1199,7 +1201,7 @@ intrinsics: exception: true signature: ret: void - args: [string_id] + args: [string_id, any] impl: panda::ecmascript::intrinsics::ThrowConstAssignment - name: ThrowTdz @@ -1210,7 +1212,7 @@ intrinsics: exception: true signature: ret: void - args: [string_id] + args: [string_id, any] impl: panda::ecmascript::intrinsics::ThrowTdz - name: Copyrestargs @@ -1267,7 +1269,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any] + args: [string_id, any, any] impl: panda::ecmascript::intrinsics::GetMethod set_flags: [heap_inv] @@ -1291,7 +1293,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, u16] + args: [string_id, u16, any, any] impl: panda::ecmascript::intrinsics::TryLdGlobalByName set_flags: [heap_inv] @@ -1303,7 +1305,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, acc, u16] + args: [string_id, acc, u16, any, any] impl: panda::ecmascript::intrinsics::TryStGlobalByName set_flags: [heap_inv] @@ -1315,7 +1317,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, u16] + args: [string_id, u16, any, any] impl: panda::ecmascript::intrinsics::LdGlobalVar fast_path: FastPathLdGlobalVar set_flags: [heap_inv] @@ -1328,7 +1330,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, acc, u16] + args: [string_id, acc, u16, any, any] impl: panda::ecmascript::intrinsics::StGlobalVar fast_path: FastPathStGlobalVar set_flags: [heap_inv] @@ -1341,7 +1343,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, acc, u16] + args: [string_id, acc, u16, any, any] impl: panda::ecmascript::intrinsics::LdObjByName fast_path: FastPathLdObjByName set_flags: [heap_inv] @@ -1354,7 +1356,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any, acc, u16] + args: [string_id, any, acc, u16, any, any] impl: panda::ecmascript::intrinsics::StObjByName fast_path: FastPathStObjByName set_flags: [heap_inv] @@ -1557,7 +1559,7 @@ intrinsics: exception: true signature: ret: any - args: [u16] + args: [u16, any] impl: panda::ecmascript::intrinsics::CreateObjectWithBuffer - name: CopyDataProperties @@ -1604,7 +1606,7 @@ intrinsics: exception: true signature: ret: any - args: [u16] + args: [u16, any] impl: panda::ecmascript::intrinsics::CreateArrayWithBuffer - name: CreateRegExpWithLiteral @@ -1615,7 +1617,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, u8] + args: [string_id, u8, any] impl: panda::ecmascript::intrinsics::CreateRegExpWithLiteral @@ -1627,7 +1629,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any, acc] + args: [string_id, any, acc, any] impl: panda::ecmascript::intrinsics::StOwnByName set_flags: [heap_inv] @@ -1756,7 +1758,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id] + args: [string_id, any] impl: panda::ecmascript::intrinsics::ImportModule clear_flags: [no_dce] @@ -1768,7 +1770,7 @@ intrinsics: exception: true signature: ret: void - args: [string_id, acc] + args: [string_id, acc, any] impl: panda::ecmascript::intrinsics::StModuleVar - name: CopyModule @@ -1790,7 +1792,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any] + args: [string_id, any, any] impl: panda::ecmascript::intrinsics::LdModvarByName clear_flags: [no_dce] set_flags: [heap_inv] @@ -1825,7 +1827,7 @@ intrinsics: exception: true signature: ret: any - args: [method_id, u16, any, any] + args: [method_id, u16, any, any, any] impl: panda::ecmascript::intrinsics::DefineClassWithBuffer - name: ClassFieldAdd @@ -1847,7 +1849,7 @@ intrinsics: exception: true signature: ret: void - args: [u16, any, acc] + args: [u16, any, acc, any] impl: panda::ecmascript::intrinsics::DefineClassPrivateFields - name: ClassPrivateMethodOrAccessorAdd @@ -1869,7 +1871,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any, any, acc] + args: [string_id, any, any, acc, any] impl: panda::ecmascript::intrinsics::ClassPrivateFieldAdd - name: ClassPrivateFieldGet @@ -1880,7 +1882,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any, any] + args: [string_id, any, any, any] impl: panda::ecmascript::intrinsics::ClassPrivateFieldGet - name: ClassPrivateFieldSet @@ -1891,7 +1893,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any, any, acc] + args: [string_id, any, any, acc, any] impl: panda::ecmascript::intrinsics::ClassPrivateFieldSet - name: ClassPrivateFieldIn @@ -1902,7 +1904,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any, acc] + args: [string_id, any, acc, any] impl: panda::ecmascript::intrinsics::ClassPrivateFieldIn - name: SuperCall @@ -1937,7 +1939,7 @@ intrinsics: exception: true signature: ret: any - args: [method_id, any, acc] + args: [method_id, any, acc, any] impl: panda::ecmascript::intrinsics::DefineMethod - name: LdSuperByName @@ -1948,7 +1950,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, acc] + args: [string_id, acc, any, any] impl: panda::ecmascript::intrinsics::LdSuperByName set_flags: [heap_inv] @@ -1960,7 +1962,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any, acc] + args: [string_id, any, acc, any, any] impl: panda::ecmascript::intrinsics::StSuperByName set_flags: [heap_inv] @@ -1972,7 +1974,7 @@ intrinsics: exception: true signature: ret: any - args: [any, any, acc] + args: [any, any, acc, any] impl: panda::ecmascript::intrinsics::StSuperByValue set_flags: [heap_inv] @@ -1984,7 +1986,7 @@ intrinsics: exception: true signature: ret: any - args: [any, acc] + args: [any, acc, any] impl: panda::ecmascript::intrinsics::LdSuperByValue set_flags: [heap_inv] @@ -1996,7 +1998,7 @@ intrinsics: exception: true signature: ret: any - args: [u16, acc] + args: [u16, acc, any] impl: panda::ecmascript::intrinsics::CreateObjectHavingMethod - name: ThrowIfSuperNotCorrectCall @@ -2017,7 +2019,7 @@ intrinsics: static: true signature: ret: any - args: [] + args: [any] impl: panda::ecmascript::intrinsics::LdHomeObject clear_flags: [no_dce] @@ -2051,7 +2053,7 @@ intrinsics: exception: true signature: ret: any - args: [u16] + args: [u16, any] impl: panda::ecmascript::intrinsics::LdEvalBindings - name: DirectEval @@ -2073,7 +2075,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, acc] + args: [string_id, acc, any] impl: panda::ecmascript::intrinsics::LdEvalVar - name: StEvalVar @@ -2084,7 +2086,7 @@ intrinsics: exception: true signature: ret: any - args: [string_id, any, acc] + args: [string_id, any, acc, any] impl: panda::ecmascript::intrinsics::StEvalVar - name: Debugger @@ -2134,30 +2136,6 @@ intrinsics: impl: panda::ecmascript::intrinsics::IsNan use_thread: false -- name: GetEcmaConstantPool - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: GetEcmaConstantPool - static: true - codegen_func: GetEcmaConstantPool - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::GetEcmaConstantPool - clear_flags: [no_dce, barrier, require_state, runtime_call] - -- name: GetEcmaThisFunc - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: GetEcmaThisFunc - static: true - codegen_func: GetEcmaThisFunc - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::GetEcmaThisFunc - clear_flags: [no_dce, barrier, require_state, runtime_call] - - name: GetWeakReferent space: ecmascript class_name: Ecmascript.Intrinsics @@ -2287,3 +2265,4 @@ intrinsics: ret: any args: [any, any, any] codegen_func: CreateResolveAllocResult + set_flags: [can_throw] diff --git a/runtime/ecma_vm.cpp b/runtime/ecma_vm.cpp index 9ff93ce4d..526474811 100644 --- a/runtime/ecma_vm.cpp +++ b/runtime/ecma_vm.cpp @@ -950,17 +950,22 @@ void EcmaVM::SetupRegExpResultCache() void EcmaVM::HandleLdaStr(Frame *frame, BytecodeId string_id) { - auto value = GetConstantPool(GetJSThread())->GetObjectFromCache(string_id.AsIndex()); + auto cp = ConstantPool::Cast(JSFrame::GetJSEnv(frame)->GetConstantPool()); + auto value = cp->GetObjectFromCache(string_id.AsIndex()); frame->GetAcc().Set(value.GetRawData()); } -coretypes::String *EcmaVM::ResolveStringFromCompiledCode([[maybe_unused]] const panda_file::File &pf, - panda_file::File::EntityId id) +coretypes::String *EcmaVM::ResolveString(ConstantPool *cp, panda_file::File::EntityId id) { - auto value = GetConstantPool(GetJSThread())->GetObjectFromCache(id.GetOffset()); + auto value = cp->GetObjectFromCache(id.GetOffset()); return coretypes::String::Cast(value.GetHeapObject()); } +coretypes::String *EcmaVM::ResolveString(Frame *frame, panda_file::File::EntityId id) +{ + return EcmaVM::ResolveString(ConstantPool::Cast(JSFrame::GetJSEnv(frame)->GetConstantPool()), id); +} + std::unique_ptr EcmaVM::OpenPandaFile(std::string_view location) { panda_file::File::OpenMode open_mode = GetLanguageContext().GetBootPandaFilesOpenMode(); @@ -982,13 +987,7 @@ coretypes::String *EcmaVM::GetNonMovableString([[maybe_unused]] const panda_file return nullptr; } -void EcmaVM::HandleReturnFrame() -{ - JSThread *js_thread = GetAssociatedJSThread(); - - // Update EmcascriptEnv - js_thread->SetEcmascriptEnv(js_thread->GetEcmascriptEnv()->GetPrevEnvironment()); -} +void EcmaVM::HandleReturnFrame() {} void EcmaVM::VisitVmRoots(const GCRootVisitor &visitor) { diff --git a/runtime/ecma_vm.h b/runtime/ecma_vm.h index ea77d595b..9e7c26d68 100644 --- a/runtime/ecma_vm.h +++ b/runtime/ecma_vm.h @@ -26,6 +26,7 @@ #include "plugins/ecmascript/runtime/global_handle_collection.h" #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/js_method.h" +#include "plugins/ecmascript/runtime/interpreter/js_frame.h" #include "plugins/ecmascript/runtime/js_runtime_options.h" #include "plugins/ecmascript/runtime/mem/ecma_string.h" #include "plugins/ecmascript/runtime/mem/object_xray.h" @@ -45,6 +46,7 @@ class File; } // namespace panda_file namespace ecmascript { +class ConstantPool; class GlobalEnv; class ObjectFactory; class RegExpParserCache; @@ -200,8 +202,9 @@ public: return coretypes::String::Cast(str); } - coretypes::String *ResolveStringFromCompiledCode(const panda_file::File &pf, - panda_file::File::EntityId id) override; + coretypes::String *ResolveString(ConstantPool *cp, panda_file::File::EntityId id); + + coretypes::String *ResolveString(Frame *frame, panda_file::File::EntityId id) override; void HandleReturnFrame() override; diff --git a/runtime/ic/ic_runtime_stub-inl.h b/runtime/ic/ic_runtime_stub-inl.h index 95b35f571..9f5b0ab4c 100644 --- a/runtime/ic/ic_runtime_stub-inl.h +++ b/runtime/ic/ic_runtime_stub-inl.h @@ -36,35 +36,32 @@ #include "plugins/ecmascript/runtime/runtime_call_id.h" namespace panda::ecmascript { -bool ICRuntimeStub::HaveICForFunction(JSThread *thread) +bool ICRuntimeStub::HaveICForFunction(JSFunction *func) { - auto *func = JSFunction::Cast(GetThisFunc(thread).GetHeapObject()); return !func->GetProfileTypeInfo().IsUndefined(); } -uint32_t ICRuntimeStub::MapSlotId(JSThread *thread, uint32_t slot_id) +uint32_t ICRuntimeStub::MapSlotId(JSFunction *func, uint32_t slot_id) { - auto *func = JSFunction::Cast(GetThisFunc(thread).GetHeapObject()); uint8_t *mapping = func->GetMethod()->GetICMapping(); ASSERT(mapping != nullptr); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) return mapping[slot_id]; } -ProfileTypeInfo *ICRuntimeStub::GetRuntimeProfileTypeInfo(JSThread *thread) +ProfileTypeInfo *ICRuntimeStub::GetRuntimeProfileTypeInfo(JSFunction *func) { - auto *func = JSFunction::Cast(GetThisFunc(thread).GetHeapObject()); JSTaggedValue profile_type_info = func->GetProfileTypeInfo(); return ProfileTypeInfo::Cast(profile_type_info.GetTaggedObject()); } -JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, JSTaggedValue global_value, JSTaggedValue key, - uint32_t slot_id, bool is_try_load) +JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, JSFunction *func, JSTaggedValue global_value, + JSTaggedValue key, uint32_t slot_id, bool is_try_load) { INTERPRETER_TRACE(thread, LoadGlobalICByName); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); + ASSERT(HaveICForFunction(func)); + slot_id = MapSlotId(func, slot_id); + ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(func); JSTaggedValue handler = profile_type_info->Get(slot_id); if (handler.IsHeapObject()) { auto result = LoadGlobal(handler); @@ -82,13 +79,14 @@ JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, JSTaggedValue return ic_runtime.LoadMiss(receiver_handle, key_handle); } -JSTaggedValue ICRuntimeStub::StoreGlobalICByName(JSThread *thread, JSTaggedValue global_value, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id, bool is_try_store) +JSTaggedValue ICRuntimeStub::StoreGlobalICByName(JSThread *thread, JSFunction *func, JSTaggedValue global_value, + JSTaggedValue key, JSTaggedValue value, uint32_t slot_id, + bool is_try_store) { INTERPRETER_TRACE(thread, StoreGlobalICByName); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); + ASSERT(HaveICForFunction(func)); + slot_id = MapSlotId(func, slot_id); + ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(func); JSTaggedValue handler = profile_type_info->Get(slot_id); if (handler.IsHeapObject()) { auto result = StoreGlobal(thread, value, handler); @@ -123,12 +121,13 @@ JSTaggedValue ICRuntimeStub::CheckPolyHClass(JSTaggedValue cached_value, JSHClas return JSTaggedValue::Hole(); } -JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, uint32_t slot_id) +JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, JSFunction *func, JSTaggedValue receiver, JSTaggedValue key, + uint32_t slot_id) { INTERPRETER_TRACE(thread, LoadICByName); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); + ASSERT(HaveICForFunction(func)); + slot_id = MapSlotId(func, slot_id); + ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(func); JSTaggedValue hclass_value = profile_type_info->Get(slot_id); if (hclass_value.IsHole()) { return JSTaggedValue::Hole(); @@ -157,13 +156,13 @@ JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, JSTaggedValue receiv return LoadMissedICByName(thread, profile_type_info, receiver, key, slot_id); } -JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - uint32_t slot_id) +JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, JSFunction *func, JSTaggedValue receiver, + JSTaggedValue key, uint32_t slot_id) { INTERPRETER_TRACE(thread, LoadICByValue); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); + ASSERT(HaveICForFunction(func)); + slot_id = MapSlotId(func, slot_id); + ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(func); JSTaggedValue first_value = profile_type_info->Get(slot_id); if (first_value.IsHole()) { return JSTaggedValue::Hole(); @@ -203,13 +202,13 @@ JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, JSTaggedValue recei return LoadMissedICByValue(thread, profile_type_info, receiver, key, slot_id); } -JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id) +JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, JSFunction *func, JSTaggedValue receiver, + JSTaggedValue key, JSTaggedValue value, uint32_t slot_id) { INTERPRETER_TRACE(thread, StoreICByValue); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); + ASSERT(HaveICForFunction(func)); + slot_id = MapSlotId(func, slot_id); + ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(func); JSTaggedValue first_value = profile_type_info->Get(slot_id); if (first_value.IsHole()) { return JSTaggedValue::Hole(); @@ -252,13 +251,13 @@ JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, JSTaggedValue rece return StoreMissedICByValue(thread, profile_type_info, receiver, key, value, slot_id); } -JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id) +JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, JSFunction *func, JSTaggedValue receiver, + JSTaggedValue key, JSTaggedValue value, uint32_t slot_id) { INTERPRETER_TRACE(thread, StoreICByName); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); + ASSERT(HaveICForFunction(func)); + slot_id = MapSlotId(func, slot_id); + ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(func); JSTaggedValue hclass_value = profile_type_info->Get(slot_id); if (hclass_value.IsHole()) { return JSTaggedValue::Hole(); diff --git a/runtime/ic/ic_runtime_stub.h b/runtime/ic/ic_runtime_stub.h index d72102925..bb77bde5d 100644 --- a/runtime/ic/ic_runtime_stub.h +++ b/runtime/ic/ic_runtime_stub.h @@ -16,6 +16,7 @@ #ifndef ECMASCRIPT_IC_IC_RUNTIME_STUB_H_ #define ECMASCRIPT_IC_IC_RUNTIME_STUB_H_ +#include "plugins/ecmascript/runtime/js_function.h" #include "plugins/ecmascript/runtime/base/config.h" #include "plugins/ecmascript/runtime/js_tagged_value.h" #include "plugins/ecmascript/runtime/property_attributes.h" @@ -42,17 +43,18 @@ public: return 4U; } - ARK_INLINE static inline bool HaveICForFunction(JSThread *thread); - ARK_INLINE static inline JSTaggedValue LoadGlobalICByName(JSThread *thread, JSTaggedValue global_value, - JSTaggedValue key, uint32_t slot_id, - bool is_try_load = false); - ARK_INLINE static inline JSTaggedValue StoreGlobalICByName(JSThread *thread, JSTaggedValue global_value, - JSTaggedValue key, JSTaggedValue value, uint32_t slot_id, + ARK_INLINE static inline bool HaveICForFunction(JSFunction *func); + ARK_INLINE static inline JSTaggedValue LoadGlobalICByName(JSThread *thread, JSFunction *func, + JSTaggedValue global_value, JSTaggedValue key, + uint32_t slot_id, bool is_try_load = false); + ARK_INLINE static inline JSTaggedValue StoreGlobalICByName(JSThread *thread, JSFunction *func, + JSTaggedValue global_value, JSTaggedValue key, + JSTaggedValue value, uint32_t slot_id, bool is_try_store = false); - ARK_INLINE static inline JSTaggedValue LoadICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - uint32_t slot_id); - ARK_INLINE static inline JSTaggedValue StoreICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id); + ARK_INLINE static inline JSTaggedValue LoadICByName(JSThread *thread, JSFunction *func, JSTaggedValue receiver, + JSTaggedValue key, uint32_t slot_id); + ARK_INLINE static inline JSTaggedValue StoreICByName(JSThread *thread, JSFunction *func, JSTaggedValue receiver, + JSTaggedValue key, JSTaggedValue value, uint32_t slot_id); ARK_INLINE static inline JSTaggedValue CheckPolyHClass(JSTaggedValue cached_value, JSHClass *hclass); static inline JSTaggedValue LoadICWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder, JSTaggedValue handler); @@ -69,18 +71,18 @@ public: ARK_INLINE static inline JSTaggedValue StoreGlobal(JSThread *thread, JSTaggedValue value, JSTaggedValue handler); ARK_INLINE static inline JSTaggedValue LoadPrototype(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler); - ARK_INLINE static inline JSTaggedValue LoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - uint32_t slot_id); - ARK_INLINE static inline JSTaggedValue StoreICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id); + ARK_INLINE static inline JSTaggedValue LoadICByValue(JSThread *thread, JSFunction *func, JSTaggedValue receiver, + JSTaggedValue key, uint32_t slot_id); + ARK_INLINE static inline JSTaggedValue StoreICByValue(JSThread *thread, JSFunction *func, JSTaggedValue receiver, + JSTaggedValue key, JSTaggedValue value, uint32_t slot_id); ARK_INLINE static inline JSTaggedValue LoadElement(JSObject *receiver, JSTaggedValue key); ARK_INLINE static inline JSTaggedValue StoreElement(JSThread *thread, JSObject *receiver, JSTaggedValue key, JSTaggedValue value, uint32_t handler_info); ARK_INLINE static inline uint32_t TryToElementsIndex(JSTaggedValue key); private: - static inline uint32_t MapSlotId(JSThread *thread, uint32_t slot_id); - static inline ProfileTypeInfo *GetRuntimeProfileTypeInfo(JSThread *thread); + static inline uint32_t MapSlotId(JSFunction *func, uint32_t slot_id); + static inline ProfileTypeInfo *GetRuntimeProfileTypeInfo(JSFunction *func); ARK_NOINLINE static JSTaggedValue LoadMissedICByName(JSThread *thread, ProfileTypeInfo *profile_type_array, JSTaggedValue receiver, JSTaggedValue key, uint32_t slot_id); ARK_NOINLINE static JSTaggedValue StoreMissedICByName(JSThread *thread, ProfileTypeInfo *profile_type_info, diff --git a/runtime/interpreter/ecma-interpreter-inl.h b/runtime/interpreter/ecma-interpreter-inl.h index a6f2a7b7f..97522c710 100644 --- a/runtime/interpreter/ecma-interpreter-inl.h +++ b/runtime/interpreter/ecma-interpreter-inl.h @@ -55,6 +55,19 @@ namespace panda::ecmascript { SetAccFromTaggedValue(result); \ } +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define INTRINSIC_CALL_CHECK_SETACC_SETENV(intrinsic_call) \ + { \ + JSTaggedValue result(intrinsic_call); \ + if (UNLIKELY(result.IsException())) { \ + this->MoveToExceptionHandler(); \ + return; \ + } \ + ASSERT(!this->GetJSThread()->HasPendingException()); \ + SetLexicalEnv(result); \ + SetAccFromTaggedValue(result); \ + } + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define INTERPRETER_RETURN_IF_ABRUPT(result) \ do { \ @@ -227,6 +240,41 @@ public: return JSFunctionBase::GetFunctionName(thread, JSHandle(this_func)); } + ALWAYS_INLINE EcmascriptEnvironment *GetCurrentEnv() + { + return JSFrame::GetJSEnv(this->GetFrame()); + } + + ALWAYS_INLINE uint64_t GetThisFuncRawValue() + { + return JSTaggedValue(GetCurrentEnv()->GetThisFunc()).GetRawData(); + } + + ALWAYS_INLINE ConstantPool *GetConstantPool() + { + return ConstantPool::Cast(GetCurrentEnv()->GetConstantPool()); + } + + ALWAYS_INLINE uint64_t GetConstantPoolRawValue() + { + return JSTaggedValue(GetCurrentEnv()->GetConstantPool()).GetRawData(); + } + + ALWAYS_INLINE LexicalEnv *GetLexicalEnv() + { + return LexicalEnv::Cast(GetCurrentEnv()->GetLexicalEnv()); + } + + ALWAYS_INLINE uint64_t GetLexicalEnvRawValue() + { + return JSTaggedValue(GetCurrentEnv()->GetLexicalEnv()).GetRawData(); + } + + ALWAYS_INLINE void SetLexicalEnv(JSTaggedValue lex_env) + { + return GetCurrentEnv()->SetLexicalEnv(lex_env.GetTaggedObject()); + } + template ALWAYS_INLINE void HandleEcmaReturnDyn() { @@ -284,11 +332,6 @@ public: // Redefine method from base class ALWAYS_INLINE void HandleReturnStackless() { - JSThread *js_thread = GetJSThread(); - - // Update EcmascirptEnv - js_thread->SetEcmascriptEnv(js_thread->GetEcmascriptEnv()->GetPrevEnvironment()); - interpreter::InstructionHandler::HandleReturnStackless(); } @@ -355,14 +398,8 @@ public: return; } - EcmascriptEnvironment *prev_env = js_thread->GetEcmascriptEnv(); - if (method->HasCompiledCode()) { // AOT, JIT this->template CallCompiledCode(method); - // Restore EcmascriptEnvironment if epilogue was not executed - if (UNLIKELY(js_thread->HasPendingException())) { - js_thread->SetEcmascriptEnv(prev_env); - } } else { // Interpreter [[maybe_unused]] EcmaHandleScope scope(js_thread); @@ -385,10 +422,7 @@ public: // Init EcmascriptEnvironment EcmascriptEnvironment *new_env = JSFrame::GetJSEnv(this->GetFrame()); - new (new_env) EcmascriptEnvironment(prev_env, constant_pool, lexical_env.GetHeapObject(), *function_handle); - - // Update EcmascriptEnvironment - js_thread->SetEcmascriptEnv(new_env); + new (new_env) EcmascriptEnvironment(constant_pool, lexical_env.GetHeapObject(), *function_handle); } } @@ -439,19 +473,12 @@ public: } SetAccFromTaggedValue(this_obj); - EcmascriptEnvironment *prev_env = thread->GetEcmascriptEnv(); - if (UNLIKELY(method->HasCompiledCode())) { [[maybe_unused]] EcmaHandleScope handle_scope(thread); JSHandle this_handle(thread, this_obj); // 'this' object to be set from acc in i2c this->template CallCompiledCode(method); - // Restore EcmascriptEnvironment if epilogue was not executed - if (UNLIKELY(thread->HasPendingException())) { - thread->SetEcmascriptEnv(prev_env); - return; - } auto acc_in = GetAccAsTaggedValue(); // gc may fire @@ -470,7 +497,7 @@ public: return; } } else { - method->DecrementHotnessCounter(0, nullptr); + method->DecrementHotnessCounter(0, nullptr, false, ctor); // Call stackless interpreter this->template CallInterpreterStackless, FORMAT, @@ -490,11 +517,7 @@ public: ConstantPool::Cast(ctor_func_handle->GetConstantPool().GetHeapObject()); JSTaggedValue lexical_env = ctor_func_handle->GetLexicalEnv(); EcmascriptEnvironment *new_env = JSFrame::GetJSEnv(this->GetFrame()); - new (new_env) - EcmascriptEnvironment(prev_env, constant_pool, lexical_env.GetHeapObject(), *ctor_func_handle); - - // Update EcmascriptEnvironment - thread->SetEcmascriptEnv(new_env); + new (new_env) EcmascriptEnvironment(constant_pool, lexical_env.GetHeapObject(), *ctor_func_handle); } return; @@ -782,7 +805,9 @@ public: auto big_int = this->GetInst().template GetId(); LOG_INST() << "ld.bigint " << big_int << "n"; - INTRINSIC_CALL_SETACC(intrinsics::Ldbigint(this->GetJSThread(), big_int.AsIndex())); + auto thread = this->GetJSThread(); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_SETACC(intrinsics::Ldbigint(thread, big_int.AsIndex(), cp)); this->template MoveToNextInst(); } @@ -790,7 +815,7 @@ public: ALWAYS_INLINE void HandleEcmaLdlexenvdyn() { LOG_INST() << "ldlexenvDyn "; - INTRINSIC_CALL_SETACC(intrinsics::LdlexenvDyn(this->GetJSThread())); + SetAccFromTaggedValue(JSTaggedValue(GetLexicalEnvRawValue())); this->template MoveToNextInst(); } @@ -1090,7 +1115,7 @@ public: ALWAYS_INLINE void HandleEcmaThrowconstassignment() { auto string_id = this->GetInst().template GetId(); - auto prop = GetConstantPool(this->GetJSThread())->GetObjectFromCache(string_id.AsIndex()); + auto prop = GetConstantPool()->GetObjectFromCache(string_id.AsIndex()); LOG_INST() << "throwconstassignment " << "string_id:" << ConvertToPandaString(EcmaString::Cast(prop.GetHeapObject())); @@ -1476,7 +1501,8 @@ public: << " v" << v0 << std::hex << method_id; uint64_t env = GetRegAsTaggedValue(v0).GetRawData(); - INTRINSIC_CALL_CHECK_SETACC(intrinsics::DefinefuncDyn(this->GetJSThread(), method_id.AsIndex(), env)); + uint64_t cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::DefinefuncDyn(this->GetJSThread(), method_id.AsIndex(), env, cp)); this->template MoveToNextInst(); } @@ -1491,8 +1517,9 @@ public: uint64_t env = GetRegAsTaggedValue(v0).GetRawData(); uint64_t home_object = GetAccAsTaggedValue().GetRawData(); + uint64_t cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::DefineNCFuncDyn(this->GetJSThread(), method_id.AsIndex(), env, home_object)); + intrinsics::DefineNCFuncDyn(this->GetJSThread(), method_id.AsIndex(), env, home_object, cp)); this->template MoveToNextInst(); } @@ -1508,8 +1535,9 @@ public: uint64_t home_object = GetAccAsTaggedValue().GetRawData(); SaveAccToFrame(); + auto cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::DefineMethod(this->GetJSThread(), method_id.AsIndex(), tagged_cur_env, home_object)); + intrinsics::DefineMethod(this->GetJSThread(), method_id.AsIndex(), tagged_cur_env, home_object, cp)); this->template MoveToNextInst(); } @@ -1604,8 +1632,8 @@ public: auto slot = this->GetInst().template GetImm(); LOG_INST() << "ldlexvardyn" << " level:" << level << " slot:" << slot; - - INTRINSIC_CALL_SETACC(intrinsics::LdLexVarDyn(this->GetJSThread(), level, slot)); + auto lex_env = GetLexicalEnvRawValue(); + INTRINSIC_CALL_SETACC(intrinsics::LdLexVarDyn(this->GetJSThread(), level, slot, lex_env)); this->template MoveToNextInst(); } @@ -1613,14 +1641,17 @@ public: ALWAYS_INLINE void HandleEcmaLdlexdyn() { auto string_id = this->GetInst().template GetId(); - auto prop = GetConstantPool(this->GetJSThread())->GetObjectFromCache(string_id.AsIndex()); + auto prop = GetConstantPool()->GetObjectFromCache(string_id.AsIndex()); auto level = this->GetInst().template GetImm(); auto slot = this->GetInst().template GetImm(); LOG_INST() << "ldlexdyn" << " string_id:" << ConvertToPandaString(EcmaString::Cast(prop.GetHeapObject())) << " level:" << level << " slot:" << slot; - INTRINSIC_CALL_CHECK_SETACC(intrinsics::LdLexDyn(string_id.AsIndex(), level, slot)); + auto cp = GetConstantPoolRawValue(); + auto lex_env = GetLexicalEnvRawValue(); + INTRINSIC_CALL_CHECK_SETACC( + intrinsics::LdLexDyn(this->GetJSThread(), string_id.AsIndex(), level, slot, cp, lex_env)); this->template MoveToNextInst(); } @@ -1634,7 +1665,8 @@ public: << " level:" << level << " slot:" << slot; uint64_t value = GetAccAsTaggedValue().GetRawData(); - intrinsics::StLexVarDyn(this->GetJSThread(), level, slot, value); + uint64_t lex_env = GetLexicalEnvRawValue(); + intrinsics::StLexVarDyn(this->GetJSThread(), level, slot, value, lex_env); this->template MoveToNextInst(); } @@ -1643,7 +1675,7 @@ public: ALWAYS_INLINE void HandleEcmaStlexdyn() { auto string_id = this->GetInst().template GetId(); - auto prop = GetConstantPool(this->GetJSThread())->GetObjectFromCache(string_id.AsIndex()); + auto prop = GetConstantPool()->GetObjectFromCache(string_id.AsIndex()); auto level = this->GetInst().template GetImm(); auto slot = this->GetInst().template GetImm(); LOG_INST() << "stlexdyn" @@ -1651,7 +1683,10 @@ public: << " level:" << level << " slot:" << slot; uint64_t value = GetAccAsTaggedValue().GetRawData(); - INTRINSIC_CALL_CHECK(intrinsics::StLexDyn(string_id.AsIndex(), level, slot, value)); + uint64_t cp = GetConstantPoolRawValue(); + uint64_t lex_env = GetLexicalEnvRawValue(); + INTRINSIC_CALL_CHECK_SETACC( + intrinsics::StLexDyn(this->GetJSThread(), string_id.AsIndex(), level, slot, value, cp, lex_env)); this->template MoveToNextInst(); } @@ -1664,7 +1699,8 @@ public: LOG_INST() << "newlexenvdyn" << " imm " << num_vars; - INTRINSIC_CALL_CHECK_SETACC(intrinsics::NewlexenvDyn(this->GetJSThread(), num_vars)); + auto lex_env = GetLexicalEnvRawValue(); + INTRINSIC_CALL_CHECK_SETACC_SETENV(intrinsics::NewlexenvDyn(this->GetJSThread(), num_vars, lex_env)); this->template MoveToNextInst(); } @@ -1673,7 +1709,8 @@ public: { LOG_INST() << "copylexenvdyn"; - INTRINSIC_CALL_CHECK_SETACC(intrinsics::CopylexenvDyn()); + auto lex_env = GetLexicalEnvRawValue(); + INTRINSIC_CALL_CHECK_SETACC_SETENV(intrinsics::CopylexenvDyn(lex_env)); this->template MoveToNextInst(); } @@ -1830,7 +1867,7 @@ public: ALWAYS_INLINE void HandleEcmaThrowtdz() { auto string_id = this->GetInst().template GetId(); - auto prop = GetConstantPool(this->GetJSThread())->GetObjectFromCache(string_id.AsIndex()); + auto prop = GetConstantPool()->GetObjectFromCache(string_id.AsIndex()); LOG_INST() << "intrinsic::throwundefinedifhole " << "string_id:" << ConvertToPandaString(EcmaString::Cast(prop.GetHeapObject())); @@ -1852,7 +1889,8 @@ public: uint64_t value = GetAccAsTaggedValue().GetRawData(); SaveAccToFrame(); - INTRINSIC_CALL_CHECK(intrinsics::StOwnByName(this->GetJSThread(), id.AsIndex(), obj, value)); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK(intrinsics::StOwnByName(this->GetJSThread(), id.AsIndex(), obj, value, cp)); RestoreAccFromFrame(); this->template MoveToNextInst(); } @@ -1882,7 +1920,9 @@ public: LOG_INST() << "createobjectwithbuffer" << " literalArrayId:" << literalarray_id.AsIndex(); - INTRINSIC_CALL_CHECK_SETACC(intrinsics::CreateObjectWithBuffer(this->GetJSThread(), literalarray_id.AsIndex())); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK_SETACC( + intrinsics::CreateObjectWithBuffer(this->GetJSThread(), literalarray_id.AsIndex(), cp)); this->template MoveToNextInst(); } @@ -1893,7 +1933,9 @@ public: LOG_INST() << "createarraywithbuffer" << " literalArrayId:" << literalarray_id.AsIndex(); - INTRINSIC_CALL_CHECK_SETACC(intrinsics::CreateArrayWithBuffer(this->GetJSThread(), literalarray_id.AsIndex())); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK_SETACC( + intrinsics::CreateArrayWithBuffer(this->GetJSThread(), literalarray_id.AsIndex(), cp)); this->template MoveToNextInst(); } @@ -1905,8 +1947,9 @@ public: LOG_INST() << "createregexpwithliteral" << " string_id: " << string_id << " flags:" << flags; + auto cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::CreateRegExpWithLiteral(this->GetJSThread(), string_id.AsIndex(), flags)); + intrinsics::CreateRegExpWithLiteral(this->GetJSThread(), string_id.AsIndex(), flags, cp)); this->template MoveToNextInst(); } @@ -1917,7 +1960,8 @@ public: LOG_INST() << "importmodule " << "string_id:" << std::hex << string_id.AsIndex(); - INTRINSIC_CALL_SETACC(intrinsics::ImportModule(this->GetJSThread(), string_id.AsIndex())); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_SETACC(intrinsics::ImportModule(this->GetJSThread(), string_id.AsIndex(), cp)); this->template MoveToNextInst(); } @@ -1931,7 +1975,8 @@ public: uint64_t value = GetAccAsTaggedValue().GetRawData(); SaveAccToFrame(); - intrinsics::StModuleVar(this->GetJSThread(), string_id.AsIndex(), value); + auto cp = GetConstantPoolRawValue(); + intrinsics::StModuleVar(this->GetJSThread(), string_id.AsIndex(), value, cp); RestoreAccFromFrame(); this->template MoveToNextInst(); } @@ -1961,7 +2006,8 @@ public: uint64_t module_obj = GetRegAsTaggedValue(v0).GetRawData(); - INTRINSIC_CALL_SETACC(intrinsics::LdModvarByName(this->GetJSThread(), string_id.AsIndex(), module_obj)); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_SETACC(intrinsics::LdModvarByName(this->GetJSThread(), string_id.AsIndex(), module_obj, cp)); this->template MoveToNextInst(); } @@ -1974,7 +2020,8 @@ public: LOG_INST() << "getmethod v" << v0 << " string_id:" << string_id; uint64_t obj = GetRegAsTaggedValue(v0).GetRawData(); - INTRINSIC_CALL_CHECK_SETACC(intrinsics::GetMethod(this->GetJSThread(), string_id.AsIndex(), obj)); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::GetMethod(this->GetJSThread(), string_id.AsIndex(), obj, cp)); this->template MoveToNextInst(); } @@ -2081,7 +2128,8 @@ public: << " v" << v0; uint64_t env = GetRegAsTaggedValue(v0).GetRawData(); - INTRINSIC_CALL_CHECK_SETACC(intrinsics::DefineGeneratorFunc(this->GetJSThread(), method_id.AsIndex(), env)); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::DefineGeneratorFunc(this->GetJSThread(), method_id.AsIndex(), env, cp)); this->template MoveToNextInst(); } @@ -2094,7 +2142,8 @@ public: << " v" << v0; uint64_t env = GetRegAsTaggedValue(v0).GetRawData(); - INTRINSIC_CALL_CHECK_SETACC(intrinsics::DefineAsyncFunc(this->GetJSThread(), method_id.AsIndex(), env)); + uint64_t cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::DefineAsyncFunc(this->GetJSThread(), method_id.AsIndex(), env, cp)); this->template MoveToNextInst(); } @@ -2107,8 +2156,9 @@ public: << " v" << v0; uint64_t env = GetRegAsTaggedValue(v0).GetRawData(); + auto cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::DefineAsyncGeneratorFunc(this->GetJSThread(), method_id.AsIndex(), env)); + intrinsics::DefineAsyncGeneratorFunc(this->GetJSThread(), method_id.AsIndex(), env, cp)); this->template MoveToNextInst(); } @@ -2205,9 +2255,9 @@ public: uint64_t receiver = GetRegAsTaggedValue(v0).GetRawData(); uint64_t prop_key = GetAccAsTaggedValue().GetRawData(); - + uint64_t func = GetThisFuncRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::LdObjByValue(this->GetJSThread(), receiver, prop_key, this->GetBytecodeOffset())); + intrinsics::LdObjByValue(this->GetJSThread(), receiver, prop_key, this->GetBytecodeOffset(), func)); this->template MoveToNextInst(); } @@ -2224,8 +2274,9 @@ public: uint64_t value = GetAccAsTaggedValue().GetRawData(); SaveAccToFrame(); + auto func = GetThisFuncRawValue(); INTRINSIC_CALL_CHECK( - intrinsics::StObjByValue(this->GetJSThread(), receiver, prop_key, value, this->GetBytecodeOffset())); + intrinsics::StObjByValue(this->GetJSThread(), receiver, prop_key, value, this->GetBytecodeOffset(), func)); RestoreAccFromFrame(); this->template MoveToNextInst(); } @@ -2239,8 +2290,8 @@ public: uint64_t receiver = GetRegAsTaggedValue(v0).GetRawData(); uint64_t prop_key = GetAccAsTaggedValue().GetRawData(); - - INTRINSIC_CALL_CHECK_SETACC(intrinsics::LdSuperByValue(this->GetJSThread(), receiver, prop_key)); + uint64_t func = GetThisFuncRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::LdSuperByValue(this->GetJSThread(), receiver, prop_key, func)); this->template MoveToNextInst(); } @@ -2255,9 +2306,10 @@ public: uint64_t receiver = GetRegAsTaggedValue(v0).GetRawData(); uint64_t prop_key = GetRegAsTaggedValue(v1).GetRawData(); uint64_t value = GetAccAsTaggedValue().GetRawData(); + uint64_t func = GetThisFuncRawValue(); SaveAccToFrame(); - INTRINSIC_CALL_CHECK(intrinsics::StSuperByValue(this->GetJSThread(), receiver, prop_key, value)); + INTRINSIC_CALL_CHECK(intrinsics::StSuperByValue(this->GetJSThread(), receiver, prop_key, value, func)); RestoreAccFromFrame(); this->template MoveToNextInst(); } @@ -2266,9 +2318,10 @@ public: ALWAYS_INLINE void HandleEcmaTryldglobalbyname() { auto string_id = this->GetInst().template GetId(); - - INTRINSIC_CALL_CHECK_SETACC( - intrinsics::TryLdGlobalByName(this->GetJSThread(), string_id.AsIndex(), this->GetBytecodeOffset())); + auto cp = GetConstantPoolRawValue(); + auto func = GetThisFuncRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::TryLdGlobalByName(this->GetJSThread(), string_id.AsIndex(), + this->GetBytecodeOffset(), func, cp)); this->template MoveToNextInst(); } @@ -2282,8 +2335,10 @@ public: uint64_t value = GetAccAsTaggedValue().GetRawData(); SaveAccToFrame(); - INTRINSIC_CALL_CHECK( - intrinsics::TryStGlobalByName(this->GetJSThread(), string_id.AsIndex(), value, this->GetBytecodeOffset())); + auto cp = GetConstantPoolRawValue(); + auto func = GetThisFuncRawValue(); + INTRINSIC_CALL_CHECK(intrinsics::TryStGlobalByName(this->GetJSThread(), string_id.AsIndex(), value, + this->GetBytecodeOffset(), func, cp)); RestoreAccFromFrame(); this->template MoveToNextInst(); } @@ -2296,8 +2351,10 @@ public: LOG_INST() << "ldglobalvar " << " string_id:" << string_id; + auto cp = GetConstantPoolRawValue(); + auto func = GetThisFuncRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::LdGlobalVar(this->GetJSThread(), string_id.AsIndex(), this->GetBytecodeOffset())); + intrinsics::LdGlobalVar(this->GetJSThread(), string_id.AsIndex(), this->GetBytecodeOffset(), func, cp)); this->template MoveToNextInst(); } @@ -2310,8 +2367,10 @@ public: << " string_id:" << string_id; uint64_t obj = GetAccAsTaggedValue().GetRawData(); - INTRINSIC_CALL_CHECK_SETACC( - intrinsics::LdObjByName(this->GetJSThread(), string_id.AsIndex(), obj, this->GetBytecodeOffset())); + auto cp = GetConstantPoolRawValue(); + auto func = GetThisFuncRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::LdObjByName(this->GetJSThread(), string_id.AsIndex(), obj, + this->GetBytecodeOffset(), func, cp)); this->template MoveToNextInst(); } @@ -2328,8 +2387,10 @@ public: uint64_t value = GetAccAsTaggedValue().GetRawData(); SaveAccToFrame(); - INTRINSIC_CALL_CHECK( - intrinsics::StObjByName(this->GetJSThread(), string_id.AsIndex(), obj, value, this->GetBytecodeOffset())); + auto cp = GetConstantPoolRawValue(); + auto func = GetThisFuncRawValue(); + INTRINSIC_CALL_CHECK(intrinsics::StObjByName(this->GetJSThread(), string_id.AsIndex(), obj, value, + this->GetBytecodeOffset(), func, cp)); RestoreAccFromFrame(); this->template MoveToNextInst(); } @@ -2343,8 +2404,9 @@ public: << " string_id:" << string_id.AsIndex(); uint64_t obj = GetAccAsTaggedValue().GetRawData(); - - INTRINSIC_CALL_CHECK_SETACC(intrinsics::LdSuperByName(this->GetJSThread(), string_id.AsIndex(), obj)); + auto cp = GetConstantPoolRawValue(); + auto func = GetThisFuncRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::LdSuperByName(this->GetJSThread(), string_id.AsIndex(), obj, func, cp)); this->template MoveToNextInst(); } @@ -2361,7 +2423,9 @@ public: uint64_t value = GetAccAsTaggedValue().GetRawData(); SaveAccToFrame(); - INTRINSIC_CALL_CHECK(intrinsics::StSuperByName(this->GetJSThread(), string_id.AsIndex(), obj, value)); + auto func = GetThisFuncRawValue(); + auto cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK(intrinsics::StSuperByName(this->GetJSThread(), string_id.AsIndex(), obj, value, func, cp)); RestoreAccFromFrame(); this->template MoveToNextInst(); } @@ -2377,8 +2441,10 @@ public: uint64_t value = GetAccAsTaggedValue().GetRawData(); SaveAccToFrame(); - INTRINSIC_CALL_CHECK( - intrinsics::StGlobalVar(this->GetJSThread(), string_id.AsIndex(), value, this->GetBytecodeOffset())); + auto cp = GetConstantPoolRawValue(); + auto func = GetThisFuncRawValue(); + INTRINSIC_CALL_CHECK(intrinsics::StGlobalVar(this->GetJSThread(), string_id.AsIndex(), value, + this->GetBytecodeOffset(), func, cp)); RestoreAccFromFrame(); this->template MoveToNextInst(); } @@ -2479,9 +2545,9 @@ public: uint64_t lexenv = GetRegAsTaggedValue(v0).GetRawData(); uint64_t proto = GetRegAsTaggedValue(v1).GetRawData(); - + auto cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::DefineClassWithBuffer(this->GetJSThread(), method_id, imm, lexenv, proto)); + intrinsics::DefineClassWithBuffer(this->GetJSThread(), method_id, imm, lexenv, proto, cp)); this->template MoveToNextInst(); } @@ -2514,8 +2580,8 @@ public: uint64_t env = GetRegAsTaggedValue(v0).GetRawData(); uint64_t ctor = GetAccAsTaggedValue().GetRawData(); - - intrinsics::DefineClassPrivateFields(this->GetJSThread(), literalarray_id.AsIndex(), env, ctor); + auto cp = GetConstantPoolRawValue(); + intrinsics::DefineClassPrivateFields(this->GetJSThread(), literalarray_id.AsIndex(), env, ctor, cp); this->template MoveToNextInst(); } @@ -2546,9 +2612,9 @@ public: uint64_t ctor = GetRegAsTaggedValue(v0).GetRawData(); uint64_t obj = GetRegAsTaggedValue(v1).GetRawData(); uint64_t value = GetAccAsTaggedValue().GetRawData(); - + uint64_t cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::ClassPrivateFieldAdd(this->GetJSThread(), string_id.AsIndex(), ctor, obj, value)); + intrinsics::ClassPrivateFieldAdd(this->GetJSThread(), string_id.AsIndex(), ctor, obj, value, cp)); this->template MoveToNextInst(); } @@ -2563,9 +2629,9 @@ public: uint64_t ctor = GetRegAsTaggedValue(v0).GetRawData(); uint64_t obj = GetRegAsTaggedValue(v1).GetRawData(); - + uint64_t cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::ClassPrivateFieldGet(this->GetJSThread(), string_id.AsIndex(), ctor, obj)); + intrinsics::ClassPrivateFieldGet(this->GetJSThread(), string_id.AsIndex(), ctor, obj, cp)); this->template MoveToNextInst(); } @@ -2581,9 +2647,9 @@ public: uint64_t ctor = GetRegAsTaggedValue(v0).GetRawData(); uint64_t obj = GetRegAsTaggedValue(v1).GetRawData(); uint64_t value = GetAccAsTaggedValue().GetRawData(); - + uint64_t cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::ClassPrivateFieldSet(this->GetJSThread(), string_id.AsIndex(), ctor, obj, value)); + intrinsics::ClassPrivateFieldSet(this->GetJSThread(), string_id.AsIndex(), ctor, obj, value, cp)); this->template MoveToNextInst(); } @@ -2597,9 +2663,9 @@ public: uint64_t ctor = GetRegAsTaggedValue(v0).GetRawData(); uint64_t obj = GetAccAsTaggedValue().GetRawData(); - + uint64_t cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::ClassPrivateFieldIn(this->GetJSThread(), string_id.AsIndex(), ctor, obj)); + intrinsics::ClassPrivateFieldIn(this->GetJSThread(), string_id.AsIndex(), ctor, obj, cp)); this->template MoveToNextInst(); } @@ -2649,9 +2715,9 @@ public: << " literalArrayId:" << literalarray_id.AsIndex(); uint64_t env = GetAccAsTaggedValue().GetRawData(); - + uint64_t cp = GetConstantPoolRawValue(); INTRINSIC_CALL_CHECK_SETACC( - intrinsics::CreateObjectHavingMethod(this->GetJSThread(), literalarray_id.AsIndex(), env)); + intrinsics::CreateObjectHavingMethod(this->GetJSThread(), literalarray_id.AsIndex(), env, cp)); this->template MoveToNextInst(); } @@ -2691,15 +2757,18 @@ public: ALWAYS_INLINE void HandleEcmaLdhomeobject() { LOG_INST() << "ldhomeobject"; - - INTRINSIC_CALL_SETACC(intrinsics::LdHomeObject(this->GetJSThread())); + auto func = GetThisFuncRawValue(); + INTRINSIC_CALL_SETACC(intrinsics::LdHomeObject(this->GetJSThread(), func)); this->template MoveToNextInst(); } template ALWAYS_INLINE void HandleEcmaPoplexenvdyn() { - intrinsics::PopLexenvDyn(this->GetJSThread()); + auto thread = this->GetJSThread(); + auto lex_env = GetLexicalEnvRawValue(); + auto res = JSTaggedValue(intrinsics::PopLexenvDyn(thread, lex_env)); + SetLexicalEnv(res); this->template MoveToNextInst(); } @@ -2727,8 +2796,8 @@ public: auto literalarray_id = this->GetInst().template GetId(); LOG_INST() << "ldevalbindings" << " literalArrayId:" << literalarray_id.AsIndex(); - - INTRINSIC_CALL_SETACC(intrinsics::LdEvalBindings(this->GetJSThread(), literalarray_id.AsIndex())); + uint64_t cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_SETACC(intrinsics::LdEvalBindings(this->GetJSThread(), literalarray_id.AsIndex(), cp)); this->template MoveToNextInst(); } @@ -2758,8 +2827,8 @@ public: << " name:" << id.AsIndex(); uint64_t lexical_context = GetAccAsTaggedValue().GetRawData(); - - INTRINSIC_CALL_CHECK_SETACC(intrinsics::LdEvalVar(this->GetJSThread(), id.AsIndex(), lexical_context)); + uint64_t cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK_SETACC(intrinsics::LdEvalVar(this->GetJSThread(), id.AsIndex(), lexical_context, cp)); this->template MoveToNextInst(); } @@ -2774,8 +2843,9 @@ public: uint64_t value = GetRegAsTaggedValue(v0).GetRawData(); uint64_t lexical_context = GetAccAsTaggedValue().GetRawData(); - - INTRINSIC_CALL_CHECK_SETACC(intrinsics::StEvalVar(this->GetJSThread(), id.AsIndex(), value, lexical_context)); + uint64_t cp = GetConstantPoolRawValue(); + INTRINSIC_CALL_CHECK_SETACC( + intrinsics::StEvalVar(this->GetJSThread(), id.AsIndex(), value, lexical_context, cp)); this->template MoveToNextInst(); } diff --git a/runtime/interpreter/interpreter-inl.h b/runtime/interpreter/interpreter-inl.h index 9c72d7384..df44505c2 100644 --- a/runtime/interpreter/interpreter-inl.h +++ b/runtime/interpreter/interpreter-inl.h @@ -47,34 +47,19 @@ public: JSFunction *js_function = JSFunction::Cast(func.GetHeapObject()); ObjectHeader *constant_pool = js_function->GetConstantPool().GetHeapObject(); - EcmascriptEnvironment *prev_env = js_thread->GetEcmascriptEnv(); // Init EcmascriptEnvironment EcmascriptEnvironment *new_env = JSFrame::GetJSEnv(frame); - new (new_env) EcmascriptEnvironment(prev_env, constant_pool, lexical_env, func.GetHeapObject()); - - // Change EcmascriptEnvironment - js_thread->SetEcmascriptEnv(new_env); + new (new_env) EcmascriptEnvironment(constant_pool, lexical_env, func.GetHeapObject()); InvokeHelperDynamic::InterpreterExecute(thread, pc, frame); - - // Restore EcmascriptEnvironment - js_thread->SetEcmascriptEnv(prev_env); } ALWAYS_INLINE inline static coretypes::TaggedValue CompiledCodeExecute(ManagedThread *thread, Method *method, uint32_t num_args, coretypes::TaggedValue *args) { - JSThread *js_thread = JSThread::Cast(thread); - EcmascriptEnvironment *prev_env = js_thread->GetEcmascriptEnv(); - auto ret = InvokeHelperDynamic::CompiledCodeExecute(thread, method, num_args, args); - - // Restore EcmascriptEnvironment if epilogue was not executed - if (UNLIKELY(js_thread->HasPendingException())) { - js_thread->SetEcmascriptEnv(prev_env); - } return ret; } @@ -127,10 +112,6 @@ JSTaggedValue EcmaInterpreter::ExecuteInvoke(EcmaRuntimeCallInfo *info, JSTagged ASSERT(!thread->HasPendingException()); ASSERT(fn_object.IsJSFunction()); -#ifndef NDEBUG - EcmascriptEnvironment *prev_env = thread->GetEcmascriptEnv(); -#endif // !NDEBUG - JSFunction *js_function = JSFunction::Cast(fn_object.GetHeapObject()); Method *method = js_function->GetCallTarget(); @@ -139,7 +120,6 @@ JSTaggedValue EcmaInterpreter::ExecuteInvoke(EcmaRuntimeCallInfo *info, JSTagged thread->SetInvocationLexicalEnv(js_function->GetLexicalEnv()); TaggedValue ret_value = method->InvokeDyn(thread, info->GetInternalArgsNum(), info->GetInternalArgs()); - ASSERT(thread->GetEcmascriptEnv() == prev_env); return JSTaggedValue(ret_value); } @@ -193,10 +173,6 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH return JSTaggedValue::Exception(); } -#ifndef NDEBUG - EcmascriptEnvironment *prev_env = thread->GetEcmascriptEnv(); -#endif // !NDEBUG - JSHandle func = JSHandle::Cast(JSHandle(thread, context->GetMethod())); Method *method = func->GetCallTarget(); @@ -217,7 +193,6 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH thread->SetFunctionalObject(func.GetTaggedValue()); thread->SetInvocationLexicalEnv(context->GetLexicalEnv()); TaggedValue value = method->InvokeContext(thread, resume_pc, acc, nregs, regs); - ASSERT(thread->GetEcmascriptEnv() == prev_env); return JSTaggedValue(value); } diff --git a/runtime/interpreter/js_frame.h b/runtime/interpreter/js_frame.h index ac807d878..df13b36d5 100644 --- a/runtime/interpreter/js_frame.h +++ b/runtime/interpreter/js_frame.h @@ -30,7 +30,7 @@ public: static JSTaggedValue ExecuteNativeMethod(JSThread *js_thread, Frame *frame, Method *method, uint32_t num_actual_args); - static JSEnv *GetJSEnv(Frame *frame) + static JSEnv *GetJSEnv(const Frame *frame) { return JSExtFrame::FromFrame(frame)->GetExtData(); } diff --git a/runtime/interpreter/slow_runtime_helper.cpp b/runtime/interpreter/slow_runtime_helper.cpp index e2f94fdee..37ee34601 100644 --- a/runtime/interpreter/slow_runtime_helper.cpp +++ b/runtime/interpreter/slow_runtime_helper.cpp @@ -109,7 +109,7 @@ void SlowRuntimeHelper::SaveFrameToContext(JSThread *thread, JSHandleSetAcc(thread, acc); context->SetNRegs(thread, JSTaggedValue(nregs)); context->SetBCOffset(thread, JSTaggedValue(frame->GetBytecodeOffset())); - context->SetLexicalEnv(thread, thread->GetCurrentLexenv()); + context->SetLexicalEnv(thread, JSTaggedValue(JSFrame::GetJSEnv(frame)->GetLexicalEnv())); } JSTaggedValue ConstructGeneric(JSThread *thread, JSHandle ctor, JSHandle new_tgt, diff --git a/runtime/intrinsics-inl.h b/runtime/intrinsics-inl.h index 5556ccc74..e5093800e 100644 --- a/runtime/intrinsics-inl.h +++ b/runtime/intrinsics-inl.h @@ -39,9 +39,8 @@ namespace panda::ecmascript::intrinsics { #endif #if ECMASCRIPT_ENABLE_IC -static inline JSTaggedValue GetRuntimeProfileTypeInfo(JSThread *thread) +static inline JSTaggedValue GetRuntimeProfileTypeInfo(JSFunction *func) { - auto *func = JSFunction::Cast(GetThisFunc(thread).GetHeapObject()); return func->GetProfileTypeInfo(); } #endif @@ -143,11 +142,12 @@ INLINE_ECMA_INTRINSICS uint64_t Ldstring([[maybe_unused]] JSThread *thread, [[ma } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t Ldbigint([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint32_t string_id) +INLINE_ECMA_INTRINSICS uint64_t Ldbigint([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint32_t string_id, + uint64_t cp) { INTERPRETER_TRACE(thread, Ldbigint); [[maybe_unused]] EcmaHandleScope handle_scope(thread); - JSTaggedValue number_big_int = GetConstantPool(thread)->GetObjectFromCache(string_id); + JSTaggedValue number_big_int = ConstantPool::Cast(cp)->GetObjectFromCache(string_id); JSHandle big_int_handle(thread, number_big_int); return JSTaggedValue::ToBigInt(thread, big_int_handle).GetRawData(); } @@ -417,18 +417,20 @@ INLINE_ECMA_INTRINSICS void TryStGlobalByValue([[maybe_unused]] JSThread *thread // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t TryLdGlobalByName(JSThread *thread, uint32_t string_id, - [[maybe_unused]] uint16_t slot_id) + [[maybe_unused]] uint16_t slot_id, [[maybe_unused]] uint64_t func, + uint64_t cp) { - auto constpool = GetConstantPool(thread); + auto constpool = ConstantPool::Cast(cp); JSTaggedType global_obj = GetGlobalObject(thread).GetRawData(); JSTaggedType prop = constpool->GetObjectFromCache(string_id).GetRawData(); JSTaggedValue result = JSTaggedValue::Hole(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC - if (ICRuntimeStub::HaveICForFunction(thread)) { - result = - ICRuntimeStub::LoadGlobalICByName(thread, JSTaggedValue(global_obj), JSTaggedValue(prop), slot_id, true); + auto js_func = JSFunction::Cast(JSTaggedValue(func).GetHeapObject()); + if (ICRuntimeStub::HaveICForFunction(js_func)) { + result = ICRuntimeStub::LoadGlobalICByName(thread, js_func, JSTaggedValue(global_obj), JSTaggedValue(prop), + slot_id, true); if (!result.IsHole()) { return result.GetRawData(); } @@ -548,9 +550,9 @@ INLINE_ECMA_INTRINSICS uint64_t Definefuncexpr([[maybe_unused]] JSThread *thread } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t DefinefuncDyn(JSThread *thread, uint32_t method_id, uint64_t env) +INLINE_ECMA_INTRINSICS uint64_t DefinefuncDyn(JSThread *thread, uint32_t method_id, uint64_t env, uint64_t cp) { - auto constpool = GetConstantPool(thread); + auto constpool = ConstantPool::Cast(cp); auto result = JSFunction::Cast(constpool->GetObjectFromCache(method_id).GetHeapObject()); auto lexenv = JSTaggedValue(env); if (!result->GetLexicalEnv().IsUndefined()) { @@ -608,9 +610,10 @@ INLINE_ECMA_INTRINSICS uint64_t Callruntimerange([[maybe_unused]] JSThread *thre } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdlexenvDyn(JSThread *thread) +INLINE_ECMA_INTRINSICS uint64_t LdlexenvDyn([[maybe_unused]] JSThread *thread) { - return coretypes::TaggedValue(GetEcmascriptEnvironment(thread)->GetLexicalEnv()).GetRawData(); + UNREACHABLE(); + // return GetLexicalEnvRawValue(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -905,7 +908,7 @@ INLINE_ECMA_INTRINSICS uint64_t Ldglobal(JSThread *thread) // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t LdObjByValue(JSThread *thread, uint64_t rec, uint64_t pkey, - [[maybe_unused]] uint16_t slot_id) + [[maybe_unused]] uint16_t slot_id, [[maybe_unused]] uint64_t func) { // If ICRuntimeStub::LoadICByValue triggers GC it mustn't return Hole. // Using rec and pkey after ICRuntimeStub::LoadICByValue is valid. @@ -913,8 +916,9 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByValue(JSThread *thread, uint64_t rec, uin JSTaggedValue res = JSTaggedValue::Hole(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC - if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::LoadICByValue(thread, JSTaggedValue(rec), JSTaggedValue(pkey), slot_id); + auto js_func = JSFunction::Cast(JSTaggedValue(func).GetHeapObject()); + if (ICRuntimeStub::HaveICForFunction(js_func)) { + res = ICRuntimeStub::LoadICByValue(thread, js_func, JSTaggedValue(rec), JSTaggedValue(pkey), slot_id); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -940,7 +944,7 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByValue(JSThread *thread, uint64_t rec, uin // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StObjByValue(JSThread *thread, uint64_t rec, uint64_t pkey, uint64_t val, - [[maybe_unused]] uint16_t slot_id) + [[maybe_unused]] uint16_t slot_id, [[maybe_unused]] uint64_t func) { // If ICRuntimeStub::StoreICByValue triggers GC it mustn't return Hole. // Using rec and pkey after ICRuntimeStub::StoreICByValue is valid. @@ -948,9 +952,10 @@ INLINE_ECMA_INTRINSICS uint64_t StObjByValue(JSThread *thread, uint64_t rec, uin JSTaggedValue res = JSTaggedValue::Hole(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC - if (ICRuntimeStub::HaveICForFunction(thread)) { - res = - ICRuntimeStub::StoreICByValue(thread, JSTaggedValue(rec), JSTaggedValue(pkey), JSTaggedValue(val), slot_id); + auto js_func = JSFunction::Cast(JSTaggedValue(func).GetTaggedObject()); + if (ICRuntimeStub::HaveICForFunction(js_func)) { + res = ICRuntimeStub::StoreICByValue(thread, js_func, JSTaggedValue(rec), JSTaggedValue(pkey), + JSTaggedValue(val), slot_id); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -977,16 +982,18 @@ INLINE_ECMA_INTRINSICS uint64_t StObjByValue(JSThread *thread, uint64_t rec, uin // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t TryStGlobalByName(JSThread *thread, uint32_t string_id, uint64_t value, - [[maybe_unused]] uint16_t slot_id) + [[maybe_unused]] uint16_t slot_id, [[maybe_unused]] uint64_t func, + uint64_t cp) { - JSTaggedType prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); + JSTaggedType prop_key = ConstantPool::Cast(cp)->GetObjectFromCache(string_id).GetRawData(); JSTaggedType global_obj = GetGlobalObject(thread).GetRawData(); JSTaggedValue result = JSTaggedValue::Hole(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC - if (ICRuntimeStub::HaveICForFunction(thread)) { - result = ICRuntimeStub::StoreGlobalICByName(thread, JSTaggedValue(global_obj), JSTaggedValue(prop_key), + auto js_func = JSFunction::Cast(JSTaggedValue(func).GetHeapObject()); + if (ICRuntimeStub::HaveICForFunction(js_func)) { + result = ICRuntimeStub::StoreGlobalICByName(thread, js_func, JSTaggedValue(global_obj), JSTaggedValue(prop_key), JSTaggedValue(value), slot_id, true); if (!result.IsHole()) { return result.GetRawData(); @@ -1008,16 +1015,19 @@ INLINE_ECMA_INTRINSICS uint64_t TryStGlobalByName(JSThread *thread, uint32_t str } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdGlobalVar(JSThread *thread, uint32_t string_id, [[maybe_unused]] uint16_t slot_id) +INLINE_ECMA_INTRINSICS uint64_t LdGlobalVar(JSThread *thread, uint32_t string_id, [[maybe_unused]] uint16_t slot_id, + [[maybe_unused]] uint64_t func, uint64_t cp) { JSTaggedType global_obj = thread->GetGlobalObject().GetRawData(); - JSTaggedType prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); + JSTaggedType prop_key = ConstantPool::Cast(cp)->GetObjectFromCache(string_id).GetRawData(); JSTaggedValue result = JSTaggedValue::Hole(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC - if (ICRuntimeStub::HaveICForFunction(thread)) { - result = ICRuntimeStub::LoadGlobalICByName(thread, JSTaggedValue(global_obj), JSTaggedValue(prop_key), slot_id); + auto js_func = JSFunction::Cast(JSTaggedValue(func).GetHeapObject()); + if (ICRuntimeStub::HaveICForFunction(js_func)) { + result = ICRuntimeStub::LoadGlobalICByName(thread, js_func, JSTaggedValue(global_obj), JSTaggedValue(prop_key), + slot_id); if (!result.IsHole()) { return result.GetRawData(); } @@ -1036,15 +1046,17 @@ INLINE_ECMA_INTRINSICS uint64_t LdGlobalVar(JSThread *thread, uint32_t string_id // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StGlobalVar(JSThread *thread, uint32_t string_id, uint64_t value, - [[maybe_unused]] uint16_t slot_id) + [[maybe_unused]] uint16_t slot_id, [[maybe_unused]] uint64_t func, + uint64_t cp) { JSTaggedType global_obj = thread->GetGlobalObject().GetRawData(); - JSTaggedType prop = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); + JSTaggedType prop = ConstantPool::Cast(cp)->GetObjectFromCache(string_id).GetRawData(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC - if (ICRuntimeStub::HaveICForFunction(thread)) { - JSTaggedValue result = ICRuntimeStub::StoreGlobalICByName(thread, JSTaggedValue(global_obj), + auto js_func = JSFunction::Cast(JSTaggedValue(func).GetHeapObject()); + if (ICRuntimeStub::HaveICForFunction(js_func)) { + JSTaggedValue result = ICRuntimeStub::StoreGlobalICByName(thread, js_func, JSTaggedValue(global_obj), JSTaggedValue(prop), JSTaggedValue(value), slot_id); if (!result.IsHole()) { return result.GetRawData(); @@ -1058,18 +1070,20 @@ INLINE_ECMA_INTRINSICS uint64_t StGlobalVar(JSThread *thread, uint32_t string_id // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t LdObjByName(JSThread *thread, uint32_t string_id, uint64_t object, - [[maybe_unused]] uint16_t slot_id) + [[maybe_unused]] uint16_t slot_id, [[maybe_unused]] uint64_t func, + uint64_t cp) { // CSA reports usage object and prop_key after GC triggered in ICRuntimeStub::LoadICByName. // If ICRuntimeStub::LoadICByName triggers GC it mustn't return Hole. // Using object and prop_key after ICRuntimeStub::LoadICByName is valid. // To suppress CSA keep pointers in uint64_t and JSTaggedType. - JSTaggedType prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); + JSTaggedType prop_key = ConstantPool::Cast(cp)->GetObjectFromCache(string_id).GetRawData(); JSTaggedValue res = JSTaggedValue::Hole(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC - if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::LoadICByName(thread, JSTaggedValue(object), JSTaggedValue(prop_key), slot_id); + auto js_func = JSFunction::Cast(JSTaggedValue(func).GetHeapObject()); + if (ICRuntimeStub::HaveICForFunction(js_func)) { + res = ICRuntimeStub::LoadICByName(thread, js_func, JSTaggedValue(object), JSTaggedValue(prop_key), slot_id); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -1091,19 +1105,21 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByName(JSThread *thread, uint32_t string_id // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StObjByName(JSThread *thread, uint32_t string_id, uint64_t object, uint64_t val, - [[maybe_unused]] uint16_t slot_id) + [[maybe_unused]] uint16_t slot_id, [[maybe_unused]] uint64_t func, + uint64_t cp) { // CSA reports usage object, prop_key and val after GC triggered in ICRuntimeStub::StoreICByName. // If ICRuntimeStub::StoreICByName triggers GC it mustn't return Hole. // Using object, prop_key and val after ICRuntimeStub::StoreICByName is valid. // To suppress CSA keep pointers in uint64_t and JSTaggedType. - JSTaggedType prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); + JSTaggedType prop_key = ConstantPool::Cast(cp)->GetObjectFromCache(string_id).GetRawData(); JSTaggedValue res = JSTaggedValue::Hole(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC - if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::StoreICByName(thread, JSTaggedValue(object), JSTaggedValue(prop_key), JSTaggedValue(val), - slot_id); + auto js_func = JSFunction::Cast(JSTaggedValue(func).GetHeapObject()); + if (ICRuntimeStub::HaveICForFunction(js_func)) { + res = ICRuntimeStub::StoreICByName(thread, js_func, JSTaggedValue(object), JSTaggedValue(prop_key), + JSTaggedValue(val), slot_id); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -1372,10 +1388,11 @@ INLINE_ECMA_INTRINSICS uint64_t Delobjprop(JSThread *thread, uint64_t obj, uint6 // define not constructor function // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t DefineNCFuncDyn(JSThread *thread, uint32_t method_id, uint64_t env, uint64_t home_objv) +INLINE_ECMA_INTRINSICS uint64_t DefineNCFuncDyn(JSThread *thread, uint32_t method_id, uint64_t env, uint64_t home_objv, + uint64_t cp) { auto home_obj = JSTaggedValue(home_objv); - auto constpool = GetConstantPool(thread); + auto constpool = ConstantPool::Cast(cp); auto result = JSFunction::Cast(constpool->GetObjectFromCache(method_id).GetHeapObject()); auto lexenv = JSTaggedValue(env); @@ -1400,10 +1417,10 @@ INLINE_ECMA_INTRINSICS uint64_t DefineNCFuncDyn(JSThread *thread, uint32_t metho } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdLexVarDyn(JSThread *thread, uint16_t level, uint16_t slot) +INLINE_ECMA_INTRINSICS uint64_t LdLexVarDyn([[maybe_unused]] JSThread *thread, uint16_t level, uint16_t slot, + uint64_t lex_env) { - LexicalEnv *env = GetLexicalEnv(thread); - + LexicalEnv *env = LexicalEnv::Cast(lex_env); for (int i = 0; i < level; i++) { JSTaggedValue tagged_parent_env = env->GetParentEnv(); ASSERT(!tagged_parent_env.IsUndefined()); @@ -1413,23 +1430,24 @@ INLINE_ECMA_INTRINSICS uint64_t LdLexVarDyn(JSThread *thread, uint16_t level, ui } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdLexDyn(JSThread *thread, uint32_t string_id, uint16_t level, uint16_t slot) +INLINE_ECMA_INTRINSICS uint64_t LdLexDyn([[maybe_unused]] JSThread *thread, uint32_t string_id, uint16_t level, + uint16_t slot, uint64_t cp, uint64_t lex_env) { - JSTaggedValue binding(LdLexVarDyn(level, slot)); + JSTaggedValue binding(LdLexVarDyn(level, slot, lex_env)); if (!binding.IsHole()) { return binding.GetRawData(); } - auto binding_name = GetConstantPool(thread)->GetObjectFromCache(string_id); + auto binding_name = ConstantPool::Cast(cp)->GetObjectFromCache(string_id); SlowRuntimeStub::ThrowTdz(GetJSThread(), binding_name); return JSTaggedValue(JSTaggedValue::VALUE_EXCEPTION).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS void PopLexenvDyn(JSThread *thread) +INLINE_ECMA_INTRINSICS uint64_t PopLexenvDyn([[maybe_unused]] JSThread *thread, uint64_t lex_env) { - SetLexicalEnv(thread, GetLexicalEnv(thread)->GetParentEnv()); + return LexicalEnv::Cast(lex_env)->GetParentEnv().GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -1479,11 +1497,11 @@ INLINE_ECMA_INTRINSICS uint64_t ReturnDyn([[maybe_unused]] JSThread *thread, [[m } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t NewlexenvDyn(JSThread *thread, uint16_t num_slots) +INLINE_ECMA_INTRINSICS uint64_t NewlexenvDyn(JSThread *thread, uint16_t num_slots, uint64_t lex_env) { [[maybe_unused]] EcmaHandleScope handle_scope(thread); auto factory = thread->GetEcmaVM()->GetFactory(); - JSHandle env(thread, GetEcmascriptEnvironment(thread)->GetLexicalEnv()); + JSHandle env(thread, LexicalEnv::Cast(lex_env)); JSTaggedValue res = FastRuntimeStub::NewLexicalEnvDyn(thread, factory, num_slots); if (res.IsHole()) { @@ -1493,18 +1511,16 @@ INLINE_ECMA_INTRINSICS uint64_t NewlexenvDyn(JSThread *thread, uint16_t num_slot } } LexicalEnv::Cast(res.GetHeapObject())->SetParentEnv(thread, env.GetTaggedValue()); - SetLexicalEnv(thread, res); return res.GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CopylexenvDyn(JSThread *thread) +INLINE_ECMA_INTRINSICS uint64_t CopylexenvDyn(JSThread *thread, uint64_t lex_env) { [[maybe_unused]] EcmaHandleScope handle_scope(thread); auto factory = thread->GetEcmaVM()->GetFactory(); - JSHandle old_env(thread, GetLexicalEnv(thread)); + JSHandle old_env(thread, LexicalEnv::Cast(lex_env)); JSHandle parent_env(thread, old_env->GetParentEnv()); - SetLexicalEnv(thread, parent_env.GetTaggedValue()); ArraySizeT num_of_slots = old_env->GetLength(); JSTaggedValue res = FastRuntimeStub::NewLexicalEnvDyn(thread, factory, num_of_slots); @@ -1515,7 +1531,6 @@ INLINE_ECMA_INTRINSICS uint64_t CopylexenvDyn(JSThread *thread) } } LexicalEnv::Cast(res.GetHeapObject())->SetParentEnv(thread, parent_env.GetTaggedValue()); - SetLexicalEnv(thread, res); for (ArraySizeT i = 0; i < num_of_slots; i++) { LexicalEnv::Cast(res.GetHeapObject())->Set(thread, i, old_env->Get(i)); @@ -1524,15 +1539,16 @@ INLINE_ECMA_INTRINSICS uint64_t CopylexenvDyn(JSThread *thread) } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS void ThrowTdz(JSThread *thread, uint32_t string_id) +INLINE_ECMA_INTRINSICS void ThrowTdz(JSThread *thread, uint32_t string_id, uint64_t cp) { - SlowRuntimeStub::ThrowTdz(thread, GetConstantPool(thread)->GetObjectFromCache(string_id)); + SlowRuntimeStub::ThrowTdz(thread, ConstantPool::Cast(cp)->GetObjectFromCache(string_id)); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS void StLexVarDyn(JSThread *thread, uint16_t level, uint16_t slot, uint64_t value) +INLINE_ECMA_INTRINSICS void StLexVarDyn(JSThread *thread, uint16_t level, uint16_t slot, uint64_t value, + uint64_t lex_env) { - JSTaggedValue current_lexenv(GetLexicalEnv(thread)); + JSTaggedValue current_lexenv(LexicalEnv::Cast(lex_env)); JSTaggedValue env(current_lexenv); for (int i = 0; i < level; i++) { @@ -1545,9 +1561,9 @@ INLINE_ECMA_INTRINSICS void StLexVarDyn(JSThread *thread, uint16_t level, uint16 // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StLexDyn(JSThread *thread, uint32_t string_id, uint16_t level, uint16_t slot, - uint64_t value) + uint64_t value, uint64_t cp, uint64_t lex_env) { - JSTaggedValue current_lexenv(GetLexicalEnv(thread)); + JSTaggedValue current_lexenv(LexicalEnv::Cast(lex_env)); JSTaggedValue env(current_lexenv); for (int i = 0; i < level; i++) { @@ -1556,14 +1572,14 @@ INLINE_ECMA_INTRINSICS uint64_t StLexDyn(JSThread *thread, uint32_t string_id, u env = tagged_parent_env; } - LexicalEnv *lex_env = LexicalEnv::Cast(env.GetHeapObject()); + LexicalEnv *lexenv = LexicalEnv::Cast(env.GetHeapObject()); - if (lex_env->GetProperties(slot).IsHole()) { - ThrowTdz(thread, string_id); + if (lexenv->GetProperties(slot).IsHole()) { + ThrowTdz(thread, string_id, cp); return JSTaggedValue(JSTaggedValue::VALUE_EXCEPTION).GetRawData(); } - lex_env->SetProperties(thread, slot, JSTaggedValue(value)); + lexenv->SetProperties(thread, slot, JSTaggedValue(value)); return value; } @@ -1580,9 +1596,10 @@ INLINE_ECMA_INTRINSICS uint64_t GetPropIterator(JSThread *thread, uint64_t obj) } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t DefineGeneratorFunc(JSThread *thread, uint32_t method_id, uint64_t env) +INLINE_ECMA_INTRINSICS uint64_t DefineGeneratorFunc(JSThread *thread, uint32_t method_id, uint64_t env, uint64_t cp) { - auto result = JSFunction::Cast(GetConstantPool(thread)->GetObjectFromCache(method_id).GetHeapObject()); + auto constantpool = ConstantPool::Cast(cp); + auto result = JSFunction::Cast(constantpool->GetObjectFromCache(method_id).GetHeapObject()); auto lexenv = JSTaggedValue(env); if (!result->GetLexicalEnv().IsUndefined()) { [[maybe_unused]] EcmaHandleScope handle_scope(thread); @@ -1593,7 +1610,7 @@ INLINE_ECMA_INTRINSICS uint64_t DefineGeneratorFunc(JSThread *thread, uint32_t m } result = JSFunction::Cast(res.GetHeapObject()); lexenv = lexenv_handle.GetTaggedValue(); // May be moved by GC - result->SetConstantPool(thread, JSTaggedValue(GetConstantPool(thread))); + result->SetConstantPool(thread, JSTaggedValue(constantpool)); } result->SetLexicalEnv(thread, lexenv); return JSTaggedValue(result).GetRawData(); @@ -1638,9 +1655,10 @@ INLINE_ECMA_INTRINSICS uint64_t CreateAsyncGeneratorObj(JSThread *thread, uint64 } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t DefineAsyncFunc(JSThread *thread, uint32_t method_id, uint64_t env) +INLINE_ECMA_INTRINSICS uint64_t DefineAsyncFunc(JSThread *thread, uint32_t method_id, uint64_t env, uint64_t cp) { - auto result = JSFunction::Cast(GetConstantPool(thread)->GetObjectFromCache(method_id).GetHeapObject()); + auto constantpool = ConstantPool::Cast(cp); + auto result = JSFunction::Cast(constantpool->GetObjectFromCache(method_id).GetHeapObject()); auto lexenv = JSTaggedValue(env); if (!result->GetLexicalEnv().IsUndefined()) { [[maybe_unused]] EcmaHandleScope handle_scope(thread); @@ -1651,16 +1669,18 @@ INLINE_ECMA_INTRINSICS uint64_t DefineAsyncFunc(JSThread *thread, uint32_t metho } result = JSFunction::Cast(res.GetHeapObject()); lexenv = lexenv_handle.GetTaggedValue(); // May be moved by GC - result->SetConstantPool(thread, JSTaggedValue(GetConstantPool(thread))); + result->SetConstantPool(thread, JSTaggedValue(constantpool)); } result->SetLexicalEnv(thread, lexenv); return JSTaggedValue(result).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t DefineAsyncGeneratorFunc(JSThread *thread, uint32_t method_id, uint64_t env) +INLINE_ECMA_INTRINSICS uint64_t DefineAsyncGeneratorFunc(JSThread *thread, uint32_t method_id, uint64_t env, + uint64_t cp) { - auto result = JSFunction::Cast(GetConstantPool(thread)->GetObjectFromCache(method_id).GetHeapObject()); + auto constantpool = ConstantPool::Cast(cp); + auto result = JSFunction::Cast(constantpool->GetObjectFromCache(method_id).GetHeapObject()); auto lexenv = JSTaggedValue(env); if (!result->GetLexicalEnv().IsUndefined()) { [[maybe_unused]] EcmaHandleScope handle_scope(thread); @@ -1671,7 +1691,7 @@ INLINE_ECMA_INTRINSICS uint64_t DefineAsyncGeneratorFunc(JSThread *thread, uint3 } result = JSFunction::Cast(res.GetHeapObject()); lexenv = lexenv_handle.GetTaggedValue(); // May be moved by GC - result->SetConstantPool(thread, JSTaggedValue(GetConstantPool(thread))); + result->SetConstantPool(thread, JSTaggedValue(constantpool)); } result->SetLexicalEnv(thread, lexenv); return JSTaggedValue(result).GetRawData(); @@ -1720,16 +1740,16 @@ INLINE_ECMA_INTRINSICS uint64_t AsyncGeneratorReject(JSThread *thread, uint64_t } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS void ThrowConstAssignment(JSThread *thread, uint32_t string_id) +INLINE_ECMA_INTRINSICS void ThrowConstAssignment(JSThread *thread, uint32_t string_id, uint64_t cp) { - return SlowRuntimeStub::ThrowConstAssignment(thread, GetConstantPool(thread)->GetObjectFromCache(string_id)); + return SlowRuntimeStub::ThrowConstAssignment(thread, ConstantPool::Cast(cp)->GetObjectFromCache(string_id)); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t GetMethod(JSThread *thread, uint32_t string_id, uint64_t object) +INLINE_ECMA_INTRINSICS uint64_t GetMethod(JSThread *thread, uint32_t string_id, uint64_t object, uint64_t cp) { return SlowRuntimeStub::GetMethod(thread, JSTaggedValue(object), - GetConstantPool(thread)->GetObjectFromCache(string_id)) + ConstantPool::Cast(cp)->GetObjectFromCache(string_id)) .GetRawData(); } @@ -1754,9 +1774,9 @@ INLINE_ECMA_INTRINSICS uint64_t CreateEmptyObject(JSThread *thread) } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CreateObjectWithBuffer(JSThread *thread, uint16_t index) +INLINE_ECMA_INTRINSICS uint64_t CreateObjectWithBuffer(JSThread *thread, uint16_t index, uint64_t cp) { - JSObject *result = JSObject::Cast(GetConstantPool(thread)->GetObjectFromCache(index).GetHeapObject()); + JSObject *result = JSObject::Cast(ConstantPool::Cast(cp)->GetObjectFromCache(index).GetHeapObject()); return SlowRuntimeStub::CreateObjectWithBuffer(thread, thread->GetEcmaVM()->GetFactory(), result).GetRawData(); } @@ -1791,17 +1811,18 @@ INLINE_ECMA_INTRINSICS uint64_t CreateEmptyArray(JSThread *thread) } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CreateArrayWithBuffer(JSThread *thread, uint16_t index) +INLINE_ECMA_INTRINSICS uint64_t CreateArrayWithBuffer(JSThread *thread, uint16_t index, uint64_t cp) { auto factory = thread->GetEcmaVM()->GetFactory(); - JSArray *result = JSArray::Cast(GetConstantPool(thread)->GetObjectFromCache(index).GetHeapObject()); + JSArray *result = JSArray::Cast(ConstantPool::Cast(cp)->GetObjectFromCache(index).GetHeapObject()); return SlowRuntimeStub::CreateArrayWithBuffer(thread, factory, result).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CreateRegExpWithLiteral(JSThread *thread, uint32_t string_id, uint8_t flags) +INLINE_ECMA_INTRINSICS uint64_t CreateRegExpWithLiteral(JSThread *thread, uint32_t string_id, uint8_t flags, + uint64_t cp) { - return SlowRuntimeStub::CreateRegExpWithLiteral(thread, GetConstantPool(thread)->GetObjectFromCache(string_id), + return SlowRuntimeStub::CreateRegExpWithLiteral(thread, ConstantPool::Cast(cp)->GetObjectFromCache(string_id), flags) .GetRawData(); } @@ -1824,9 +1845,10 @@ INLINE_ECMA_INTRINSICS uint64_t StOwnByIndex(JSThread *thread, uint64_t object, } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t StOwnByName(JSThread *thread, uint32_t string_id, uint64_t object, uint64_t val) +INLINE_ECMA_INTRINSICS uint64_t StOwnByName(JSThread *thread, uint32_t string_id, uint64_t object, uint64_t val, + uint64_t cp) { - JSTaggedType prop = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); + JSTaggedType prop = ConstantPool::Cast(cp)->GetObjectFromCache(string_id).GetRawData(); [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); if (JSTaggedValue(object).IsJSObject() && !JSTaggedValue(object).IsClassConstructor() && @@ -1928,16 +1950,16 @@ INLINE_ECMA_INTRINSICS uint64_t CloseIterator(JSThread *thread, uint64_t iter, u } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t ImportModule(JSThread *thread, uint32_t string_id) +INLINE_ECMA_INTRINSICS uint64_t ImportModule(JSThread *thread, uint32_t string_id, uint64_t cp) { - auto prop = GetConstantPool(thread)->GetObjectFromCache(string_id); + auto prop = ConstantPool::Cast(cp)->GetObjectFromCache(string_id); return SlowRuntimeStub::ImportModule(thread, prop).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS void StModuleVar(JSThread *thread, uint32_t string_id, uint64_t value) +INLINE_ECMA_INTRINSICS void StModuleVar(JSThread *thread, uint32_t string_id, uint64_t value, uint64_t cp) { - auto prop = GetConstantPool(thread)->GetObjectFromCache(string_id); + auto prop = ConstantPool::Cast(cp)->GetObjectFromCache(string_id); SlowRuntimeStub::StModuleVar(thread, prop, JSTaggedValue(value)); } @@ -1948,9 +1970,9 @@ INLINE_ECMA_INTRINSICS void CopyModule(JSThread *thread, uint64_t module) } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdModvarByName(JSThread *thread, uint32_t string_id, uint64_t module_obj) +INLINE_ECMA_INTRINSICS uint64_t LdModvarByName(JSThread *thread, uint32_t string_id, uint64_t module_obj, uint64_t cp) { - JSTaggedValue item_name = GetConstantPool(thread)->GetObjectFromCache(string_id); + JSTaggedValue item_name = ConstantPool::Cast(cp)->GetObjectFromCache(string_id); return SlowRuntimeStub::LdModvarByName(thread, JSTaggedValue(module_obj), item_name).GetRawData(); } @@ -1963,9 +1985,9 @@ INLINE_ECMA_INTRINSICS uint64_t ClassFieldAdd(JSThread *thread, uint64_t ctor, u // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS void DefineClassPrivateFields(JSThread *thread, uint16_t private_buf_idx, uint64_t env, - uint64_t ctor) + uint64_t ctor, uint64_t cp) { - auto *constpool = GetConstantPool(thread); + auto *constpool = ConstantPool::Cast(cp); SlowRuntimeStub::DefineClassPrivateFields(thread, constpool, JSTaggedValue(env), JSTaggedValue(ctor), constpool->GetObjectFromCache(private_buf_idx)); } @@ -1979,46 +2001,48 @@ INLINE_ECMA_INTRINSICS uint64_t ClassPrivateMethodOrAccessorAdd(JSThread *thread // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t ClassPrivateFieldAdd(JSThread *thread, uint32_t string_id, uint64_t ctor, uint64_t obj, - uint64_t value) + uint64_t value, uint64_t cp) { return SlowRuntimeStub::ClassPrivateFieldAdd(thread, JSTaggedValue(ctor), JSTaggedValue(obj), - GetConstantPool(thread)->GetObjectFromCache(string_id), + ConstantPool::Cast(cp)->GetObjectFromCache(string_id), JSTaggedValue(value)) .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t ClassPrivateFieldGet(JSThread *thread, uint32_t string_id, uint64_t ctor, uint64_t obj) +INLINE_ECMA_INTRINSICS uint64_t ClassPrivateFieldGet(JSThread *thread, uint32_t string_id, uint64_t ctor, uint64_t obj, + uint64_t cp) { return SlowRuntimeStub::ClassPrivateFieldGet(thread, JSTaggedValue(ctor), JSTaggedValue(obj), - GetConstantPool(thread)->GetObjectFromCache(string_id)) + ConstantPool::Cast(cp)->GetObjectFromCache(string_id)) .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t ClassPrivateFieldSet(JSThread *thread, uint32_t string_id, uint64_t ctor, uint64_t obj, - uint64_t value) + uint64_t value, uint64_t cp) { return SlowRuntimeStub::ClassPrivateFieldSet(thread, JSTaggedValue(ctor), JSTaggedValue(obj), - GetConstantPool(thread)->GetObjectFromCache(string_id), + ConstantPool::Cast(cp)->GetObjectFromCache(string_id), JSTaggedValue(value)) .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t ClassPrivateFieldIn(JSThread *thread, uint32_t string_id, uint64_t ctor, uint64_t obj) +INLINE_ECMA_INTRINSICS uint64_t ClassPrivateFieldIn(JSThread *thread, uint32_t string_id, uint64_t ctor, uint64_t obj, + uint64_t cp) { return SlowRuntimeStub::ClassPrivateFieldIn(thread, JSTaggedValue(ctor), JSTaggedValue(obj), - GetConstantPool(thread)->GetObjectFromCache(string_id)) + ConstantPool::Cast(cp)->GetObjectFromCache(string_id)) .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t DefineClassWithBuffer(JSThread *thread, uint32_t method_id, uint16_t imm, - uint64_t lexenv, uint64_t proto) + uint64_t lexenv, uint64_t proto, uint64_t cp) { [[maybe_unused]] EcmaHandleScope handle_scope(thread); - auto *constpool = GetConstantPool(thread); + auto *constpool = ConstantPool::Cast(cp); JSHandle lex_env(thread, JSTaggedValue(lexenv)); JSFunction *class_template = JSFunction::Cast(constpool->GetObjectFromCache(method_id).GetTaggedObject()); ASSERT(class_template != nullptr); @@ -2088,9 +2112,9 @@ INLINE_ECMA_INTRINSICS uint64_t SuperCallSpread(JSThread *thread, uint64_t array // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t DefineMethod(JSThread *thread, uint32_t method_id, uint64_t tagged_cur_env, - uint64_t home_object) + uint64_t home_object, uint64_t cp) { - auto constpool = GetConstantPool(thread); + auto constpool = ConstantPool::Cast(cp); auto result = JSFunction::Cast(constpool->GetObjectFromCache(method_id).GetHeapObject()); auto home = JSTaggedValue(home_object); auto env = JSTaggedValue(tagged_cur_env); @@ -2115,42 +2139,45 @@ INLINE_ECMA_INTRINSICS uint64_t DefineMethod(JSThread *thread, uint32_t method_i } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t StSuperByName(JSThread *thread, uint32_t string_id, uint64_t obj, uint64_t value) +INLINE_ECMA_INTRINSICS uint64_t StSuperByName(JSThread *thread, uint32_t string_id, uint64_t obj, uint64_t value, + uint64_t func, uint64_t cp) { - JSTaggedValue prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); + JSTaggedValue prop_key = ConstantPool::Cast(cp)->GetObjectFromCache(string_id); return SlowRuntimeStub::StSuperByValue(thread, JSTaggedValue(obj), prop_key, JSTaggedValue(value), - GetThisFunc(thread)) + JSTaggedValue(func)) .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdSuperByName(JSThread *thread, uint32_t string_id, uint64_t obj) +INLINE_ECMA_INTRINSICS uint64_t LdSuperByName(JSThread *thread, uint32_t string_id, uint64_t obj, uint64_t func, + uint64_t cp) { - JSTaggedValue prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); + JSTaggedValue prop_key = ConstantPool::Cast(cp)->GetObjectFromCache(string_id); - return SlowRuntimeStub::LdSuperByValue(thread, JSTaggedValue(obj), prop_key, GetThisFunc(thread)).GetRawData(); + return SlowRuntimeStub::LdSuperByValue(thread, JSTaggedValue(obj), prop_key, JSTaggedValue(func)).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t StSuperByValue(JSThread *thread, uint64_t receiver, uint64_t prop_key, uint64_t value) +INLINE_ECMA_INTRINSICS uint64_t StSuperByValue(JSThread *thread, uint64_t receiver, uint64_t prop_key, uint64_t value, + uint64_t func) { return SlowRuntimeStub::StSuperByValue(thread, JSTaggedValue(receiver), JSTaggedValue(prop_key), - JSTaggedValue(value), GetThisFunc(thread)) + JSTaggedValue(value), JSTaggedValue(func)) .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdSuperByValue(JSThread *thread, uint64_t receiver, uint64_t prop_key) +INLINE_ECMA_INTRINSICS uint64_t LdSuperByValue(JSThread *thread, uint64_t receiver, uint64_t prop_key, uint64_t func) { return SlowRuntimeStub::LdSuperByValue(thread, JSTaggedValue(receiver), JSTaggedValue(prop_key), - GetThisFunc(thread)) + JSTaggedValue(func)) .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CreateObjectHavingMethod(JSThread *thread, uint16_t imm, uint64_t env) +INLINE_ECMA_INTRINSICS uint64_t CreateObjectHavingMethod(JSThread *thread, uint16_t imm, uint64_t env, uint64_t cp) { - auto constpool = GetConstantPool(thread); + auto constpool = ConstantPool::Cast(cp); JSObject *result = JSObject::Cast(constpool->GetObjectFromCache(imm).GetHeapObject()); auto factory = GetFactory(thread); @@ -2166,9 +2193,9 @@ INLINE_ECMA_INTRINSICS uint64_t ThrowIfSuperNotCorrectCall(JSThread *thread, uin } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdHomeObject(JSThread *thread) +INLINE_ECMA_INTRINSICS uint64_t LdHomeObject([[maybe_unused]] JSThread *thread, uint64_t func) { - return JSFunction::Cast(GetThisFunc(thread).GetHeapObject())->GetHomeObject().GetRawData(); + return JSFunction::Cast(JSTaggedValue(func).GetHeapObject())->GetHomeObject().GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -2178,9 +2205,9 @@ INLINE_ECMA_INTRINSICS void ThrowDeleteSuperProperty(JSThread *thread) } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdEvalBindings(JSThread *thread, uint16_t index) +INLINE_ECMA_INTRINSICS uint64_t LdEvalBindings([[maybe_unused]] JSThread *thread, uint16_t index, uint64_t cp) { - return GetConstantPool(thread)->GetObjectFromCache(index).GetRawData(); + return ConstantPool::Cast(cp)->GetObjectFromCache(index).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -2190,18 +2217,18 @@ INLINE_ECMA_INTRINSICS uint64_t DirectEval(JSThread *thread, uint32_t status, ui } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t LdEvalVar(JSThread *thread, uint32_t string_id, uint64_t lexical_context) +INLINE_ECMA_INTRINSICS uint64_t LdEvalVar(JSThread *thread, uint32_t string_id, uint64_t lexical_context, uint64_t cp) { - return SlowRuntimeStub::LdEvalVar(thread, GetConstantPool(thread)->GetObjectFromCache(string_id), + return SlowRuntimeStub::LdEvalVar(thread, ConstantPool::Cast(cp)->GetObjectFromCache(string_id), JSTaggedValue(lexical_context)) .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StEvalVar(JSThread *thread, uint32_t string_id, uint64_t value, - uint64_t lexical_context) + uint64_t lexical_context, uint64_t cp) { - return SlowRuntimeStub::StEvalVar(thread, GetConstantPool(thread)->GetObjectFromCache(string_id), + return SlowRuntimeStub::StEvalVar(thread, ConstantPool::Cast(cp)->GetObjectFromCache(string_id), JSTaggedValue(lexical_context), JSTaggedValue(value)) .GetRawData(); } @@ -2230,18 +2257,6 @@ INLINE_ECMA_INTRINSICS uint64_t IsNan([[maybe_unused]] double arg) return static_cast(std::isnan(arg)); } -// NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t GetEcmaConstantPool(JSThread *thread) -{ - return JSTaggedValue(GetConstantPool(thread)).GetRawData(); -} - -// NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t GetEcmaThisFunc(JSThread *thread) -{ - return JSTaggedValue(GetThisFunc(thread)).GetRawData(); -} - // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t GetWeakReferent(uint64_t ref) { diff --git a/runtime/js_thread.cpp b/runtime/js_thread.cpp index 13cda0835..415753971 100644 --- a/runtime/js_thread.cpp +++ b/runtime/js_thread.cpp @@ -80,12 +80,6 @@ void JSThread::ClearException() ManagedThread::ClearException(); } -JSTaggedValue JSThread::GetCurrentLexenv() const -{ - auto *env = EcmascriptEnvironment::Cast(GetLanguageExtensionsData()); - return JSTaggedValue(env->GetLexicalEnv()); -} - void JSThread::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) { auto *exc = ManagedThread::GetException(); @@ -129,11 +123,10 @@ void JSThread::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) void JSThread::IterateEcmascriptEnvironment(const RootVisitor &v0, const RootRangeVisitor &v1) { - auto *env = EcmascriptEnvironment::Cast(GetLanguageExtensionsData()); auto adapter = [&v1]([[maybe_unused]] ObjectHeader *obj, ObjectSlot start, ObjectSlot end) { v1(Root::ROOT_VM, start, end); }; - while (env != nullptr) { + auto visit_env = [&v0, &adapter](EcmascriptEnvironment *env) { v0(Root::ROOT_VM, ObjectSlot(ToUintPtr(env) + EcmascriptEnvironment::GetConstantPoolOffset())); v0(Root::ROOT_VM, ObjectSlot(ToUintPtr(env) + EcmascriptEnvironment::GetLexicalEnvOffset())); v0(Root::ROOT_VM, ObjectSlot(ToUintPtr(env) + EcmascriptEnvironment::GetThisFuncOffset())); @@ -143,7 +136,15 @@ void JSThread::IterateEcmascriptEnvironment(const RootVisitor &v0, const RootRan LexicalEnv::Cast(lex_env.GetHeapObject())->VisitRangeSlot(adapter); lex_env = LexicalEnv::Cast(lex_env.GetHeapObject())->GetParentEnv(); } - env = env->GetPrevEnvironment(); + }; + + for (auto stack = StackWalker::Create(this); stack.HasFrame(); stack.NextFrame()) { + if (!stack.IsCFrame()) { + auto iframe = stack.GetIFrame(); + if (iframe->GetExt() != reinterpret_cast(iframe)) { + visit_env(JSFrame::GetJSEnv(iframe)); + } + } } if (properties_cache_ != nullptr) { diff --git a/runtime/js_thread.h b/runtime/js_thread.h index 9606618f3..552bc97fd 100644 --- a/runtime/js_thread.h +++ b/runtime/js_thread.h @@ -151,16 +151,6 @@ public: return &global_const_; } - EcmascriptEnvironment *GetEcmascriptEnv() const - { - return reinterpret_cast(GetLanguageExtensionsData()); - } - - void SetEcmascriptEnv(EcmascriptEnvironment *env) - { - SetLanguageExtensionsData(env); - } - JSTaggedValue GetFunctionalObject() const { return functional_object_; @@ -191,8 +181,6 @@ public: void ResetGuardians(); - JSTaggedValue GetCurrentLexenv() const; - InternalCallParams *GetInternalCallParams() const { return internal_call_params_; diff --git a/runtime/lexical_env.h b/runtime/lexical_env.h index 7b532f72f..300bdf0cd 100644 --- a/runtime/lexical_env.h +++ b/runtime/lexical_env.h @@ -30,6 +30,12 @@ public: return static_cast(object); } + static LexicalEnv *Cast(JSTaggedType object) + { + ASSERT(JSTaggedValue(object).IsTaggedArray()); + return static_cast(JSTaggedValue(object).GetHeapObject()); + } + static size_t ComputeSize(uint32_t num_slots) { return TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), num_slots + RESERVED_ENV_LENGTH); diff --git a/tests/checked/try_load_global_by_name.js b/tests/checked/try_load_global_by_name.js index ca1f791d6..7db1d66f4 100644 --- a/tests/checked/try_load_global_by_name.js +++ b/tests/checked/try_load_global_by_name.js @@ -48,12 +48,12 @@ //! METHOD "get_const" //! PASS_AFTER "IrBuilder" //! INST "Intrinsic.TryLdGlobalByName" -//! INST_COUNT "Constant", 1 +//! INST_COUNT "Constant", 2 //! PASS_AFTER "ExpandIntrinsics" //! INST_NOT "Intrinsic.TryLdGlobalByName" //! INST_NOT "DeoptimizeIf" //! INST_NOT "GetGlobalVarAddress" -//! INST_COUNT "Constant", 2 +//! INST_COUNT "Constant", 3 //! METHOD "get_always_throw" //! PASS_AFTER "Codegen" //! INST "Intrinsic.TryLdGlobalByName" diff --git a/tests/compiler/codegen_ecma_test.cpp b/tests/compiler/codegen_ecma_test.cpp index 823a6277f..4b38930ca 100644 --- a/tests/compiler/codegen_ecma_test.cpp +++ b/tests/compiler/codegen_ecma_test.cpp @@ -329,6 +329,9 @@ void CodegenEcmaTest::TestAnyTypeCheck(AnyBaseType any_type, uint64_t val) { auto graph = CreateEmptyGraph(); graph->SetDynamicMethod(); +#ifndef NDEBUG + graph->SetDynUnitTestFlag(); +#endif GRAPH(graph) { CONSTANT(0, val).any(); diff --git a/tests/compiler/expand_intrinsics_ecma_test.cpp b/tests/compiler/expand_intrinsics_ecma_test.cpp index 2a2434df9..e8b267098 100644 --- a/tests/compiler/expand_intrinsics_ecma_test.cpp +++ b/tests/compiler/expand_intrinsics_ecma_test.cpp @@ -28,42 +28,39 @@ public: TEST_F(ExpandIntrinsicsTest, LdLexVarDynApply) { constexpr uint32_t SLOT = 10U; - constexpr uint32_t INLINE_DEPTH = 0U; for (size_t level = 0U; level <= ExpandIntrinsics::GetLdLexVarDynLevelThreshold(); ++level) { auto graph = CreateGraphDynStubWithDefaultRuntime(); GRAPH(graph) { + PARAMETER(0, 0).any(); BASIC_BLOCK(2, -1) { - INST(0, Opcode::SaveState).NoVregs(); - INST(1, Opcode::Intrinsic) + INST(1, Opcode::LoadLexicalEnv).any().Inputs(0); + INST(2, Opcode::Intrinsic) .IntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LD_LEX_VAR_DYN) .any() - .Inputs({{DataType::NO_TYPE, 0}}) + .Inputs({{DataType::ANY, 1}}) .AddImm(level) .AddImm(SLOT); - INST(2, Opcode::Return).any().Inputs(1); + INST(3, Opcode::Return).any().Inputs(2); } } ASSERT_TRUE(graph->RunPass()); - ASSERT_TRUE(graph->RunPass()); + ASSERT_FALSE(graph->RunPass()); GraphChecker(graph).Check(); auto graph_opt = CreateGraphDynStubWithDefaultRuntime(); GRAPH(graph_opt) { + PARAMETER(11, 0).any(); CONSTANT(0, graph_opt->GetRuntime()->GetLexicalEnvParentEnvIndex()); CONSTANT(1, graph_opt->GetRuntime()->GetLexicalEnvStartDataIndex() + SLOT); BASIC_BLOCK(2, -1) { - INST(2, Opcode::Intrinsic) - .any() - .IntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LDLEXENV_DYN) - .AddImm(INLINE_DEPTH) - .ClearFlag(inst_flags::REQUIRE_STATE); + INST(2, Opcode::LoadLexicalEnv).any().Inputs(11); INST(3, Opcode::CastAnyTypeValue) .ref() .Inputs(2) @@ -93,41 +90,42 @@ TEST_F(ExpandIntrinsicsTest, LdLexVarDynSkip) { constexpr uint32_t LEVEL = ExpandIntrinsics::GetLdLexVarDynLevelThreshold() + 1U; constexpr uint32_t SLOT = 10U; - constexpr uint32_t INLINE_DEPTH = 0U; auto graph = CreateGraphDynStubWithDefaultRuntime(); GRAPH(graph) { + PARAMETER(0, 0).any(); BASIC_BLOCK(2, -1) { - INST(0, Opcode::SaveState).NoVregs(); - INST(1, Opcode::Intrinsic) + INST(1, Opcode::LoadLexicalEnv).any().Inputs(0); + INST(2, Opcode::Intrinsic) .IntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LD_LEX_VAR_DYN) .any() - .Inputs({{DataType::NO_TYPE, 0}}) + .Inputs({{DataType::ANY, 1}}) .AddImm(LEVEL) .AddImm(SLOT); - INST(2, Opcode::Return).any().Inputs(1); + INST(3, Opcode::Return).any().Inputs(2); } } - ASSERT_TRUE(graph->RunPass()); - ASSERT_TRUE(graph->RunPass()); + ASSERT_FALSE(graph->RunPass()); + ASSERT_FALSE(graph->RunPass()); GraphChecker(graph).Check(); auto graph_opt = CreateGraphDynStubWithDefaultRuntime(); GRAPH(graph_opt) { + PARAMETER(0, 0).any(); BASIC_BLOCK(2, -1) { - INST(0, Opcode::Intrinsic) + INST(1, Opcode::LoadLexicalEnv).any().Inputs(0); + INST(2, Opcode::Intrinsic) .IntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LD_LEX_VAR_DYN) .any() + .Inputs({{DataType::ANY, 1}}) .AddImm(LEVEL) - .AddImm(SLOT) - .AddImm(INLINE_DEPTH) - .ClearFlag(inst_flags::REQUIRE_STATE); - INST(1, Opcode::Return).any().Inputs(0); + .AddImm(SLOT); + INST(3, Opcode::Return).any().Inputs(2); } } @@ -139,48 +137,51 @@ TEST_F(ExpandIntrinsicsTest, LdLexDyn) constexpr uint32_t STRING_ID = 0xABCDU; constexpr uint32_t LEVEL = ExpandIntrinsics::GetLdLexVarDynLevelThreshold() + 1U; constexpr uint32_t SLOT = 10U; - constexpr uint32_t INLINE_DEPTH = 0U; auto graph = CreateGraphDynStubWithDefaultRuntime(); GRAPH(graph) { + PARAMETER(0, 0).any(); BASIC_BLOCK(2, -1) { - INST(0, Opcode::SaveState).NoVregs(); - INST(1, Opcode::Intrinsic) + INST(1, Opcode::LoadConstantPool).any().Inputs(0); + INST(2, Opcode::LoadLexicalEnv).any().Inputs(0); + INST(3, Opcode::SaveState).NoVregs(); + INST(4, Opcode::Intrinsic) .IntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LD_LEX_DYN) .any() - .Inputs({{DataType::NO_TYPE, 0}}) + .Inputs({{DataType::ANY, 1}, {DataType::ANY, 2}, {DataType::NO_TYPE, 3}}) .AddImm(STRING_ID) .AddImm(LEVEL) .AddImm(SLOT); - INST(2, Opcode::Return).any().Inputs(1); + INST(5, Opcode::Return).any().Inputs(4); } } ASSERT_TRUE(graph->RunPass()); - ASSERT_FALSE(graph->RunPass()); + ASSERT_TRUE(graph->RunPass()); GraphChecker(graph).Check(); auto graph_opt = CreateGraphDynStubWithDefaultRuntime(); GRAPH(graph_opt) { - CONSTANT(0, DataType::Any(panda::coretypes::TaggedValue::VALUE_HOLE)); - + PARAMETER(0, 0).any(); + CONSTANT(1, DataType::Any(panda::coretypes::TaggedValue::VALUE_HOLE)); BASIC_BLOCK(2, -1) { - INST(1, Opcode::SaveState).NoVregs(); + INST(3, Opcode::LoadLexicalEnv).any().Inputs(0); + INST(4, Opcode::SaveState).NoVregs(); // We do not check LdLexVarDyn expansion in this test! - INST(2, Opcode::Intrinsic) + INST(5, Opcode::Intrinsic) .IntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LD_LEX_VAR_DYN) .any() + .Inputs({{DataType::ANY, 3}}) .AddImm(LEVEL) .AddImm(SLOT) - .AddImm(INLINE_DEPTH) .ClearFlag(inst_flags::REQUIRE_STATE); - INST(3, Opcode::Compare).b().Inputs(2, 0).SrcType(DataType::ANY).CC(ConditionCode::CC_EQ); - INST(4, Opcode::DeoptimizeIf).Inputs(3, 1).DeoptimizeType(DeoptimizeType::HOLE); - INST(5, Opcode::Return).any().Inputs(2); + INST(6, Opcode::Compare).b().Inputs(5, 1).SrcType(DataType::ANY).CC(ConditionCode::CC_EQ); + INST(7, Opcode::DeoptimizeIf).Inputs(6, 4).DeoptimizeType(DeoptimizeType::HOLE); + INST(8, Opcode::Return).any().Inputs(5); } } -- Gitee