diff --git a/ecmascript_plugin_options.yaml b/ecmascript_plugin_options.yaml index 4adf5cda8fa407c89f029db9adfb3cda810ad02c..e17718993526b7ef92e1410c8d84cb73ac472548 100644 --- a/ecmascript_plugin_options.yaml +++ b/ecmascript_plugin_options.yaml @@ -78,9 +78,6 @@ runtime_defines: defines_header_path: plugins/ecmascript/runtime/asm_defines/defines.h asm_defines_def: plugins/ecmascript/runtime/asm_defines/asm_defines.def - irtoc_files: - - plugins_interpreter_handlers: plugins/ecmascript/irtoc_scripts/interpreter_handlers.irt - - plugins_main_loop: plugins/ecmascript/irtoc_scripts/interpreter_main_loop.irt logger: components: - name: ecmascript diff --git a/irtoc_scripts/interpreter_handlers.irt b/irtoc_scripts/interpreter_handlers.irt index 2e7e6e3180ff8f8346bd65b59d5aa8ab454163a4..25c8ad43cbb24b7c1a2edc260a91e106ac33bb3e 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 d28e1dcf08800492e2e7719420bcc4d20642fa30..4269076778d842dc11895e5ff4a85536da226395 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 27ec082dc612d18ea8ecc9112b923f89ff0ce9e6..5b60b9d84fb81e62a9ef7eef7c517fb5accf6108 100644 --- a/tests/runtime/irtoc/advanced/advanced.js +++ b/tests/runtime/irtoc/advanced/advanced.js @@ -1,3 +1,18 @@ +/* + * 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. + */ + let res = 99; let expected = 0; @@ -96,7 +111,7 @@ function test_shifts() { verify((-1.6) << 2, -4, "shl f64 neg"); verify(NaN << 2, 0, "shl nan 1"); verify(6 << NaN, 6, "shl nan 2"); - verify(((1 / 0) / (1 / 0)) << 1, 0, "shl qnan"); + verify(((1 / 0) / (2 / 0)) << 1, 0, "shl qnan"); verify(Infinity << 2, 0, "shl inf 1"); verify(7 << Infinity, 7, "shl inf 2"); verify(1000000000 << 3, -589934592, "shl i32 ovf"); @@ -107,7 +122,7 @@ function test_shifts() { verify((-16.6) >> 2, -4, "shr f64 neg"); verify(NaN >> 2, 0, "shr nan 1"); verify(6 >> NaN, 6, "shr nan 2"); - verify(((1 / 0) / (1 / 0)) >> 1, 0, "shr qnan"); + verify(((1 / 0) / (2 / 0)) >> 1, 0, "shr qnan"); verify(Infinity >> 2, 0, "shr inf 1"); verify(7 >> Infinity, 7, "shr inf 2"); verify(2147483648 >> 1, -1073741824, "shr left i32 ovf"); @@ -186,4 +201,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; +} diff --git a/tests/runtime/irtoc/basic/basic.js b/tests/runtime/irtoc/basic/basic.js index d920e3be7c6ed9f4fa5e3a95fec3f1c7a16fbe4c..28f311b5c56660c09d3d490b9dce75da61330493 100644 --- a/tests/runtime/irtoc/basic/basic.js +++ b/tests/runtime/irtoc/basic/basic.js @@ -1,3 +1,18 @@ +/* + * 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. + */ + let res = 0; let expected = 5050; @@ -184,6 +199,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