diff --git a/src/libcoreint/interpreter.c b/src/libcoreint/interpreter.c index 530030617..0c9153180 100644 --- a/src/libcoreint/interpreter.c +++ b/src/libcoreint/interpreter.c @@ -119,7 +119,7 @@ run_int_from_pos (opcode_counter_t start_pos, __memset (regs, 0, sizeof (regs)); JERRY_ASSERT (ecma_is_value_empty (regs[0])); - struct __int_data int_data; + __int_data int_data; int_data.pos = (opcode_counter_t) (start_pos + 1); int_data.this_binding = this_binding_value; int_data.lex_env_p = lex_env_p; diff --git a/src/libcoreint/interpreter.h b/src/libcoreint/interpreter.h index ac3d81e6d..25a3681d6 100644 --- a/src/libcoreint/interpreter.h +++ b/src/libcoreint/interpreter.h @@ -20,21 +20,7 @@ #include "globals.h" #include "opcodes.h" -typedef uint16_t opcode_counter_t; - -struct __int_data -{ - opcode_counter_t pos; /**< current opcode to execute */ - ecma_value_t this_binding; /**< this binding for current context */ - ecma_object_t *lex_env_p; /**< current lexical environment */ - bool is_strict; /**< is current code execution mode strict? */ - bool is_eval_code; /**< is current code executed with eval */ - T_IDX min_reg_num; /**< minimum idx used for register identification */ - T_IDX max_reg_num; /**< maximum idx used for register identification */ - ecma_value_t *regs_p; /**< register variables */ -}; - -void init_int (const OPCODE* program_p); +void init_int (const __opcode* program_p); bool run_int (void); ecma_completion_value_t run_int_from_pos (opcode_counter_t start_pos, ecma_value_t this_binding_value, @@ -45,7 +31,7 @@ ecma_completion_value_t run_int_from_pos (opcode_counter_t start_pos, ssize_t try_get_string_by_idx (T_IDX idx, ecma_char_t *buffer_p, ssize_t buffer_size); ecma_number_t get_number_by_idx (T_IDX idx); -OPCODE read_opcode (opcode_counter_t counter); +__opcode read_opcode (opcode_counter_t counter); #endif /* INTERPRETER_H */ diff --git a/src/libcoreint/opcode-structures.h b/src/libcoreint/opcode-structures.h deleted file mode 100644 index d7ea1b184..000000000 --- a/src/libcoreint/opcode-structures.h +++ /dev/null @@ -1,434 +0,0 @@ -/* 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. - */ - -#ifndef OPCODE_STRUCTURES_H -#define OPCODE_STRUCTURES_H - -#define OP_DEF(name, list) struct __op_##name { list ; } ; - - -#define OP_CODE_DECL_VOID(name) \ - struct __op_##name { T_IDX __do_not_use; }; \ - OPCODE getop_##name (void); - -#define OP_CODE_DECL(name, type, ...) \ - OP_DEF (name, type##_DECL(__VA_ARGS__)) \ - OPCODE getop_##name (type); - -#define T_IDX_IDX T_IDX, T_IDX -#define T_IDX_IDX_IDX T_IDX, T_IDX, T_IDX - -#define T_IDX_DECL(name) T_IDX name -#define T_IDX_IDX_DECL(name1, name2) \ - T_IDX_DECL (name1) ; \ - T_IDX_DECL (name2) -#define T_IDX_IDX_IDX_DECL(name1, name2, name3) \ - T_IDX_DECL (name1) ; \ - T_IDX_DECL (name2); \ - T_IDX_DECL (name3) - -#define GETOP_IMPL_0(name) \ - OPCODE getop_##name () \ - { \ - OPCODE opdata; \ - opdata.op_idx = __op__idx_##name; \ - return opdata; \ - } - -#define GETOP_IMPL_1(name, field1) \ - OPCODE getop_##name (T_IDX arg1) \ - { \ - OPCODE opdata; \ - opdata.op_idx = __op__idx_##name; \ - opdata.data.name.field1 = arg1; \ - return opdata; \ - } - -#define GETOP_IMPL_2(name, field1, field2) \ - OPCODE getop_##name (T_IDX arg1, T_IDX arg2) \ - { \ - OPCODE opdata; \ - opdata.op_idx = __op__idx_##name; \ - opdata.data.name.field1 = arg1; \ - opdata.data.name.field2 = arg2; \ - return opdata; \ - } - -#define GETOP_IMPL_3(name, field1, field2, field3) \ - OPCODE getop_##name (T_IDX arg1, T_IDX arg2, T_IDX arg3) \ - { \ - OPCODE opdata; \ - opdata.op_idx = __op__idx_##name; \ - opdata.data.name.field1 = arg1; \ - opdata.data.name.field2 = arg2; \ - opdata.data.name.field3 = arg3; \ - return opdata; \ - } - -/** Instruction tests if BOOLEAN value is TRUE and JMP to DST */ -OP_CODE_DECL (is_true_jmp, T_IDX_IDX, - value, - opcode) - -/** Instruction tests if BOOLEAN value is FALSE and JMP to DST */ -OP_CODE_DECL (is_false_jmp, T_IDX_IDX, - value, - opcode) - -/** Unconditional JMP to the specified opcode index */ -OP_CODE_DECL (jmp, T_IDX, - opcode_idx) - -/** Unconditional JMP on opcode_count up */ -OP_CODE_DECL (jmp_up, T_IDX, - opcode_count) - -/** Unconditional JMP on opcode_count down */ -OP_CODE_DECL (jmp_down, T_IDX, - opcode_count) - -/** dst = L + R */ -OP_CODE_DECL (addition, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L - R */ -OP_CODE_DECL (substraction, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L / R */ -OP_CODE_DECL (division, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L * R */ -OP_CODE_DECL (multiplication, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L % R */ -OP_CODE_DECL (remainder, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L << R */ -OP_CODE_DECL (b_shift_left, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L >> R */ -OP_CODE_DECL (b_shift_right, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L >>> R */ -OP_CODE_DECL (b_shift_uright, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -// Binary bitwise operators. -// Operands is a set of 32 bits -// Returns numerical. - -/** dst = L & R */ -OP_CODE_DECL (b_and, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L | R */ -OP_CODE_DECL (b_or, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L ^ R */ -OP_CODE_DECL (b_xor, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = ~ R */ -OP_CODE_DECL (b_not, T_IDX_IDX, - dst, - var_right) - -// Binary logical operators. -// Operands are booleans. -// Return boolean. - -/** dst = L && R */ -OP_CODE_DECL (logical_and, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L || R */ -OP_CODE_DECL (logical_or, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = ! R */ -OP_CODE_DECL (logical_not, T_IDX_IDX, - dst, - var_right) - -// Equality operations. - -/** dst = L == R. */ -OP_CODE_DECL (equal_value, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L != R. */ -OP_CODE_DECL (not_equal_value, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L === R. */ -OP_CODE_DECL (equal_value_type, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L !== R. */ -OP_CODE_DECL (not_equal_value_type, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -// Relational operations. - -/** dst = L < R. */ -OP_CODE_DECL (less_than, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L > R. */ -OP_CODE_DECL (greater_than, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L <= R. */ -OP_CODE_DECL (less_or_equal_than, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L >= R. */ -OP_CODE_DECL (greater_or_equal_than, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L instanceof R. */ -OP_CODE_DECL (instanceof, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = L in R. */ -OP_CODE_DECL (in, T_IDX_IDX_IDX, - dst, - var_left, - var_right) - -/** dst = var_right++. */ -OP_CODE_DECL (post_incr, T_IDX_IDX, - dst, - var_right) - -/** dst = var_right--. */ -OP_CODE_DECL (post_decr, T_IDX_IDX, - dst, - var_right) - -/** dst = ++var_right. */ -OP_CODE_DECL (pre_incr, T_IDX_IDX, - dst, - var_right) - -/** dst = --var_right. */ -OP_CODE_DECL (pre_decr, T_IDX_IDX, - dst, - var_right) - -// Assignment operators. -// Assign value to LEFT operand based on value of RIGHT operand. - -/** L = R */ -OP_CODE_DECL (assignment, T_IDX_IDX_IDX, - var_left, - type_value_right, - value_right) - -// Functions calls, declarations and argument handling - -/** a = name (); */ -OP_CODE_DECL (call_0, T_IDX_IDX, - lhs, - name_lit_idx) - -/** a = name (arg1); */ -OP_CODE_DECL (call_1, T_IDX_IDX_IDX, - lhs, - name_lit_idx, - arg1_lit_idx) - -/** a = name (arg1, ... */ -OP_CODE_DECL (call_n, T_IDX_IDX_IDX, - lhs, - name_lit_idx, - arg1_lit_idx) - -/** lhs = name (arg_list) */ -OP_CODE_DECL (native_call, T_IDX_IDX_IDX, - lhs, - name, - arg_list) - -/** a = new name (arg_list */ -OP_CODE_DECL (construct_decl, T_IDX_IDX_IDX, - lhs, - name_lit_idx, - arg_list) - -/** name (); */ -OP_CODE_DECL (func_decl_0, T_IDX, - name_lit_idx) - -/** name (arg1); */ -OP_CODE_DECL (func_decl_1, T_IDX_IDX, - name_lit_idx, - arg1_lit_idx) - -/** name (arg1, arg2); */ -OP_CODE_DECL (func_decl_2, T_IDX_IDX_IDX, - name_lit_idx, - arg1_lit_idx, - arg2_lit_idx) - -/** name (arg1, arg2, ... */ -OP_CODE_DECL (func_decl_n, T_IDX_IDX_IDX, - name_lit_idx, - arg1_lit_idx, - arg2_lit_idx) - -/** arg1, arg2, arg3 */ -OP_CODE_DECL (varg_list, T_IDX_IDX_IDX, - arg1_lit_idx, - arg2_lit_idx, - arg3_lit_idx) - -/** exit with status code; */ -OP_CODE_DECL (exitval, T_IDX, - status_code) - -/** return value; */ -OP_CODE_DECL (retval, T_IDX, - ret_value) -OP_CODE_DECL_VOID (ret) - -OP_CODE_DECL_VOID (nop) - -/** a = [list] */ -OP_CODE_DECL (array_decl, T_IDX_IDX, - lhs, - list) - -/** a = b : c */ -OP_CODE_DECL (prop, T_IDX_IDX_IDX, - lhs, - name, - value) - -/** a = b.c OR a = b[c] */ -OP_CODE_DECL (prop_getter, T_IDX_IDX_IDX, - lhs, - obj, - prop) - -/** a.b = c OR a[b] = c */ -OP_CODE_DECL (prop_setter, T_IDX_IDX_IDX, - obj, - prop, - rhs) - -/** a = get prop () */ -OP_CODE_DECL (prop_get_decl, T_IDX_IDX, - lhs, - prop) - -/** a = set prop (arg) */ -OP_CODE_DECL (prop_set_decl, T_IDX_IDX_IDX, - lhs, - prop, - arg) - -/** a = { } */ -OP_CODE_DECL (obj_decl, T_IDX_IDX, - lhs, - list) - -/** a = this */ -OP_CODE_DECL (this, T_IDX, - lhs) - -/** a = delete b */ -OP_CODE_DECL (delete, T_IDX_IDX, - lhs, - obj) - -/** a = typeof b */ -OP_CODE_DECL (typeof, T_IDX_IDX, - lhs, - obj) - -/** with (b) { */ -OP_CODE_DECL (with, T_IDX, - expr) - -/** } */ -OP_CODE_DECL_VOID (end_with) - -// Variable declaration -OP_CODE_DECL (var_decl, T_IDX, - variable_name) - -OP_CODE_DECL (reg_var_decl, T_IDX_IDX, - min, - max) - -/** meta */ -OP_CODE_DECL (meta, T_IDX_IDX_IDX, - type, - data_1, - data_2) - -#endif /* OPCODE_STRUCTURES_H */ diff --git a/src/libcoreint/opcodes-agnostic.c b/src/libcoreint/opcodes-agnostic.c new file mode 100644 index 000000000..e5f1f1d58 --- /dev/null +++ b/src/libcoreint/opcodes-agnostic.c @@ -0,0 +1,140 @@ +/* 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 "opcodes.h" +#include "opcodes-ecma-support.h" + +/** + * 'Jump if true' opcode handler. + * + * Note: + * the opcode changes current opcode position to specified opcode index + * if argument evaluates to true. + */ +ecma_completion_value_t +opfunc_is_true_jmp (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX cond_var_idx = opdata.data.is_true_jmp.value; + const T_IDX dst_opcode_idx = opdata.data.is_true_jmp.opcode; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (cond_value, get_variable_value (int_data, cond_var_idx, false), ret_value); + + ecma_completion_value_t to_bool_completion = ecma_op_to_boolean (cond_value.value); + JERRY_ASSERT (ecma_is_completion_value_normal (to_bool_completion)); + + if (ecma_is_value_true (to_bool_completion.value)) + { + int_data->pos = dst_opcode_idx; + } + else + { + int_data->pos++; + } + + ret_value = ecma_make_empty_completion_value (); + + ECMA_FINALIZE (cond_value); + + return ret_value; +} /* opfunc_is_true_jmp */ + +/** + * 'Jump if false' opcode handler. + * + * Note: + * the opcode changes current opcode position to specified opcode index + * if argument evaluates to false. + */ +ecma_completion_value_t +opfunc_is_false_jmp (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX cond_var_idx = opdata.data.is_false_jmp.value; + const T_IDX dst_opcode_idx = opdata.data.is_false_jmp.opcode; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (cond_value, get_variable_value (int_data, cond_var_idx, false), ret_value); + + ecma_completion_value_t to_bool_completion = ecma_op_to_boolean (cond_value.value); + JERRY_ASSERT (ecma_is_completion_value_normal (to_bool_completion)); + + if (!ecma_is_value_true (to_bool_completion.value)) + { + int_data->pos = dst_opcode_idx; + } + else + { + int_data->pos++; + } + + ret_value = ecma_make_empty_completion_value (); + + ECMA_FINALIZE (cond_value); + + return ret_value; +} /* opfunc_is_false_jmp */ + +/** + * 'Jump' opcode handler. + * + * Note: + * the opcode changes current opcode position to specified opcode index + */ +ecma_completion_value_t +opfunc_jmp (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + int_data->pos = opdata.data.jmp.opcode_idx; + + return ecma_make_empty_completion_value (); +} /* opfunc_jmp */ + +/** + * 'Jump down' opcode handler. + * + * Note: + * the opcode changes adds specified value to current opcode position + */ +ecma_completion_value_t +opfunc_jmp_down (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + JERRY_ASSERT (int_data->pos <= int_data->pos + opdata.data.jmp_up.opcode_count); + + int_data->pos = (opcode_counter_t) (int_data->pos + opdata.data.jmp_down.opcode_count); + + return ecma_make_empty_completion_value (); +} /* opfunc_jmp_down */ + +/** + * 'Jump up' opcode handler. + * + * Note: + * the opcode changes substracts specified value from current opcode position + */ +ecma_completion_value_t +opfunc_jmp_up (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + JERRY_ASSERT (int_data->pos >= opdata.data.jmp_up.opcode_count); + + int_data->pos = (opcode_counter_t) (int_data->pos - opdata.data.jmp_down.opcode_count); + + return ecma_make_empty_completion_value (); +} /* opfunc_jmp_up */ diff --git a/src/libcoreint/opcodes-bitwise.c b/src/libcoreint/opcodes-bitwise.c new file mode 100644 index 000000000..25b4a9fd2 --- /dev/null +++ b/src/libcoreint/opcodes-bitwise.c @@ -0,0 +1,359 @@ +/* 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 "opcodes.h" +#include "opcodes-ecma-support.h" + +/** + * Number bitwise logic operations. + */ +typedef enum +{ + number_bitwise_logic_and, /**< bitwise AND calculation */ + number_bitwise_logic_or, /**< bitwise OR calculation */ + number_bitwise_logic_xor, /**< bitwise XOR calculation */ + number_bitwise_shift_left, /**< bitwise LEFT SHIFT calculation */ + number_bitwise_shift_right, /**< bitwise RIGHT_SHIFT calculation */ + number_bitwise_shift_uright, /**< bitwise UNSIGNED RIGHT SHIFT calculation */ + number_bitwise_not, /**< bitwise NOT calculation */ +} number_bitwise_logic_op; + +/** + * Perform ECMA number logic operation. + * + * The algorithm of the operation is following: + * leftNum = ToNumber (leftValue); + * rightNum = ToNumber (rightValue); + * result = leftNum BitwiseLogicOp rightNum; + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +static ecma_completion_value_t +do_number_bitwise_logic (__int_data *int_data, /**< interpreter context */ + T_IDX dst_var_idx, /**< destination variable identifier */ + number_bitwise_logic_op op, /**< number bitwise logic operation */ + ecma_value_t left_value, /**< left value */ + ecma_value_t right_value) /** right value */ +{ + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (num_left_value, ecma_op_to_number (left_value), ret_value); + ECMA_TRY_CATCH (num_right_value, ecma_op_to_number (right_value), ret_value); + + ecma_number_t *left_p, *right_p; + left_p = (ecma_number_t*) ECMA_GET_POINTER (num_left_value.value.value); + right_p = (ecma_number_t*) ECMA_GET_POINTER (num_right_value.value.value); + + ecma_number_t* res_p = ecma_alloc_number (); + + int32_t left_int32 = ecma_number_to_int32 (*left_p); + int32_t right_int32 = ecma_number_to_int32 (*right_p); + + uint32_t left_uint32 = ecma_number_to_uint32 (*left_p); + uint32_t right_uint32 = ecma_number_to_uint32 (*right_p); + + switch (op) + { + case number_bitwise_logic_and: + { + *res_p = ecma_int32_to_number (left_int32 & right_int32); + break; + } + case number_bitwise_logic_or: + { + *res_p = ecma_int32_to_number (left_int32 | right_int32); + break; + } + case number_bitwise_logic_xor: + { + *res_p = ecma_int32_to_number (left_int32 ^ right_int32); + break; + } + case number_bitwise_shift_left: + { + *res_p = ecma_int32_to_number (left_int32 << (right_uint32 & 0x1F)); + break; + } + case number_bitwise_shift_right: + { + *res_p = ecma_int32_to_number (left_int32 >> (right_uint32 & 0x1F)); + break; + } + case number_bitwise_shift_uright: + { + *res_p = ecma_uint32_to_number (left_uint32 >> (right_uint32 & 0x1F)); + break; + } + case number_bitwise_not: + { + *res_p = ecma_int32_to_number (~right_int32); + break; + } + } + + ret_value = set_variable_value (int_data, + dst_var_idx, + ecma_make_number_value (res_p)); + + ecma_dealloc_number (res_p); + + ECMA_FINALIZE (num_right_value); + ECMA_FINALIZE (num_left_value); + + return ret_value; +} /* do_number_bitwise_logic */ + +/** + * 'Bitwise AND' opcode handler. + * + * See also: ECMA-262 v5, 11.10 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_b_and (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.b_and.dst; + const T_IDX left_var_idx = opdata.data.b_and.var_left; + const T_IDX right_var_idx = opdata.data.b_and.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + ret_value = do_number_bitwise_logic (int_data, + dst_var_idx, + number_bitwise_logic_and, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_b_and */ + +/** + * 'Bitwise OR' opcode handler. + * + * See also: ECMA-262 v5, 11.10 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_b_or (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.b_or.dst; + const T_IDX left_var_idx = opdata.data.b_or.var_left; + const T_IDX right_var_idx = opdata.data.b_or.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + ret_value = do_number_bitwise_logic (int_data, + dst_var_idx, + number_bitwise_logic_or, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_b_or */ + +/** + * 'Bitwise XOR' opcode handler. + * + * See also: ECMA-262 v5, 11.10 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_b_xor (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.b_xor.dst; + const T_IDX left_var_idx = opdata.data.b_xor.var_left; + const T_IDX right_var_idx = opdata.data.b_xor.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + ret_value = do_number_bitwise_logic (int_data, + dst_var_idx, + number_bitwise_logic_xor, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_b_xor */ + +/** + * 'Left Shift Operator' opcode handler. + * + * See also: ECMA-262 v5, 11.7.1 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_b_shift_left (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.b_shift_left.dst; + const T_IDX left_var_idx = opdata.data.b_shift_left.var_left; + const T_IDX right_var_idx = opdata.data.b_shift_left.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + ret_value = do_number_bitwise_logic (int_data, + dst_var_idx, + number_bitwise_shift_left, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_b_shift_left */ + +/** + * 'Right Shift Operator' opcode handler. + * + * See also: ECMA-262 v5, 11.7.2 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_b_shift_right (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.b_shift_right.dst; + const T_IDX left_var_idx = opdata.data.b_shift_right.var_left; + const T_IDX right_var_idx = opdata.data.b_shift_right.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + ret_value = do_number_bitwise_logic (int_data, + dst_var_idx, + number_bitwise_shift_right, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_b_shift_right */ + +/** + * 'Unsigned Right Shift Operator' opcode handler. + * + * See also: ECMA-262 v5, 11.7.3 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_b_shift_uright (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.b_shift_uright.dst; + const T_IDX left_var_idx = opdata.data.b_shift_uright.var_left; + const T_IDX right_var_idx = opdata.data.b_shift_uright.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + ret_value = do_number_bitwise_logic (int_data, + dst_var_idx, + number_bitwise_shift_uright, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_b_shift_uright */ + +/** + * 'Bitwise NOT Operator' opcode handler. + * + * See also: ECMA-262 v5, 10.4 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_b_not (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.b_not.dst; + const T_IDX right_var_idx = opdata.data.b_not.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + ret_value = do_number_bitwise_logic (int_data, + dst_var_idx, + number_bitwise_not, + right_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + + return ret_value; +} /* opfunc_b_not */ diff --git a/src/libcoreint/opcodes-ecma-arithmetics.c b/src/libcoreint/opcodes-ecma-arithmetics.c new file mode 100644 index 000000000..8762c78a0 --- /dev/null +++ b/src/libcoreint/opcodes-ecma-arithmetics.c @@ -0,0 +1,287 @@ +/* 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 "opcodes.h" +#include "opcodes-ecma-support.h" +#include "ecma-number-arithmetic.h" + +/** + * Number arithmetic operations. + */ +typedef enum +{ + number_arithmetic_addition, /**< addition */ + number_arithmetic_substraction, /**< substraction */ + number_arithmetic_multiplication, /**< multiplication */ + number_arithmetic_division, /**< division */ + number_arithmetic_remainder, /**< remainder calculation */ +} number_arithmetic_op; + +/** + * Perform ECMA number arithmetic operation. + * + * The algorithm of the operation is following: + * leftNum = ToNumber (leftValue); + * rightNum = ToNumber (rightValue); + * result = leftNum ArithmeticOp rightNum; + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +static ecma_completion_value_t +do_number_arithmetic (__int_data *int_data, /**< interpreter context */ + T_IDX dst_var_idx, /**< destination variable identifier */ + number_arithmetic_op op, /**< number arithmetic operation */ + ecma_value_t left_value, /**< left value */ + ecma_value_t right_value) /** right value */ +{ + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (num_left_value, ecma_op_to_number (left_value), ret_value); + ECMA_TRY_CATCH (num_right_value, ecma_op_to_number (right_value), ret_value); + + ecma_number_t *left_p, *right_p, *res_p; + left_p = (ecma_number_t*) ECMA_GET_POINTER (num_left_value.value.value); + right_p = (ecma_number_t*) ECMA_GET_POINTER (num_right_value.value.value); + + res_p = ecma_alloc_number (); + + switch (op) + { + case number_arithmetic_addition: + { + *res_p = ecma_op_number_add (*left_p, *right_p); + break; + } + case number_arithmetic_substraction: + { + *res_p = ecma_op_number_substract (*left_p, *right_p); + break; + } + case number_arithmetic_multiplication: + { + *res_p = ecma_op_number_multiply (*left_p, *right_p); + break; + } + case number_arithmetic_division: + { + *res_p = ecma_op_number_divide (*left_p, *right_p); + break; + } + case number_arithmetic_remainder: + { + *res_p = ecma_op_number_remainder (*left_p, *right_p); + break; + } + } + + ret_value = set_variable_value (int_data, + dst_var_idx, + ecma_make_number_value (res_p)); + + ecma_dealloc_number (res_p); + + ECMA_FINALIZE (num_right_value); + ECMA_FINALIZE (num_left_value); + + return ret_value; +} /* do_number_arithmetic */ + +/** + * '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_completion_value_t +opfunc_addition (OPCODE opdata, /**< operation data */ + __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_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + ECMA_TRY_CATCH (prim_left_value, ecma_op_to_primitive (left_value.value, ECMA_PREFERRED_TYPE_NO), ret_value); + ECMA_TRY_CATCH (prim_right_value, ecma_op_to_primitive (right_value.value, ECMA_PREFERRED_TYPE_NO), ret_value); + + if (prim_left_value.value.value_type == ECMA_TYPE_STRING + || prim_right_value.value.value_type == 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); + } + + ECMA_FINALIZE (prim_right_value); + ECMA_FINALIZE (prim_left_value); + ECMA_FINALIZE (right_value); + ECMA_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_completion_value_t +opfunc_substraction (OPCODE opdata, /**< operation data */ + __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_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_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); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_substraction */ + +/** + * 'Multiplication' opcode handler. + * + * See also: ECMA-262 v5, 11.5, 11.5.1 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_multiplication (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.multiplication.dst; + const T_IDX left_var_idx = opdata.data.multiplication.var_left; + const T_IDX right_var_idx = opdata.data.multiplication.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_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_multiplication, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_multiplication */ + +/** + * 'Division' opcode handler. + * + * See also: ECMA-262 v5, 11.5, 11.5.2 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_division (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.division.dst; + const T_IDX left_var_idx = opdata.data.division.var_left; + const T_IDX right_var_idx = opdata.data.division.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_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_division, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_division */ + +/** + * 'Remainder calculation' opcode handler. + * + * See also: ECMA-262 v5, 11.5, 11.5.3 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_remainder (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.remainder.dst; + const T_IDX left_var_idx = opdata.data.remainder.var_left; + const T_IDX right_var_idx = opdata.data.remainder.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_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_remainder, + left_value.value, + right_value.value); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_remainder */ diff --git a/src/libcoreint/opcodes-ecma-support.h b/src/libcoreint/opcodes-ecma-support.h new file mode 100644 index 000000000..7be7d5cfe --- /dev/null +++ b/src/libcoreint/opcodes-ecma-support.h @@ -0,0 +1,182 @@ +/* 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. + */ + +#ifndef OPCODES_ECMA_SUPPORT_H +#define OPCODES_ECMA_SUPPORT_H + +#include "ecma-alloc.h" +#include "ecma-comparison.h" +#include "ecma-conversion.h" +#include "ecma-exceptions.h" +#include "ecma-function-object.h" +#include "ecma-gc.h" +#include "ecma-helpers.h" +#include "ecma-magic-strings.h" +#include "ecma-number-arithmetic.h" +#include "ecma-operations.h" +#include "ecma-try-catch-macro.h" +#include "ecma-objects.h" + +#include "opcodes.h" + +static bool do_strict_eval_arguments_check (ecma_reference_t) __unused; +static ecma_completion_value_t get_variable_value (__int_data *, T_IDX, bool) __unused; +static ecma_completion_value_t set_variable_value (__int_data *, T_IDX, ecma_value_t) __unused; + +/** + * Perform so-called 'strict eval or arguments reference' check + * that is used in definition of several statement handling algorithms, + * but has no ECMA-defined name. + * + * @return true - if ref is strict reference + * and it's base is lexical environment + * and it's referenced name is 'eval' or 'arguments'; + * false - otherwise. + */ +static bool +do_strict_eval_arguments_check (ecma_reference_t ref) /**< ECMA-reference */ +{ + bool ret; + + if (ref.is_strict + && (ref.base.value_type == ECMA_TYPE_OBJECT) + && (ECMA_GET_POINTER (ref.base.value) != NULL) + && (((ecma_object_t*) ECMA_GET_POINTER (ref.base.value))->is_lexical_environment)) + { + ecma_string_t* magic_string_eval = ecma_get_magic_string (ECMA_MAGIC_STRING_EVAL); + ecma_string_t* magic_string_arguments = ecma_get_magic_string (ECMA_MAGIC_STRING_ARGUMENTS); + + ret = (ecma_compare_ecma_string_to_ecma_string (ref.referenced_name_p, + magic_string_eval) == 0 + || ecma_compare_ecma_string_to_ecma_string (ref.referenced_name_p, + magic_string_arguments) == 0); + + ecma_deref_ecma_string (magic_string_eval); + ecma_deref_ecma_string (magic_string_arguments); + } + else + { + ret = false; + } + + return ret; +} /* do_strict_eval_arguments_check */ + +/** + * Get variable's value. + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +static ecma_completion_value_t +get_variable_value (__int_data *int_data, /**< interpreter context */ + T_IDX var_idx, /**< variable identifier */ + bool do_eval_or_arguments_check) /** run 'strict eval or arguments reference' check + See also: do_strict_eval_arguments_check */ +{ + ecma_completion_value_t ret_value; + + if (var_idx >= int_data->min_reg_num + && var_idx <= int_data->max_reg_num) + { + ecma_value_t reg_value = int_data->regs_p[ var_idx - int_data->min_reg_num ]; + + JERRY_ASSERT (!ecma_is_value_empty (reg_value)); + + ret_value = ecma_make_completion_value (ECMA_COMPLETION_TYPE_NORMAL, + ecma_copy_value (reg_value, true), + ECMA_TARGET_ID_RESERVED); + } + else + { + ecma_reference_t ref; + + ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (var_idx); + + ref = ecma_op_get_identifier_reference (int_data->lex_env_p, + var_name_string_p, + int_data->is_strict); + + if (unlikely (do_eval_or_arguments_check + && do_strict_eval_arguments_check (ref))) + { + ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_SYNTAX)); + } + else + { + ret_value = ecma_op_get_value (ref); + } + + ecma_deref_ecma_string (var_name_string_p); + ecma_free_reference (ref); + } + + return ret_value; +} /* get_variable_value */ + +/** + * Set variable's value. + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +static ecma_completion_value_t +set_variable_value (__int_data *int_data, /**< interpreter context */ + T_IDX var_idx, /**< variable identifier */ + ecma_value_t value) /**< value to set */ +{ + ecma_completion_value_t ret_value; + + if (var_idx >= int_data->min_reg_num + && var_idx <= int_data->max_reg_num) + { + ecma_value_t reg_value = int_data->regs_p[ var_idx - int_data->min_reg_num ]; + + if (!ecma_is_value_empty (reg_value)) + { + ecma_free_value (reg_value, true); + } + + int_data->regs_p[ var_idx - int_data->min_reg_num ] = ecma_copy_value (value, true); + + ret_value = ecma_make_empty_completion_value (); + } + else + { + ecma_reference_t ref; + + ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (var_idx); + + ref = ecma_op_get_identifier_reference (int_data->lex_env_p, + var_name_string_p, + int_data->is_strict); + + if (unlikely (do_strict_eval_arguments_check (ref))) + { + ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_SYNTAX)); + } + else + { + ret_value = ecma_op_put_value (ref, value); + } + + ecma_deref_ecma_string (var_name_string_p); + ecma_free_reference (ref); + } + + return ret_value; +} /* set_variable_value */ + +#endif /* OPCODES_ECMA_SUPPORT_H */ diff --git a/src/libcoreint/opcodes-equality.c b/src/libcoreint/opcodes-equality.c new file mode 100644 index 000000000..c4339a31d --- /dev/null +++ b/src/libcoreint/opcodes-equality.c @@ -0,0 +1,155 @@ +/* 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 "opcodes.h" +#include "opcodes-ecma-support.h" + +/** + * 'Equals' opcode handler. + * + * See also: ECMA-262 v5, 11.9.1 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_equal_value (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.equal_value.dst; + const T_IDX left_var_idx = opdata.data.equal_value.var_left; + const T_IDX right_var_idx = opdata.data.equal_value.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + bool is_equal = ecma_op_abstract_equality_compare (left_value.value, right_value.value); + + ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE + : ECMA_SIMPLE_VALUE_FALSE)); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_equal_value */ + +/** + * 'Does-not-equals' opcode handler. + * + * See also: ECMA-262 v5, 11.9.2 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_not_equal_value (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.not_equal_value.dst; + const T_IDX left_var_idx = opdata.data.not_equal_value.var_left; + const T_IDX right_var_idx = opdata.data.not_equal_value.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + bool is_equal = ecma_op_abstract_equality_compare (left_value.value, right_value.value); + + ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE + : ECMA_SIMPLE_VALUE_TRUE)); + + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_not_equal_value */ + +/** + * 'Strict Equals' opcode handler. + * + * See also: ECMA-262 v5, 11.9.4 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_equal_value_type (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.equal_value_type.dst; + const T_IDX left_var_idx = opdata.data.equal_value_type.var_left; + const T_IDX right_var_idx = opdata.data.equal_value_type.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + bool is_equal = ecma_op_strict_equality_compare (left_value.value, right_value.value); + + ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE + : ECMA_SIMPLE_VALUE_FALSE)); + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_equal_value_type */ + +/** + * 'Strict Does-not-equals' opcode handler. + * + * See also: ECMA-262 v5, 11.9.5 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_not_equal_value_type (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.not_equal_value_type.dst; + const T_IDX left_var_idx = opdata.data.not_equal_value_type.var_left; + const T_IDX right_var_idx = opdata.data.not_equal_value_type.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + bool is_equal = ecma_op_strict_equality_compare (left_value.value, right_value.value); + + ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE + : ECMA_SIMPLE_VALUE_TRUE)); + + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_not_equal_value_type */ diff --git a/src/libcoreint/opcodes-relational.c b/src/libcoreint/opcodes-relational.c new file mode 100644 index 000000000..3a3fae933 --- /dev/null +++ b/src/libcoreint/opcodes-relational.c @@ -0,0 +1,331 @@ +/* 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 "opcodes.h" +#include "opcodes-ecma-support.h" + +/** + * 'Less-than' opcode handler. + * + * See also: ECMA-262 v5, 11.8.1 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_less_than (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.less_than.dst; + const T_IDX left_var_idx = opdata.data.less_than.var_left; + const T_IDX right_var_idx = opdata.data.less_than.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + ECMA_TRY_CATCH (compare_result, + ecma_op_abstract_relational_compare (left_value.value, + right_value.value, + true), + ret_value); + + ecma_simple_value_t res; + + if (ecma_is_value_undefined (compare_result.value)) + { + res = ECMA_SIMPLE_VALUE_FALSE; + } + else + { + JERRY_ASSERT (ecma_is_value_boolean (compare_result.value)); + + res = compare_result.value.value; + } + + ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res)); + + ECMA_FINALIZE (compare_result); + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_less_than */ + +/** + * 'Greater-than' opcode handler. + * + * See also: ECMA-262 v5, 11.8.2 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_greater_than (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.greater_than.dst; + const T_IDX left_var_idx = opdata.data.greater_than.var_left; + const T_IDX right_var_idx = opdata.data.greater_than.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + ECMA_TRY_CATCH (compare_result, + ecma_op_abstract_relational_compare (right_value.value, + left_value.value, + false), + ret_value); + + ecma_simple_value_t res; + + if (ecma_is_value_undefined (compare_result.value)) + { + res = ECMA_SIMPLE_VALUE_FALSE; + } + else + { + JERRY_ASSERT (ecma_is_value_boolean (compare_result.value)); + + res = compare_result.value.value; + } + + ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res)); + + ECMA_FINALIZE (compare_result); + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_greater_than */ + +/** + * 'Less-than-or-equal' opcode handler. + * + * See also: ECMA-262 v5, 11.8.3 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_less_or_equal_than (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.less_or_equal_than.dst; + const T_IDX left_var_idx = opdata.data.less_or_equal_than.var_left; + const T_IDX right_var_idx = opdata.data.less_or_equal_than.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + ECMA_TRY_CATCH (compare_result, + ecma_op_abstract_relational_compare (right_value.value, + left_value.value, + false), + ret_value); + + ecma_simple_value_t res; + + if (ecma_is_value_undefined (compare_result.value)) + { + res = ECMA_SIMPLE_VALUE_FALSE; + } + else + { + JERRY_ASSERT (ecma_is_value_boolean (compare_result.value)); + + if (compare_result.value.value == ECMA_SIMPLE_VALUE_TRUE) + { + res = ECMA_SIMPLE_VALUE_FALSE; + } + else + { + res = ECMA_SIMPLE_VALUE_TRUE; + } + } + + ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res)); + + ECMA_FINALIZE (compare_result); + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_less_or_equal_than */ + +/** + * 'Greater-than-or-equal' opcode handler. + * + * See also: ECMA-262 v5, 11.8.4 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_greater_or_equal_than (OPCODE opdata, /**< operation data */ + __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.greater_or_equal_than.dst; + const T_IDX left_var_idx = opdata.data.greater_or_equal_than.var_left; + const T_IDX right_var_idx = opdata.data.greater_or_equal_than.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + ECMA_TRY_CATCH (compare_result, + ecma_op_abstract_relational_compare (left_value.value, + right_value.value, + true), + ret_value); + + ecma_simple_value_t res; + + if (ecma_is_value_undefined (compare_result.value)) + { + res = ECMA_SIMPLE_VALUE_FALSE; + } + else + { + JERRY_ASSERT (ecma_is_value_boolean (compare_result.value)); + + if (compare_result.value.value == ECMA_SIMPLE_VALUE_TRUE) + { + res = ECMA_SIMPLE_VALUE_FALSE; + } + else + { + res = ECMA_SIMPLE_VALUE_TRUE; + } + } + + ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res)); + + ECMA_FINALIZE (compare_result); + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_greater_or_equal_than */ + +/** + * 'instanceof' opcode handler. + * + * See also: ECMA-262 v5, 11.8.6 + * + * @return completion value + * returned value must be freed with ecma_free_completion_value. + */ +ecma_completion_value_t +opfunc_instanceof (OPCODE opdata __unused, /**< operation data */ + __int_data *int_data __unused) /**< interpreter context */ +{ + const T_IDX dst_idx = opdata.data.instanceof.dst; + const T_IDX left_var_idx = opdata.data.instanceof.var_left; + const T_IDX right_var_idx = opdata.data.instanceof.var_right; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + if (right_value.value.value_type != ECMA_TYPE_OBJECT) + { + ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); + } + else + { + ecma_object_t *right_value_obj_p = ECMA_GET_POINTER (right_value.value.value); + + ECMA_TRY_CATCH (is_instance_of, + ecma_op_object_has_instance (right_value_obj_p, + left_value.value), + ret_value); + + ret_value = set_variable_value (int_data, dst_idx, is_instance_of.value); + + ECMA_FINALIZE (is_instance_of); + } + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_instanceof */ + +/** + * 'in' opcode handler. + * + * See also: ECMA-262 v5, 11.8.7 + * + * @return completion value + * returned value must be freed with ecma_free_completion_value. + */ +ecma_completion_value_t +opfunc_in (OPCODE opdata __unused, /**< operation data */ + __int_data *int_data __unused) /**< interpreter context */ +{ + const T_IDX dst_idx = opdata.data.in.dst; + const T_IDX left_var_idx = opdata.data.in.var_left; + const T_IDX right_var_idx = opdata.data.in.var_right; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); + + if (right_value.value.value_type != ECMA_TYPE_OBJECT) + { + ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); + } + else + { + ECMA_TRY_CATCH (str_left_value, ecma_op_to_string (left_value.value), ret_value); + + ecma_simple_value_t is_in = ECMA_SIMPLE_VALUE_UNDEFINED; + ecma_string_t *left_value_prop_name_p = ECMA_GET_POINTER (str_left_value.value.value); + ecma_object_t *right_value_obj_p = ECMA_GET_POINTER (right_value.value.value); + + if (ecma_op_object_has_property (right_value_obj_p, left_value_prop_name_p)) + { + is_in = ECMA_SIMPLE_VALUE_TRUE; + } + else + { + is_in = ECMA_SIMPLE_VALUE_FALSE; + } + + ret_value = set_variable_value (int_data, + dst_idx, + ecma_make_simple_value (is_in)); + + ECMA_FINALIZE (str_left_value); + } + + ECMA_FINALIZE (right_value); + ECMA_FINALIZE (left_value); + + return ret_value; +} /* opfunc_in */ diff --git a/src/libcoreint/opcodes-support.c b/src/libcoreint/opcodes-support.c new file mode 100644 index 000000000..bb66c5dbb --- /dev/null +++ b/src/libcoreint/opcodes-support.c @@ -0,0 +1,119 @@ +/* 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 "opcodes-support.h" + +#define GETOP_DEF_0(name) \ + __opcode getop_##name (void) \ + { \ + __opcode opdata; \ + opdata.op_idx = __op__idx_##name; \ + return opdata; \ + } + +#define GETOP_DEF_1(name, field1) \ + __opcode getop_##name (T_IDX arg1) \ + { \ + __opcode opdata; \ + opdata.op_idx = __op__idx_##name; \ + opdata.data.name.field1 = arg1; \ + return opdata; \ + } + +#define GETOP_DEF_2(name, field1, field2) \ + __opcode getop_##name (T_IDX arg1, T_IDX arg2) \ + { \ + __opcode opdata; \ + opdata.op_idx = __op__idx_##name; \ + opdata.data.name.field1 = arg1; \ + opdata.data.name.field2 = arg2; \ + return opdata; \ + } + +#define GETOP_DEF_3(name, field1, field2, field3) \ + __opcode getop_##name (T_IDX arg1, T_IDX arg2, T_IDX arg3) \ + { \ + __opcode opdata; \ + opdata.op_idx = __op__idx_##name; \ + opdata.data.name.field1 = arg1; \ + opdata.data.name.field2 = arg2; \ + opdata.data.name.field3 = arg3; \ + return opdata; \ + } + +GETOP_DEF_3 (construct_decl, lhs, name_lit_idx, arg_list) +GETOP_DEF_1 (func_decl_0, name_lit_idx) +GETOP_DEF_2 (array_decl, lhs, list) +GETOP_DEF_3 (prop, lhs, name, value) +GETOP_DEF_3 (prop_getter, lhs, obj, prop) +GETOP_DEF_3 (prop_setter, obj, prop, rhs) +GETOP_DEF_2 (prop_get_decl, lhs, prop) +GETOP_DEF_3 (prop_set_decl, lhs, prop, arg) +GETOP_DEF_2 (obj_decl, lhs, list) +GETOP_DEF_1 (this, lhs) +GETOP_DEF_2 (delete, lhs, obj) +GETOP_DEF_2 (typeof, lhs, obj) +GETOP_DEF_1 (with, expr) +GETOP_DEF_0 (end_with) +GETOP_DEF_1 (var_decl, variable_name) +GETOP_DEF_2 (reg_var_decl, min, max) +GETOP_DEF_3 (meta, type, data_1, data_2) +GETOP_DEF_2 (is_true_jmp, value, opcode) +GETOP_DEF_2 (is_false_jmp, value, opcode) +GETOP_DEF_1 (jmp, opcode_idx) +GETOP_DEF_1 (jmp_up, opcode_count) +GETOP_DEF_1 (jmp_down, opcode_count) +GETOP_DEF_3 (addition, dst, var_left, var_right) +GETOP_DEF_2 (post_incr, dst, var_right) +GETOP_DEF_2 (post_decr, dst, var_right) +GETOP_DEF_2 (pre_incr, dst, var_right) +GETOP_DEF_2 (pre_decr, dst, var_right) +GETOP_DEF_3 (substraction, dst, var_left, var_right) +GETOP_DEF_3 (division, dst, var_left, var_right) +GETOP_DEF_3 (multiplication, dst, var_left, var_right) +GETOP_DEF_3 (remainder, dst, var_left, var_right) +GETOP_DEF_3 (b_shift_left, dst, var_left, var_right) +GETOP_DEF_3 (b_shift_right, dst, var_left, var_right) +GETOP_DEF_3 (b_shift_uright, dst, var_left, var_right) +GETOP_DEF_3 (b_and, dst, var_left, var_right) +GETOP_DEF_3 (b_or, dst, var_left, var_right) +GETOP_DEF_3 (b_xor, dst, var_left, var_right) +GETOP_DEF_3 (logical_and, dst, var_left, var_right) +GETOP_DEF_3 (logical_or, dst, var_left, var_right) +GETOP_DEF_3 (equal_value, dst, var_left, var_right) +GETOP_DEF_3 (not_equal_value, dst, var_left, var_right) +GETOP_DEF_3 (equal_value_type, dst, var_left, var_right) +GETOP_DEF_3 (not_equal_value_type, dst, var_left, var_right) +GETOP_DEF_3 (less_than, dst, var_left, var_right) +GETOP_DEF_3 (greater_than, dst, var_left, var_right) +GETOP_DEF_3 (less_or_equal_than, dst, var_left, var_right) +GETOP_DEF_3 (greater_or_equal_than, dst, var_left, var_right) +GETOP_DEF_3 (assignment, var_left, type_value_right, value_right) +GETOP_DEF_2 (call_0, lhs, name_lit_idx) +GETOP_DEF_3 (call_1, lhs, name_lit_idx, arg1_lit_idx) +GETOP_DEF_3 (call_n, lhs, name_lit_idx, arg1_lit_idx) +GETOP_DEF_3 (native_call, lhs, name, arg_list) +GETOP_DEF_2 (func_decl_1, name_lit_idx, arg1_lit_idx) +GETOP_DEF_3 (func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx) +GETOP_DEF_3 (func_decl_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx) +GETOP_DEF_3 (varg_list, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx) +GETOP_DEF_1 (exitval, status_code) +GETOP_DEF_1 (retval, ret_value) +GETOP_DEF_0 (ret) +GETOP_DEF_0 (nop) +GETOP_DEF_2 (b_not, dst, var_right) +GETOP_DEF_2 (logical_not, dst, var_right) +GETOP_DEF_3 (instanceof, dst, var_left, var_right) +GETOP_DEF_3 (in, dst, var_left, var_right) diff --git a/src/libcoreint/opcodes-support.h b/src/libcoreint/opcodes-support.h new file mode 100644 index 000000000..821c60f32 --- /dev/null +++ b/src/libcoreint/opcodes-support.h @@ -0,0 +1,99 @@ +/* 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. + */ + +#ifndef OPCODES_SUPPORT_H +#define OPCODES_SUPPORT_H + +#include "opcodes.h" + +#define GETOP_DECL_0(name) \ + __opcode getop_##name (void); + +#define GETOP_DECL_1(name, field1) \ + __opcode getop_##name (T_IDX); + +#define GETOP_DECL_2(name, field1, field2) \ + __opcode getop_##name (T_IDX, T_IDX); + +#define GETOP_DECL_3(name, field1, field2, field3) \ + __opcode getop_##name (T_IDX, T_IDX, T_IDX); + +GETOP_DECL_3 (construct_decl, lhs, name_lit_idx, arg_list) +GETOP_DECL_1 (func_decl_0, name_lit_idx) +GETOP_DECL_2 (array_decl, lhs, list) +GETOP_DECL_3 (prop, lhs, name, value) +GETOP_DECL_3 (prop_getter, lhs, obj, prop) +GETOP_DECL_3 (prop_setter, obj, prop, rhs) +GETOP_DECL_2 (prop_get_decl, lhs, prop) +GETOP_DECL_3 (prop_set_decl, lhs, prop, arg) +GETOP_DECL_2 (obj_decl, lhs, list) +GETOP_DECL_1 (this, lhs) +GETOP_DECL_2 (delete, lhs, obj) +GETOP_DECL_2 (typeof, lhs, obj) +GETOP_DECL_1 (with, expr) +GETOP_DECL_0 (end_with) +GETOP_DECL_1 (var_decl, variable_name) +GETOP_DECL_2 (reg_var_decl, min, max) +GETOP_DECL_3 (meta, type, data_1, data_2) +GETOP_DECL_2 (is_true_jmp, value, opcode) +GETOP_DECL_2 (is_false_jmp, value, opcode) +GETOP_DECL_1 (jmp, opcode_idx) +GETOP_DECL_1 (jmp_up, opcode_count) +GETOP_DECL_1 (jmp_down, opcode_count) +GETOP_DECL_3 (addition, dst, var_left, var_right) +GETOP_DECL_2 (post_incr, dst, var_right) +GETOP_DECL_2 (post_decr, dst, var_right) +GETOP_DECL_2 (pre_incr, dst, var_right) +GETOP_DECL_2 (pre_decr, dst, var_right) +GETOP_DECL_3 (substraction, dst, var_left, var_right) +GETOP_DECL_3 (division, dst, var_left, var_right) +GETOP_DECL_3 (multiplication, dst, var_left, var_right) +GETOP_DECL_3 (remainder, dst, var_left, var_right) +GETOP_DECL_3 (b_shift_left, dst, var_left, var_right) +GETOP_DECL_3 (b_shift_right, dst, var_left, var_right) +GETOP_DECL_3 (b_shift_uright, dst, var_left, var_right) +GETOP_DECL_3 (b_and, dst, var_left, var_right) +GETOP_DECL_3 (b_or, dst, var_left, var_right) +GETOP_DECL_3 (b_xor, dst, var_left, var_right) +GETOP_DECL_3 (logical_and, dst, var_left, var_right) +GETOP_DECL_3 (logical_or, dst, var_left, var_right) +GETOP_DECL_3 (equal_value, dst, var_left, var_right) +GETOP_DECL_3 (not_equal_value, dst, var_left, var_right) +GETOP_DECL_3 (equal_value_type, dst, var_left, var_right) +GETOP_DECL_3 (not_equal_value_type, dst, var_left, var_right) +GETOP_DECL_3 (less_than, dst, var_left, var_right) +GETOP_DECL_3 (greater_than, dst, var_left, var_right) +GETOP_DECL_3 (less_or_equal_than, dst, var_left, var_right) +GETOP_DECL_3 (greater_or_equal_than, dst, var_left, var_right) +GETOP_DECL_3 (assignment, var_left, type_value_right, value_right) +GETOP_DECL_2 (call_0, lhs, name_lit_idx) +GETOP_DECL_3 (call_1, lhs, name_lit_idx, arg1_lit_idx) +GETOP_DECL_3 (call_n, lhs, name_lit_idx, arg1_lit_idx) +GETOP_DECL_3 (native_call, lhs, name, arg_list) +GETOP_DECL_2 (func_decl_1, name_lit_idx, arg1_lit_idx) +GETOP_DECL_3 (func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx) +GETOP_DECL_3 (func_decl_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx) +GETOP_DECL_3 (varg_list, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx) +GETOP_DECL_1 (exitval, status_code) +GETOP_DECL_1 (retval, ret_value) +GETOP_DECL_0 (ret) +GETOP_DECL_0 (nop) +GETOP_DECL_2 (b_not, dst, var_right) +GETOP_DECL_2 (logical_not, dst, var_right) +GETOP_DECL_3 (instanceof, dst, var_left, var_right) +GETOP_DECL_3 (in, dst, var_left, var_right) + +#endif /* OPCODES_SUPPORT_H */ + diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 41204fc66..00830871a 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -13,17 +13,8 @@ * limitations under the License. */ -#include "ecma-alloc.h" -#include "ecma-comparison.h" -#include "ecma-conversion.h" -#include "ecma-exceptions.h" -#include "ecma-function-object.h" -#include "ecma-gc.h" -#include "ecma-helpers.h" -#include "ecma-magic-strings.h" -#include "ecma-number-arithmetic.h" -#include "ecma-operations.h" -#include "ecma-try-catch-macro.h" +#include "opcodes-ecma-support.h" + #include "globals.h" #include "interpreter.h" #include "jerry-libc.h" @@ -125,332 +116,6 @@ free_string_literal_copy (string_literal_copy *str_lit_descr_p) /**< string lite return; } /* free_string_literal */ -/** - * Perform so-called 'strict eval or arguments reference' check - * that is used in definition of several statement handling algorithms, - * but has no ECMA-defined name. - * - * @return true - if ref is strict reference - * and it's base is lexical environment - * and it's referenced name is 'eval' or 'arguments'; - * false - otherwise. - */ -static bool -do_strict_eval_arguments_check (ecma_reference_t ref) /**< ECMA-reference */ -{ - bool ret; - - if (ref.is_strict - && (ref.base.value_type == ECMA_TYPE_OBJECT) - && (ECMA_GET_POINTER (ref.base.value) != NULL) - && (((ecma_object_t*) ECMA_GET_POINTER (ref.base.value))->is_lexical_environment)) - { - ecma_string_t* magic_string_eval = ecma_get_magic_string (ECMA_MAGIC_STRING_EVAL); - ecma_string_t* magic_string_arguments = ecma_get_magic_string (ECMA_MAGIC_STRING_ARGUMENTS); - - ret = (ecma_compare_ecma_string_to_ecma_string (ref.referenced_name_p, - magic_string_eval) == 0 - || ecma_compare_ecma_string_to_ecma_string (ref.referenced_name_p, - magic_string_arguments) == 0); - - ecma_deref_ecma_string (magic_string_eval); - ecma_deref_ecma_string (magic_string_arguments); - } - else - { - ret = false; - } - - return ret; -} /* do_strict_eval_arguments_check */ - -/** - * Get variable's value. - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -static ecma_completion_value_t -get_variable_value (struct __int_data *int_data, /**< interpreter context */ - T_IDX var_idx, /**< variable identifier */ - bool do_eval_or_arguments_check) /** run 'strict eval or arguments reference' check - See also: do_strict_eval_arguments_check */ -{ - ecma_completion_value_t ret_value; - - if (var_idx >= int_data->min_reg_num - && var_idx <= int_data->max_reg_num) - { - ecma_value_t reg_value = int_data->regs_p[ var_idx - int_data->min_reg_num ]; - - JERRY_ASSERT (!ecma_is_value_empty (reg_value)); - - ret_value = ecma_make_completion_value (ECMA_COMPLETION_TYPE_NORMAL, - ecma_copy_value (reg_value, true), - ECMA_TARGET_ID_RESERVED); - } - else - { - ecma_reference_t ref; - - ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (var_idx); - - ref = ecma_op_get_identifier_reference (int_data->lex_env_p, - var_name_string_p, - int_data->is_strict); - - if (unlikely (do_eval_or_arguments_check - && do_strict_eval_arguments_check (ref))) - { - ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_SYNTAX)); - } - else - { - ret_value = ecma_op_get_value (ref); - } - - ecma_deref_ecma_string (var_name_string_p); - ecma_free_reference (ref); - } - - return ret_value; -} /* get_variable_value */ - -/** - * Set variable's value. - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -static ecma_completion_value_t -set_variable_value (struct __int_data *int_data, /**< interpreter context */ - T_IDX var_idx, /**< variable identifier */ - ecma_value_t value) /**< value to set */ -{ - ecma_completion_value_t ret_value; - - if (var_idx >= int_data->min_reg_num - && var_idx <= int_data->max_reg_num) - { - ecma_value_t reg_value = int_data->regs_p[ var_idx - int_data->min_reg_num ]; - - if (!ecma_is_value_empty (reg_value)) - { - ecma_free_value (reg_value, true); - } - - int_data->regs_p[ var_idx - int_data->min_reg_num ] = ecma_copy_value (value, true); - - ret_value = ecma_make_empty_completion_value (); - } - else - { - ecma_reference_t ref; - - ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (var_idx); - - ref = ecma_op_get_identifier_reference (int_data->lex_env_p, - var_name_string_p, - int_data->is_strict); - - if (unlikely (do_strict_eval_arguments_check (ref))) - { - ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_SYNTAX)); - } - else - { - ret_value = ecma_op_put_value (ref, value); - } - - ecma_deref_ecma_string (var_name_string_p); - ecma_free_reference (ref); - } - - return ret_value; -} /* set_variable_value */ - -/** - * Number arithmetic operations. - */ -typedef enum -{ - number_arithmetic_addition, /**< addition */ - number_arithmetic_substraction, /**< substraction */ - number_arithmetic_multiplication, /**< multiplication */ - number_arithmetic_division, /**< division */ - number_arithmetic_remainder, /**< remainder calculation */ -} number_arithmetic_op; - -/** - * Number bitwise logic operations. - */ -typedef enum -{ - number_bitwise_logic_and, /**< bitwise AND calculation */ - number_bitwise_logic_or, /**< bitwise OR calculation */ - number_bitwise_logic_xor, /**< bitwise XOR calculation */ - number_bitwise_shift_left, /**< bitwise LEFT SHIFT calculation */ - number_bitwise_shift_right, /**< bitwise RIGHT_SHIFT calculation */ - number_bitwise_shift_uright, /**< bitwise UNSIGNED RIGHT SHIFT calculation */ - number_bitwise_not, /**< bitwise NOT calculation */ -} number_bitwise_logic_op; - -/** - * Perform ECMA number arithmetic operation. - * - * The algorithm of the operation is following: - * leftNum = ToNumber (leftValue); - * rightNum = ToNumber (rightValue); - * result = leftNum ArithmeticOp rightNum; - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -static ecma_completion_value_t -do_number_arithmetic (struct __int_data *int_data, /**< interpreter context */ - T_IDX dst_var_idx, /**< destination variable identifier */ - number_arithmetic_op op, /**< number arithmetic operation */ - ecma_value_t left_value, /**< left value */ - ecma_value_t right_value) /** right value */ -{ - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (num_left_value, ecma_op_to_number (left_value), ret_value); - ECMA_TRY_CATCH (num_right_value, ecma_op_to_number (right_value), ret_value); - - ecma_number_t *left_p, *right_p, *res_p; - left_p = (ecma_number_t*) ECMA_GET_POINTER (num_left_value.value.value); - right_p = (ecma_number_t*) ECMA_GET_POINTER (num_right_value.value.value); - - res_p = ecma_alloc_number (); - - switch (op) - { - case number_arithmetic_addition: - { - *res_p = ecma_op_number_add (*left_p, *right_p); - break; - } - case number_arithmetic_substraction: - { - *res_p = ecma_op_number_substract (*left_p, *right_p); - break; - } - case number_arithmetic_multiplication: - { - *res_p = ecma_op_number_multiply (*left_p, *right_p); - break; - } - case number_arithmetic_division: - { - *res_p = ecma_op_number_divide (*left_p, *right_p); - break; - } - case number_arithmetic_remainder: - { - *res_p = ecma_op_number_remainder (*left_p, *right_p); - break; - } - } - - ret_value = set_variable_value (int_data, - dst_var_idx, - ecma_make_number_value (res_p)); - - ecma_dealloc_number (res_p); - - ECMA_FINALIZE (num_right_value); - ECMA_FINALIZE (num_left_value); - - return ret_value; -} /* do_number_arithmetic */ - -/** - * Perform ECMA number logic operation. - * - * The algorithm of the operation is following: - * leftNum = ToNumber (leftValue); - * rightNum = ToNumber (rightValue); - * result = leftNum BitwiseLogicOp rightNum; - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -static ecma_completion_value_t -do_number_bitwise_logic (struct __int_data *int_data, /**< interpreter context */ - T_IDX dst_var_idx, /**< destination variable identifier */ - number_bitwise_logic_op op, /**< number bitwise logic operation */ - ecma_value_t left_value, /**< left value */ - ecma_value_t right_value) /** right value */ -{ - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (num_left_value, ecma_op_to_number (left_value), ret_value); - ECMA_TRY_CATCH (num_right_value, ecma_op_to_number (right_value), ret_value); - - ecma_number_t *left_p, *right_p; - left_p = (ecma_number_t*) ECMA_GET_POINTER (num_left_value.value.value); - right_p = (ecma_number_t*) ECMA_GET_POINTER (num_right_value.value.value); - - ecma_number_t* res_p = ecma_alloc_number (); - - int32_t left_int32 = ecma_number_to_int32 (*left_p); - int32_t right_int32 = ecma_number_to_int32 (*right_p); - - uint32_t left_uint32 = ecma_number_to_uint32 (*left_p); - uint32_t right_uint32 = ecma_number_to_uint32 (*right_p); - - switch (op) - { - case number_bitwise_logic_and: - { - *res_p = ecma_int32_to_number (left_int32 & right_int32); - break; - } - case number_bitwise_logic_or: - { - *res_p = ecma_int32_to_number (left_int32 | right_int32); - break; - } - case number_bitwise_logic_xor: - { - *res_p = ecma_int32_to_number (left_int32 ^ right_int32); - break; - } - case number_bitwise_shift_left: - { - *res_p = ecma_int32_to_number (left_int32 << (right_uint32 & 0x1F)); - break; - } - case number_bitwise_shift_right: - { - *res_p = ecma_int32_to_number (left_int32 >> (right_uint32 & 0x1F)); - break; - } - case number_bitwise_shift_uright: - { - *res_p = ecma_uint32_to_number (left_uint32 >> (right_uint32 & 0x1F)); - break; - } - case number_bitwise_not: - { - *res_p = ecma_int32_to_number (~right_int32); - break; - } - } - - ret_value = set_variable_value (int_data, - dst_var_idx, - ecma_make_number_value (res_p)); - - ecma_dealloc_number (res_p); - - ECMA_FINALIZE (num_right_value); - ECMA_FINALIZE (num_left_value); - - return ret_value; -} /* do_number_bitwise_logic */ - #define OP_UNIMPLEMENTED_LIST(op) \ op (call_n) \ op (native_call) \ @@ -471,7 +136,7 @@ do_number_bitwise_logic (struct __int_data *int_data, /**< interpreter context * static char __unused unimplemented_list_end #define DEFINE_UNIMPLEMENTED_OP(op) \ - ecma_completion_value_t opfunc_ ## op (OPCODE opdata, struct __int_data *int_data) \ + ecma_completion_value_t opfunc_ ## op (OPCODE opdata, __int_data *int_data) \ { \ JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (opdata, int_data); \ } @@ -484,7 +149,7 @@ OP_UNIMPLEMENTED_LIST (DEFINE_UNIMPLEMENTED_OP); */ ecma_completion_value_t opfunc_nop (OPCODE opdata __unused, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { int_data->pos++; @@ -492,7 +157,7 @@ opfunc_nop (OPCODE opdata __unused, /**< operation data */ } /* opfunc_nop */ ecma_completion_value_t -opfunc_call_1 (OPCODE opdata __unused, struct __int_data *int_data) +opfunc_call_1 (OPCODE opdata __unused, __int_data *int_data) { ecma_completion_value_t ret_value; ret_value = ecma_make_empty_completion_value (); @@ -617,129 +282,6 @@ opfunc_call_1 (OPCODE opdata __unused, struct __int_data *int_data) return ret_value; } -/** - * 'Jump if true' opcode handler. - * - * Note: - * the opcode changes current opcode position to specified opcode index - * if argument evaluates to true. - */ -ecma_completion_value_t -opfunc_is_true_jmp (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX cond_var_idx = opdata.data.is_true_jmp.value; - const T_IDX dst_opcode_idx = opdata.data.is_true_jmp.opcode; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (cond_value, get_variable_value (int_data, cond_var_idx, false), ret_value); - - ecma_completion_value_t to_bool_completion = ecma_op_to_boolean (cond_value.value); - JERRY_ASSERT (ecma_is_completion_value_normal (to_bool_completion)); - - if (ecma_is_value_true (to_bool_completion.value)) - { - int_data->pos = dst_opcode_idx; - } - else - { - int_data->pos++; - } - - ret_value = ecma_make_empty_completion_value (); - - ECMA_FINALIZE (cond_value); - - return ret_value; -} /* opfunc_is_true_jmp */ - -/** - * 'Jump if false' opcode handler. - * - * Note: - * the opcode changes current opcode position to specified opcode index - * if argument evaluates to false. - */ -ecma_completion_value_t -opfunc_is_false_jmp (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX cond_var_idx = opdata.data.is_false_jmp.value; - const T_IDX dst_opcode_idx = opdata.data.is_false_jmp.opcode; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (cond_value, get_variable_value (int_data, cond_var_idx, false), ret_value); - - ecma_completion_value_t to_bool_completion = ecma_op_to_boolean (cond_value.value); - JERRY_ASSERT (ecma_is_completion_value_normal (to_bool_completion)); - - if (!ecma_is_value_true (to_bool_completion.value)) - { - int_data->pos = dst_opcode_idx; - } - else - { - int_data->pos++; - } - - ret_value = ecma_make_empty_completion_value (); - - ECMA_FINALIZE (cond_value); - - return ret_value; -} /* opfunc_is_false_jmp */ - -/** - * 'Jump' opcode handler. - * - * Note: - * the opcode changes current opcode position to specified opcode index - */ -ecma_completion_value_t -opfunc_jmp (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - int_data->pos = opdata.data.jmp.opcode_idx; - - return ecma_make_empty_completion_value (); -} /* opfunc_jmp */ - -/** - * 'Jump down' opcode handler. - * - * Note: - * the opcode changes adds specified value to current opcode position - */ -ecma_completion_value_t -opfunc_jmp_down (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - JERRY_ASSERT (int_data->pos <= int_data->pos + opdata.data.jmp_up.opcode_count); - - int_data->pos = (opcode_counter_t) (int_data->pos + opdata.data.jmp_down.opcode_count); - - return ecma_make_empty_completion_value (); -} /* opfunc_jmp_down */ - -/** - * 'Jump up' opcode handler. - * - * Note: - * the opcode changes substracts specified value from current opcode position - */ -ecma_completion_value_t -opfunc_jmp_up (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - JERRY_ASSERT (int_data->pos >= opdata.data.jmp_up.opcode_count); - - int_data->pos = (opcode_counter_t) (int_data->pos - opdata.data.jmp_down.opcode_count); - - return ecma_make_empty_completion_value (); -} /* opfunc_jmp_up */ - /** * 'Assignment' opcode handler. * @@ -757,7 +299,7 @@ opfunc_jmp_up (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_assignment (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX dst_var_idx = opdata.data.assignment.var_left; const opcode_arg_type_operand type_value_right = opdata.data.assignment.type_value_right; @@ -833,436 +375,6 @@ 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_completion_value_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_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - ECMA_TRY_CATCH (prim_left_value, ecma_op_to_primitive (left_value.value, ECMA_PREFERRED_TYPE_NO), ret_value); - ECMA_TRY_CATCH (prim_right_value, ecma_op_to_primitive (right_value.value, ECMA_PREFERRED_TYPE_NO), ret_value); - - if (prim_left_value.value.value_type == ECMA_TYPE_STRING - || prim_right_value.value.value_type == 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); - } - - ECMA_FINALIZE (prim_right_value); - ECMA_FINALIZE (prim_left_value); - ECMA_FINALIZE (right_value); - ECMA_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_completion_value_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_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_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); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_substraction */ - -/** - * 'Multiplication' opcode handler. - * - * See also: ECMA-262 v5, 11.5, 11.5.1 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_multiplication (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.multiplication.dst; - const T_IDX left_var_idx = opdata.data.multiplication.var_left; - const T_IDX right_var_idx = opdata.data.multiplication.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_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_multiplication, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_multiplication */ - -/** - * 'Division' opcode handler. - * - * See also: ECMA-262 v5, 11.5, 11.5.2 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_division (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.division.dst; - const T_IDX left_var_idx = opdata.data.division.var_left; - const T_IDX right_var_idx = opdata.data.division.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_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_division, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_division */ - -/** - * 'Remainder calculation' opcode handler. - * - * See also: ECMA-262 v5, 11.5, 11.5.3 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_remainder (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.remainder.dst; - const T_IDX left_var_idx = opdata.data.remainder.var_left; - const T_IDX right_var_idx = opdata.data.remainder.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_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_remainder, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_remainder */ - -/** - * 'Bitwise AND' opcode handler. - * - * See also: ECMA-262 v5, 11.10 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_b_and (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.b_and.dst; - const T_IDX left_var_idx = opdata.data.b_and.var_left; - const T_IDX right_var_idx = opdata.data.b_and.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - ret_value = do_number_bitwise_logic (int_data, - dst_var_idx, - number_bitwise_logic_and, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_b_and */ - -/** - * 'Bitwise OR' opcode handler. - * - * See also: ECMA-262 v5, 11.10 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_b_or (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.b_or.dst; - const T_IDX left_var_idx = opdata.data.b_or.var_left; - const T_IDX right_var_idx = opdata.data.b_or.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - ret_value = do_number_bitwise_logic (int_data, - dst_var_idx, - number_bitwise_logic_or, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_b_or */ - -/** - * 'Bitwise XOR' opcode handler. - * - * See also: ECMA-262 v5, 11.10 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_b_xor (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.b_xor.dst; - const T_IDX left_var_idx = opdata.data.b_xor.var_left; - const T_IDX right_var_idx = opdata.data.b_xor.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - ret_value = do_number_bitwise_logic (int_data, - dst_var_idx, - number_bitwise_logic_xor, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_b_xor */ - -/** - * 'Left Shift Operator' opcode handler. - * - * See also: ECMA-262 v5, 11.7.1 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_b_shift_left (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.b_shift_left.dst; - const T_IDX left_var_idx = opdata.data.b_shift_left.var_left; - const T_IDX right_var_idx = opdata.data.b_shift_left.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - ret_value = do_number_bitwise_logic (int_data, - dst_var_idx, - number_bitwise_shift_left, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_b_shift_left */ - -/** - * 'Right Shift Operator' opcode handler. - * - * See also: ECMA-262 v5, 11.7.2 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_b_shift_right (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.b_shift_right.dst; - const T_IDX left_var_idx = opdata.data.b_shift_right.var_left; - const T_IDX right_var_idx = opdata.data.b_shift_right.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - ret_value = do_number_bitwise_logic (int_data, - dst_var_idx, - number_bitwise_shift_right, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_b_shift_right */ - -/** - * 'Unsigned Right Shift Operator' opcode handler. - * - * See also: ECMA-262 v5, 11.7.3 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_b_shift_uright (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.b_shift_uright.dst; - const T_IDX left_var_idx = opdata.data.b_shift_uright.var_left; - const T_IDX right_var_idx = opdata.data.b_shift_uright.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - ret_value = do_number_bitwise_logic (int_data, - dst_var_idx, - number_bitwise_shift_uright, - left_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_b_shift_uright */ - -/** - * 'Bitwise NOT Operator' opcode handler. - * - * See also: ECMA-262 v5, 10.4 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_b_not (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.b_not.dst; - const T_IDX right_var_idx = opdata.data.b_not.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - ret_value = do_number_bitwise_logic (int_data, - dst_var_idx, - number_bitwise_not, - right_value.value, - right_value.value); - - ECMA_FINALIZE (right_value); - - return ret_value; -} /* opfunc_b_not */ - - /** * 'Pre increment' opcode handler. * @@ -1273,7 +385,7 @@ opfunc_b_not (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_pre_incr (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX dst_var_idx = opdata.data.pre_incr.dst; const T_IDX incr_var_idx = opdata.data.pre_incr.var_right; @@ -1323,7 +435,7 @@ opfunc_pre_incr (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_pre_decr (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX dst_var_idx = opdata.data.pre_decr.dst; const T_IDX decr_var_idx = opdata.data.pre_decr.var_right; @@ -1373,7 +485,7 @@ opfunc_pre_decr (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_post_incr (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX dst_var_idx = opdata.data.post_incr.dst; const T_IDX incr_var_idx = opdata.data.post_incr.var_right; @@ -1421,7 +533,7 @@ opfunc_post_incr (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_post_decr (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX dst_var_idx = opdata.data.post_decr.dst; const T_IDX decr_var_idx = opdata.data.post_decr.var_right; @@ -1459,358 +571,6 @@ opfunc_post_decr (OPCODE opdata, /**< operation data */ return ret_value; } /* opfunc_post_decr */ -/** - * 'Equals' opcode handler. - * - * See also: ECMA-262 v5, 11.9.1 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_equal_value (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.equal_value.dst; - const T_IDX left_var_idx = opdata.data.equal_value.var_left; - const T_IDX right_var_idx = opdata.data.equal_value.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - bool is_equal = ecma_op_abstract_equality_compare (left_value.value, right_value.value); - - ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE - : ECMA_SIMPLE_VALUE_FALSE)); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_equal_value */ - -/** - * 'Does-not-equals' opcode handler. - * - * See also: ECMA-262 v5, 11.9.2 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_not_equal_value (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.not_equal_value.dst; - const T_IDX left_var_idx = opdata.data.not_equal_value.var_left; - const T_IDX right_var_idx = opdata.data.not_equal_value.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - bool is_equal = ecma_op_abstract_equality_compare (left_value.value, right_value.value); - - ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE - : ECMA_SIMPLE_VALUE_TRUE)); - - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_not_equal_value */ - -/** - * 'Strict Equals' opcode handler. - * - * See also: ECMA-262 v5, 11.9.4 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_equal_value_type (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.equal_value_type.dst; - const T_IDX left_var_idx = opdata.data.equal_value_type.var_left; - const T_IDX right_var_idx = opdata.data.equal_value_type.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - bool is_equal = ecma_op_strict_equality_compare (left_value.value, right_value.value); - - ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE - : ECMA_SIMPLE_VALUE_FALSE)); - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_equal_value_type */ - -/** - * 'Strict Does-not-equals' opcode handler. - * - * See also: ECMA-262 v5, 11.9.5 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_not_equal_value_type (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.not_equal_value_type.dst; - const T_IDX left_var_idx = opdata.data.not_equal_value_type.var_left; - const T_IDX right_var_idx = opdata.data.not_equal_value_type.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - bool is_equal = ecma_op_strict_equality_compare (left_value.value, right_value.value); - - ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE - : ECMA_SIMPLE_VALUE_TRUE)); - - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_not_equal_value_type */ - -/** - * 'Less-than' opcode handler. - * - * See also: ECMA-262 v5, 11.8.1 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_less_than (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.less_than.dst; - const T_IDX left_var_idx = opdata.data.less_than.var_left; - const T_IDX right_var_idx = opdata.data.less_than.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - ECMA_TRY_CATCH (compare_result, - ecma_op_abstract_relational_compare (left_value.value, - right_value.value, - true), - ret_value); - - ecma_simple_value_t res; - - if (ecma_is_value_undefined (compare_result.value)) - { - res = ECMA_SIMPLE_VALUE_FALSE; - } - else - { - JERRY_ASSERT (ecma_is_value_boolean (compare_result.value)); - - res = compare_result.value.value; - } - - ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res)); - - ECMA_FINALIZE (compare_result); - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_less_than */ - -/** - * 'Greater-than' opcode handler. - * - * See also: ECMA-262 v5, 11.8.2 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_greater_than (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.greater_than.dst; - const T_IDX left_var_idx = opdata.data.greater_than.var_left; - const T_IDX right_var_idx = opdata.data.greater_than.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - ECMA_TRY_CATCH (compare_result, - ecma_op_abstract_relational_compare (right_value.value, - left_value.value, - false), - ret_value); - - ecma_simple_value_t res; - - if (ecma_is_value_undefined (compare_result.value)) - { - res = ECMA_SIMPLE_VALUE_FALSE; - } - else - { - JERRY_ASSERT (ecma_is_value_boolean (compare_result.value)); - - res = compare_result.value.value; - } - - ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res)); - - ECMA_FINALIZE (compare_result); - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_greater_than */ - -/** - * 'Less-than-or-equal' opcode handler. - * - * See also: ECMA-262 v5, 11.8.3 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_less_or_equal_than (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.less_or_equal_than.dst; - const T_IDX left_var_idx = opdata.data.less_or_equal_than.var_left; - const T_IDX right_var_idx = opdata.data.less_or_equal_than.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - ECMA_TRY_CATCH (compare_result, - ecma_op_abstract_relational_compare (right_value.value, - left_value.value, - false), - ret_value); - - ecma_simple_value_t res; - - if (ecma_is_value_undefined (compare_result.value)) - { - res = ECMA_SIMPLE_VALUE_FALSE; - } - else - { - JERRY_ASSERT (ecma_is_value_boolean (compare_result.value)); - - if (compare_result.value.value == ECMA_SIMPLE_VALUE_TRUE) - { - res = ECMA_SIMPLE_VALUE_FALSE; - } - else - { - res = ECMA_SIMPLE_VALUE_TRUE; - } - } - - ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res)); - - ECMA_FINALIZE (compare_result); - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_less_or_equal_than */ - -/** - * 'Greater-than-or-equal' opcode handler. - * - * See also: ECMA-262 v5, 11.8.4 - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value - */ -ecma_completion_value_t -opfunc_greater_or_equal_than (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ -{ - const T_IDX dst_var_idx = opdata.data.greater_or_equal_than.dst; - const T_IDX left_var_idx = opdata.data.greater_or_equal_than.var_left; - const T_IDX right_var_idx = opdata.data.greater_or_equal_than.var_right; - - int_data->pos++; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - ECMA_TRY_CATCH (compare_result, - ecma_op_abstract_relational_compare (left_value.value, - right_value.value, - true), - ret_value); - - ecma_simple_value_t res; - - if (ecma_is_value_undefined (compare_result.value)) - { - res = ECMA_SIMPLE_VALUE_FALSE; - } - else - { - JERRY_ASSERT (ecma_is_value_boolean (compare_result.value)); - - if (compare_result.value.value == ECMA_SIMPLE_VALUE_TRUE) - { - res = ECMA_SIMPLE_VALUE_FALSE; - } - else - { - res = ECMA_SIMPLE_VALUE_TRUE; - } - } - - ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res)); - - ECMA_FINALIZE (compare_result); - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_greater_or_equal_than */ - /** * 'Register variable declaration' opcode handler. * @@ -1818,7 +578,7 @@ opfunc_greater_or_equal_than (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_reg_var_decl (OPCODE opdata __unused, /**< operation data */ - struct __int_data *int_data __unused) /**< interpreter context */ + __int_data *int_data __unused) /**< interpreter context */ { JERRY_UNREACHABLE (); } /* opfunc_reg_var_decl */ @@ -1834,7 +594,7 @@ opfunc_reg_var_decl (OPCODE opdata __unused, /**< operation data */ */ ecma_completion_value_t opfunc_var_decl (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (opdata.data.var_decl.variable_name); @@ -1872,7 +632,7 @@ opfunc_var_decl (OPCODE opdata, /**< operation data */ * returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t -function_declaration (struct __int_data *int_data, /**< interpreter context */ +function_declaration (__int_data *int_data, /**< interpreter context */ T_IDX function_name_lit_idx, /**< identifier of literal with function name */ ecma_string_t* args_names[], /**< names of arguments */ ecma_length_t args_number) /**< number of arguments */ @@ -1911,7 +671,7 @@ function_declaration (struct __int_data *int_data, /**< interpreter context */ */ ecma_completion_value_t opfunc_func_decl_0 (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { int_data->pos++; @@ -1929,7 +689,7 @@ opfunc_func_decl_0 (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_func_decl_1 (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { int_data->pos++; @@ -1953,7 +713,7 @@ opfunc_func_decl_1 (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_func_decl_2 (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { int_data->pos++; @@ -1984,7 +744,7 @@ opfunc_func_decl_2 (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_call_0 (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX func_name_lit_idx = opdata.data.call_0.name_lit_idx; const T_IDX lhs_var_idx = opdata.data.call_0.lhs; @@ -2030,7 +790,7 @@ opfunc_call_0 (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_ret (OPCODE opdata __unused, /**< operation data */ - struct __int_data *int_data __unused) /**< interpreter context */ + __int_data *int_data __unused) /**< interpreter context */ { return ecma_make_completion_value (ECMA_COMPLETION_TYPE_RETURN, ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), @@ -2048,7 +808,7 @@ opfunc_ret (OPCODE opdata __unused, /**< operation data */ */ ecma_completion_value_t opfunc_retval (OPCODE opdata __unused, /**< operation data */ - struct __int_data *int_data __unused) /**< interpreter context */ + __int_data *int_data __unused) /**< interpreter context */ { ecma_completion_value_t ret_value; @@ -2074,7 +834,7 @@ opfunc_retval (OPCODE opdata __unused, /**< operation data */ */ ecma_completion_value_t opfunc_prop_getter (OPCODE opdata __unused, /**< operation data */ - struct __int_data *int_data __unused) /**< interpreter context */ + __int_data *int_data __unused) /**< interpreter context */ { const T_IDX lhs_var_idx = opdata.data.prop_getter.lhs; const T_IDX base_var_idx = opdata.data.prop_getter.obj; @@ -2121,7 +881,7 @@ opfunc_prop_getter (OPCODE opdata __unused, /**< operation data */ */ ecma_completion_value_t opfunc_prop_setter (OPCODE opdata __unused, /**< operation data */ - struct __int_data *int_data __unused) /**< interpreter context */ + __int_data *int_data __unused) /**< interpreter context */ { const T_IDX base_var_idx = opdata.data.prop_setter.obj; const T_IDX prop_name_var_idx = opdata.data.prop_setter.prop; @@ -2170,7 +930,7 @@ opfunc_prop_setter (OPCODE opdata __unused, /**< operation data */ */ ecma_completion_value_t opfunc_exitval (OPCODE opdata, /**< operation data */ - struct __int_data *int_data __unused) /**< interpreter context */ + __int_data *int_data __unused) /**< interpreter context */ { JERRY_ASSERT (opdata.data.exitval.status_code == 0 || opdata.data.exitval.status_code == 1); @@ -2182,106 +942,6 @@ opfunc_exitval (OPCODE opdata, /**< operation data */ ECMA_TARGET_ID_RESERVED); } /* opfunc_exitval */ -/** - * 'instanceof' opcode handler. - * - * See also: ECMA-262 v5, 11.8.6 - * - * @return completion value - * returned value must be freed with ecma_free_completion_value. - */ -ecma_completion_value_t -opfunc_instanceof (OPCODE opdata __unused, /**< operation data */ - struct __int_data *int_data __unused) /**< interpreter context */ -{ - const T_IDX dst_idx = opdata.data.instanceof.dst; - const T_IDX left_var_idx = opdata.data.instanceof.var_left; - const T_IDX right_var_idx = opdata.data.instanceof.var_right; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - if (right_value.value.value_type != ECMA_TYPE_OBJECT) - { - ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); - } - else - { - ecma_object_t *right_value_obj_p = ECMA_GET_POINTER (right_value.value.value); - - ECMA_TRY_CATCH (is_instance_of, - ecma_op_object_has_instance (right_value_obj_p, - left_value.value), - ret_value); - - ret_value = set_variable_value (int_data, dst_idx, is_instance_of.value); - - ECMA_FINALIZE (is_instance_of); - } - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_instanceof */ - -/** - * 'in' opcode handler. - * - * See also: ECMA-262 v5, 11.8.7 - * - * @return completion value - * returned value must be freed with ecma_free_completion_value. - */ -ecma_completion_value_t -opfunc_in (OPCODE opdata __unused, /**< operation data */ - struct __int_data *int_data __unused) /**< interpreter context */ -{ - const T_IDX dst_idx = opdata.data.in.dst; - const T_IDX left_var_idx = opdata.data.in.var_left; - const T_IDX right_var_idx = opdata.data.in.var_right; - - ecma_completion_value_t ret_value; - - ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value); - ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value); - - if (right_value.value.value_type != ECMA_TYPE_OBJECT) - { - ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); - } - else - { - ECMA_TRY_CATCH (str_left_value, ecma_op_to_string (left_value.value), ret_value); - - ecma_simple_value_t is_in = ECMA_SIMPLE_VALUE_UNDEFINED; - ecma_string_t *left_value_prop_name_p = ECMA_GET_POINTER (str_left_value.value.value); - ecma_object_t *right_value_obj_p = ECMA_GET_POINTER (right_value.value.value); - - if (ecma_op_object_has_property (right_value_obj_p, left_value_prop_name_p)) - { - is_in = ECMA_SIMPLE_VALUE_TRUE; - } - else - { - is_in = ECMA_SIMPLE_VALUE_FALSE; - } - - ret_value = set_variable_value (int_data, - dst_idx, - ecma_make_simple_value (is_in)); - - ECMA_FINALIZE (str_left_value); - } - - ECMA_FINALIZE (right_value); - ECMA_FINALIZE (left_value); - - return ret_value; -} /* opfunc_in */ - /** * 'Logical NOT Operator' opcode handler. * @@ -2292,7 +952,7 @@ opfunc_in (OPCODE opdata __unused, /**< operation data */ */ ecma_completion_value_t opfunc_logical_not (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX dst_var_idx = opdata.data.logical_not.dst; const T_IDX right_var_idx = opdata.data.logical_not.var_right; @@ -2330,7 +990,7 @@ opfunc_logical_not (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_logical_or (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX dst_var_idx = opdata.data.logical_or.dst; const T_IDX left_var_idx = opdata.data.logical_or.var_left; @@ -2374,7 +1034,7 @@ opfunc_logical_or (OPCODE opdata, /**< operation data */ */ ecma_completion_value_t opfunc_logical_and (OPCODE opdata, /**< operation data */ - struct __int_data *int_data) /**< interpreter context */ + __int_data *int_data) /**< interpreter context */ { const T_IDX dst_var_idx = opdata.data.logical_and.dst; const T_IDX left_var_idx = opdata.data.logical_and.var_left; @@ -2407,69 +1067,3 @@ opfunc_logical_and (OPCODE opdata, /**< operation data */ return ret_value; } /* opfunc_logical_and */ - -/** Opcode generators. */ -GETOP_IMPL_2 (is_true_jmp, value, opcode) -GETOP_IMPL_2 (is_false_jmp, value, opcode) -GETOP_IMPL_1 (jmp, opcode_idx) -GETOP_IMPL_1 (jmp_up, opcode_count) -GETOP_IMPL_1 (jmp_down, opcode_count) -GETOP_IMPL_3 (addition, dst, var_left, var_right) -GETOP_IMPL_2 (post_incr, dst, var_right) -GETOP_IMPL_2 (post_decr, dst, var_right) -GETOP_IMPL_2 (pre_incr, dst, var_right) -GETOP_IMPL_2 (pre_decr, dst, var_right) -GETOP_IMPL_3 (substraction, dst, var_left, var_right) -GETOP_IMPL_3 (division, dst, var_left, var_right) -GETOP_IMPL_3 (multiplication, dst, var_left, var_right) -GETOP_IMPL_3 (remainder, dst, var_left, var_right) -GETOP_IMPL_3 (b_shift_left, dst, var_left, var_right) -GETOP_IMPL_3 (b_shift_right, dst, var_left, var_right) -GETOP_IMPL_3 (b_shift_uright, dst, var_left, var_right) -GETOP_IMPL_3 (b_and, dst, var_left, var_right) -GETOP_IMPL_3 (b_or, dst, var_left, var_right) -GETOP_IMPL_3 (b_xor, dst, var_left, var_right) -GETOP_IMPL_3 (logical_and, dst, var_left, var_right) -GETOP_IMPL_3 (logical_or, dst, var_left, var_right) -GETOP_IMPL_3 (equal_value, dst, var_left, var_right) -GETOP_IMPL_3 (not_equal_value, dst, var_left, var_right) -GETOP_IMPL_3 (equal_value_type, dst, var_left, var_right) -GETOP_IMPL_3 (not_equal_value_type, dst, var_left, var_right) -GETOP_IMPL_3 (less_than, dst, var_left, var_right) -GETOP_IMPL_3 (greater_than, dst, var_left, var_right) -GETOP_IMPL_3 (less_or_equal_than, dst, var_left, var_right) -GETOP_IMPL_3 (greater_or_equal_than, dst, var_left, var_right) -GETOP_IMPL_3 (assignment, var_left, type_value_right, value_right) -GETOP_IMPL_2 (call_0, lhs, name_lit_idx) -GETOP_IMPL_3 (call_1, lhs, name_lit_idx, arg1_lit_idx) -GETOP_IMPL_3 (call_n, lhs, name_lit_idx, arg1_lit_idx) -GETOP_IMPL_3 (native_call, lhs, name, arg_list) -GETOP_IMPL_2 (func_decl_1, name_lit_idx, arg1_lit_idx) -GETOP_IMPL_3 (func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx) -GETOP_IMPL_3 (func_decl_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx) -GETOP_IMPL_3 (varg_list, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx) -GETOP_IMPL_1 (exitval, status_code) -GETOP_IMPL_1 (retval, ret_value) -GETOP_IMPL_0 (ret) -GETOP_IMPL_0 (nop) -GETOP_IMPL_1 (var_decl, variable_name) -GETOP_IMPL_2 (b_not, dst, var_right) -GETOP_IMPL_2 (logical_not, dst, var_right) -GETOP_IMPL_3 (instanceof, dst, var_left, var_right) -GETOP_IMPL_3 (in, dst, var_left, var_right) -GETOP_IMPL_3 (construct_decl, lhs, name_lit_idx, arg_list) -GETOP_IMPL_1 (func_decl_0, name_lit_idx) -GETOP_IMPL_2 (array_decl, lhs, list) -GETOP_IMPL_3 (prop, lhs, name, value) -GETOP_IMPL_3 (prop_getter, lhs, obj, prop) -GETOP_IMPL_3 (prop_setter, obj, prop, rhs) -GETOP_IMPL_2 (prop_get_decl, lhs, prop) -GETOP_IMPL_3 (prop_set_decl, lhs, prop, arg) -GETOP_IMPL_2 (obj_decl, lhs, list) -GETOP_IMPL_1 (this, lhs) -GETOP_IMPL_2 (delete, lhs, obj) -GETOP_IMPL_2 (typeof, lhs, obj) -GETOP_IMPL_1 (with, expr) -GETOP_IMPL_0 (end_with) -GETOP_IMPL_2 (reg_var_decl, min, max) -GETOP_IMPL_3 (meta, type, data_1, data_2) diff --git a/src/libcoreint/opcodes.h b/src/libcoreint/opcodes.h index 4e911725c..cbc2d28a8 100644 --- a/src/libcoreint/opcodes.h +++ b/src/libcoreint/opcodes.h @@ -19,22 +19,26 @@ #include "ecma-globals.h" #include "globals.h" -#define OPCODE struct __opcode -struct __int_data; - -#define OP_STRUCT_FIELD(name) struct __op_##name name; -#define OP_ENUM_FIELD(name) __op__idx_##name , -#define OP_FUNC_DECL(name) ecma_completion_value_t opfunc_##name (OPCODE, struct __int_data *); - -/** A single bytecode instruction is 32bit wide and has an 8bit opcode field - and several operand of 8 of 16 bit.*/ - -// OPCODE FIELD TYPES #define T_IDX uint8_t /** index values */ +#define OPCODE __opcode -OPCODE; -typedef -ecma_completion_value_t (*opfunc) (OPCODE, struct __int_data *); +#define OP_STRUCT_FIELD(name) __op_##name name; +#define OP_ENUM_FIELD(name) __op__idx_##name , +#define OP_FUNC_DECL(name) ecma_completion_value_t opfunc_##name (__opcode, __int_data*); + +typedef uint16_t opcode_counter_t; + +typedef struct +{ + opcode_counter_t pos; /**< current opcode to execute */ + ecma_value_t this_binding; /**< this binding for current context */ + ecma_object_t *lex_env_p; /**< current lexical environment */ + bool is_strict; /**< is current code execution mode strict? */ + bool is_eval_code; /**< is current code executed with eval */ + T_IDX min_reg_num; /**< minimum idx used for register identification */ + T_IDX max_reg_num; /**< maximum idx used for register identification */ + ecma_value_t *regs_p; /**< register variables */ +} __int_data; #define OP_CALLS_AND_ARGS(op) \ op (call_0) \ @@ -135,7 +139,108 @@ ecma_completion_value_t (*opfunc) (OPCODE, struct __int_data *); op (reg_var_decl)\ op (meta) -#include "opcode-structures.h" +#define OP_DATA (name, list) typedef struct { list ; } __op_##name; + +#define OP_DATA_0(name) \ + typedef struct \ + { \ + T_IDX __do_not_use; \ + } __op_##name + +#define OP_DATA_1(name, arg1) \ + typedef struct \ + { \ + T_IDX arg1; \ + } __op_##name + +#define OP_DATA_2(name, arg1, arg2) \ + typedef struct \ + { \ + T_IDX arg1; \ + T_IDX arg2; \ + } __op_##name + +#define OP_DATA_3(name, arg1, arg2, arg3) \ + typedef struct \ + { \ + T_IDX arg1; \ + T_IDX arg2; \ + T_IDX arg3; \ + } __op_##name + +OP_DATA_2 (is_true_jmp, value, opcode); +OP_DATA_2 (is_false_jmp, value, opcode); +OP_DATA_1 (jmp, opcode_idx); +OP_DATA_1 (jmp_up, opcode_count); +OP_DATA_1 (jmp_down, opcode_count); +OP_DATA_3 (addition, dst, var_left, var_right); +OP_DATA_2 (post_incr, dst, var_right); +OP_DATA_2 (post_decr, dst, var_right); +OP_DATA_2 (pre_incr, dst, var_right); +OP_DATA_2 (pre_decr, dst, var_right); +OP_DATA_3 (substraction, dst, var_left, var_right); +OP_DATA_3 (division, dst, var_left, var_right); +OP_DATA_3 (multiplication, dst, var_left, var_right); +OP_DATA_3 (remainder, dst, var_left, var_right); +OP_DATA_3 (b_shift_left, dst, var_left, var_right); +OP_DATA_3 (b_shift_right, dst, var_left, var_right); +OP_DATA_3 (b_shift_uright, dst, var_left, var_right); +OP_DATA_3 (b_and, dst, var_left, var_right); +OP_DATA_3 (b_or, dst, var_left, var_right); +OP_DATA_3 (b_xor, dst, var_left, var_right); +OP_DATA_3 (logical_and, dst, var_left, var_right); +OP_DATA_3 (logical_or, dst, var_left, var_right); +OP_DATA_3 (equal_value, dst, var_left, var_right); +OP_DATA_3 (not_equal_value, dst, var_left, var_right); +OP_DATA_3 (equal_value_type, dst, var_left, var_right); +OP_DATA_3 (not_equal_value_type, dst, var_left, var_right); +OP_DATA_3 (less_than, dst, var_left, var_right); +OP_DATA_3 (greater_than, dst, var_left, var_right); +OP_DATA_3 (less_or_equal_than, dst, var_left, var_right); +OP_DATA_3 (greater_or_equal_than, dst, var_left, var_right); +OP_DATA_3 (assignment, var_left, type_value_right, value_right); +OP_DATA_2 (call_0, lhs, name_lit_idx); +OP_DATA_3 (call_1, lhs, name_lit_idx, arg1_lit_idx); +OP_DATA_3 (call_n, lhs, name_lit_idx, arg1_lit_idx); +OP_DATA_3 (native_call, lhs, name, arg_list); +OP_DATA_2 (func_decl_1, name_lit_idx, arg1_lit_idx); +OP_DATA_3 (func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx); +OP_DATA_3 (func_decl_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx); +OP_DATA_3 (varg_list, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx); +OP_DATA_1 (exitval, status_code); +OP_DATA_1 (retval, ret_value); +OP_DATA_0 (ret); +OP_DATA_0 (nop); +OP_DATA_1 (var_decl, variable_name); +OP_DATA_2 (b_not, dst, var_right); +OP_DATA_2 (logical_not, dst, var_right); +OP_DATA_3 (instanceof, dst, var_left, var_right); +OP_DATA_3 (in, dst, var_left, var_right); +OP_DATA_3 (construct_decl, lhs, name_lit_idx, arg_list); +OP_DATA_1 (func_decl_0, name_lit_idx); +OP_DATA_2 (array_decl, lhs, list); +OP_DATA_3 (prop, lhs, name, value); +OP_DATA_3 (prop_getter, lhs, obj, prop); +OP_DATA_3 (prop_setter, obj, prop, rhs); +OP_DATA_2 (prop_get_decl, lhs, prop); +OP_DATA_3 (prop_set_decl, lhs, prop, arg); +OP_DATA_2 (obj_decl, lhs, list); +OP_DATA_1 (this, lhs); +OP_DATA_2 (delete, lhs, obj); +OP_DATA_2 (typeof, lhs, obj); +OP_DATA_1 (with, expr); +OP_DATA_0 (end_with); +OP_DATA_2 (reg_var_decl, min, max); +OP_DATA_3 (meta, type, data_1, data_2); + +typedef struct +{ + T_IDX op_idx; + union + { + OP_LIST (OP_STRUCT_FIELD) + } data; +} __opcode; enum __opcode_idx { @@ -143,19 +248,10 @@ enum __opcode_idx LAST_OP }; -union __opdata -{ - OP_LIST (OP_STRUCT_FIELD) -}; - OP_LIST (OP_FUNC_DECL) -OPCODE -{ - T_IDX op_idx; - union __opdata data; -} -__packed; + +typedef ecma_completion_value_t (*opfunc) (__opcode, __int_data *); /** * Descriptor of assignment's second argument diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index 06766b0cf..0088f276f 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -17,7 +17,7 @@ #include "jerry-libc.h" #include "lexer.h" #include "parser.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" #include "interpreter.h" diff --git a/src/liboptimizer/pretty-printer.c b/src/liboptimizer/pretty-printer.c index 974c480b7..c303265cc 100644 --- a/src/liboptimizer/pretty-printer.c +++ b/src/liboptimizer/pretty-printer.c @@ -25,7 +25,7 @@ #op, #define OPCODE_SIZE(op) \ - sizeof (struct __op_##op) + 1, + sizeof (__op_##op) + 1, static char* opcode_names[] = { diff --git a/tests/unit/common.h b/tests/unit/common.h index e910222e3..11bd3d4aa 100644 --- a/tests/unit/common.h +++ b/tests/unit/common.h @@ -19,7 +19,7 @@ #define NAME_TO_ID(op) (__op__idx_##op) #define OPCODE_SIZE(op) \ - sizeof (struct __op_##op) + 1, + sizeof (__op_##op) + 1, static uint8_t opcode_sizes[] = { OP_LIST (OPCODE_SIZE) @@ -28,7 +28,7 @@ static uint8_t opcode_sizes[] = { static bool opcodes_equal (const OPCODE *opcodes1, OPCODE *opcodes2, uint16_t size) -{ +{ uint16_t i; for (i = 0; i < size; i++) { @@ -37,11 +37,11 @@ opcodes_equal (const OPCODE *opcodes1, OPCODE *opcodes2, uint16_t size) if (opcode_num1 != opcode_num2) return false; - + if (opcode_num1 == NAME_TO_ID (nop) || opcode_num1 == NAME_TO_ID (ret) || opcode_num1 == NAME_TO_ID (end_with)) return true; - + for (j = 1; j < opcode_sizes[opcode_num1]; j++) if (((uint8_t*)&opcodes1[i])[j] != ((uint8_t*)&opcodes2[i])[j]) return false; diff --git a/tests/unit/test_addition_opcode_number_operands.c b/tests/unit/test_addition_opcode_number_operands.c index e40494530..fc3187ec3 100644 --- a/tests/unit/test_addition_opcode_number_operands.c +++ b/tests/unit/test_addition_opcode_number_operands.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" /** diff --git a/tests/unit/test_assignment_opcode.c b/tests/unit/test_assignment_opcode.c index f7030774e..622997683 100644 --- a/tests/unit/test_assignment_opcode.c +++ b/tests/unit/test_assignment_opcode.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" /** diff --git a/tests/unit/test_division_opcode.c b/tests/unit/test_division_opcode.c index e8237b11a..e9fbf01ca 100644 --- a/tests/unit/test_division_opcode.c +++ b/tests/unit/test_division_opcode.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" /** diff --git a/tests/unit/test_multiplication_opcode.c b/tests/unit/test_multiplication_opcode.c index 0052f60df..1af4a14a8 100644 --- a/tests/unit/test_multiplication_opcode.c +++ b/tests/unit/test_multiplication_opcode.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" /** diff --git a/tests/unit/test_optimizer_adjust_jumps.c b/tests/unit/test_optimizer_adjust_jumps.c index 182ff8a88..e087651c8 100644 --- a/tests/unit/test_optimizer_adjust_jumps.c +++ b/tests/unit/test_optimizer_adjust_jumps.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" #include "optimizer-passes.h" #include "jerry-libc.h" @@ -91,4 +91,4 @@ main( int __unused argc, return 1; return 0; -} +} diff --git a/tests/unit/test_optimizer_for_loops.c b/tests/unit/test_optimizer_for_loops.c index 066ffe3e5..2c0bdd570 100644 --- a/tests/unit/test_optimizer_for_loops.c +++ b/tests/unit/test_optimizer_for_loops.c @@ -22,6 +22,7 @@ #include "lexer.h" #include "parser.h" #include "mem-allocator.h" +#include "opcodes-support.h" #define MAX_STRINGS 100 #define MAX_NUMS 25 @@ -55,43 +56,43 @@ main( int __unused argc, offset = serializer_dump_strings (strings, strings_num); serializer_dump_nums (nums, nums_count, offset, strings_num); - + parser_init (); parser_parse_program (); opcodes = deserialize_bytecode (); serializer_print_opcodes (); if (!opcodes_equal (opcodes, (OPCODE[]) { - [0] = getop_reg_var_decl (2, 5), // var tmp2 .. tmp5; - [1] = getop_var_decl (0), // var i; - [2] = getop_var_decl (1), // var j; - [3] = getop_assignment (2, 1, 0), // tmp2 = 0; - [4] = getop_assignment (0, 4, 2), // i = tmp2; - [5] = getop_assignment (4, 1, 10),// tmp4 = 10; - [6] = getop_less_than (3, 0, 4), // tmp3 = i < tmp4; - [7] = getop_is_false_jmp (3, 14), // if (!tmp3) goto 14; - [8] = getop_jmp_down (3), // goto 11; - [9] = getop_post_incr (5, 0), // tmp5 = i ++; - [10] = getop_jmp_up (5), // goto 5; - [11] = getop_assignment (2, 1, 10),// tmp2 = 10; - [12] = getop_assignment (1, 4, 2), // j = tmp2; - [13] = getop_jmp_up (5), // goto 8; - [14] = getop_nop (), // ; - [15] = getop_assignment (2, 1, 0), // tmp2 = 0; - [16] = getop_assignment (0, 4, 2), // i = tmp2; - [17] = getop_assignment (4, 1, 10),// tmp7 = 10; - [18] = getop_less_than (3, 0, 4), // tmp3 = i < tmp7; - [19] = getop_is_false_jmp (3, 27), // if (!tmp3) goto 27; - [20] = getop_jmp_down (3), // goto 23; - [21] = getop_post_incr (5, 0), // tmp5 = i ++; - [22] = getop_jmp_up (5), // goto 17; - [23] = getop_nop (), // ; - [24] = getop_assignment (2, 1, 10),// tmp2 = 10; - [25] = getop_assignment (1, 4, 5), // j = tmp2; - [26] = getop_jmp_up (5), // goto 21; - [27] = getop_exitval (0) // exit 0; + [0] = getop_reg_var_decl (2, 5), // var tmp2 .. tmp5; + [1] = getop_var_decl (0), // var i; + [2] = getop_var_decl (1), // var j; + [3] = getop_assignment (2, 1, 0), // tmp2 = 0; + [4] = getop_assignment (0, 4, 2), // i = tmp2; + [5] = getop_assignment (4, 1, 10),// tmp4 = 10; + [6] = getop_less_than (3, 0, 4), // tmp3 = i < tmp4; + [7] = getop_is_false_jmp (3, 14), // if (!tmp3) goto 14; + [8] = getop_jmp_down (3), // goto 11; + [9] = getop_post_incr (5, 0), // tmp5 = i ++; + [10] = getop_jmp_up (5), // goto 5; + [11] = getop_assignment (2, 1, 10),// tmp2 = 10; + [12] = getop_assignment (1, 4, 2), // j = tmp2; + [13] = getop_jmp_up (5), // goto 8; + [14] = getop_nop (), // ; + [15] = getop_assignment (2, 1, 0), // tmp2 = 0; + [16] = getop_assignment (0, 4, 2), // i = tmp2; + [17] = getop_assignment (4, 1, 10),// tmp7 = 10; + [18] = getop_less_than (3, 0, 4), // tmp3 = i < tmp7; + [19] = getop_is_false_jmp (3, 27), // if (!tmp3) goto 27; + [20] = getop_jmp_down (3), // goto 23; + [21] = getop_post_incr (5, 0), // tmp5 = i ++; + [22] = getop_jmp_up (5), // goto 17; + [23] = getop_nop (), // ; + [24] = getop_assignment (2, 1, 10),// tmp2 = 10; + [25] = getop_assignment (1, 4, 5), // j = tmp2; + [26] = getop_jmp_up (5), // goto 21; + [27] = getop_exitval (0) // exit 0; }, 28)) return 1; return 0; -} +} diff --git a/tests/unit/test_optimizer_reorder_scope.c b/tests/unit/test_optimizer_reorder_scope.c index e78ee1a9a..a9298004b 100644 --- a/tests/unit/test_optimizer_reorder_scope.c +++ b/tests/unit/test_optimizer_reorder_scope.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" #include "optimizer-passes.h" #include "jerry-libc.h" @@ -35,12 +35,12 @@ main( int __unused argc, [0] = getop_reg_var_decl (5, 5), // tmp6 [1] = getop_assignment (0, OPCODE_ARG_TYPE_STRING, 1), // a = "b" [2] = getop_var_decl (1), // var b - [3] = getop_func_decl_0 (2), // function c() + [3] = getop_func_decl_0 (2), // function c() [4] = getop_jmp_down (3), // { [5] = getop_var_decl (1), // var b [6] = getop_retval (1), // return b; } [7] = getop_assignment (5, OPCODE_ARG_TYPE_STRING, 3), // "use strict" - [8] = getop_exitval (0) + [8] = getop_exitval (0) }; mem_init(); @@ -60,16 +60,16 @@ main( int __unused argc, if (!opcodes_equal (opcodes, (OPCODE[]) { [0] = getop_reg_var_decl (5, 5), // tmp6 [1] = getop_assignment (5, OPCODE_ARG_TYPE_STRING, 3), // "use strict" - [2] = getop_func_decl_0 (2), // function c() + [2] = getop_func_decl_0 (2), // function c() [3] = getop_jmp_down (3), // { [4] = getop_var_decl (1), // var b [5] = getop_retval (1), // return b; } [6] = getop_var_decl (1), // var b [7] = getop_assignment (0, OPCODE_ARG_TYPE_STRING, 1), // a = "b" - [8] = getop_exitval (0) + [8] = getop_exitval (0) }, 9)) return 1; return 0; -} +} diff --git a/tests/unit/test_remainder_opcode.c b/tests/unit/test_remainder_opcode.c index f7f4fa2e7..05a7f4b14 100644 --- a/tests/unit/test_remainder_opcode.c +++ b/tests/unit/test_remainder_opcode.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" /** diff --git a/tests/unit/test_substraction_opcode.c b/tests/unit/test_substraction_opcode.c index 61b8d28a1..699b9c0e9 100644 --- a/tests/unit/test_substraction_opcode.c +++ b/tests/unit/test_substraction_opcode.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" /** diff --git a/tests/unit/test_var_decl_opcode_in_decl_lex_env.c b/tests/unit/test_var_decl_opcode_in_decl_lex_env.c index 1ca720f99..4f06e0a7e 100644 --- a/tests/unit/test_var_decl_opcode_in_decl_lex_env.c +++ b/tests/unit/test_var_decl_opcode_in_decl_lex_env.c @@ -16,7 +16,7 @@ #include "globals.h" #include "interpreter.h" #include "mem-allocator.h" -#include "opcodes.h" +#include "opcodes-support.h" #include "serializer.h" /**