Parser improvements.

The number of delete opcodes is reduced to two from six. The
range of numbers which can be included in the byte code is
doubled from (-127,127) to (-256,256).

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-06-09 05:52:17 -07:00
parent 3c83af9f23
commit eed84a7dd9
8 changed files with 79 additions and 64 deletions
+8 -14
View File
@@ -144,10 +144,10 @@
*/ */
#define CBC_NO_RESULT_OPERATION(opcode) \ #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) \ #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) \ #define CBC_NO_RESULT_COMPOUND_ASSIGMENT(opcode) \
((opcode) >= CBC_ASSIGN_ADD && (opcode) < CBC_END) ((opcode) >= CBC_ASSIGN_ADD && (opcode) < CBC_END)
@@ -271,9 +271,11 @@
CBC_OPCODE (CBC_PUSH_THIS_LITERAL, CBC_HAS_LITERAL_ARG, 2, \ CBC_OPCODE (CBC_PUSH_THIS_LITERAL, CBC_HAS_LITERAL_ARG, 2, \
VM_OC_PUSH_TWO | VM_OC_GET_THIS_LITERAL) \ VM_OC_PUSH_TWO | VM_OC_GET_THIS_LITERAL) \
CBC_OPCODE (CBC_PUSH_NUMBER_0, CBC_NO_FLAG, 1, \ CBC_OPCODE (CBC_PUSH_NUMBER_0, CBC_NO_FLAG, 1, \
VM_OC_PUSH_NUMBER | VM_OC_PUT_STACK) \ VM_OC_PUSH_NUMBER_0 | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_PUSH_NUMBER_1, CBC_HAS_BYTE_ARG, 1, \ CBC_OPCODE (CBC_PUSH_NUMBER_POS_BYTE, CBC_HAS_BYTE_ARG, 1, \
VM_OC_PUSH_NUMBER | VM_OC_PUT_STACK) \ 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, \ CBC_OPCODE (CBC_PUSH_PROP, CBC_NO_FLAG, -1, \
VM_OC_PROP_GET | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \ VM_OC_PROP_GET | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_PUSH_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 0, \ CBC_OPCODE (CBC_PUSH_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
@@ -376,18 +378,10 @@
MOD) \ MOD) \
\ \
/* Unary lvalue opcodes. */ \ /* 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, \ CBC_OPCODE (CBC_DELETE_PUSH_RESULT, CBC_NO_FLAG, -1, \
VM_OC_PROP_DELETE | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \ 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, \ CBC_OPCODE (CBC_DELETE_IDENT_PUSH_RESULT, CBC_HAS_LITERAL_ARG, 1, \
VM_OC_DELETE | VM_OC_PUT_STACK) \ 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, \ CBC_UNARY_LVALUE_OPERATION (CBC_PRE_INCR, \
PRE_INCR) \ PRE_INCR) \
CBC_UNARY_LVALUE_OPERATION (CBC_PRE_DECR, \ CBC_UNARY_LVALUE_OPERATION (CBC_PRE_DECR, \
@@ -597,7 +591,7 @@
#define CBC_MAXIMUM_SMALL_VALUE 510 #define CBC_MAXIMUM_SMALL_VALUE 510
#define CBC_MAXIMUM_FULL_VALUE 32767 #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_HIGHEST_BIT_MASK 0x80
#define CBC_LOWER_SEVEN_BIT_MASK 0x7f #define CBC_LOWER_SEVEN_BIT_MASK 0x7f
+1 -1
View File
@@ -1553,7 +1553,7 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
if (int_num == num) 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)) && (int_num != 0 || !is_negative_number))
{ {
context_p->lit_object.index = (uint16_t) int_num; context_p->lit_object.index = (uint16_t) int_num;
+1 -1
View File
@@ -185,7 +185,7 @@ typedef enum
((((token_type) - LEXER_PLUS) * 2) + CBC_PLUS) ((((token_type) - LEXER_PLUS) * 2) + CBC_PLUS)
#define LEXER_UNARY_LVALUE_OP_TOKEN_TO_OPCODE(token_type) \ #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) \ #define LEXER_BINARY_OP_TOKEN_TO_OPCODE(token_type) \
((cbc_opcode_t) ((((token_type) - LEXER_BIT_OR) * 3) + CBC_BIT_OR)) ((cbc_opcode_t) ((((token_type) - LEXER_BIT_OR) * 3) + CBC_BIT_OR))
+37 -8
View File
@@ -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) if (PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode)
&& context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL) && 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->status_flags & PARSER_IS_STRICT)
{ {
if (context_p->last_cbc.literal_object_type != LEXER_LITERAL_OBJECT_ANY) 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); 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); 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; 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) if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
{ {
context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT); 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: default:
{ {
/* Invalid LeftHandSide expression. */ /* Invalid LeftHandSide expression. */
parser_emit_cbc_ext (context_p, (opcode == CBC_DELETE) ? CBC_EXT_PUSH_UNDEFINED_BASE parser_emit_cbc_ext (context_p, (opcode == CBC_DELETE_PUSH_RESULT) ? CBC_EXT_PUSH_UNDEFINED_BASE
: CBC_EXT_THROW_REFERENCE_ERROR); : CBC_EXT_THROW_REFERENCE_ERROR);
break; 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)) 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) 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)) 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); parser_emit_unary_lvalue_opcode (context_p, (cbc_opcode_t) token);
} }
else else
+6 -11
View File
@@ -310,8 +310,10 @@ parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */
parser_flush_cbc (context_p); parser_flush_cbc (context_p);
} }
JERRY_ASSERT (value < CBC_PUSH_NUMBER_1_RANGE_END); cbc_opcode_t opcode = is_negative_number ? CBC_PUSH_NUMBER_NEG_BYTE : CBC_PUSH_NUMBER_POS_BYTE;
JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (cbc_flags[CBC_PUSH_NUMBER_1]) == 1);
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++; context_p->stack_depth++;
@@ -325,18 +327,11 @@ parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */
real_value = -real_value; 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 */ #endif /* PARSER_DUMP_BYTE_CODE */
if (is_negative_number) parser_emit_two_bytes (context_p, opcode, (uint8_t) (value - 1));
{
PARSER_PLUS_EQUAL_U16 (value, CBC_PUSH_NUMBER_1_RANGE_END);
}
parser_emit_two_bytes (context_p,
CBC_PUSH_NUMBER_1,
(uint8_t) value);
context_p->byte_code_size += 2; context_p->byte_code_size += 2;
+8 -7
View File
@@ -1135,16 +1135,17 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
continue; continue;
} }
if (opcode == CBC_PUSH_NUMBER_1) if (opcode == CBC_PUSH_NUMBER_POS_BYTE)
{ {
int value = *byte_code_p++; int value = *byte_code_p++;
printf (" number:%d\n", value + 1);
continue;
}
if (value >= CBC_PUSH_NUMBER_1_RANGE_END) if (opcode == CBC_PUSH_NUMBER_NEG_BYTE)
{ {
value = -(value - CBC_PUSH_NUMBER_1_RANGE_END); int value = *byte_code_p++;
} printf (" number:%d\n", -(value + 1));
printf (" number:%d\n", value);
continue; continue;
} }
} }
+15 -21
View File
@@ -910,28 +910,22 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
result = ecma_copy_value (frame_ctx_p->this_binding); result = ecma_copy_value (frame_ctx_p->this_binding);
break; break;
} }
case VM_OC_PUSH_NUMBER: case VM_OC_PUSH_NUMBER_0:
{ {
ecma_integer_value_t number; *stack_top_p++ = ecma_make_integer_value (0);
continue;
if (opcode == CBC_PUSH_NUMBER_0) }
{ case VM_OC_PUSH_NUMBER_POS_BYTE:
number = 0; {
} ecma_integer_value_t number = *byte_code_p++;
else *stack_top_p++ = ecma_make_integer_value (number + 1);
{ continue;
number = *byte_code_p++; }
case VM_OC_PUSH_NUMBER_NEG_BYTE:
JERRY_ASSERT (opcode == CBC_PUSH_NUMBER_1); {
ecma_integer_value_t number = *byte_code_p++;
if (number >= CBC_PUSH_NUMBER_1_RANGE_END) *stack_top_p++ = ecma_make_integer_value (-(number + 1));
{ continue;
number = -(number - CBC_PUSH_NUMBER_1_RANGE_END);
}
}
result = ecma_make_integer_value (number);
break;
} }
case VM_OC_PUSH_OBJECT: case VM_OC_PUSH_OBJECT:
{ {
+3 -1
View File
@@ -115,7 +115,9 @@ typedef enum
VM_OC_PUSH_FALSE, /**< push false value */ VM_OC_PUSH_FALSE, /**< push false value */
VM_OC_PUSH_NULL, /**< push null value */ VM_OC_PUSH_NULL, /**< push null value */
VM_OC_PUSH_THIS, /**< push this */ 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_PUSH_OBJECT, /**< push object */
VM_OC_SET_PROPERTY, /**< set property */ VM_OC_SET_PROPERTY, /**< set property */
VM_OC_SET_GETTER, /**< set getter */ VM_OC_SET_GETTER, /**< set getter */