From 04d98dd10377a459307aa018fd5480a72bcab3a5 Mon Sep 17 00:00:00 2001 From: vagin ivan Date: Mon, 22 Aug 2022 15:11:02 +0300 Subject: [PATCH] Implemented irtoc handlers Signed-off-by: vagin ivan --- ecmastdlib/ecmastdlib.pa | 7 +- irtoc_scripts/interpreter_handlers.irt | 1 - irtoc_scripts/interpreter_main_loop.irt | 173 ++++++++++++++++++++++-- isa/isa.yaml | 6 +- runtime/ecma_runtime.yaml | 59 +++++++- runtime/intrinsics-inl.h | 111 ++++++++++++--- 6 files changed, 323 insertions(+), 34 deletions(-) diff --git a/ecmastdlib/ecmastdlib.pa b/ecmastdlib/ecmastdlib.pa index 5358c0f2e..34cba78fe 100644 --- a/ecmastdlib/ecmastdlib.pa +++ b/ecmastdlib/ecmastdlib.pa @@ -84,6 +84,7 @@ .function any Ecmascript.Intrinsics.ldlexenvDyn() .function void Ecmascript.Intrinsics.popLexenvDyn() .function any Ecmascript.Intrinsics.getUnmappedArgs() +.function any Ecmascript.Intrinsics.getUnmappedArgsInterp() .function any Ecmascript.Intrinsics.toboolean(any a0) .function any Ecmascript.Intrinsics.negate(any a0) .function any Ecmascript.Intrinsics.isUndefined(any a0) @@ -95,7 +96,9 @@ .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) +.function any Ecmascript.Intrinsics.suspendGeneratorInterp(any a0, any a1, any a2) .function any Ecmascript.Intrinsics.suspendAsyncGenerator(any a0, any a1) +.function any Ecmascript.Intrinsics.suspendAsyncGeneratorInterp(any a0, any a1, any a2) .function any Ecmascript.Intrinsics.resumeGenerator(any a0) .function any Ecmascript.Intrinsics.getResumeMode(any a0) .function any Ecmascript.Intrinsics.createGeneratorObj(any a0) @@ -112,6 +115,7 @@ .function void Ecmascript.Intrinsics.throwConstAssignment(u32 a0) .function any Ecmascript.Intrinsics.throwUndefinedIfHole(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.getTemplateObject(any a0) @@ -132,6 +136,7 @@ .function any Ecmascript.Intrinsics.Call2Dyn(any a0, any a1, any a2) .function any Ecmascript.Intrinsics.Call3Dyn(any a0, any a1, any a2, any a3) .function any Ecmascript.Intrinsics.CalliRangeDyn(u16 a0, any a1) +.function any Ecmascript.Intrinsics.CalliRangeDynInterp(u16 a0, any a1) .function any Ecmascript.Intrinsics.CalliThisRangeDyn(u16 a0, any a1) .function any Ecmascript.Intrinsics.createemptyobject() .function any Ecmascript.Intrinsics.createobjectwithbuffer(u16 a0) @@ -156,7 +161,7 @@ .function void Ecmascript.Intrinsics.CopyModule(any a0) .function any Ecmascript.Intrinsics.LdModvarByName(u32 a0, any a1) .function any Ecmascript.Intrinsics.DefineClassWithBuffer(u32 a0, u16 a1, any a2, any a3) -.function any Ecmascript.Intrinsics.SuperCall(u16 a0, any a1, any a2) +.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) diff --git a/irtoc_scripts/interpreter_handlers.irt b/irtoc_scripts/interpreter_handlers.irt index f2fa1a322..5dae0e8c5 100644 --- a/irtoc_scripts/interpreter_handlers.irt +++ b/irtoc_scripts/interpreter_handlers.irt @@ -30,7 +30,6 @@ macro(:ecma_intrinsic_check_setacc) do |sym, size, *args| frame := Phi(frame_eh, frame).ptr pc := Phi(pc_eh, pc_inc).ptr acc := Phi(acc_eh, acc.u64).u64 - acc_tag := Phi(acc_tag_eh, acc_tag.u64).u64 end macro(:ecma_intrinsic_invoke) do |sym, *args| diff --git a/irtoc_scripts/interpreter_main_loop.irt b/irtoc_scripts/interpreter_main_loop.irt index cf912ddac..ad9867072 100644 --- a/irtoc_scripts/interpreter_main_loop.irt +++ b/irtoc_scripts/interpreter_main_loop.irt @@ -47,6 +47,8 @@ when "ECMA_SHR2DYN_PREF_V8" acc := handle_ecma_shr2dyn(vreg_value(op[0]), acc) # ecma_intrinsic_setacc("Shr2Dyn", vreg_value(op[0]).u64, acc.u64) + when "ECMA_ASHR2DYN_PREF_V8" + ecma_intrinsic_setacc("Ashr2Dyn", vreg_value(op[0]).any, acc.any) when "ECMA_STRICTEQDYN_PREF_V8" acc := handle_ecma_stricteqdyn(vreg_value(op[0]), acc) when "ECMA_STRICTNOTEQDYN_PREF_V8" @@ -112,16 +114,70 @@ ecma_intrinsic_setacc("Ldnan") when "ECMA_ISUNDEFINED_PREF_NONE" acc := handle_ecma_isundefined(acc.any) + when "ECMA_ISTRUE_PREF_NONE" + ecma_intrinsic_setacc("IsTrue", acc.any) + when "ECMA_ISFALSE_PREF_NONE" + ecma_intrinsic_setacc("IsFalse", acc.any) + when "ECMA_ISINDYN_PREF_V8" + ecma_intrinsic_setacc("IsinDyn", vreg_value(op[0]).any, acc.any) + when "ECMA_ISCOERCIBLE_PREF_NONE" + ecma_intrinsic_setacc("IsCoercible", acc.any) when "ECMA_CREATEOBJECTWITHBUFFER_PREF_IMM16" ecma_intrinsic_setacc("CreateObjectWithBuffer", as_imm(op[0])) + when "ECMA_CREATEOBJECTHAVINGMETHOD_PREF_IMM16" + ecma_intrinsic_setacc("CreateObjectHavingMethod", as_imm(op[0]), acc.any) + 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" + ecma_intrinsic_setacc("CreateEmptyObject") when "ECMA_GETPROPITERATOR_PREF_NONE" ecma_intrinsic_setacc("GetPropIterator", acc.u64) when "ECMA_GETNEXTPROPNAME_PREF_V8" acc := handle_ecma_getnextpropname(vreg_value(op[0]).u64) + when "ECMA_COPYDATAPROPERTIES_PREF_V8_V8" + ecma_intrinsic_setacc("CopyDataProperties", vreg_value(op[0]).any, vreg_value(op[1]).any) + when "ECMA_SETOBJECTWITHPROTO_PREF_V8_V8" + ecma_intrinsic_invoke("SetObjectWithProto", vreg_value(op[0]).any, vreg_value(op[1]).any) + when "ECMA_GETTEMPLATEOBJECT_PREF_V8" + ecma_intrinsic_setacc("GetTemplateObject", vreg_value(op[0]).any) # ecma runtime when "ECMA_DEFINEFUNCDYN_PREF_ID16_V8" ecma_intrinsic_setacc("DefinefuncDyn", as_id(op[0]), vreg_value(op[1]).u64) + when "ECMA_DEFINEGENERATORFUNC_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineGeneratorFunc", as_id(op[0]), vreg_value(op[1]).any) + when "ECMA_DEFINENCFUNCDYN_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineNCFuncDyn", as_id(op[0]), vreg_value(op[1]).any, acc.any) + when "ECMA_DEFINEASYNCFUNC_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineAsyncFunc", as_id(op[0]), vreg_value(op[1]).any) + when "ECMA_ASYNCFUNCTIONENTER_PREF_NONE" + ecma_intrinsic_setacc("AsyncFunctionEnter") + when "ECMA_ASYNCFUNCTIONRESOLVE_PREF_V8" + ecma_intrinsic_setacc("AsyncFunctionResolve", vreg_value(op[0]).any, acc.any) + when "ECMA_ASYNCFUNCTIONAWAIT_PREF_V8" + ecma_intrinsic_setacc("AsyncFunctionAwait", vreg_value(op[0]).any, acc.any) + when "ECMA_ASYNCFUNCTIONREJECT_PREF_V8" + ecma_intrinsic_setacc("AsyncFunctionReject", vreg_value(op[0]).any, acc.any) + 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) + when "ECMA_DEFINEMETHOD_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineMethod", as_id(op[0]), vreg_value(op[1]).any, acc.any) + 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" + ecma_intrinsic_setacc("TypeofDyn", acc.any) + when "ECMA_INSTANCEOFDYN_PREF_V8" + ecma_intrinsic_setacc("InstanceofDyn", vreg_value(op[0]).any, acc.any) + 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) + when "ECMA_GETRESUMEMODE_PREF_V8" + ecma_intrinsic_setacc("GetResumeMode", vreg_value(op[0]).any) + when "ECMA_GETUNMAPPEDARGS_PREF_NONE" + ecma_intrinsic_setacc("GetUnmappedArgsInterp") + when "ECMA_COPYRESTARGS_PREF_IMM16" + ecma_intrinsic_setacc("CopyrestargsInterp", as_imm(op[0])) # ecma frames when "ECMA_CALL0DYN_PREF_V8" @@ -132,31 +188,64 @@ ecma_intrinsic_check_setacc("Call2Dyn", i.format.size, vreg_value(op[0]).u64, vreg_value(op[1]).u64, vreg_value(op[2]).u64) when "ECMA_CALL3DYN_PREF_V8_V8_V8_V8" ecma_intrinsic_check_setacc("Call3Dyn", i.format.size, vreg_value(op[0]).u64, vreg_value(op[1]).u64, vreg_value(op[2]).u64, vreg_value(op[3]).u64) + when "ECMA_CALLSPREADDYN_PREF_V8_V8_V8" + ecma_intrinsic_setacc("CallspreadDyn", vreg_value(op[0]).any, vreg_value(op[1]).any, vreg_value(op[2]).any) + when "ECMA_NEWOBJSPREADDYN_PREF_V8_V8" + ecma_intrinsic_setacc("NewobjspreadDyn", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any) + when "ECMA_SUPERCALLSPREAD_PREF_V8" + method_ptr := LoadI(%frame).Imm(Constants::FRAME_METHOD_OFFSET).ptr + num_vregs := u32toword(read_uleb(method_file_data(method_ptr))) + new_target_idx := AddI(num_vregs).Imm(1).word + new_target := get_value(frame_vreg_ptr(%frame, new_target_idx)) + ecma_intrinsic_setacc("SuperCallSpread", vreg_value(op[0]).any, new_target, acc.any) when "ECMA_LDLEXENVDYN_PREF_NONE" acc := handle_ecma_ldlexenvdyn() + when "ECMA_POPLEXENVDYN_PREF_NONE" + ecma_intrinsic_invoke("popLexenvDyn") when "ECMA_NEWLEXENVDYN_PREF_IMM16" ecma_intrinsic_setacc("NewlexenvDyn", as_imm(op[0])) + when "ECMA_COPYLEXENVDYN_PREF_NONE" + ecma_intrinsic_setacc("CopylexenvDyn") when "ECMA_STLEXVARDYN_PREF_IMM4_IMM4" - ecma_intrinsic_setacc("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) when "ECMA_STLEXVARDYN_PREF_IMM8_IMM8" - ecma_intrinsic_setacc("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64) - when "ECMA_LEXVARDYN_PREF_IMM16_IMM16" - ecma_intrinsic_setacc("StLexVarDyn", as_imm(op[0]), as_imm(op[1]), acc.u64) + ecma_intrinsic_invoke("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64) + when "ECMA_STLEXVARDYN_PREF_IMM16_IMM16" + ecma_intrinsic_invoke("StLexVarDyn", as_imm(op[0]), as_imm(op[1]), acc.u64) when "ECMA_LDLEXVARDYN_PREF_IMM4_IMM4" ecma_intrinsic_setacc("LdLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1]))) when "ECMA_LDLEXVARDYN_PREF_IMM8_IMM8" ecma_intrinsic_setacc("LdLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1]))) when "ECMA_LDLEXVARDYN_PREF_IMM16_IMM16" ecma_intrinsic_setacc("LdLexVarDyn", as_imm(op[0]), as_imm(op[1])) - when "ECMA_CREATEEMPTYOBJECT_PREF_NONE" - ecma_intrinsic_setacc("CreateEmptyObject") + when "ECMA_LDHOMEOBJECT_PREF_NONE" + ecma_intrinsic_setacc("LdHomeObject") when "ECMA_RETURNUNDEFINED_PREF_NONE" - acc := 10 + handle_ecma_ldconst(Constants::VALUE_UNDEFINED) + StoreI(%frame, acc).Imm(Constants::GET_ACC_OFFSET).send(acc.type) Intrinsic(:INTERPRETER_RETURN).ptr when "ECMA_RETURN_DYN_PREF_NONE" Intrinsic(:INTERPRETER_RETURN).ptr when "ECMA_CREATEARRAYWITHBUFFER_PREF_IMM16" ecma_intrinsic_setacc("CreateArrayWithBuffer", as_imm(op[0])) + when "ECMA_CREATEEMPTYARRAY_PREF_NONE" + ecma_intrinsic_setacc("CreateEmptyArray") + when "ECMA_STARRAYSPREAD_PREF_V8_V8" + ecma_intrinsic_setacc("StArraySpread", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any) + + # ecma range calls + when "ECMA_CALLITHISRANGEDYN_PREF_IMM16_V8" + ecma_intrinsic_check_setacc("CalliThisRangeDyn", i.format.size, as_imm(op[0]), vreg_ptr(op[1])) + when "ECMA_CALLIRANGEDYN_PREF_IMM16_V8" + ecma_intrinsic_check_setacc("CalliRangeDynInterp", i.format.size, i8tou16(as_imm(op[0])), vreg_ptr(op[1])) + when "ECMA_NEWOBJDYNRANGE_PREF_IMM16_V8" + ecma_intrinsic_setacc("NewobjDynrange", i8tou16(as_imm(op[0])), vreg_ptr(op[1])) + when "ECMA_SUPERCALL_PREF_IMM16_V8" + method_ptr := LoadI(%frame).Imm(Constants::FRAME_METHOD_OFFSET).ptr + num_vregs := u32toword(read_uleb(method_file_data(method_ptr))) + new_target_idx := AddI(num_vregs).Imm(1).word + new_target := get_value(frame_vreg_ptr(%frame, new_target_idx)) + ecma_intrinsic_setacc("SuperCall", as_imm(op[0]), vreg_ptr(op[1]), new_target, acc.any) # ecma load/stores by index when "ECMA_STOBJBYINDEX_PREF_IMM8_V8" @@ -185,20 +274,68 @@ handle_ecma_stobjbyvalue(vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any, ins_offset) when "ECMA_LDOBJBYVALUE_PREF_V8_V8" acc := handle_ecma_ldobjbyvalue(vreg_value(op[0]).any, vreg_value(op[1]).any, ins_offset) + when "ECMA_LDSUPERBYVALUE_PREF_V8_V8" + ecma_intrinsic_setacc("LdSuperByValue", vreg_value(op[0]).any, vreg_value(op[1]).any) + 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) when "ECMA_LDOBJBYNAME_PREF_ID32_V8" acc := handle_ecma_ldobjbyname(vreg_value(op[1]).any, as_id(op[0]), ins_offset) + when "ECMA_LDSUPERBYNAME_PREF_ID32_V8" + ecma_intrinsic_setacc("LdSuperByName", as_id(op[0]), vreg_value(op[1]).any) + when "ECMA_STSUPERBYNAME_PREF_ID32_V8" + ecma_intrinsic_invoke("StSuperByName", as_id(op[0]), vreg_value(op[1]).any, acc.any) + when "ECMA_STOWNBYNAME_PREF_ID32_V8" + ecma_intrinsic_invoke("StOwnByName", as_id(op[0]), vreg_value(op[1]).any, acc.any) # 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) + when "ECMA_TRYSTGLOBALBYNAME_PREF_ID32" + ecma_intrinsic_invoke("TryStGlobalByName", as_id(op[0]), acc.any, ins_offset) when "ECMA_LDGLOBALVAR_PREF_ID32" acc := handle_ecma_ldglobalvar(as_id(op[0]), ins_offset) when "ECMA_STGLOBALVAR_PREF_ID32" handle_ecma_stglobalvar(as_id(op[0]), acc.any, ins_offset) + when "ECMA_STGLOBALLET_PREF_ID32" + ecma_intrinsic_invoke("StGlobalLet", as_id(op[0]), acc.any) + + # ecma generators + when "ECMA_CREATEGENERATOROBJ_PREF_V8" + ecma_intrinsic_setacc("CreateGeneratorObj", vreg_value(op[0]).any) + when "ECMA_SUSPENDGENERATOR_PREF_V8" + ecma_intrinsic_setacc("SuspendGeneratorInterp", vreg_value(op[0]).any, acc.any, ins_offset.u64) + handle_return() + when "ECMA_SETGENERATORSTATE_PREF_V8_IMM8" + ecma_intrinsic_invoke("SetGeneratorState", vreg_value(op[0]).any, i8tou16(as_imm(op[1]))) + when "ECMA_RESUMEGENERATOR_PREF_V8" + ecma_intrinsic_setacc("ResumeGenerator", vreg_value(op[0]).any) + when "ECMA_CREATEITERRESULTOBJ_PREF_IMM8" + ecma_intrinsic_setacc("CreateIterResultObj", acc.any, as_imm(op[0])) + + 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) + when "ECMA_GETASYNCITERATOR_PREF_NONE" + ecma_intrinsic_setacc("GetAsyncIterator", acc.u64) + when "ECMA_ASYNCGENERATORRESOLVE_PREF_V8" + ecma_intrinsic_setacc("AsyncGeneratorResolve", vreg_value(op[0]).any, acc.any) + when "ECMA_SUSPENDASYNCGENERATOR_PREF_V8" + ecma_intrinsic_setacc("SuspendAsyncGeneratorInterp", vreg_value(op[0]).any, acc.any, ins_offset.u64) + handle_return() + when "ECMA_ASYNCGENERATORREJECT_PREF_V8" + ecma_intrinsic_setacc("AsyncGeneratorReject", vreg_value(op[0]).any, acc.any) + + when "ECMA_GETITERATOR_PREF_NONE" + ecma_intrinsic_setacc("GetIterator", acc.any) + when "ECMA_CLOSEITERATOR_PREF_V8" + ecma_intrinsic_setacc("CloseIterator", vreg_value(op[0]).any, acc.any) # ecma exceptions when "ECMA_THROWDYN_PREF_NONE" @@ -206,6 +343,26 @@ pc := find_catch_block() frame := frame_eh acc := acc_eh - acc_tag := acc_tag_eh + when "ECMA_THROWCONSTASSIGNMENT_PREF_ID32" + ecma_intrinsic_invoke("ThrowConstAssignment", as_id(op[0])) + pc := find_catch_block() + frame := frame_eh + acc := acc_eh + when "ECMA_THROWPATTERNNONCOERCIBLE_PREF_NONE" + ecma_intrinsic_invoke("ThrowPatternNonCoercible") + pc := find_catch_block() + frame := frame_eh + acc := acc_eh + when "ECMA_THROWTHROWNOTEXISTS_PREF_NONE" + ecma_intrinsic_invoke("ThrowThrowNotExists") + pc := find_catch_block() + frame := frame_eh + acc := acc_eh when "ECMA_THROWUNDEFINEDIFHOLE_PREF_ID32" ecma_intrinsic_setacc("ThrowUndefinedIfHole", as_id(op[0]), acc.any) + when "ECMA_THROWIFNOTOBJECT_PREF_NONE" + ecma_intrinsic_invoke("ThrowIfNotObject", acc.any) + when "ECMA_THROWIFSUPERNOTCORRECTCALL_PREF_IMM16" + ecma_intrinsic_invoke("ThrowIfSuperNotCorrectCall", i8tou16(as_imm(op[0])), acc.any) + when "ECMA_RETHROWDYN_PREF_NONE" + ecma_intrinsic_invoke("RethrowDyn", acc.any) diff --git a/isa/isa.yaml b/isa/isa.yaml index cd2108209..659de8815 100644 --- a/isa/isa.yaml +++ b/isa/isa.yaml @@ -726,17 +726,17 @@ groups: format: [pref_op_imm1_16_imm2_16] intrinsic_name: INTRINSIC_LD_LEX_VAR_DYN - sig: ecma.stlexvardyn imm1, imm2 - acc: inout:top + acc: in:top prefix: ecma format: [pref_op_imm1_4_imm2_4] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN - sig: ecma.stlexvardyn imm1, imm2 - acc: inout:top + acc: in:top prefix: ecma format: [pref_op_imm1_8_imm2_8] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN - sig: ecma.stlexvardyn imm1, imm2 - acc: inout:top + acc: in:top prefix: ecma format: [pref_op_imm1_16_imm2_16] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN diff --git a/runtime/ecma_runtime.yaml b/runtime/ecma_runtime.yaml index d4d094d22..b7138a607 100644 --- a/runtime/ecma_runtime.yaml +++ b/runtime/ecma_runtime.yaml @@ -781,6 +781,17 @@ intrinsics: args: [] impl: panda::ecmascript::intrinsics::GetUnmappedArgs +- name: GetUnmappedArgsInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: getUnmappedArgsInterp + static: true + exception: true + signature: + ret: any + args: [] + impl: panda::ecmascript::intrinsics::GetUnmappedArgsInterp + - name: Toboolean space: ecmascript class_name: Ecmascript.Intrinsics @@ -891,7 +902,7 @@ intrinsics: args: [acc, u8] impl: panda::ecmascript::intrinsics::CreateIterResultObj -- name: SuspendGenerator +- name: suspendGenerator space: ecmascript class_name: Ecmascript.Intrinsics method_name: suspendGenerator @@ -902,6 +913,17 @@ intrinsics: args: [any, acc] impl: panda::ecmascript::intrinsics::SuspendGenerator +- name: suspendGeneratorInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: suspendGeneratorInterp + static: true + exception: true + signature: + ret: any + args: [any, acc, any] + impl: panda::ecmascript::intrinsics::SuspendGeneratorInterp + - name: SuspendAsyncGenerator space: ecmascript class_name: Ecmascript.Intrinsics @@ -913,6 +935,17 @@ intrinsics: args: [any, acc] impl: panda::ecmascript::intrinsics::SuspendAsyncGenerator +- name: SuspendAsyncGeneratorInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: suspendAsyncGeneratorInterp + static: true + exception: true + signature: + ret: any + args: [any, acc, any] + impl: panda::ecmascript::intrinsics::SuspendAsyncGeneratorInterp + - name: ResumeGenerator space: ecmascript class_name: Ecmascript.Intrinsics @@ -1104,6 +1137,17 @@ intrinsics: args: [u16] impl: panda::ecmascript::intrinsics::Copyrestargs +- name: CopyrestargsInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: copyrestargsInterp + static: true + exception: true + signature: + ret: any + args: [u16] + impl: panda::ecmascript::intrinsics::CopyrestargsInterp + - name: Ldhole space: ecmascript class_name: Ecmascript.Intrinsics @@ -1324,6 +1368,17 @@ intrinsics: args: [u16, any] impl: panda::ecmascript::intrinsics::CalliRangeDyn +- name: CalliRangeDynInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: CalliRangeDynInterp + static: true + exception: true + signature: + ret: any + args: [u16, any] + impl: panda::ecmascript::intrinsics::CalliRangeDynInterp + - name: CalliThisRangeDyn space: ecmascript class_name: Ecmascript.Intrinsics @@ -1590,7 +1645,7 @@ intrinsics: exception: true signature: ret: any - args: [u16, any, acc] + args: [u16, any, any, acc] impl: panda::ecmascript::intrinsics::SuperCall - name: SuperCallSpread diff --git a/runtime/intrinsics-inl.h b/runtime/intrinsics-inl.h index aba490471..d339bd8f7 100644 --- a/runtime/intrinsics-inl.h +++ b/runtime/intrinsics-inl.h @@ -19,6 +19,7 @@ #include #include "intrinsics.h" +#include "macros.h" #include "runtime/include/method-inl.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" #include "plugins/ecmascript/runtime/interpreter/slow_runtime_stub.h" @@ -557,12 +558,10 @@ INLINE_ECMA_INTRINSICS uint64_t DefinefuncDyn(JSThread *thread, uint32_t methodI return result.GetTaggedValue().GetRawData(); } -// a0 is args' length which include ctor and new_target, and a1 is the start index of args // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t NewobjDynrange([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint16_t numArgs, - [[maybe_unused]] uint64_t a1) +INLINE_ECMA_INTRINSICS uint64_t NewobjDynrange(JSThread *thread, uint16_t args_num, uint64_t args) { - UNREACHABLE(); + return SlowRuntimeStub::NewObjDynRange(thread, args_num, reinterpret_cast(args)).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -597,6 +596,17 @@ INLINE_ECMA_INTRINSICS uint64_t GetUnmappedArgs([[maybe_unused]] JSThread *threa UNREACHABLE(); } +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t GetUnmappedArgsInterp(JSThread *thread) +{ + ASSERT(!thread->IsCurrentFrameCompiled()); + uint32_t actual_num_args = thread->GetCurrentFrame()->GetNumActualArgs() - NUM_MANDATORY_JSFUNC_ARGS; + uint32_t start_idx = thread->GetCurrentFrame()->GetMethod()->GetNumVregs() + NUM_MANDATORY_JSFUNC_ARGS; + auto args = reinterpret_cast(&thread->GetCurrentFrame()->GetVReg(start_idx)); + return SlowRuntimeStub::GetUnmappedArgs(thread, actual_num_args, reinterpret_cast(args)) + .GetRawData(); +} + // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t Negate(uint64_t value) { @@ -641,12 +651,30 @@ INLINE_ECMA_INTRINSICS uint64_t SuspendGenerator([[maybe_unused]] JSThread *thre } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t SuspendAsyncGenerator([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint64_t a0, - [[maybe_unused]] uint64_t a1) +INLINE_ECMA_INTRINSICS uint64_t SuspendGeneratorInterp(JSThread *thread, uint64_t gen_obj, uint64_t value, uint64_t pc) +{ + ASSERT(!thread->IsCurrentFrameCompiled()); + thread->GetCurrentFrame()->SetBytecodeOffset(pc); + return SlowRuntimeStub::SuspendGenerator(thread, JSTaggedValue(gen_obj), JSTaggedValue(value)).GetRawData(); +} + +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t SuspendAsyncGenerator([[maybe_unused]] JSThread *thread, + [[maybe_unused]] uint64_t gen_obj, + [[maybe_unused]] uint64_t value) { UNREACHABLE(); } +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t SuspendAsyncGeneratorInterp(JSThread *thread, uint64_t gen_obj, uint64_t value, + uint64_t pc) +{ + ASSERT(!thread->IsCurrentFrameCompiled()); + thread->GetCurrentFrame()->SetBytecodeOffset(pc); + return SlowRuntimeStub::SuspendAsyncGenerator(thread, JSTaggedValue(gen_obj), JSTaggedValue(value)).GetRawData(); +} + // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS void ThrowUndefined([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint64_t objValue) { @@ -659,6 +687,22 @@ INLINE_ECMA_INTRINSICS uint64_t Copyrestargs([[maybe_unused]] JSThread *thread, UNREACHABLE(); } +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t CopyrestargsInterp(JSThread *thread, uint16_t index) +{ + ASSERT(!thread->IsCurrentFrameCompiled()); + auto *frame = thread->GetCurrentFrame(); + uint32_t num_vregs = frame->GetMethod()->GetNumVregs(); + int32_t actual_num_args = frame->GetNumActualArgs() - NUM_MANDATORY_JSFUNC_ARGS; + int32_t tmp = actual_num_args - index; + uint32_t rest_num_args = (tmp > 0) ? tmp : 0; + uint32_t start_idx = num_vregs + NUM_MANDATORY_JSFUNC_ARGS + index; + + auto args = reinterpret_cast(&thread->GetCurrentFrame()->GetVReg(start_idx)); + + return SlowRuntimeStub::CopyRestArgs(thread, rest_num_args, args).GetRawData(); +} + // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t Ldhole() { @@ -724,12 +768,40 @@ INLINE_ECMA_INTRINSICS uint64_t CalliRangeDyn([[maybe_unused]] JSThread *thread, UNREACHABLE(); } -// Just declared here, not used // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CalliThisRangeDyn([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint16_t num, - [[maybe_unused]] uint64_t objValue) +INLINE_ECMA_INTRINSICS uint64_t CalliRangeDynInterp(JSThread *thread, uint16_t args_num, uint64_t args_ptr) { - UNREACHABLE(); + auto args = reinterpret_cast(args_ptr); + thread_local std::vector args_vec; + const size_t actual_num_args = args_num + NUM_MANDATORY_JSFUNC_ARGS; + args_vec.reserve(actual_num_args); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + auto fn_object = args[0]; + args_vec = {fn_object, JSTaggedValue::Undefined(), JSTaggedValue::Undefined()}; + for (int i(0); i < args_num; ++i) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + args_vec[i + NUM_MANDATORY_JSFUNC_ARGS] = args[i + 1]; + } + + return HandlerCall(thread, fn_object, args_vec.data(), actual_num_args).GetRawData(); +} + +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t CalliThisRangeDyn(JSThread *thread, uint16_t args_num, uint64_t args_ptr) +{ + auto args = reinterpret_cast(args_ptr); + thread_local std::vector args_vec; + const size_t actual_num_args = args_num + NUM_MANDATORY_JSFUNC_ARGS - 1; + args_vec.reserve(actual_num_args); + auto fn_object = args[0]; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + args_vec = {fn_object, JSTaggedValue::Undefined(), args[1]}; + for (int i(0); i < args_num - 1; ++i) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + args_vec[i + NUM_MANDATORY_JSFUNC_ARGS] = args[i + 2]; + } + + return HandlerCall(thread, fn_object, args_vec.data(), actual_num_args).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -1645,12 +1717,12 @@ INLINE_ECMA_INTRINSICS void ThrowThrowNotExists(JSThread *thread) } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CreateObjectWithExcludedKeys([[maybe_unused]] JSThread *thread, - [[maybe_unused]] uint16_t numKeys, - [[maybe_unused]] uint64_t objValue, - [[maybe_unused]] uint64_t a0) +INLINE_ECMA_INTRINSICS uint64_t CreateObjectWithExcludedKeys(JSThread *thread, uint16_t numKeys, uint64_t obj_value, + uint64_t excluded_keys) { - UNREACHABLE(); + return SlowRuntimeStub::CreateObjectWithExcludedKeys(thread, numKeys, JSTaggedValue(obj_value), + reinterpret_cast(excluded_keys)) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -1728,12 +1800,13 @@ INLINE_ECMA_INTRINSICS uint64_t DefineClassWithBuffer(JSThread *thread, uint32_t return res.GetRawData(); } -// Just declared here, not used // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t SuperCall([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint16_t range, - [[maybe_unused]] uint64_t firstVRegValue, [[maybe_unused]] uint64_t objValue) +INLINE_ECMA_INTRINSICS uint64_t SuperCall(JSThread *thread, uint16_t range, uint64_t args, uint64_t new_target, + uint64_t obj_value) { - UNREACHABLE(); + return SlowRuntimeStub::SuperCall(thread, JSTaggedValue(obj_value), JSTaggedValue(new_target), range, + reinterpret_cast(args)) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) -- Gitee