From 93ec22665029cfa6e0aa2d24b61f89522ea29f69 Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Thu, 10 Jan 2019 08:47:45 +0100 Subject: [PATCH] Extract binary lvalue operators (#2630) This patch substitutes all binary lvalue operators with an assigment + the corresponding binary operator. E.g. A += (expression) is pasred as A = A + (expression). Due to this replacement, all the related binary lvalue CBC opcodes can be removed. Also the arithmetic related VM instructions can put their result directly onto the stack, since no more checking is needed. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu --- jerry-core/ecma/base/ecma-helpers-value.c | 15 +++ jerry-core/ecma/base/ecma-helpers.h | 1 + jerry-core/parser/js/byte-code.h | 98 ------------------ jerry-core/parser/js/js-lexer.c | 41 ++++++++ jerry-core/parser/js/js-parser-expr.c | 32 ++---- jerry-core/parser/js/js-parser-internal.h | 1 + jerry-core/vm/vm.c | 121 +++++++++++++--------- 7 files changed, 134 insertions(+), 175 deletions(-) diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c index 1235cac25..6bb76ed53 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.c +++ b/jerry-core/ecma/base/ecma-helpers-value.c @@ -975,6 +975,21 @@ ecma_free_value_if_not_object (ecma_value_t value) /**< value description */ } } /* ecma_free_value_if_not_object */ +/** + * Free an ecma-value number + */ +inline void JERRY_ATTR_ALWAYS_INLINE +ecma_free_number (ecma_value_t value) /**< value description */ +{ + JERRY_ASSERT (ecma_is_value_number (value)); + + if (ecma_is_value_float_number (value)) + { + ecma_number_t *number_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (value); + ecma_dealloc_number (number_p); + } +} /* ecma_free_number */ + /** * Get the literal id associated with the given ecma_value type. * This operation is equivalent to the JavaScript 'typeof' operator. diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 78107aba8..620033e49 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -190,6 +190,7 @@ void ecma_value_assign_number (ecma_value_t *value_p, ecma_number_t ecma_number) void ecma_free_value (ecma_value_t value); void ecma_fast_free_value (ecma_value_t value); void ecma_free_value_if_not_object (ecma_value_t value); +void ecma_free_number (ecma_value_t value); lit_magic_string_id_t ecma_get_typeof_lit_id (ecma_value_t value); /* ecma-helpers-string.c */ diff --git a/jerry-core/parser/js/byte-code.h b/jerry-core/parser/js/byte-code.h index f5ebdb37d..1f2a44dbc 100644 --- a/jerry-core/parser/js/byte-code.h +++ b/jerry-core/parser/js/byte-code.h @@ -116,28 +116,8 @@ CBC_OPCODE (name ## _IDENT_BLOCK, CBC_HAS_LITERAL_ARG, 0, \ (VM_OC_ ## group) | VM_OC_GET_LITERAL | VM_OC_PUT_IDENT | VM_OC_PUT_BLOCK) -#define CBC_BINARY_LVALUE_OPERATION(name, group) \ - CBC_OPCODE (name, CBC_NO_FLAG, -4, \ - (VM_OC_ ## group) | VM_OC_GET_STACK_STACK | VM_OC_PUT_REFERENCE) \ - CBC_OPCODE (name ## _LITERAL, CBC_HAS_LITERAL_ARG, -3, \ - (VM_OC_ ## group) | VM_OC_GET_STACK_LITERAL | VM_OC_PUT_REFERENCE) \ - -#define CBC_EXT_BINARY_LVALUE_OPERATION(name, group) \ - CBC_OPCODE (name ## _PUSH_RESULT, CBC_NO_FLAG, -3, \ - (VM_OC_ ## group) | VM_OC_GET_STACK_STACK | VM_OC_PUT_REFERENCE | VM_OC_PUT_STACK) \ - CBC_OPCODE (name ## _LITERAL_PUSH_RESULT, CBC_HAS_LITERAL_ARG, -2, \ - (VM_OC_ ## group) | VM_OC_GET_STACK_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_STACK) \ - -#define CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION(name, group) \ - CBC_OPCODE (name ## _BLOCK, CBC_NO_FLAG, -4, \ - (VM_OC_ ## group) | VM_OC_GET_STACK_STACK | VM_OC_PUT_REFERENCE | VM_OC_PUT_BLOCK) \ - CBC_OPCODE (name ## _LITERAL_BLOCK, CBC_HAS_LITERAL_ARG, -3, \ - (VM_OC_ ## group) | VM_OC_GET_STACK_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_BLOCK) \ - #define CBC_UNARY_LVALUE_WITH_IDENT 3 -#define CBC_BINARY_LVALUE_WITH_LITERAL 1 - #define CBC_BINARY_WITH_LITERAL 1 #define CBC_BINARY_WITH_TWO_LITERALS 2 @@ -162,12 +142,6 @@ #define CBC_NO_RESULT_OPERATION(opcode) \ (((opcode) >= CBC_PRE_INCR && (opcode) < CBC_END) || CBC_SUPER_CALL_OPERATION ((opcode))) -#define CBC_NO_RESULT_BLOCK(opcode) \ - (((opcode) >= CBC_PRE_INCR && (opcode) < CBC_ASSIGN_ADD) || CBC_SUPER_CALL_OPERATION ((opcode))) - -#define CBC_NO_RESULT_COMPOUND_ASSIGMENT(opcode) \ - ((opcode) >= CBC_ASSIGN_ADD && (opcode) < CBC_END && !CBC_SUPER_CALL_OPERATION ((opcode))) - /** * Branch instructions are organized in group of 8 opcodes. * - 1st opcode: unused, can be used for other purpose @@ -497,30 +471,6 @@ CBC_OPCODE (CBC_ASSIGN_PROP_THIS_LITERAL_BLOCK, CBC_HAS_LITERAL_ARG, -1, \ VM_OC_ASSIGN_PROP_THIS | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_BLOCK) \ \ - /* Binary compound assignment opcodes. */ \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_ADD, \ - ADD) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_SUBTRACT, \ - SUB) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_MULTIPLY, \ - MUL) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_DIVIDE, \ - DIV) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_MODULO, \ - MOD) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_LEFT_SHIFT, \ - LEFT_SHIFT) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_RIGHT_SHIFT, \ - RIGHT_SHIFT) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_UNS_RIGHT_SHIFT, \ - UNS_RIGHT_SHIFT) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_BIT_AND, \ - BIT_AND) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_BIT_OR, \ - BIT_OR) \ - CBC_BINARY_LVALUE_OPERATION (CBC_ASSIGN_BIT_XOR, \ - BIT_XOR) \ - \ /* Last opcode (not a real opcode). */ \ CBC_OPCODE (CBC_END, CBC_NO_FLAG, 0, \ VM_OC_NONE) @@ -631,54 +581,6 @@ CBC_OPCODE (CBC_EXT_ERROR, CBC_NO_FLAG, 0, \ VM_OC_ERROR) \ \ - /* Binary compound assignment opcodes with pushing the result. */ \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_ADD, \ - ADD) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_SUBTRACT, \ - SUB) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_MULTIPLY, \ - MUL) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_DIVIDE, \ - DIV) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_MODULO, \ - MOD) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_LEFT_SHIFT, \ - LEFT_SHIFT) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_RIGHT_SHIFT, \ - RIGHT_SHIFT) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_UNS_RIGHT_SHIFT, \ - UNS_RIGHT_SHIFT) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_BIT_AND, \ - BIT_AND) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_BIT_OR, \ - BIT_OR) \ - CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_BIT_XOR, \ - BIT_XOR) \ - \ - /* Binary compound assignment opcodes with saving the result. */ \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_ADD, \ - ADD) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_SUBTRACT, \ - SUB) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_MULTIPLY, \ - MUL) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_DIVIDE, \ - DIV) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_MODULO, \ - MOD) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_LEFT_SHIFT, \ - LEFT_SHIFT) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_RIGHT_SHIFT, \ - RIGHT_SHIFT) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_UNS_RIGHT_SHIFT, \ - UNS_RIGHT_SHIFT) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_BIT_AND, \ - BIT_AND) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_BIT_OR, \ - BIT_OR) \ - CBC_EXT_BINARY_LVALUE_BLOCK_OPERATION (CBC_EXT_ASSIGN_BIT_XOR, \ - BIT_XOR) \ - \ /* Last opcode (not a real opcode). */ \ CBC_OPCODE (CBC_EXT_END, CBC_NO_FLAG, 0, \ VM_OC_NONE) diff --git a/jerry-core/parser/js/js-lexer.c b/jerry-core/parser/js/js-lexer.c index f3ba9cc7e..9eddeb4c0 100644 --- a/jerry-core/parser/js/js-lexer.c +++ b/jerry-core/parser/js/js-lexer.c @@ -2567,6 +2567,47 @@ lexer_compare_raw_identifier_to_current (parser_context_t *context_p, /**< conte return memcmp (left_ident_p->char_p, right_ident_p, right_ident_length) == 0; } /* lexer_compare_raw_identifier_to_current */ +/** + * Convert binary lvalue token to binary token + * e.g. += -> + + * ^= -> ^ + * + * @return binary token + */ +uint8_t +lexer_convert_binary_lvalue_token_to_binary (uint8_t token) /**< binary lvalue token */ +{ + JERRY_ASSERT (LEXER_IS_BINARY_LVALUE_TOKEN (token)); + JERRY_ASSERT (token != LEXER_ASSIGN); + + if (token <= LEXER_ASSIGN_MODULO) + { + return (uint8_t) (LEXER_ADD + (token - LEXER_ASSIGN_ADD)); + } + + if (token <= LEXER_ASSIGN_UNS_RIGHT_SHIFT) + { + return (uint8_t) (LEXER_LEFT_SHIFT + (token - LEXER_ASSIGN_LEFT_SHIFT)); + } + + switch (token) + { + case LEXER_ASSIGN_BIT_AND: + { + return LEXER_BIT_AND; + } + case LEXER_ASSIGN_BIT_OR: + { + return LEXER_BIT_OR; + } + default: + { + JERRY_ASSERT (token == LEXER_ASSIGN_BIT_XOR); + return LEXER_BIT_XOR; + } + } +} /* lexer_convert_binary_lvalue_token_to_binary */ + /** * @} * @} diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index 0c42e9bf1..7d72c5371 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -49,12 +49,7 @@ static const uint8_t parser_binary_precedence_table[36] = static inline void parser_push_result (parser_context_t *context_p) /**< context */ { - if (CBC_NO_RESULT_COMPOUND_ASSIGMENT (context_p->last_cbc_opcode)) - { - context_p->last_cbc_opcode = (uint16_t) PARSER_TO_BINARY_OPERATION_WITH_RESULT (context_p->last_cbc_opcode); - parser_flush_cbc (context_p); - } - else if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)) + if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)) { JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 1)); @@ -2100,15 +2095,10 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */ } else if (LEXER_IS_BINARY_LVALUE_TOKEN (token)) { - opcode = LEXER_BINARY_LVALUE_OP_TOKEN_TO_OPCODE (token); - - if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) - { - JERRY_ASSERT (CBC_ARGS_EQ (opcode + CBC_BINARY_LVALUE_WITH_LITERAL, - CBC_HAS_LITERAL_ARG)); - context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_BINARY_LVALUE_WITH_LITERAL); - continue; - } + parser_stack_push_uint8 (context_p, CBC_ASSIGN); + parser_stack_push_uint8 (context_p, LEXER_ASSIGN); + parser_stack_push_uint8 (context_p, lexer_convert_binary_lvalue_token_to_binary (token)); + continue; } else if (token == LEXER_LOGICAL_OR || token == LEXER_LOGICAL_AND) { @@ -2304,12 +2294,7 @@ parser_parse_expression (parser_context_t *context_p, /**< context */ } else if (options & PARSE_EXPR_BLOCK) { - if (CBC_NO_RESULT_COMPOUND_ASSIGMENT (context_p->last_cbc_opcode)) - { - context_p->last_cbc_opcode = PARSER_TO_BINARY_OPERATION_WITH_BLOCK (context_p->last_cbc_opcode); - parser_flush_cbc (context_p); - } - else if (CBC_NO_RESULT_BLOCK (context_p->last_cbc_opcode)) + if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)) { JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 2)); PARSER_PLUS_EQUAL_U16 (context_p->last_cbc_opcode, 2); @@ -2317,11 +2302,6 @@ parser_parse_expression (parser_context_t *context_p, /**< context */ } else { - if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)) - { - JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 1)); - context_p->last_cbc_opcode++; - } parser_emit_cbc (context_p, CBC_POP_BLOCK); } } diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h index 5c9002fdd..19ed76748 100644 --- a/jerry-core/parser/js/js-parser-internal.h +++ b/jerry-core/parser/js/js-parser-internal.h @@ -507,6 +507,7 @@ void lexer_construct_regexp_object (parser_context_t *context_p, bool parse_only bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right_ident_p); bool lexer_compare_raw_identifier_to_current (parser_context_t *context_p, const char *right_ident_p, size_t right_ident_length); +uint8_t lexer_convert_binary_lvalue_token_to_binary (uint8_t token); /** * @} diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index dc137191e..42e3aa2c2 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -2172,8 +2172,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); - result = ecma_make_int32_value ((int32_t) (left_integer + right_integer)); - break; + *stack_top_p++ = ecma_make_int32_value ((int32_t) (left_integer + right_integer)); + continue; } if (ecma_is_value_float_number (left_value) @@ -2182,9 +2182,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_number_t new_value = (ecma_get_float_from_value (left_value) + ecma_get_number_from_value (right_value)); - result = ecma_update_float_number (left_value, new_value); - left_value = ECMA_VALUE_UNDEFINED; - break; + *stack_top_p++ = ecma_update_float_number (left_value, new_value); + ecma_free_number (right_value); + continue; } if (ecma_is_value_float_number (right_value) @@ -2193,9 +2193,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_number_t new_value = ((ecma_number_t) ecma_get_integer_from_value (left_value) + ecma_get_float_from_value (right_value)); - result = ecma_update_float_number (right_value, new_value); - right_value = ECMA_VALUE_UNDEFINED; - break; + *stack_top_p++ = ecma_update_float_number (right_value, new_value); + continue; } result = opfunc_addition (left_value, right_value); @@ -2204,7 +2203,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_SUB: { @@ -2219,8 +2220,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); - result = ecma_make_int32_value ((int32_t) (left_integer - right_integer)); - break; + *stack_top_p++ = ecma_make_int32_value ((int32_t) (left_integer - right_integer)); + continue; } if (ecma_is_value_float_number (left_value) @@ -2229,9 +2230,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_number_t new_value = (ecma_get_float_from_value (left_value) - ecma_get_number_from_value (right_value)); - result = ecma_update_float_number (left_value, new_value); - left_value = ECMA_VALUE_UNDEFINED; - break; + *stack_top_p++ = ecma_update_float_number (left_value, new_value); + ecma_free_number (right_value); + continue; } if (ecma_is_value_float_number (right_value) @@ -2240,9 +2241,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_number_t new_value = ((ecma_number_t) ecma_get_integer_from_value (left_value) - ecma_get_float_from_value (right_value)); - result = ecma_update_float_number (right_value, new_value); - right_value = ECMA_VALUE_UNDEFINED; - break; + *stack_top_p++ = ecma_update_float_number (right_value, new_value); + continue; } result = do_number_arithmetic (NUMBER_ARITHMETIC_SUBSTRACTION, @@ -2253,7 +2253,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_MUL: { @@ -2276,13 +2278,13 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ && left_value != 0 && right_value != 0) { - result = ecma_integer_multiply (left_integer, right_integer); - break; + *stack_top_p++ = ecma_integer_multiply (left_integer, right_integer); + continue; } ecma_number_t multiply = (ecma_number_t) left_integer * (ecma_number_t) right_integer; - result = ecma_make_number_value (multiply); - break; + *stack_top_p++ = ecma_make_number_value (multiply); + continue; } if (ecma_is_value_float_number (left_value) @@ -2291,9 +2293,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_number_t new_value = (ecma_get_float_from_value (left_value) * ecma_get_number_from_value (right_value)); - result = ecma_update_float_number (left_value, new_value); - left_value = ECMA_VALUE_UNDEFINED; - break; + *stack_top_p++ = ecma_update_float_number (left_value, new_value); + ecma_free_number (right_value); + continue; } if (ecma_is_value_float_number (right_value) @@ -2302,9 +2304,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_number_t new_value = ((ecma_number_t) ecma_get_integer_from_value (left_value) * ecma_get_float_from_value (right_value)); - result = ecma_update_float_number (right_value, new_value); - right_value = ECMA_VALUE_UNDEFINED; - break; + *stack_top_p++ = ecma_update_float_number (right_value, new_value); + continue; } result = do_number_arithmetic (NUMBER_ARITHMETIC_MULTIPLICATION, @@ -2315,7 +2316,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_DIV: { @@ -2330,7 +2333,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_MOD: { @@ -2348,8 +2353,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ if (mod_result != 0 || left_integer >= 0) { - result = ecma_make_integer_value (mod_result); - break; + *stack_top_p++ = ecma_make_integer_value (mod_result); + continue; } } } @@ -2362,7 +2367,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_EQUAL: { @@ -2413,8 +2420,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ if (ecma_are_values_integer_numbers (left_value, right_value)) { - result = left_value | right_value; - break; + *stack_top_p++ = left_value | right_value; + continue; } result = do_number_bitwise_logic (NUMBER_BITWISE_LOGIC_OR, @@ -2425,7 +2432,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_BIT_XOR: { @@ -2434,8 +2443,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ if (ecma_are_values_integer_numbers (left_value, right_value)) { - result = (left_value ^ right_value) & (ecma_value_t) (~ECMA_DIRECT_TYPE_MASK); - break; + *stack_top_p++ = (left_value ^ right_value) & (ecma_value_t) (~ECMA_DIRECT_TYPE_MASK); + continue; } result = do_number_bitwise_logic (NUMBER_BITWISE_LOGIC_XOR, @@ -2446,7 +2455,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_BIT_AND: { @@ -2455,8 +2466,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ if (ecma_are_values_integer_numbers (left_value, right_value)) { - result = left_value & right_value; - break; + *stack_top_p++ = left_value & right_value; + continue; } result = do_number_bitwise_logic (NUMBER_BITWISE_LOGIC_AND, @@ -2467,7 +2478,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_LEFT_SHIFT: { @@ -2478,8 +2491,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); - result = ecma_make_int32_value ((int32_t) (left_integer << (right_integer & 0x1f))); - break; + *stack_top_p++ = ecma_make_int32_value ((int32_t) (left_integer << (right_integer & 0x1f))); + continue; } result = do_number_bitwise_logic (NUMBER_BITWISE_SHIFT_LEFT, @@ -2490,7 +2503,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_RIGHT_SHIFT: { @@ -2501,8 +2516,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); - result = ecma_make_integer_value (left_integer >> (right_integer & 0x1f)); - break; + *stack_top_p++ = ecma_make_integer_value (left_integer >> (right_integer & 0x1f)); + continue; } result = do_number_bitwise_logic (NUMBER_BITWISE_SHIFT_RIGHT, @@ -2513,7 +2528,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_UNS_RIGHT_SHIFT: { @@ -2524,8 +2541,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { uint32_t left_uint32 = (uint32_t) ecma_get_integer_from_value (left_value); ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); - result = ecma_make_uint32_value (left_uint32 >> (right_integer & 0x1f)); - break; + *stack_top_p++ = ecma_make_uint32_value (left_uint32 >> (right_integer & 0x1f)); + continue; } result = do_number_bitwise_logic (NUMBER_BITWISE_SHIFT_URIGHT, @@ -2536,7 +2553,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } - break; + + *stack_top_p++ = result; + goto free_both_values; } case VM_OC_LESS: {