From 8aa84dfb332a4040bc94ac4bf8e00c6dca8ad920 Mon Sep 17 00:00:00 2001 From: Anna Antipina Date: Mon, 11 Jul 2022 16:31:43 +0300 Subject: [PATCH] Implement throwing and handling exceptions in irtoc; enable cts tests Change-Id: I203ae5098f835e1568b3ffb9841ec9d247b46a1d5 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 | 43 ++++++++++++++++++++-- tests/runtime/irtoc/basic/basic.js | 47 ++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 16 deletions(-) diff --git a/ecmascript_plugin_options.yaml b/ecmascript_plugin_options.yaml index 4adf5cda8..e17718993 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 2e7e6e318..25c8ad43c 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..5b60b9d84 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 d920e3be7..28f311b5c 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 -- Gitee