Convert certain push number opcodes to literals (#2328)
Binary operations are much faster with literal arguments. The byte immediates are still kept for other cases, e.g. array declarations. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -41,7 +41,7 @@ typedef struct
|
|||||||
/**
|
/**
|
||||||
* Jerry snapshot format version.
|
* Jerry snapshot format version.
|
||||||
*/
|
*/
|
||||||
#define JERRY_SNAPSHOT_VERSION (12u)
|
#define JERRY_SNAPSHOT_VERSION (13u)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Snapshot configuration flags.
|
* Snapshot configuration flags.
|
||||||
|
|||||||
@@ -272,11 +272,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_0 | VM_OC_PUT_STACK) \
|
VM_OC_PUSH_0 | VM_OC_PUT_STACK) \
|
||||||
CBC_OPCODE (CBC_PUSH_NUMBER_POS_BYTE, CBC_HAS_BYTE_ARG, 1, \
|
CBC_OPCODE (CBC_PUSH_NUMBER_POS_BYTE, CBC_HAS_BYTE_ARG, 1, \
|
||||||
VM_OC_PUSH_NUMBER_POS_BYTE | VM_OC_PUT_STACK) \
|
VM_OC_PUSH_POS_BYTE | VM_OC_PUT_STACK) \
|
||||||
CBC_OPCODE (CBC_PUSH_NUMBER_NEG_BYTE, CBC_HAS_BYTE_ARG, 1, \
|
CBC_OPCODE (CBC_PUSH_NUMBER_NEG_BYTE, CBC_HAS_BYTE_ARG, 1, \
|
||||||
VM_OC_PUSH_NUMBER_NEG_BYTE | VM_OC_PUT_STACK) \
|
VM_OC_PUSH_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, \
|
||||||
@@ -539,6 +539,12 @@
|
|||||||
/* Basic opcodes. */ \
|
/* Basic opcodes. */ \
|
||||||
CBC_OPCODE (CBC_EXT_DEBUGGER, CBC_NO_FLAG, 0, \
|
CBC_OPCODE (CBC_EXT_DEBUGGER, CBC_NO_FLAG, 0, \
|
||||||
VM_OC_NONE) \
|
VM_OC_NONE) \
|
||||||
|
CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0, CBC_HAS_LITERAL_ARG, 2, \
|
||||||
|
VM_OC_PUSH_LIT_0 | VM_OC_GET_LITERAL) \
|
||||||
|
CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
|
||||||
|
VM_OC_PUSH_LIT_POS_BYTE | VM_OC_GET_LITERAL) \
|
||||||
|
CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
|
||||||
|
VM_OC_PUSH_LIT_NEG_BYTE | VM_OC_GET_LITERAL) \
|
||||||
CBC_OPCODE (CBC_EXT_RESOURCE_NAME, CBC_NO_FLAG, 0, \
|
CBC_OPCODE (CBC_EXT_RESOURCE_NAME, CBC_NO_FLAG, 0, \
|
||||||
VM_OC_RESOURCE_NAME) \
|
VM_OC_RESOURCE_NAME) \
|
||||||
CBC_OPCODE (CBC_EXT_LINE, CBC_NO_FLAG, 0, \
|
CBC_OPCODE (CBC_EXT_LINE, CBC_NO_FLAG, 0, \
|
||||||
|
|||||||
@@ -1745,7 +1745,7 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
|
|||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
lexer_construct_number_object (parser_context_t *context_p, /**< context */
|
lexer_construct_number_object (parser_context_t *context_p, /**< context */
|
||||||
bool push_number_allowed, /**< push number support is allowed */
|
bool is_expr, /**< expression is parsed */
|
||||||
bool is_negative_number) /**< sign is negative */
|
bool is_negative_number) /**< sign is negative */
|
||||||
{
|
{
|
||||||
parser_list_iterator_t literal_iterator;
|
parser_list_iterator_t literal_iterator;
|
||||||
@@ -1773,7 +1773,7 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
|
|||||||
while (src_p < src_end_p);
|
while (src_p < src_end_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (push_number_allowed)
|
if (is_expr)
|
||||||
{
|
{
|
||||||
int32_t int_num = (int32_t) num;
|
int32_t int_num = (int32_t) num;
|
||||||
|
|
||||||
@@ -1818,22 +1818,99 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
|
|||||||
}
|
}
|
||||||
|
|
||||||
literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
|
literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
|
||||||
literal_p->prop.length = context_p->token.lit_location.length;
|
|
||||||
literal_p->type = LEXER_UNUSED_LITERAL;
|
|
||||||
literal_p->status_flags = 0;
|
|
||||||
|
|
||||||
context_p->literal_count++;
|
|
||||||
|
|
||||||
literal_p->u.value = lit_value;
|
literal_p->u.value = lit_value;
|
||||||
|
literal_p->prop.length = 0; /* Unused. */
|
||||||
literal_p->type = LEXER_NUMBER_LITERAL;
|
literal_p->type = LEXER_NUMBER_LITERAL;
|
||||||
|
literal_p->status_flags = 0;
|
||||||
|
|
||||||
context_p->lit_object.literal_p = literal_p;
|
context_p->lit_object.literal_p = literal_p;
|
||||||
context_p->lit_object.index = (uint16_t) literal_index;
|
context_p->lit_object.index = (uint16_t) literal_index;
|
||||||
context_p->lit_object.type = LEXER_LITERAL_OBJECT_ANY;
|
context_p->lit_object.type = LEXER_LITERAL_OBJECT_ANY;
|
||||||
|
|
||||||
|
context_p->literal_count++;
|
||||||
return false;
|
return false;
|
||||||
} /* lexer_construct_number_object */
|
} /* lexer_construct_number_object */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a push number opcode to push literal opcode
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
lexer_convert_push_number_to_push_literal (parser_context_t *context_p) /**< context */
|
||||||
|
{
|
||||||
|
ecma_integer_value_t value;
|
||||||
|
bool two_literals = !PARSER_IS_BASIC_OPCODE (context_p->last_cbc_opcode);
|
||||||
|
|
||||||
|
if (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_0
|
||||||
|
|| context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0))
|
||||||
|
{
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
else if (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_POS_BYTE
|
||||||
|
|| context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE))
|
||||||
|
{
|
||||||
|
value = ((ecma_integer_value_t) context_p->last_cbc.value) + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_NEG_BYTE
|
||||||
|
|| context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE));
|
||||||
|
value = -((ecma_integer_value_t) context_p->last_cbc.value) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_value_t lit_value = ecma_make_integer_value (value);
|
||||||
|
|
||||||
|
parser_list_iterator_t literal_iterator;
|
||||||
|
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
|
||||||
|
|
||||||
|
context_p->last_cbc_opcode = two_literals ? CBC_PUSH_TWO_LITERALS : CBC_PUSH_LITERAL;
|
||||||
|
|
||||||
|
uint32_t literal_index = 0;
|
||||||
|
lexer_literal_t *literal_p;
|
||||||
|
|
||||||
|
while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
|
||||||
|
{
|
||||||
|
if (literal_p->type == LEXER_NUMBER_LITERAL
|
||||||
|
&& literal_p->u.value == lit_value)
|
||||||
|
{
|
||||||
|
if (two_literals)
|
||||||
|
{
|
||||||
|
context_p->last_cbc.value = (uint16_t) literal_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context_p->last_cbc.literal_index = (uint16_t) literal_index;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
literal_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
JERRY_ASSERT (literal_index == context_p->literal_count);
|
||||||
|
|
||||||
|
if (literal_index >= PARSER_MAXIMUM_NUMBER_OF_LITERALS)
|
||||||
|
{
|
||||||
|
parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
|
||||||
|
literal_p->u.value = lit_value;
|
||||||
|
literal_p->prop.length = 0; /* Unused. */
|
||||||
|
literal_p->type = LEXER_NUMBER_LITERAL;
|
||||||
|
literal_p->status_flags = 0;
|
||||||
|
|
||||||
|
context_p->literal_count++;
|
||||||
|
|
||||||
|
if (two_literals)
|
||||||
|
{
|
||||||
|
context_p->last_cbc.value = (uint16_t) literal_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context_p->last_cbc.literal_index = (uint16_t) literal_index;
|
||||||
|
}
|
||||||
|
} /* lexer_convert_push_number_to_push_literal */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a function literal object.
|
* Construct a function literal object.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -808,12 +808,6 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
|
|||||||
{
|
{
|
||||||
JERRY_ASSERT (context_p->lit_object.index <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
|
JERRY_ASSERT (context_p->lit_object.index <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
|
||||||
|
|
||||||
if (context_p->lit_object.index == 0)
|
|
||||||
{
|
|
||||||
parser_emit_cbc (context_p, CBC_PUSH_NUMBER_0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
parser_emit_cbc_push_number (context_p, is_negative_number);
|
parser_emit_cbc_push_number (context_p, is_negative_number);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1563,6 +1557,11 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
|
|||||||
{
|
{
|
||||||
opcode = LEXER_BINARY_OP_TOKEN_TO_OPCODE (token);
|
opcode = LEXER_BINARY_OP_TOKEN_TO_OPCODE (token);
|
||||||
|
|
||||||
|
if (PARSER_IS_PUSH_NUMBER (context_p->last_cbc_opcode))
|
||||||
|
{
|
||||||
|
lexer_convert_push_number_to_push_literal (context_p);
|
||||||
|
}
|
||||||
|
|
||||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, opcode + CBC_BINARY_WITH_LITERAL));
|
JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, opcode + CBC_BINARY_WITH_LITERAL));
|
||||||
|
|||||||
@@ -117,6 +117,13 @@ typedef struct
|
|||||||
((opcode) == CBC_PUSH_LITERAL \
|
((opcode) == CBC_PUSH_LITERAL \
|
||||||
|| (opcode) == CBC_PUSH_TWO_LITERALS \
|
|| (opcode) == CBC_PUSH_TWO_LITERALS \
|
||||||
|| (opcode) == CBC_PUSH_THREE_LITERALS)
|
|| (opcode) == CBC_PUSH_THREE_LITERALS)
|
||||||
|
#define PARSER_IS_PUSH_NUMBER(opcode) \
|
||||||
|
((opcode) == CBC_PUSH_NUMBER_0 \
|
||||||
|
|| (opcode) == CBC_PUSH_NUMBER_POS_BYTE \
|
||||||
|
|| (opcode) == CBC_PUSH_NUMBER_NEG_BYTE \
|
||||||
|
|| (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0) \
|
||||||
|
|| (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE) \
|
||||||
|
|| (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE))
|
||||||
|
|
||||||
#define PARSER_GET_LITERAL(literal_index) \
|
#define PARSER_GET_LITERAL(literal_index) \
|
||||||
((lexer_literal_t *) parser_list_get (&context_p->literal_pool, (literal_index)))
|
((lexer_literal_t *) parser_list_get (&context_p->literal_pool, (literal_index)))
|
||||||
@@ -429,7 +436,8 @@ ecma_char_t lexer_hex_to_character (parser_context_t *context_p, const uint8_t *
|
|||||||
void lexer_expect_object_literal_id (parser_context_t *context_p, bool must_be_identifier);
|
void lexer_expect_object_literal_id (parser_context_t *context_p, bool must_be_identifier);
|
||||||
void lexer_construct_literal_object (parser_context_t *context_p, lexer_lit_location_t *literal_p,
|
void lexer_construct_literal_object (parser_context_t *context_p, lexer_lit_location_t *literal_p,
|
||||||
uint8_t literal_type);
|
uint8_t literal_type);
|
||||||
bool lexer_construct_number_object (parser_context_t *context_p, bool push_number_allowed, bool is_negative_number);
|
bool lexer_construct_number_object (parser_context_t *context_p, bool is_expr, bool is_negative_number);
|
||||||
|
void lexer_convert_push_number_to_push_literal (parser_context_t *context_p);
|
||||||
uint16_t lexer_construct_function_object (parser_context_t *context_p, uint32_t extra_status_flags);
|
uint16_t lexer_construct_function_object (parser_context_t *context_p, uint32_t extra_status_flags);
|
||||||
void lexer_construct_regexp_object (parser_context_t *context_p, bool parse_only);
|
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);
|
bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right);
|
||||||
|
|||||||
@@ -206,7 +206,20 @@ parser_flush_cbc (parser_context_t *context_p) /**< context */
|
|||||||
|
|
||||||
if (flags & CBC_HAS_BYTE_ARG)
|
if (flags & CBC_HAS_BYTE_ARG)
|
||||||
{
|
{
|
||||||
JERRY_DEBUG_MSG (" byte_arg:%d", (int) context_p->last_cbc.value);
|
if ((last_opcode == CBC_PUSH_NUMBER_POS_BYTE)
|
||||||
|
|| (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)))
|
||||||
|
{
|
||||||
|
JERRY_DEBUG_MSG (" number:%d", (int) context_p->last_cbc.value + 1);
|
||||||
|
}
|
||||||
|
else if ((last_opcode == CBC_PUSH_NUMBER_NEG_BYTE)
|
||||||
|
|| (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)))
|
||||||
|
{
|
||||||
|
JERRY_DEBUG_MSG (" number:%d", -((int) context_p->last_cbc.value + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JERRY_DEBUG_MSG (" byte_arg:%d", (int) context_p->last_cbc.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JERRY_DEBUG_MSG ("\n");
|
JERRY_DEBUG_MSG ("\n");
|
||||||
@@ -311,41 +324,66 @@ parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */
|
|||||||
bool is_negative_number) /**< sign is negative */
|
bool is_negative_number) /**< sign is negative */
|
||||||
{
|
{
|
||||||
uint16_t value = context_p->lit_object.index;
|
uint16_t value = context_p->lit_object.index;
|
||||||
|
uint16_t lit_value = UINT16_MAX;
|
||||||
|
|
||||||
if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
|
if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
|
||||||
{
|
{
|
||||||
parser_flush_cbc (context_p);
|
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||||
}
|
|
||||||
|
|
||||||
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++;
|
|
||||||
|
|
||||||
#ifdef PARSER_DUMP_BYTE_CODE
|
|
||||||
if (context_p->is_show_opcodes)
|
|
||||||
{
|
|
||||||
JERRY_DEBUG_MSG (" [%3d] %s number:%d\n",
|
|
||||||
(int) context_p->stack_depth,
|
|
||||||
cbc_names[opcode],
|
|
||||||
is_negative_number ? -(int) value : (int) value);
|
|
||||||
}
|
|
||||||
#endif /* PARSER_DUMP_BYTE_CODE */
|
|
||||||
|
|
||||||
parser_emit_two_bytes (context_p, opcode, (uint8_t) (value - 1));
|
|
||||||
|
|
||||||
context_p->byte_code_size += 2;
|
|
||||||
|
|
||||||
if (context_p->stack_depth > context_p->stack_limit)
|
|
||||||
{
|
|
||||||
context_p->stack_limit = context_p->stack_depth;
|
|
||||||
if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
|
|
||||||
{
|
{
|
||||||
parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
|
lit_value = context_p->last_cbc.literal_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
|
||||||
|
{
|
||||||
|
context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
|
||||||
|
lit_value = context_p->last_cbc.value;
|
||||||
|
}
|
||||||
|
else if (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS)
|
||||||
|
{
|
||||||
|
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
||||||
|
lit_value = context_p->last_cbc.third_literal_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_flush_cbc (context_p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
if (lit_value == UINT16_MAX)
|
||||||
|
{
|
||||||
|
context_p->last_cbc_opcode = CBC_PUSH_NUMBER_0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0);
|
||||||
|
context_p->last_cbc.literal_index = lit_value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t opcode;
|
||||||
|
|
||||||
|
if (lit_value == UINT16_MAX)
|
||||||
|
{
|
||||||
|
opcode = (is_negative_number ? CBC_PUSH_NUMBER_NEG_BYTE
|
||||||
|
: CBC_PUSH_NUMBER_POS_BYTE);
|
||||||
|
|
||||||
|
JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opcode = PARSER_TO_EXT_OPCODE (is_negative_number ? CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE
|
||||||
|
: CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE);
|
||||||
|
JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 2);
|
||||||
|
|
||||||
|
context_p->last_cbc.literal_index = lit_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
JERRY_ASSERT (value > 0 && value <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
|
||||||
|
|
||||||
|
context_p->last_cbc_opcode = opcode;
|
||||||
|
context_p->last_cbc.value = (uint16_t) (value - 1);
|
||||||
} /* parser_emit_cbc_push_number */
|
} /* parser_emit_cbc_push_number */
|
||||||
|
|
||||||
#ifdef JERRY_ENABLE_LINE_INFO
|
#ifdef JERRY_ENABLE_LINE_INFO
|
||||||
|
|||||||
@@ -356,11 +356,6 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
|
|||||||
{
|
{
|
||||||
uint16_t init_index;
|
uint16_t init_index;
|
||||||
|
|
||||||
if (literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (literal_p->type != LEXER_IDENT_LITERAL)
|
if (literal_p->type != LEXER_IDENT_LITERAL)
|
||||||
{
|
{
|
||||||
if (literal_p->type == LEXER_STRING_LITERAL
|
if (literal_p->type == LEXER_STRING_LITERAL
|
||||||
@@ -392,6 +387,11 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(literal_p->status_flags & LEXER_FLAG_VAR))
|
if (!(literal_p->status_flags & LEXER_FLAG_VAR))
|
||||||
{
|
{
|
||||||
literal_p->prop.index = ident_index;
|
literal_p->prop.index = ident_index;
|
||||||
@@ -560,8 +560,6 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
|
|||||||
uint16_t next_index = uninitialized_var_end;
|
uint16_t next_index = uninitialized_var_end;
|
||||||
#endif /* !JERRY_NDEBUG */
|
#endif /* !JERRY_NDEBUG */
|
||||||
|
|
||||||
context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
|
|
||||||
|
|
||||||
*dst_p++ = CBC_INITIALIZE_VARS;
|
*dst_p++ = CBC_INITIALIZE_VARS;
|
||||||
dst_p = parser_encode_literal (dst_p,
|
dst_p = parser_encode_literal (dst_p,
|
||||||
(uint16_t) uninitialized_var_end,
|
(uint16_t) uninitialized_var_end,
|
||||||
@@ -1267,20 +1265,6 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
|
|||||||
literal_pool_p);
|
literal_pool_p);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode == CBC_PUSH_NUMBER_POS_BYTE)
|
|
||||||
{
|
|
||||||
JERRY_DEBUG_MSG (" number:%d\n", *byte_code_p + 1);
|
|
||||||
byte_code_p++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opcode == CBC_PUSH_NUMBER_NEG_BYTE)
|
|
||||||
{
|
|
||||||
JERRY_DEBUG_MSG (" number:%d\n", -(*byte_code_p + 1));
|
|
||||||
byte_code_p++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1332,7 +1316,20 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
|
|||||||
|
|
||||||
if (flags & CBC_HAS_BYTE_ARG)
|
if (flags & CBC_HAS_BYTE_ARG)
|
||||||
{
|
{
|
||||||
JERRY_DEBUG_MSG (" byte_arg:%d", *byte_code_p);
|
if (opcode == CBC_PUSH_NUMBER_POS_BYTE
|
||||||
|
|| ext_opcode == CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
|
||||||
|
{
|
||||||
|
JERRY_DEBUG_MSG (" number:%d", (int) *byte_code_p + 1);
|
||||||
|
}
|
||||||
|
else if (opcode == CBC_PUSH_NUMBER_NEG_BYTE
|
||||||
|
|| ext_opcode == CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
|
||||||
|
{
|
||||||
|
JERRY_DEBUG_MSG (" number:%d", -((int) *byte_code_p + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JERRY_DEBUG_MSG (" byte_arg:%d", *byte_code_p);
|
||||||
|
}
|
||||||
byte_code_p++;
|
byte_code_p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
-3
@@ -999,23 +999,46 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
*stack_top_p++ = ecma_copy_value (frame_ctx_p->this_binding);
|
*stack_top_p++ = ecma_copy_value (frame_ctx_p->this_binding);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case VM_OC_PUSH_NUMBER_0:
|
case VM_OC_PUSH_0:
|
||||||
{
|
{
|
||||||
*stack_top_p++ = ecma_make_integer_value (0);
|
*stack_top_p++ = ecma_make_integer_value (0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case VM_OC_PUSH_NUMBER_POS_BYTE:
|
case VM_OC_PUSH_POS_BYTE:
|
||||||
{
|
{
|
||||||
ecma_integer_value_t number = *byte_code_p++;
|
ecma_integer_value_t number = *byte_code_p++;
|
||||||
*stack_top_p++ = ecma_make_integer_value (number + 1);
|
*stack_top_p++ = ecma_make_integer_value (number + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case VM_OC_PUSH_NUMBER_NEG_BYTE:
|
case VM_OC_PUSH_NEG_BYTE:
|
||||||
{
|
{
|
||||||
ecma_integer_value_t number = *byte_code_p++;
|
ecma_integer_value_t number = *byte_code_p++;
|
||||||
*stack_top_p++ = ecma_make_integer_value (-(number + 1));
|
*stack_top_p++ = ecma_make_integer_value (-(number + 1));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
case VM_OC_PUSH_LIT_0:
|
||||||
|
{
|
||||||
|
stack_top_p[0] = left_value;
|
||||||
|
stack_top_p[1] = ecma_make_integer_value (0);
|
||||||
|
stack_top_p += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case VM_OC_PUSH_LIT_POS_BYTE:
|
||||||
|
{
|
||||||
|
ecma_integer_value_t number = *byte_code_p++;
|
||||||
|
stack_top_p[0] = left_value;
|
||||||
|
stack_top_p[1] = ecma_make_integer_value (number + 1);
|
||||||
|
stack_top_p += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case VM_OC_PUSH_LIT_NEG_BYTE:
|
||||||
|
{
|
||||||
|
ecma_integer_value_t number = *byte_code_p++;
|
||||||
|
stack_top_p[0] = left_value;
|
||||||
|
stack_top_p[1] = ecma_make_integer_value (-(number + 1));
|
||||||
|
stack_top_p += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
case VM_OC_PUSH_OBJECT:
|
case VM_OC_PUSH_OBJECT:
|
||||||
{
|
{
|
||||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||||
|
|||||||
+9
-6
@@ -105,17 +105,20 @@ typedef enum
|
|||||||
VM_OC_NONE, /**< do nothing */
|
VM_OC_NONE, /**< do nothing */
|
||||||
VM_OC_POP, /**< pop from stack */
|
VM_OC_POP, /**< pop from stack */
|
||||||
VM_OC_POP_BLOCK, /**< pop block */
|
VM_OC_POP_BLOCK, /**< pop block */
|
||||||
VM_OC_PUSH, /**< push one element */
|
VM_OC_PUSH, /**< push one literal */
|
||||||
VM_OC_PUSH_TWO, /**< push two elements onto the stack */
|
VM_OC_PUSH_TWO, /**< push two literals */
|
||||||
VM_OC_PUSH_THREE, /**< push three elements onto the stack */
|
VM_OC_PUSH_THREE, /**< push three literals */
|
||||||
VM_OC_PUSH_UNDEFINED, /**< push undefined value */
|
VM_OC_PUSH_UNDEFINED, /**< push undefined value */
|
||||||
VM_OC_PUSH_TRUE, /**< push true value */
|
VM_OC_PUSH_TRUE, /**< push true value */
|
||||||
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_0, /**< push number zero */
|
VM_OC_PUSH_0, /**< push number zero */
|
||||||
VM_OC_PUSH_NUMBER_POS_BYTE, /**< push number between 1 and 256 */
|
VM_OC_PUSH_POS_BYTE, /**< push number between 1 and 256 */
|
||||||
VM_OC_PUSH_NUMBER_NEG_BYTE, /**< push number between -1 and -256 */
|
VM_OC_PUSH_NEG_BYTE, /**< push number between -1 and -256 */
|
||||||
|
VM_OC_PUSH_LIT_0, /**< push literal and number zero */
|
||||||
|
VM_OC_PUSH_LIT_POS_BYTE, /**< push literal and number between 1 and 256 */
|
||||||
|
VM_OC_PUSH_LIT_NEG_BYTE, /**< push literal and 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 */
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ main (void)
|
|||||||
/* Check the snapshot data. Unused bytes should be filled with zeroes */
|
/* Check the snapshot data. Unused bytes should be filled with zeroes */
|
||||||
const uint8_t expected_data[] =
|
const uint8_t expected_data[] =
|
||||||
{
|
{
|
||||||
0x4A, 0x52, 0x52, 0x59, 0x0C, 0x00, 0x00, 0x00,
|
0x4A, 0x52, 0x52, 0x59, 0x0D, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||||
0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
|
0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||||
|
|||||||
Reference in New Issue
Block a user