diff --git a/jerry-core/parser/js/byte-code.h b/jerry-core/parser/js/byte-code.h index d21bafd383..c5220b1d0a 100644 --- a/jerry-core/parser/js/byte-code.h +++ b/jerry-core/parser/js/byte-code.h @@ -144,10 +144,10 @@ */ #define CBC_NO_RESULT_OPERATION(opcode) \ - ((opcode) >= CBC_DELETE && (opcode) < CBC_END) + ((opcode) >= CBC_PRE_INCR && (opcode) < CBC_END) #define CBC_NO_RESULT_BLOCK(opcode) \ - ((opcode) >= CBC_DELETE && (opcode) < CBC_ASSIGN_ADD) + ((opcode) >= CBC_PRE_INCR && (opcode) < CBC_ASSIGN_ADD) #define CBC_NO_RESULT_COMPOUND_ASSIGMENT(opcode) \ ((opcode) >= CBC_ASSIGN_ADD && (opcode) < CBC_END) @@ -271,9 +271,11 @@ CBC_OPCODE (CBC_PUSH_THIS_LITERAL, CBC_HAS_LITERAL_ARG, 2, \ VM_OC_PUSH_TWO | VM_OC_GET_THIS_LITERAL) \ CBC_OPCODE (CBC_PUSH_NUMBER_0, CBC_NO_FLAG, 1, \ - VM_OC_PUSH_NUMBER | VM_OC_PUT_STACK) \ - CBC_OPCODE (CBC_PUSH_NUMBER_1, CBC_HAS_BYTE_ARG, 1, \ - VM_OC_PUSH_NUMBER | VM_OC_PUT_STACK) \ + VM_OC_PUSH_NUMBER_0 | VM_OC_PUT_STACK) \ + CBC_OPCODE (CBC_PUSH_NUMBER_POS_BYTE, CBC_HAS_BYTE_ARG, 1, \ + VM_OC_PUSH_NUMBER_POS_BYTE | VM_OC_PUT_STACK) \ + CBC_OPCODE (CBC_PUSH_NUMBER_NEG_BYTE, CBC_HAS_BYTE_ARG, 1, \ + VM_OC_PUSH_NUMBER_NEG_BYTE | VM_OC_PUT_STACK) \ CBC_OPCODE (CBC_PUSH_PROP, CBC_NO_FLAG, -1, \ VM_OC_PROP_GET | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \ CBC_OPCODE (CBC_PUSH_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 0, \ @@ -376,18 +378,10 @@ MOD) \ \ /* Unary lvalue opcodes. */ \ - CBC_OPCODE (CBC_DELETE, CBC_NO_FLAG, -2, \ - VM_OC_PROP_DELETE | VM_OC_GET_STACK_STACK) \ CBC_OPCODE (CBC_DELETE_PUSH_RESULT, CBC_NO_FLAG, -1, \ VM_OC_PROP_DELETE | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \ - CBC_OPCODE (CBC_DELETE_BLOCK, CBC_NO_FLAG, -2, \ - VM_OC_PROP_DELETE | VM_OC_GET_STACK_STACK | VM_OC_PUT_BLOCK) \ - CBC_OPCODE (CBC_DELETE_IDENT, CBC_HAS_LITERAL_ARG, 0, \ - VM_OC_DELETE) \ CBC_OPCODE (CBC_DELETE_IDENT_PUSH_RESULT, CBC_HAS_LITERAL_ARG, 1, \ VM_OC_DELETE | VM_OC_PUT_STACK) \ - CBC_OPCODE (CBC_DELETE_IDENT_BLOCK, CBC_HAS_LITERAL_ARG, 0, \ - VM_OC_DELETE | VM_OC_PUT_BLOCK) \ CBC_UNARY_LVALUE_OPERATION (CBC_PRE_INCR, \ PRE_INCR) \ CBC_UNARY_LVALUE_OPERATION (CBC_PRE_DECR, \ @@ -597,7 +591,7 @@ #define CBC_MAXIMUM_SMALL_VALUE 510 #define CBC_MAXIMUM_FULL_VALUE 32767 -#define CBC_PUSH_NUMBER_1_RANGE_END 128 +#define CBC_PUSH_NUMBER_BYTE_RANGE_END 256 #define CBC_HIGHEST_BIT_MASK 0x80 #define CBC_LOWER_SEVEN_BIT_MASK 0x7f diff --git a/jerry-core/parser/js/js-lexer.c b/jerry-core/parser/js/js-lexer.c index 0f9f6b4bd2..baa201cf02 100644 --- a/jerry-core/parser/js/js-lexer.c +++ b/jerry-core/parser/js/js-lexer.c @@ -1553,7 +1553,7 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */ if (int_num == num) { - if (int_num < CBC_PUSH_NUMBER_1_RANGE_END + if (int_num <= CBC_PUSH_NUMBER_BYTE_RANGE_END && (int_num != 0 || !is_negative_number)) { context_p->lit_object.index = (uint16_t) int_num; diff --git a/jerry-core/parser/js/js-lexer.h b/jerry-core/parser/js/js-lexer.h index 1f08fe3134..41a9c5ccf2 100644 --- a/jerry-core/parser/js/js-lexer.h +++ b/jerry-core/parser/js/js-lexer.h @@ -185,7 +185,7 @@ typedef enum ((((token_type) - LEXER_PLUS) * 2) + CBC_PLUS) #define LEXER_UNARY_LVALUE_OP_TOKEN_TO_OPCODE(token_type) \ - ((((token_type) - LEXER_KEYW_DELETE) * 6) + CBC_DELETE) + ((((token_type) - LEXER_INCREASE) * 6) + CBC_PRE_INCR) #define LEXER_BINARY_OP_TOKEN_TO_OPCODE(token_type) \ ((cbc_opcode_t) ((((token_type) - LEXER_BIT_OR) * 3) + CBC_BIT_OR)) diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index db7aaa8c8d..febbe2b902 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -88,8 +88,6 @@ parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */ if (PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode) && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL) { - JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, opcode + CBC_UNARY_LVALUE_WITH_IDENT)); - if (context_p->status_flags & PARSER_IS_STRICT) { if (context_p->last_cbc.literal_object_type != LEXER_LITERAL_OBJECT_ANY) @@ -107,17 +105,41 @@ parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */ } parser_raise_error (context_p, error); } - if (opcode == CBC_DELETE) + if (opcode == CBC_DELETE_PUSH_RESULT) { parser_raise_error (context_p, PARSER_ERR_DELETE_IDENT_NOT_ALLOWED); } } - if (opcode == CBC_DELETE) + if (opcode == CBC_DELETE_PUSH_RESULT) { context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED; + + if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) + { + context_p->last_cbc_opcode = CBC_DELETE_IDENT_PUSH_RESULT; + } + else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS) + { + context_p->last_cbc_opcode = CBC_PUSH_LITERAL; + parser_emit_cbc_literal (context_p, + CBC_DELETE_IDENT_PUSH_RESULT, + context_p->last_cbc.value); + } + else + { + JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS); + + context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS; + parser_emit_cbc_literal (context_p, + CBC_DELETE_IDENT_PUSH_RESULT, + context_p->last_cbc.third_literal_index); + } + return; } + JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, opcode + CBC_UNARY_LVALUE_WITH_IDENT)); + if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) { context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT); @@ -169,8 +191,8 @@ parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */ default: { /* Invalid LeftHandSide expression. */ - parser_emit_cbc_ext (context_p, (opcode == CBC_DELETE) ? CBC_EXT_PUSH_UNDEFINED_BASE - : CBC_EXT_THROW_REFERENCE_ERROR); + parser_emit_cbc_ext (context_p, (opcode == CBC_DELETE_PUSH_RESULT) ? CBC_EXT_PUSH_UNDEFINED_BASE + : CBC_EXT_THROW_REFERENCE_ERROR); break; } } @@ -505,7 +527,7 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */ if (lexer_construct_number_object (context_p, PARSER_TRUE, is_negative_number)) { - JERRY_ASSERT (context_p->lit_object.index < CBC_PUSH_NUMBER_1_RANGE_END); + JERRY_ASSERT (context_p->lit_object.index <= CBC_PUSH_NUMBER_BYTE_RANGE_END); if (context_p->lit_object.index == 0) { @@ -949,7 +971,14 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */ if (LEXER_IS_UNARY_LVALUE_OP_TOKEN (token)) { - token = (uint8_t) (LEXER_UNARY_LVALUE_OP_TOKEN_TO_OPCODE (token)); + if (token == LEXER_KEYW_DELETE) + { + token = CBC_DELETE_PUSH_RESULT; + } + else + { + token = (uint8_t) (LEXER_UNARY_LVALUE_OP_TOKEN_TO_OPCODE (token)); + } parser_emit_unary_lvalue_opcode (context_p, (cbc_opcode_t) token); } else diff --git a/jerry-core/parser/js/js-parser-util.c b/jerry-core/parser/js/js-parser-util.c index be29e90ff3..528ff56de8 100644 --- a/jerry-core/parser/js/js-parser-util.c +++ b/jerry-core/parser/js/js-parser-util.c @@ -310,8 +310,10 @@ parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */ parser_flush_cbc (context_p); } - JERRY_ASSERT (value < CBC_PUSH_NUMBER_1_RANGE_END); - JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (cbc_flags[CBC_PUSH_NUMBER_1]) == 1); + cbc_opcode_t opcode = is_negative_number ? CBC_PUSH_NUMBER_NEG_BYTE : CBC_PUSH_NUMBER_POS_BYTE; + + JERRY_ASSERT (value > 0 && value <= CBC_PUSH_NUMBER_BYTE_RANGE_END); + JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (cbc_flags[opcode]) == 1); context_p->stack_depth++; @@ -325,18 +327,11 @@ parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */ real_value = -real_value; } - printf (" [%3d] %s number:%d\n", (int) context_p->stack_depth, cbc_names[CBC_PUSH_NUMBER_1], real_value); + printf (" [%3d] %s number:%d\n", (int) context_p->stack_depth, cbc_names[opcode], real_value); } #endif /* PARSER_DUMP_BYTE_CODE */ - if (is_negative_number) - { - PARSER_PLUS_EQUAL_U16 (value, CBC_PUSH_NUMBER_1_RANGE_END); - } - - parser_emit_two_bytes (context_p, - CBC_PUSH_NUMBER_1, - (uint8_t) value); + parser_emit_two_bytes (context_p, opcode, (uint8_t) (value - 1)); context_p->byte_code_size += 2; diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index a51a93533b..e956d1903e 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -1135,16 +1135,17 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code continue; } - if (opcode == CBC_PUSH_NUMBER_1) + if (opcode == CBC_PUSH_NUMBER_POS_BYTE) { int value = *byte_code_p++; + printf (" number:%d\n", value + 1); + continue; + } - if (value >= CBC_PUSH_NUMBER_1_RANGE_END) - { - value = -(value - CBC_PUSH_NUMBER_1_RANGE_END); - } - - printf (" number:%d\n", value); + if (opcode == CBC_PUSH_NUMBER_NEG_BYTE) + { + int value = *byte_code_p++; + printf (" number:%d\n", -(value + 1)); continue; } } diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 98f75c6723..50076c6d4e 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -910,28 +910,22 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ result = ecma_copy_value (frame_ctx_p->this_binding); break; } - case VM_OC_PUSH_NUMBER: + case VM_OC_PUSH_NUMBER_0: { - ecma_integer_value_t number; - - if (opcode == CBC_PUSH_NUMBER_0) - { - number = 0; - } - else - { - number = *byte_code_p++; - - JERRY_ASSERT (opcode == CBC_PUSH_NUMBER_1); - - if (number >= CBC_PUSH_NUMBER_1_RANGE_END) - { - number = -(number - CBC_PUSH_NUMBER_1_RANGE_END); - } - } - - result = ecma_make_integer_value (number); - break; + *stack_top_p++ = ecma_make_integer_value (0); + continue; + } + case VM_OC_PUSH_NUMBER_POS_BYTE: + { + ecma_integer_value_t number = *byte_code_p++; + *stack_top_p++ = ecma_make_integer_value (number + 1); + continue; + } + case VM_OC_PUSH_NUMBER_NEG_BYTE: + { + ecma_integer_value_t number = *byte_code_p++; + *stack_top_p++ = ecma_make_integer_value (-(number + 1)); + continue; } case VM_OC_PUSH_OBJECT: { diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index 61b50b1ece..ab369f392f 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -115,7 +115,9 @@ typedef enum VM_OC_PUSH_FALSE, /**< push false value */ VM_OC_PUSH_NULL, /**< push null value */ VM_OC_PUSH_THIS, /**< push this */ - VM_OC_PUSH_NUMBER, /**< push number */ + VM_OC_PUSH_NUMBER_0, /**< push number zero */ + VM_OC_PUSH_NUMBER_POS_BYTE, /**< push number between 1 and 256 */ + VM_OC_PUSH_NUMBER_NEG_BYTE, /**< push number between -1 and -256 */ VM_OC_PUSH_OBJECT, /**< push object */ VM_OC_SET_PROPERTY, /**< set property */ VM_OC_SET_GETTER, /**< set getter */