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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-21
@@ -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:
|
||||
{
|
||||
|
||||
+3
-1
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user