diff --git a/compiler/codegen_intrinsics_ecmascript.cpp b/compiler/codegen_intrinsics_ecmascript.cpp index 0031d8b55a7f39dc3a460d35cdb40af85c4abdce..30534d7377916178fdf59a41bffb7315cc866457 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 3fa409ee9321aaccc9f112c14b444cb364a228e2..a54856f6f75c6adad7cd8bb9214f0363d05b83fd 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 a407f9d85b503481f2b7a7f8b5f505eaf8468679..0a9683ec79c21e172e8ecc12acd939a69437ebf1 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 5facccee7e4a5fae3d2ce73a4212c1fb1c7a85a8..23b4429a04e1419e1ee514f1a336725f609b4ec3 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 84673c1b619537753ea569f60dc75f4d1cddfe05..d8cb2bbee9136dd2bcaa6bcafd29e2b5187fdb4c 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 4820fdfdad6bb11d89d372419fdef10741c07604..ace74e71c2a903e13f3626b40c34fc5d7a38df44 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 b228e37c4e8372ac2577ea342e9d9a3c63b60ef3..114ac3c2ebe3731e14b47b0f07ad87545fd5c0a4 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 1ea70fc6e5b4ff68b4e09987f7a9418555022402..76dddcf6966829ae399ca8efc1116b0eb013a912 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 4920f197082a1885b8bd3de7d8c1473603bc3e58..e6e7b9177bd913767e3d675b7fdf3ef3ad42cc43 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 674d6e4b82e128c15d99d58fac0b64777dd292ce..f8a5e4e0d2b2221883eee34475b44ceeb0f531cc 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 93ee637f7ec71a858c08c030272810ee96b72318..4866eb5e5de8588e1efa264ee266ca7085bcda75 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 3cd5dcca33d8c17898f592cae343f3f3aa2a7e71..698f2712fd811b41f309ab271a4689ebde27a4f2 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 c11fc3339ce6220cb653b7c57f5a536522abd8ea..104f39aefddf8844da73ffb2ae2ccf005e3c58bb 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 8a73062ff86a28aad35981fb2296d3a3582e1923..4b1fd16b45e61a27220516586a36fd1ca312f3c7 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 3c19ce0fab850adc760672c863e75e3d97164ae1..9c02ac2eaa5297b6a67651cd72b81ecf35a5e5de 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 02ed39d212e674ffdb4bcfe03abf528546ba49d5..7653d023beb2dcaa9ed2237ba39fb0c44f8aef4c 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 0d3b956e3197947f5ef3a90003cdb90135b380a2..9e50ebb88a158c3c350c09486deac81428061e27 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 2ec92d391e96d40734fa5485b18ed65684cfe4bc..fe7943aa0d5483ae3ad37146ede5123abe4747b4 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 a6064ba5a1056c7feb6de766f21f2158e04e4ce6..86d9712f5a45ec4033cfb203ba85798fab77d108 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 c1093baf80719527ca38b5ce55f969f7a88b68e7..72588841c2ff958b6788b6e66496cf9c9b9e4de1 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 56b389e6ec2b431ae19ffa148547236bd98ac11e..19bb57592d7b8295215458ae9092cd43323446f6 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 d6785f1632bd77f56a641858ce4aeb52f5a8a6c1..1f65697ba8d940569d54d0b7f1af276eb5ced178 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 73245ee68f41b18357bcc14fb74d9923d7c7a718..8cefcfc1464ed549a50f2184c1476751562deb50 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 b25067f2cf9dddfb0e0ce94550182eceade008f2..b7ec883db8854d87207082c7db34da10c6935831 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 6c2db5b400b5bc94bf3060cd9a0e10cebeb409cb..b962ae834617885481f8e7368bdd06d4ce45f968 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 df57a0c21b5a7dca86ddea22b6fc21c57610edbb..79013806bddf210a01a124a91df083565b255adc 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 2764c9182dc40ae5c94a07f29ff2fb1a92390fac..8e7d4fd49c50ae1d6f3400037d1ec7274b0bfd7c 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 9ff93ce4d3e49d6f57d05cb52a20247b988bc7e1..526474811ba723671375b9fa9737bb7d07f3df30 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 ea77d595b3aab2d53eff72913671d1d8e2304632..9e7c26d68873d727310d696e5d96756baf015bfc 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 95b35f57103494b3f86bcc4eae592a0dc4595d1d..9f5b0ab4c0ea4946b940a5286857e5e51482d724 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 d72102925f7fd1f21a8b751bc7406ceb767c879a..bb77bde5dc0a8cd51d1fa136dc56cd93609037a4 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 a6f2a7b7f4c93950ebda9b1d0c478f1cb867c663..97522c7106fe3fdb3ef860737ce1cf8ef0a2b885 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 9c72d7384c09e6aad86bb03bece1eb6246245287..df44505c2f0039f7b94adc978ccce8af79b58111 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 ac807d878c1ca293e5ef043346f30b86436628dc..df13b36d5382d61301507583bfeb5c8d71c684bb 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 e2f94fdee4b84719350ddf5fc53bc9b31cccf4f7..37ee34601d364161d751f7099445504e69e58537 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 5556ccc741c62cedea062213140ad83dca5e4193..e5093800e985dfe511b4285427bc2be8f3081f3c 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 13cda0835fe2031399ae3974c72e7d57bff206c4..415753971b700bd9e51346c674b0dcd0bc11ce28 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 9606618f319cc0b1ddf0079df34777e63b40ab14..552bc97fde15ab8f67bbf2e638f2e37f6353e6f8 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 7b532f72f0fa8571cb885f332a7954fb1e810ee5..300bdf0cd3d04152e6b5c24854466316aa27bf89 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 ca1f791d697540fa194226d0106c155f4b77fdee..7db1d66f489d4602cb72cff1bc0ac6c2e2903a3d 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 823a6277f4ea1f2cbabcc1fbf35ac288e57d2e9d..4b38930cad3244d25d0dddeecf2f07d994914250 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 2a2434df93dc362be3ec2285795772aa6a42c43a..e8b26709870097d8db92c2e1f706772579e440ca 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); } }