From fa5f87fa9319eb4483cf102ada99d1ec48a17001 Mon Sep 17 00:00:00 2001 From: Anna Antipina Date: Thu, 4 Aug 2022 13:53:27 +0300 Subject: [PATCH] Implement exceptions throwing and handling in irtoc. Signed-off-by: Anna Antipina --- ecmascript_plugin_options.yaml | 3 --- irtoc_scripts/interpreter_handlers.irt | 11 ++++++++ irtoc_scripts/interpreter_main_loop.irt | 16 +++++------- tests/runtime/irtoc/advanced/advanced.js | 24 +++++++++++++++++- tests/runtime/irtoc/basic/basic.js | 32 ++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 14 deletions(-) diff --git a/ecmascript_plugin_options.yaml b/ecmascript_plugin_options.yaml index 4adf5cda8..191e9a709 100644 --- a/ecmascript_plugin_options.yaml +++ b/ecmascript_plugin_options.yaml @@ -72,9 +72,6 @@ - ParamMetadata: new_class_name: panda::pandasm::extensions::ecmascript::ParamMetadata header_path: plugins/ecmascript/assembler/extension/ecmascript_meta.h - irtoc_files: - - plugins_interpreter_handlers: plugins/ecmascript/irtoc_scripts/interpreter_handlers.irt - - plugins_main_loop: plugins/ecmascript/irtoc_scripts/interpreter_main_loop.irt runtime_defines: defines_header_path: plugins/ecmascript/runtime/asm_defines/defines.h asm_defines_def: plugins/ecmascript/runtime/asm_defines/asm_defines.def diff --git a/irtoc_scripts/interpreter_handlers.irt b/irtoc_scripts/interpreter_handlers.irt index e89452af8..738340a6f 100644 --- a/irtoc_scripts/interpreter_handlers.irt +++ b/irtoc_scripts/interpreter_handlers.irt @@ -21,6 +21,17 @@ macro(:ecma_intrinsic_setacc) do |sym, *args| set_value(acc_ptr, res).u64 end +macro(:ecma_intrinsic_check_setacc) do |sym, size, *args| + ecma_intrinsic_setacc(sym, *args) + If(exception_val(), 0).CC(:CC_NE).b { + pc_eh := find_catch_block() + } Else { + pc_inc := advance_pc_imm(pc, size) + } + frame := Phi(frame_eh, frame).ptr + pc := Phi(pc_eh, pc_inc).ptr +end + macro(:ecma_intrinsic_invoke) do |sym, *args| Call(*args).Method(sym).any end diff --git a/irtoc_scripts/interpreter_main_loop.irt b/irtoc_scripts/interpreter_main_loop.irt index d28e1dcf0..426907677 100644 --- a/irtoc_scripts/interpreter_main_loop.irt +++ b/irtoc_scripts/interpreter_main_loop.irt @@ -152,21 +152,16 @@ # ecma frames when "ECMA_CALL0DYN_PREF_V8" - ecma_intrinsic_setacc("Call0Dyn", vreg_value(op[0]).u64) - pc := advance_pc_imm(pc, i.format.size) + ecma_intrinsic_check_setacc("Call0Dyn", i.format.size, vreg_value(op[0]).u64) when "ECMA_CALL1DYN_PREF_V8_V8" - ecma_intrinsic_setacc("Call1Dyn", vreg_value(op[0]).u64, vreg_value(op[1]).u64) - pc := advance_pc_imm(pc, i.format.size) + ecma_intrinsic_check_setacc("Call1Dyn", i.format.size, vreg_value(op[0]).u64, vreg_value(op[1]).u64) when "ECMA_CALL2DYN_PREF_V8_V8_V8" - ecma_intrinsic_setacc("Call2Dyn", vreg_value(op[0]).u64, vreg_value(op[1]).u64, vreg_value(op[2]).u64) - pc := advance_pc_imm(pc, i.format.size) + 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_setacc("Call3Dyn", vreg_value(op[0]).u64, vreg_value(op[1]).u64, vreg_value(op[2]).u64, vreg_value(op[3]).u64) - pc := advance_pc_imm(pc, i.format.size) + 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_LDLEXENVDYN_PREF_NONE" res := handle_ecma_ldlexenvdyn() set_value(acc_ptr, res).any - # ecma_intrinsic_setacc("LdlexenvDyn") when "ECMA_NEWLEXENVDYN_PREF_IMM16" ecma_intrinsic_setacc("NewlexenvDyn", as_imm(op[0])) when "ECMA_STLEXVARDYN_PREF_IMM4_IMM4" @@ -243,6 +238,7 @@ # ecma exceptions when "ECMA_THROWDYN_PREF_NONE" ecma_intrinsic_setacc("ThrowDyn", acc_value.u64) - Intrinsic(:INTERPRETER_RETURN).ptr # TODO: goto exc handler + pc := find_catch_block() + frame := frame_eh when "ECMA_THROWUNDEFINEDIFHOLE_PREF_ID32" ecma_intrinsic_setacc("ThrowUndefinedIfHole", as_id(op[0]), acc_value.any) diff --git a/tests/runtime/irtoc/advanced/advanced.js b/tests/runtime/irtoc/advanced/advanced.js index 27ec082dc..ca2bf086d 100644 --- a/tests/runtime/irtoc/advanced/advanced.js +++ b/tests/runtime/irtoc/advanced/advanced.js @@ -186,4 +186,26 @@ function test_1() { verify(~1 ^ 0xffffffff, 1, "Xor: smi, double"); verify(0xffffffff ^ 0xaaaaaaaa, 1431655765, "Xor: double, double"); } -test_1(); \ No newline at end of file +test_1(); + +//exception handling +function foo1() { + let capt1 = "capt1"; + try { + let capt2 = "capt2"; + let fn = function() { return capt1 + capt2; }; + fn(); + function foo2() { + throw fn; + } + foo2(); + } catch(e) { + return String("foo1 caught " + e()); + } +} +res = foo1(); +expected = "foo1 caught capt1capt2" + +if (res != expected) { + throw "res = " + res + ", expected = " + expected; +} \ No newline at end of file diff --git a/tests/runtime/irtoc/basic/basic.js b/tests/runtime/irtoc/basic/basic.js index d920e3be7..cc641a9d3 100644 --- a/tests/runtime/irtoc/basic/basic.js +++ b/tests/runtime/irtoc/basic/basic.js @@ -184,6 +184,38 @@ x = 0.1; res = !x; expected = false; +if (res != expected) { + throw "res = " + res + ", expected = " + expected; +} + +// ecma.throwdyn and exception handling +function foo() { + try { + throw 1; + } catch(e) { + return String("foo1 caught" + e); + } +} +res = foo(); +expected = "foo1 caught1"; + +if (res != expected) { + throw "res = " + res + ", expected = " + expected; +} + +function bar1() { + try { + function bar2() { + throw 1; + } + bar2(); + } catch(e) { + return String("bar1 caught" + e); + } +} +res = bar1(); +expected = "bar1 caught1"; + if (res != expected) { throw "res = " + res + ", expected = " + expected; } \ No newline at end of file -- Gitee