From 488ed41c2b7ced2e9e0b4e1d519ff61271f99a13 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Tue, 22 Jul 2014 18:55:13 +0400 Subject: [PATCH] Implementing 'substraction' opcode handler and, partially (except string operands), 'addition' opcode handler; adding unit tests for them. --- src/libcoreint/opcodes.c | 84 ++++++++++++++++++- .../test_addition_opcode_number_operands.c | 43 ++++++++++ tests/unit/test_substraction_opcode.c | 43 ++++++++++ 3 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 tests/unit/test_addition_opcode_number_operands.c create mode 100644 tests/unit/test_substraction_opcode.c diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 6fde8d637..f4806645c 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -351,8 +351,6 @@ do_number_arithmetic(struct __int_data *int_data, /**< interpreter context */ op(greater_than) \ op(less_or_equal_than) \ op(greater_or_equal_than) \ - op(addition) \ - op(substraction) \ op(jmp_up) \ op(jmp_down) \ op(nop) @@ -513,6 +511,88 @@ opfunc_assignment (OPCODE opdata, /**< operation data */ } } /* opfunc_assignment */ +/** + * Addition opcode handler. + * + * See also: ECMA-262 v5, 11.6.1 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_CompletionValue_t +opfunc_addition(OPCODE opdata, /**< operation data */ + struct __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.addition.dst; + const T_IDX left_var_idx = opdata.data.addition.var_left; + const T_IDX right_var_idx = opdata.data.addition.var_right; + + int_data->pos++; + + ecma_CompletionValue_t ret_value; + + TRY_CATCH(left_value, get_variable_value( int_data, left_var_idx, false), ret_value); + TRY_CATCH(right_value, get_variable_value( int_data, right_var_idx, false), ret_value); + TRY_CATCH(prim_left_value, ecma_op_to_primitive( left_value.value), ret_value); + TRY_CATCH(prim_right_value, ecma_op_to_primitive( right_value.value), ret_value); + + if ( prim_left_value.value.m_ValueType == ECMA_TYPE_STRING + || prim_right_value.value.m_ValueType == ECMA_TYPE_STRING ) + { + JERRY_UNIMPLEMENTED(); + } + else + { + ret_value = do_number_arithmetic(int_data, + dst_var_idx, + number_arithmetic_addition, + prim_left_value.value, + prim_right_value.value); + } + + FINALIZE(prim_right_value); + FINALIZE(prim_left_value); + FINALIZE(right_value); + FINALIZE(left_value); + + return ret_value; +} /* opfunc_addition */ + +/** + * Substraction opcode handler. + * + * See also: ECMA-262 v5, 11.6.2 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_CompletionValue_t +opfunc_substraction(OPCODE opdata, /**< operation data */ + struct __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.substraction.dst; + const T_IDX left_var_idx = opdata.data.substraction.var_left; + const T_IDX right_var_idx = opdata.data.substraction.var_right; + + int_data->pos++; + + ecma_CompletionValue_t ret_value; + + TRY_CATCH(left_value, get_variable_value( int_data, left_var_idx, false), ret_value); + TRY_CATCH(right_value, get_variable_value( int_data, right_var_idx, false), ret_value); + + ret_value = do_number_arithmetic(int_data, + dst_var_idx, + number_arithmetic_substraction, + left_value.value, + right_value.value); + + FINALIZE(right_value); + FINALIZE(left_value); + + return ret_value; +} /* opfunc_substraction */ + /** * Multiplication opcode handler. * diff --git a/tests/unit/test_addition_opcode_number_operands.c b/tests/unit/test_addition_opcode_number_operands.c new file mode 100644 index 000000000..8af97574b --- /dev/null +++ b/tests/unit/test_addition_opcode_number_operands.c @@ -0,0 +1,43 @@ +/* Copyright 2014 Samsung Electronics 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. + */ + +#include "globals.h" +#include "interpreter.h" +#include "mem-allocator.h" +#include "opcodes.h" + +/** + * Unit test's main function. + */ +int +main( int __unused argc, + char __unused **argv) +{ + const OPCODE test_program[] = { + getop_var_decl( 0), + getop_var_decl( 1), + getop_assignment( 0, OPCODE_ARG_TYPE_SMALLINT, 253), + getop_assignment( 1, OPCODE_ARG_TYPE_NUMBER, 2), + getop_addition( 0, 0, 1), + getop_exitval( 0) + }; + + mem_Init(); + + init_int( test_program); + + return run_int() ? 0 + : 1; +} /* main */ diff --git a/tests/unit/test_substraction_opcode.c b/tests/unit/test_substraction_opcode.c new file mode 100644 index 000000000..19e0371a4 --- /dev/null +++ b/tests/unit/test_substraction_opcode.c @@ -0,0 +1,43 @@ +/* Copyright 2014 Samsung Electronics 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. + */ + +#include "globals.h" +#include "interpreter.h" +#include "mem-allocator.h" +#include "opcodes.h" + +/** + * Unit test's main function. + */ +int +main( int __unused argc, + char __unused **argv) +{ + const OPCODE test_program[] = { + getop_var_decl( 0), + getop_var_decl( 1), + getop_assignment( 0, OPCODE_ARG_TYPE_SMALLINT, 253), + getop_assignment( 1, OPCODE_ARG_TYPE_NUMBER, 2), + getop_substraction( 0, 0, 1), + getop_exitval( 0) + }; + + mem_Init(); + + init_int( test_program); + + return run_int() ? 0 + : 1; +} /* main */