Reduce code duplication in js-parser-expr.c (#3159)
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
committed by
Dániel Bátyai
parent
f5e3faeaff
commit
2a89eec98b
@@ -30,7 +30,7 @@ extern "C"
|
|||||||
/**
|
/**
|
||||||
* Jerry snapshot format version.
|
* Jerry snapshot format version.
|
||||||
*/
|
*/
|
||||||
#define JERRY_SNAPSHOT_VERSION (23u)
|
#define JERRY_SNAPSHOT_VERSION (24u)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
|
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
|
||||||
|
|||||||
@@ -245,11 +245,13 @@
|
|||||||
CBC_FORWARD_BRANCH (CBC_BRANCH_IF_STRICT_EQUAL, -1, \
|
CBC_FORWARD_BRANCH (CBC_BRANCH_IF_STRICT_EQUAL, -1, \
|
||||||
VM_OC_BRANCH_IF_STRICT_EQUAL) \
|
VM_OC_BRANCH_IF_STRICT_EQUAL) \
|
||||||
\
|
\
|
||||||
/* Basic opcodes. */ \
|
/* Basic opcodes. Note: These 4 opcodes must me in this order */ \
|
||||||
CBC_OPCODE (CBC_PUSH_LITERAL, CBC_HAS_LITERAL_ARG, 1, \
|
CBC_OPCODE (CBC_PUSH_LITERAL, CBC_HAS_LITERAL_ARG, 1, \
|
||||||
VM_OC_PUSH | VM_OC_GET_LITERAL) \
|
VM_OC_PUSH | VM_OC_GET_LITERAL) \
|
||||||
CBC_OPCODE (CBC_PUSH_TWO_LITERALS, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 2, \
|
CBC_OPCODE (CBC_PUSH_TWO_LITERALS, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 2, \
|
||||||
VM_OC_PUSH_TWO | VM_OC_GET_LITERAL_LITERAL) \
|
VM_OC_PUSH_TWO | VM_OC_GET_LITERAL_LITERAL) \
|
||||||
|
CBC_OPCODE (CBC_PUSH_THIS_LITERAL, CBC_HAS_LITERAL_ARG, 2, \
|
||||||
|
VM_OC_PUSH_TWO | VM_OC_GET_THIS_LITERAL) \
|
||||||
CBC_OPCODE (CBC_PUSH_THREE_LITERALS, CBC_HAS_LITERAL_ARG2, 3, \
|
CBC_OPCODE (CBC_PUSH_THREE_LITERALS, CBC_HAS_LITERAL_ARG2, 3, \
|
||||||
VM_OC_PUSH_THREE | VM_OC_GET_LITERAL_LITERAL) \
|
VM_OC_PUSH_THREE | VM_OC_GET_LITERAL_LITERAL) \
|
||||||
CBC_OPCODE (CBC_PUSH_UNDEFINED, CBC_NO_FLAG, 1, \
|
CBC_OPCODE (CBC_PUSH_UNDEFINED, CBC_NO_FLAG, 1, \
|
||||||
@@ -262,14 +264,13 @@
|
|||||||
VM_OC_PUSH_NULL | VM_OC_PUT_STACK) \
|
VM_OC_PUSH_NULL | VM_OC_PUT_STACK) \
|
||||||
CBC_OPCODE (CBC_PUSH_THIS, CBC_NO_FLAG, 1, \
|
CBC_OPCODE (CBC_PUSH_THIS, CBC_NO_FLAG, 1, \
|
||||||
VM_OC_PUSH_THIS | VM_OC_PUT_STACK) \
|
VM_OC_PUSH_THIS | VM_OC_PUT_STACK) \
|
||||||
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, \
|
CBC_OPCODE (CBC_PUSH_NUMBER_0, CBC_NO_FLAG, 1, \
|
||||||
VM_OC_PUSH_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_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_NEG_BYTE | VM_OC_PUT_STACK) \
|
VM_OC_PUSH_NEG_BYTE | VM_OC_PUT_STACK) \
|
||||||
|
/* Note: These 4 opcodes must me in this order */ \
|
||||||
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, \
|
||||||
@@ -280,6 +281,7 @@
|
|||||||
VM_OC_PROP_GET | VM_OC_GET_THIS_LITERAL | VM_OC_PUT_STACK) \
|
VM_OC_PROP_GET | VM_OC_GET_THIS_LITERAL | VM_OC_PUT_STACK) \
|
||||||
CBC_OPCODE (CBC_PUSH_IDENT_REFERENCE, CBC_HAS_LITERAL_ARG, 3, \
|
CBC_OPCODE (CBC_PUSH_IDENT_REFERENCE, CBC_HAS_LITERAL_ARG, 3, \
|
||||||
VM_OC_IDENT_REFERENCE | VM_OC_PUT_STACK) \
|
VM_OC_IDENT_REFERENCE | VM_OC_PUT_STACK) \
|
||||||
|
/* Note: These 4 opcodes must me in this order */ \
|
||||||
CBC_OPCODE (CBC_PUSH_PROP_REFERENCE, CBC_NO_FLAG, 1, \
|
CBC_OPCODE (CBC_PUSH_PROP_REFERENCE, CBC_NO_FLAG, 1, \
|
||||||
VM_OC_PROP_REFERENCE | VM_OC_PUT_STACK) \
|
VM_OC_PROP_REFERENCE | VM_OC_PUT_STACK) \
|
||||||
CBC_OPCODE (CBC_PUSH_PROP_LITERAL_REFERENCE, CBC_HAS_LITERAL_ARG, 2, \
|
CBC_OPCODE (CBC_PUSH_PROP_LITERAL_REFERENCE, CBC_HAS_LITERAL_ARG, 2, \
|
||||||
|
|||||||
@@ -31,6 +31,16 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum precedence for right-to-left binary operation evaluation
|
||||||
|
*/
|
||||||
|
#define PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE 6
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Precende for ternary operation
|
||||||
|
*/
|
||||||
|
#define PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Precedence of the binary tokens.
|
* Precedence of the binary tokens.
|
||||||
*
|
*
|
||||||
@@ -76,6 +86,68 @@ parser_push_result (parser_context_t *context_p) /**< context */
|
|||||||
}
|
}
|
||||||
} /* parser_push_result */
|
} /* parser_push_result */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for invalid assignment for "eval" and "arguments"
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parser_check_invalid_assign (parser_context_t *context_p) /**< context */
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL);
|
||||||
|
|
||||||
|
if (JERRY_UNLIKELY ((context_p->status_flags & PARSER_IS_STRICT)
|
||||||
|
&& context_p->last_cbc.literal_object_type != LEXER_LITERAL_OBJECT_ANY))
|
||||||
|
{
|
||||||
|
parser_error_t error;
|
||||||
|
|
||||||
|
if (context_p->last_cbc.literal_object_type == LEXER_LITERAL_OBJECT_EVAL)
|
||||||
|
{
|
||||||
|
error = PARSER_ERR_EVAL_CANNOT_ASSIGNED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (context_p->last_cbc.literal_object_type == LEXER_LITERAL_OBJECT_ARGUMENTS);
|
||||||
|
error = PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_raise_error (context_p, error);
|
||||||
|
}
|
||||||
|
} /* parser_check_invalid_assign */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit identifier reference
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parser_emit_ident_reference (parser_context_t *context_p, /**< context */
|
||||||
|
uint16_t opcode) /* opcode */
|
||||||
|
{
|
||||||
|
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||||
|
{
|
||||||
|
context_p->last_cbc_opcode = opcode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t literal_index;
|
||||||
|
|
||||||
|
if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
|
||||||
|
{
|
||||||
|
context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
|
||||||
|
literal_index = context_p->last_cbc.value;
|
||||||
|
}
|
||||||
|
else if (context_p->last_cbc_opcode == CBC_PUSH_THIS_LITERAL)
|
||||||
|
{
|
||||||
|
context_p->last_cbc_opcode = CBC_PUSH_THIS;
|
||||||
|
literal_index = context_p->lit_object.index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
|
||||||
|
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
||||||
|
literal_index = context_p->last_cbc.third_literal_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_emit_cbc_literal (context_p, opcode, literal_index);
|
||||||
|
} /* parser_emit_ident_reference */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate byte code for operators with lvalue.
|
* Generate byte code for operators with lvalue.
|
||||||
*/
|
*/
|
||||||
@@ -83,134 +155,52 @@ static void
|
|||||||
parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */
|
parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */
|
||||||
cbc_opcode_t opcode) /**< opcode */
|
cbc_opcode_t opcode) /**< opcode */
|
||||||
{
|
{
|
||||||
if ((PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode)
|
if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
|
||||||
|| context_p->last_cbc_opcode == CBC_PUSH_THIS_LITERAL)
|
|
||||||
&& context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
|
&& context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
|
||||||
{
|
{
|
||||||
if (context_p->status_flags & PARSER_IS_STRICT)
|
parser_check_invalid_assign (context_p);
|
||||||
{
|
|
||||||
if (context_p->last_cbc.literal_object_type != LEXER_LITERAL_OBJECT_ANY)
|
|
||||||
{
|
|
||||||
parser_error_t error;
|
|
||||||
|
|
||||||
if (context_p->last_cbc.literal_object_type == LEXER_LITERAL_OBJECT_EVAL)
|
uint16_t unary_opcode;
|
||||||
{
|
|
||||||
error = PARSER_ERR_EVAL_CANNOT_ASSIGNED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (context_p->last_cbc.literal_object_type == LEXER_LITERAL_OBJECT_ARGUMENTS);
|
|
||||||
error = PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED;
|
|
||||||
}
|
|
||||||
parser_raise_error (context_p, error);
|
|
||||||
}
|
|
||||||
if (opcode == CBC_DELETE_PUSH_RESULT)
|
|
||||||
{
|
|
||||||
parser_raise_error (context_p, PARSER_ERR_DELETE_IDENT_NOT_ALLOWED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opcode == CBC_DELETE_PUSH_RESULT)
|
if (opcode == CBC_DELETE_PUSH_RESULT)
|
||||||
{
|
{
|
||||||
|
if (JERRY_UNLIKELY (context_p->status_flags & PARSER_IS_STRICT))
|
||||||
|
{
|
||||||
|
parser_raise_error (context_p, PARSER_ERR_DELETE_IDENT_NOT_ALLOWED);
|
||||||
|
}
|
||||||
|
|
||||||
context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
|
context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
|
||||||
|
unary_opcode = CBC_DELETE_IDENT_PUSH_RESULT;
|
||||||
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 if (context_p->last_cbc_opcode == CBC_PUSH_THIS_LITERAL)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_THIS;
|
|
||||||
parser_emit_cbc_literal (context_p,
|
|
||||||
CBC_DELETE_IDENT_PUSH_RESULT,
|
|
||||||
context_p->lit_object.index);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
(uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT),
|
|
||||||
context_p->last_cbc.value);
|
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_THIS_LITERAL)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_THIS;
|
|
||||||
parser_emit_cbc_literal (context_p,
|
|
||||||
(uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT),
|
|
||||||
context_p->lit_object.index);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
|
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, opcode + CBC_UNARY_LVALUE_WITH_IDENT));
|
||||||
|
unary_opcode = (uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT);
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
|
||||||
parser_emit_cbc_literal (context_p,
|
|
||||||
(uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT),
|
|
||||||
context_p->last_cbc.third_literal_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parser_emit_ident_reference (context_p, unary_opcode);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
|
|
||||||
|
if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, opcode));
|
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, opcode));
|
||||||
context_p->last_cbc_opcode = (uint16_t) opcode;
|
context_p->last_cbc_opcode = (uint16_t) opcode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PARSER_IS_PUSH_PROP_LITERAL (context_p->last_cbc_opcode))
|
||||||
|
{
|
||||||
|
context_p->last_cbc_opcode = PARSER_PUSH_PROP_LITERAL_TO_PUSH_LITERAL (context_p->last_cbc_opcode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (context_p->last_cbc_opcode)
|
/* Invalid LeftHandSide expression. */
|
||||||
{
|
parser_emit_cbc_ext (context_p, (opcode == CBC_DELETE_PUSH_RESULT) ? CBC_EXT_PUSH_UNDEFINED_BASE
|
||||||
case CBC_PUSH_PROP_LITERAL:
|
: CBC_EXT_THROW_REFERENCE_ERROR);
|
||||||
{
|
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL, CBC_PUSH_LITERAL));
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CBC_PUSH_PROP_LITERAL_LITERAL:
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL_LITERAL, CBC_PUSH_TWO_LITERALS));
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CBC_PUSH_PROP_THIS_LITERAL:
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_THIS_LITERAL, CBC_PUSH_THIS_LITERAL));
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
/* Invalid LeftHandSide expression. */
|
|
||||||
parser_emit_cbc_ext (context_p, (opcode == CBC_DELETE_PUSH_RESULT) ? CBC_EXT_PUSH_UNDEFINED_BASE
|
|
||||||
: CBC_EXT_THROW_REFERENCE_ERROR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parser_emit_cbc (context_p, (uint16_t) opcode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parser_emit_cbc (context_p, (uint16_t) opcode);
|
||||||
} /* parser_emit_unary_lvalue_opcode */
|
} /* parser_emit_unary_lvalue_opcode */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1320,21 +1310,21 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
|
|||||||
{
|
{
|
||||||
lexer_construct_regexp_object (context_p, false);
|
lexer_construct_regexp_object (context_p, false);
|
||||||
|
|
||||||
|
uint16_t literal_index = (uint16_t) (context_p->literal_count - 1);
|
||||||
|
|
||||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||||
{
|
{
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
||||||
context_p->last_cbc.value = (uint16_t) (context_p->literal_count - 1);
|
context_p->last_cbc.value = literal_index;
|
||||||
}
|
}
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
|
else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
|
||||||
{
|
{
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS;
|
context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS;
|
||||||
context_p->last_cbc.third_literal_index = (uint16_t) (context_p->literal_count - 1);
|
context_p->last_cbc.third_literal_index = literal_index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parser_emit_cbc_literal (context_p,
|
parser_emit_cbc_literal (context_p, CBC_PUSH_LITERAL, literal_index);
|
||||||
CBC_PUSH_LITERAL,
|
|
||||||
(uint16_t) (context_p->literal_count - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context_p->last_cbc.literal_type = LEXER_REGEXP_LITERAL;
|
context_p->last_cbc.literal_type = LEXER_REGEXP_LITERAL;
|
||||||
@@ -1523,17 +1513,9 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */
|
|||||||
}
|
}
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
|
|
||||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
if (PARSER_IS_MUTABLE_PUSH_LITERAL (context_p->last_cbc_opcode))
|
||||||
{
|
{
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL;
|
context_p->last_cbc_opcode = PARSER_PUSH_LITERAL_TO_PUSH_PROP_LITERAL (context_p->last_cbc_opcode);
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL_LITERAL;
|
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_THIS_LITERAL)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_THIS_LITERAL;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1565,25 +1547,10 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */
|
|||||||
is_eval = true;
|
is_eval = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
|
if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
|
||||||
{
|
{
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_REFERENCE;
|
|
||||||
opcode = CBC_CALL_PROP;
|
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL_REFERENCE;
|
|
||||||
opcode = CBC_CALL_PROP;
|
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE;
|
|
||||||
opcode = CBC_CALL_PROP;
|
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_THIS_LITERAL)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_THIS_LITERAL_REFERENCE;
|
|
||||||
opcode = CBC_CALL_PROP;
|
opcode = CBC_CALL_PROP;
|
||||||
|
context_p->last_cbc_opcode = PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE (context_p->last_cbc_opcode);
|
||||||
}
|
}
|
||||||
#if ENABLED (JERRY_ES2015_CLASS)
|
#if ENABLED (JERRY_ES2015_CLASS)
|
||||||
else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_CONSTRUCTOR_SUPER))
|
else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_CONSTRUCTOR_SUPER))
|
||||||
@@ -1591,33 +1558,12 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */
|
|||||||
opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL);
|
opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL);
|
||||||
}
|
}
|
||||||
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
||||||
else if ((context_p->status_flags & (PARSER_INSIDE_WITH | PARSER_RESOLVE_BASE_FOR_CALLS))
|
else if (JERRY_UNLIKELY ((context_p->status_flags & (PARSER_INSIDE_WITH | PARSER_RESOLVE_BASE_FOR_CALLS))
|
||||||
&& PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode)
|
&& 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))
|
||||||
{
|
{
|
||||||
opcode = CBC_CALL_PROP;
|
opcode = CBC_CALL_PROP;
|
||||||
|
parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE);
|
||||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_IDENT_REFERENCE;
|
|
||||||
}
|
|
||||||
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_PUSH_IDENT_REFERENCE,
|
|
||||||
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_PUSH_IDENT_REFERENCE,
|
|
||||||
context_p->last_cbc.third_literal_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_BASE);
|
parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_BASE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1676,40 +1622,21 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */
|
|||||||
}
|
}
|
||||||
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
||||||
|
|
||||||
if (call_arguments == 0)
|
if (call_arguments <= 1)
|
||||||
{
|
{
|
||||||
if (opcode == CBC_CALL)
|
if (opcode == CBC_CALL)
|
||||||
{
|
{
|
||||||
parser_emit_cbc (context_p, CBC_CALL0);
|
parser_emit_cbc (context_p, (uint16_t) (CBC_CALL0 + (call_arguments * 6)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (opcode == CBC_CALL_PROP)
|
if (opcode == CBC_CALL_PROP)
|
||||||
{
|
{
|
||||||
parser_emit_cbc (context_p, CBC_CALL0_PROP);
|
parser_emit_cbc (context_p, (uint16_t) (CBC_CALL0_PROP + (call_arguments * 6)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (opcode == CBC_NEW)
|
if (opcode == CBC_NEW)
|
||||||
{
|
{
|
||||||
parser_emit_cbc (context_p, CBC_NEW0);
|
parser_emit_cbc (context_p, (uint16_t) (CBC_NEW0 + call_arguments));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (call_arguments == 1)
|
|
||||||
{
|
|
||||||
if (opcode == CBC_CALL)
|
|
||||||
{
|
|
||||||
parser_emit_cbc (context_p, CBC_CALL1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (opcode == CBC_CALL_PROP)
|
|
||||||
{
|
|
||||||
parser_emit_cbc (context_p, CBC_CALL1_PROP);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (opcode == CBC_NEW)
|
|
||||||
{
|
|
||||||
parser_emit_cbc (context_p, CBC_NEW1);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1793,26 +1720,7 @@ parser_process_unary_expression (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)
|
||||||
{
|
{
|
||||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
parser_emit_ident_reference (context_p, CBC_TYPEOF_IDENT);
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_TYPEOF_IDENT;
|
|
||||||
}
|
|
||||||
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_TYPEOF_IDENT,
|
|
||||||
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_TYPEOF_IDENT,
|
|
||||||
context_p->last_cbc.third_literal_index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1858,40 +1766,28 @@ parser_append_binary_token (parser_context_t *context_p) /**< context */
|
|||||||
{
|
{
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, CBC_ASSIGN_SET_IDENT));
|
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, CBC_ASSIGN_SET_IDENT));
|
||||||
|
|
||||||
if ((context_p->status_flags & PARSER_IS_STRICT)
|
parser_check_invalid_assign (context_p);
|
||||||
&& context_p->last_cbc.literal_object_type != LEXER_LITERAL_OBJECT_ANY)
|
|
||||||
{
|
|
||||||
parser_error_t error;
|
|
||||||
|
|
||||||
if (context_p->last_cbc.literal_object_type == LEXER_LITERAL_OBJECT_EVAL)
|
uint16_t literal_index;
|
||||||
{
|
|
||||||
error = PARSER_ERR_EVAL_CANNOT_ASSIGNED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (context_p->last_cbc.literal_object_type == LEXER_LITERAL_OBJECT_ARGUMENTS);
|
|
||||||
error = PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED;
|
|
||||||
}
|
|
||||||
parser_raise_error (context_p, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||||
{
|
{
|
||||||
parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
|
literal_index = context_p->last_cbc.literal_index;
|
||||||
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
|
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
|
else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
|
||||||
{
|
{
|
||||||
parser_stack_push_uint16 (context_p, context_p->last_cbc.value);
|
literal_index = context_p->last_cbc.value;
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
|
context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
|
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
|
||||||
|
literal_index = context_p->last_cbc.third_literal_index;
|
||||||
parser_stack_push_uint16 (context_p, context_p->last_cbc.third_literal_index);
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parser_stack_push_uint16 (context_p, literal_index);
|
||||||
parser_stack_push_uint8 (context_p, CBC_ASSIGN_SET_IDENT);
|
parser_stack_push_uint8 (context_p, CBC_ASSIGN_SET_IDENT);
|
||||||
}
|
}
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
|
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
|
||||||
@@ -1900,6 +1796,7 @@ parser_append_binary_token (parser_context_t *context_p) /**< context */
|
|||||||
parser_stack_push_uint8 (context_p, CBC_ASSIGN);
|
parser_stack_push_uint8 (context_p, CBC_ASSIGN);
|
||||||
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
|
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL)
|
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL)
|
||||||
{
|
{
|
||||||
if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
|
if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
|
||||||
@@ -1956,66 +1853,13 @@ parser_append_binary_token (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)
|
||||||
{
|
{
|
||||||
if ((context_p->status_flags & PARSER_IS_STRICT)
|
parser_check_invalid_assign (context_p);
|
||||||
&& context_p->last_cbc.literal_object_type != LEXER_LITERAL_OBJECT_ANY)
|
|
||||||
{
|
|
||||||
parser_error_t error;
|
|
||||||
|
|
||||||
if (context_p->last_cbc.literal_object_type == LEXER_LITERAL_OBJECT_EVAL)
|
parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE);
|
||||||
{
|
|
||||||
error = PARSER_ERR_EVAL_CANNOT_ASSIGNED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (context_p->last_cbc.literal_object_type == LEXER_LITERAL_OBJECT_ARGUMENTS);
|
|
||||||
error = PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED;
|
|
||||||
}
|
|
||||||
parser_raise_error (context_p, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_IDENT_REFERENCE;
|
|
||||||
}
|
|
||||||
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_PUSH_IDENT_REFERENCE,
|
|
||||||
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_PUSH_IDENT_REFERENCE,
|
|
||||||
context_p->last_cbc.third_literal_index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
|
else if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, CBC_PUSH_PROP_REFERENCE));
|
context_p->last_cbc_opcode = PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE (context_p->last_cbc_opcode);
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_REFERENCE;
|
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL)
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL,
|
|
||||||
CBC_PUSH_PROP_LITERAL_REFERENCE));
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL_REFERENCE;
|
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL_LITERAL,
|
|
||||||
CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE));
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE;
|
|
||||||
}
|
|
||||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_THIS_LITERAL)
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_THIS_LITERAL,
|
|
||||||
CBC_PUSH_PROP_THIS_LITERAL_REFERENCE));
|
|
||||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_THIS_LITERAL_REFERENCE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2146,6 +1990,134 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
|
|||||||
}
|
}
|
||||||
} /* parser_process_binary_opcodes */
|
} /* parser_process_binary_opcodes */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process ternary expression.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parser_process_ternary_expression (parser_context_t *context_p) /**< context */
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (context_p->token.type == LEXER_QUESTION_MARK);
|
||||||
|
|
||||||
|
cbc_opcode_t opcode = CBC_BRANCH_IF_FALSE_FORWARD;
|
||||||
|
parser_branch_t cond_branch;
|
||||||
|
parser_branch_t uncond_branch;
|
||||||
|
|
||||||
|
parser_push_result (context_p);
|
||||||
|
|
||||||
|
if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT)
|
||||||
|
{
|
||||||
|
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
|
||||||
|
opcode = CBC_BRANCH_IF_TRUE_FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_emit_cbc_forward_branch (context_p, (uint16_t) opcode, &cond_branch);
|
||||||
|
|
||||||
|
lexer_next_token (context_p);
|
||||||
|
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
||||||
|
parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &uncond_branch);
|
||||||
|
parser_set_branch_to_current_position (context_p, &cond_branch);
|
||||||
|
|
||||||
|
/* Although byte code is constructed for two branches,
|
||||||
|
* only one of them will be executed. To reflect this
|
||||||
|
* the stack is manually adjusted. */
|
||||||
|
JERRY_ASSERT (context_p->stack_depth > 0);
|
||||||
|
context_p->stack_depth--;
|
||||||
|
|
||||||
|
if (context_p->token.type != LEXER_COLON)
|
||||||
|
{
|
||||||
|
parser_raise_error (context_p, PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer_next_token (context_p);
|
||||||
|
|
||||||
|
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
||||||
|
parser_set_branch_to_current_position (context_p, &uncond_branch);
|
||||||
|
|
||||||
|
/* Last opcode rewrite is not allowed because
|
||||||
|
* the result may come from the first branch. */
|
||||||
|
parser_flush_cbc (context_p);
|
||||||
|
} /* parser_process_ternary_expression */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process expression sequence.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parser_process_expression_sequence (parser_context_t *context_p) /**< context */
|
||||||
|
{
|
||||||
|
if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
|
||||||
|
{
|
||||||
|
parser_emit_cbc (context_p, CBC_POP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context_p->stack_top_uint8 == LEXER_LEFT_PAREN)
|
||||||
|
{
|
||||||
|
parser_mem_page_t *page_p = context_p->stack.first_p;
|
||||||
|
|
||||||
|
JERRY_ASSERT (page_p != NULL);
|
||||||
|
|
||||||
|
page_p->bytes[context_p->stack.last_position - 1] = LEXER_COMMA_SEP_LIST;
|
||||||
|
context_p->stack_top_uint8 = LEXER_COMMA_SEP_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer_next_token (context_p);
|
||||||
|
} /* parser_process_expression_sequence */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process group expression.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parser_process_group_expression (parser_context_t *context_p, /**< context */
|
||||||
|
size_t *grouping_level_p) /**< grouping level */
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (*grouping_level_p > 0);
|
||||||
|
(*grouping_level_p)--;
|
||||||
|
|
||||||
|
if (context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST)
|
||||||
|
{
|
||||||
|
parser_push_result (context_p);
|
||||||
|
parser_flush_cbc (context_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_stack_pop_uint8 (context_p);
|
||||||
|
lexer_next_token (context_p);
|
||||||
|
} /* parser_process_group_expression */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse block expression.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parser_parse_block_expression (parser_context_t *context_p, /**< context */
|
||||||
|
int options) /**< option flags */
|
||||||
|
{
|
||||||
|
parser_parse_expression (context_p, options | PARSE_EXPR_NO_PUSH_RESULT);
|
||||||
|
|
||||||
|
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);
|
||||||
|
parser_flush_cbc (context_p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parser_emit_cbc (context_p, CBC_POP_BLOCK);
|
||||||
|
}
|
||||||
|
} /* parser_parse_block_expression */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse expression statement.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parser_parse_expression_statement (parser_context_t *context_p, /**< context */
|
||||||
|
int options) /**< option flags */
|
||||||
|
{
|
||||||
|
parser_parse_expression (context_p, options | PARSE_EXPR_NO_PUSH_RESULT);
|
||||||
|
|
||||||
|
if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
|
||||||
|
{
|
||||||
|
parser_emit_cbc (context_p, CBC_POP);
|
||||||
|
}
|
||||||
|
} /* parser_parse_expression_statement */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse expression.
|
* Parse expression.
|
||||||
*/
|
*/
|
||||||
@@ -2167,130 +2139,62 @@ parser_parse_expression (parser_context_t *context_p, /**< context */
|
|||||||
context_p->status_flags &= (uint32_t) ~PARSER_CLASS_SUPER_PROP_REFERENCE;
|
context_p->status_flags &= (uint32_t) ~PARSER_CLASS_SUPER_PROP_REFERENCE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (options & PARSE_EXPR_HAS_LITERAL)
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
|
||||||
|
goto process_unary_expression;
|
||||||
|
}
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (options & PARSE_EXPR_HAS_LITERAL)
|
parser_parse_unary_expression (context_p, &grouping_level);
|
||||||
{
|
|
||||||
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
|
|
||||||
/* True only for the first expression. */
|
|
||||||
options &= ~PARSE_EXPR_HAS_LITERAL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parser_parse_unary_expression (context_p, &grouping_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
process_unary_expression:
|
||||||
parser_process_unary_expression (context_p);
|
parser_process_unary_expression (context_p);
|
||||||
|
|
||||||
/* The engine flush binary opcodes above this precedence. */
|
uint8_t min_prec_treshold = 0;
|
||||||
uint8_t min_prec_treshold = CBC_MAXIMUM_BYTE_VALUE;
|
|
||||||
|
|
||||||
if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type))
|
if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type))
|
||||||
{
|
{
|
||||||
min_prec_treshold = parser_binary_precedence_table[context_p->token.type - LEXER_FIRST_BINARY_OP];
|
min_prec_treshold = parser_binary_precedence_table[context_p->token.type - LEXER_FIRST_BINARY_OP];
|
||||||
if (LEXER_IS_BINARY_LVALUE_TOKEN (context_p->token.type)
|
|
||||||
|| context_p->token.type == LEXER_LOGICAL_OR
|
/* Check for BINARY_LVALUE tokens + LEXER_LOGICAL_OR + LEXER_LOGICAL_AND */
|
||||||
|| context_p->token.type == LEXER_LOGICAL_AND)
|
if (min_prec_treshold <= PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE
|
||||||
|
&& min_prec_treshold != PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE)
|
||||||
{
|
{
|
||||||
/* Right-to-left evaluation order. */
|
/* Right-to-left evaluation order. */
|
||||||
min_prec_treshold++;
|
min_prec_treshold++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
min_prec_treshold = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
parser_process_binary_opcodes (context_p, min_prec_treshold);
|
parser_process_binary_opcodes (context_p, min_prec_treshold);
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_RIGHT_PAREN)
|
if (context_p->token.type == LEXER_RIGHT_PAREN
|
||||||
|
&& (context_p->stack_top_uint8 == LEXER_LEFT_PAREN
|
||||||
|
|| context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST))
|
||||||
{
|
{
|
||||||
if (context_p->stack_top_uint8 == LEXER_LEFT_PAREN
|
parser_process_group_expression (context_p, &grouping_level);
|
||||||
|| context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST)
|
continue;
|
||||||
{
|
|
||||||
JERRY_ASSERT (grouping_level > 0);
|
|
||||||
grouping_level--;
|
|
||||||
|
|
||||||
if (context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST)
|
|
||||||
{
|
|
||||||
parser_push_result (context_p);
|
|
||||||
parser_flush_cbc (context_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
parser_stack_pop_uint8 (context_p);
|
|
||||||
lexer_next_token (context_p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (context_p->token.type == LEXER_QUESTION_MARK)
|
|
||||||
|
if (context_p->token.type == LEXER_QUESTION_MARK)
|
||||||
{
|
{
|
||||||
cbc_opcode_t opcode = CBC_BRANCH_IF_FALSE_FORWARD;
|
parser_process_ternary_expression (context_p);
|
||||||
parser_branch_t cond_branch;
|
|
||||||
parser_branch_t uncond_branch;
|
|
||||||
|
|
||||||
parser_push_result (context_p);
|
|
||||||
|
|
||||||
if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT)
|
|
||||||
{
|
|
||||||
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
|
|
||||||
opcode = CBC_BRANCH_IF_TRUE_FORWARD;
|
|
||||||
}
|
|
||||||
|
|
||||||
parser_emit_cbc_forward_branch (context_p, (uint16_t) opcode, &cond_branch);
|
|
||||||
|
|
||||||
lexer_next_token (context_p);
|
|
||||||
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
|
||||||
parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &uncond_branch);
|
|
||||||
parser_set_branch_to_current_position (context_p, &cond_branch);
|
|
||||||
|
|
||||||
/* Although byte code is constructed for two branches,
|
|
||||||
* only one of them will be executed. To reflect this
|
|
||||||
* the stack is manually adjusted. */
|
|
||||||
JERRY_ASSERT (context_p->stack_depth > 0);
|
|
||||||
context_p->stack_depth--;
|
|
||||||
|
|
||||||
if (context_p->token.type != LEXER_COLON)
|
|
||||||
{
|
|
||||||
parser_raise_error (context_p, PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
lexer_next_token (context_p);
|
|
||||||
|
|
||||||
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
|
||||||
parser_set_branch_to_current_position (context_p, &uncond_branch);
|
|
||||||
|
|
||||||
/* Last opcode rewrite is not allowed because
|
|
||||||
* the result may come from the first branch. */
|
|
||||||
parser_flush_cbc (context_p);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_COMMA)
|
if (JERRY_UNLIKELY (context_p->token.type == LEXER_COMMA)
|
||||||
|
&& (!(options & PARSE_EXPR_NO_COMMA) || grouping_level > 0))
|
||||||
{
|
{
|
||||||
if (!(options & PARSE_EXPR_NO_COMMA) || grouping_level > 0)
|
parser_process_expression_sequence (context_p);
|
||||||
{
|
continue;
|
||||||
if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
|
|
||||||
{
|
|
||||||
parser_emit_cbc (context_p, CBC_POP);
|
|
||||||
}
|
|
||||||
if (context_p->stack_top_uint8 == LEXER_LEFT_PAREN)
|
|
||||||
{
|
|
||||||
parser_mem_page_t *page_p = context_p->stack.first_p;
|
|
||||||
|
|
||||||
JERRY_ASSERT (page_p != NULL);
|
|
||||||
|
|
||||||
page_p->bytes[context_p->stack.last_position - 1] = LEXER_COMMA_SEP_LIST;
|
|
||||||
context_p->stack_top_uint8 = LEXER_COMMA_SEP_LIST;
|
|
||||||
}
|
|
||||||
lexer_next_token (context_p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type))
|
|
||||||
|
if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type))
|
||||||
{
|
{
|
||||||
parser_append_binary_token (context_p);
|
parser_append_binary_token (context_p);
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
@@ -2307,27 +2211,7 @@ parser_parse_expression (parser_context_t *context_p, /**< context */
|
|||||||
JERRY_ASSERT (context_p->stack_top_uint8 == LEXER_EXPRESSION_START);
|
JERRY_ASSERT (context_p->stack_top_uint8 == LEXER_EXPRESSION_START);
|
||||||
parser_stack_pop_uint8 (context_p);
|
parser_stack_pop_uint8 (context_p);
|
||||||
|
|
||||||
if (options & PARSE_EXPR_STATEMENT)
|
if (!(options & PARSE_EXPR_NO_PUSH_RESULT))
|
||||||
{
|
|
||||||
if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
|
|
||||||
{
|
|
||||||
parser_emit_cbc (context_p, CBC_POP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (options & PARSE_EXPR_BLOCK)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
parser_flush_cbc (context_p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parser_emit_cbc (context_p, CBC_POP_BLOCK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
parser_push_result (context_p);
|
parser_push_result (context_p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,10 +97,9 @@ typedef enum
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PARSE_EXPR = 0, /**< parse an expression without any special flags */
|
PARSE_EXPR = 0, /**< parse an expression without any special flags */
|
||||||
PARSE_EXPR_STATEMENT = (1u << 0), /**< discard the result of the expression */
|
PARSE_EXPR_NO_PUSH_RESULT = (1u << 0), /**< do not push the result of the expression onto the stack */
|
||||||
PARSE_EXPR_BLOCK = (1u << 1), /**< copy the expression result into the block result */
|
PARSE_EXPR_NO_COMMA = (1u << 1), /**< do not parse comma operator */
|
||||||
PARSE_EXPR_NO_COMMA = (1u << 2), /**< do not parse comma operator */
|
PARSE_EXPR_HAS_LITERAL = (1u << 2), /**< a primary literal is provided by a
|
||||||
PARSE_EXPR_HAS_LITERAL = (1u << 3), /**< a primary literal is provided by a
|
|
||||||
* CBC_PUSH_LITERAL instruction */
|
* CBC_PUSH_LITERAL instruction */
|
||||||
} parser_expression_flags_t;
|
} parser_expression_flags_t;
|
||||||
|
|
||||||
@@ -195,6 +194,30 @@ typedef struct
|
|||||||
|| (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE) \
|
|| (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))
|
|| (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE))
|
||||||
|
|
||||||
|
#define PARSER_IS_MUTABLE_PUSH_LITERAL(opcode) \
|
||||||
|
((opcode) >= CBC_PUSH_LITERAL && (opcode) <= CBC_PUSH_THIS_LITERAL)
|
||||||
|
|
||||||
|
#define PARSER_IS_PUSH_LITERALS_WITH_THIS(opcode) \
|
||||||
|
((opcode) >= CBC_PUSH_LITERAL && (opcode) <= CBC_PUSH_THREE_LITERALS)
|
||||||
|
|
||||||
|
#define PARSER_IS_PUSH_PROP(opcode) \
|
||||||
|
((opcode) >= CBC_PUSH_PROP && (opcode) <= CBC_PUSH_PROP_THIS_LITERAL)
|
||||||
|
|
||||||
|
#define PARSER_IS_PUSH_PROP_LITERAL(opcode) \
|
||||||
|
((opcode) >= CBC_PUSH_PROP_LITERAL && (opcode) <= CBC_PUSH_PROP_THIS_LITERAL)
|
||||||
|
|
||||||
|
#define PARSER_PUSH_LITERAL_TO_PUSH_PROP_LITERAL(opcode) \
|
||||||
|
(uint16_t) ((opcode) + (CBC_PUSH_PROP_LITERAL - CBC_PUSH_LITERAL))
|
||||||
|
|
||||||
|
#define PARSER_PUSH_PROP_LITERAL_TO_PUSH_LITERAL(opcode) \
|
||||||
|
(uint16_t) ((opcode) - (CBC_PUSH_PROP_LITERAL - CBC_PUSH_LITERAL))
|
||||||
|
|
||||||
|
#define PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE(opcode) \
|
||||||
|
(uint16_t) ((opcode) + (CBC_PUSH_PROP_REFERENCE - CBC_PUSH_PROP))
|
||||||
|
|
||||||
|
#define PARSER_PUSH_PROP_REFERENCE_TO_PUSH_PROP(opcode) \
|
||||||
|
(uint16_t) ((opcode) - (CBC_PUSH_PROP_REFERENCE - CBC_PUSH_PROP))
|
||||||
|
|
||||||
#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)))
|
||||||
|
|
||||||
@@ -545,6 +568,8 @@ uint8_t lexer_convert_binary_lvalue_token_to_binary (uint8_t token);
|
|||||||
|
|
||||||
/* Parser functions. */
|
/* Parser functions. */
|
||||||
|
|
||||||
|
void parser_parse_block_expression (parser_context_t *context_p, int options);
|
||||||
|
void parser_parse_expression_statement (parser_context_t *context_p, int options);
|
||||||
void parser_parse_expression (parser_context_t *context_p, int options);
|
void parser_parse_expression (parser_context_t *context_p, int options);
|
||||||
#if ENABLED (JERRY_ES2015_CLASS)
|
#if ENABLED (JERRY_ES2015_CLASS)
|
||||||
void parser_parse_class (parser_context_t *context_p, bool is_statement);
|
void parser_parse_class (parser_context_t *context_p, bool is_statement);
|
||||||
|
|||||||
@@ -345,8 +345,7 @@ parser_parse_var_statement (parser_context_t *context_p) /**< context */
|
|||||||
#endif /* ENABLED (JERRY_LINE_INFO) */
|
#endif /* ENABLED (JERRY_LINE_INFO) */
|
||||||
|
|
||||||
parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
|
parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
|
||||||
parser_parse_expression (context_p,
|
parser_parse_expression_statement (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
|
||||||
PARSE_EXPR_STATEMENT | PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->token.type != LEXER_COMMA)
|
if (context_p->token.type != LEXER_COMMA)
|
||||||
@@ -981,8 +980,7 @@ parser_parse_for_statement_start (parser_context_t *context_p) /**< context */
|
|||||||
/* Initialiser is never executed. */
|
/* Initialiser is never executed. */
|
||||||
parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &branch);
|
parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &branch);
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
parser_parse_expression (context_p,
|
parser_parse_expression_statement (context_p, PARSE_EXPR_NO_COMMA);
|
||||||
PARSE_EXPR_STATEMENT | PARSE_EXPR_NO_COMMA);
|
|
||||||
parser_set_branch_to_current_position (context_p, &branch);
|
parser_set_branch_to_current_position (context_p, &branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1049,7 +1047,7 @@ parser_parse_for_statement_start (parser_context_t *context_p) /**< context */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parser_parse_expression (context_p, PARSE_EXPR_STATEMENT);
|
parser_parse_expression_statement (context_p, PARSE_EXPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->token.type != LEXER_SEMICOLON)
|
if (context_p->token.type != LEXER_SEMICOLON)
|
||||||
@@ -1081,7 +1079,7 @@ parser_parse_for_statement_start (parser_context_t *context_p) /**< context */
|
|||||||
}
|
}
|
||||||
|
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
parser_parse_expression (context_p, PARSE_EXPR_STATEMENT);
|
parser_parse_expression_statement (context_p, PARSE_EXPR);
|
||||||
|
|
||||||
JERRY_ASSERT (context_p->token.type != LEXER_RIGHT_PAREN);
|
JERRY_ASSERT (context_p->token.type != LEXER_RIGHT_PAREN);
|
||||||
parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
|
parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
|
||||||
@@ -1144,7 +1142,7 @@ parser_parse_for_statement_end (parser_context_t *context_p) /**< context */
|
|||||||
|
|
||||||
if (context_p->token.type != LEXER_RIGHT_PAREN)
|
if (context_p->token.type != LEXER_RIGHT_PAREN)
|
||||||
{
|
{
|
||||||
parser_parse_expression (context_p, PARSE_EXPR_STATEMENT);
|
parser_parse_expression_statement (context_p, PARSE_EXPR);
|
||||||
|
|
||||||
if (context_p->token.type != LEXER_RIGHT_PAREN)
|
if (context_p->token.type != LEXER_RIGHT_PAREN)
|
||||||
{
|
{
|
||||||
@@ -1979,8 +1977,7 @@ parser_parse_export_statement (parser_context_t *context_p) /**< context */
|
|||||||
/* Fake an assignment to the default identifier */
|
/* Fake an assignment to the default identifier */
|
||||||
context_p->token.type = LEXER_ASSIGN;
|
context_p->token.type = LEXER_ASSIGN;
|
||||||
|
|
||||||
parser_parse_expression (context_p,
|
parser_parse_expression_statement (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
|
||||||
PARSE_EXPR_STATEMENT | PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_string_t *name_p = ecma_new_ecma_string_from_utf8 (context_p->module_identifier_lit_p->u.char_p,
|
ecma_string_t *name_p = ecma_new_ecma_string_from_utf8 (context_p->module_identifier_lit_p->u.char_p,
|
||||||
@@ -2567,12 +2564,7 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
int options = PARSE_EXPR_BLOCK;
|
int options = PARSE_EXPR;
|
||||||
|
|
||||||
if (context_p->status_flags & PARSER_IS_FUNCTION)
|
|
||||||
{
|
|
||||||
options = PARSE_EXPR_STATEMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_EXPRESSION_START)
|
if (context_p->token.type == LEXER_EXPRESSION_START)
|
||||||
{
|
{
|
||||||
@@ -2581,7 +2573,15 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
|
|||||||
options |= PARSE_EXPR_HAS_LITERAL;
|
options |= PARSE_EXPR_HAS_LITERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_parse_expression (context_p, options);
|
if (context_p->status_flags & PARSER_IS_FUNCTION)
|
||||||
|
{
|
||||||
|
parser_parse_expression_statement (context_p, options);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parser_parse_block_expression (context_p, options);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2342,7 +2342,7 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
|
|||||||
parser_emit_cbc_forward_branch (context_p, CBC_BRANCH_IF_FALSE_FORWARD, &skip_init);
|
parser_emit_cbc_forward_branch (context_p, CBC_BRANCH_IF_FALSE_FORWARD, &skip_init);
|
||||||
|
|
||||||
parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
|
parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
|
||||||
parser_parse_expression (context_p, PARSE_EXPR_STATEMENT | PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
|
parser_parse_expression_statement (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
|
||||||
|
|
||||||
parser_set_branch_to_current_position (context_p, &skip_init);
|
parser_set_branch_to_current_position (context_p, &skip_init);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,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, 0x17, 0x00, 0x00, 0x00,
|
0x4A, 0x52, 0x52, 0x59, 0x18, 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