Add SyntaxErrors on parsing ObjectDeclarations.
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
/* Length-prefixed or "pascal" string. */
|
/* Length-prefixed or "pascal" string. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ecma_char_t *str;
|
const ecma_char_t *str;
|
||||||
ecma_length_t length;
|
ecma_length_t length;
|
||||||
}
|
}
|
||||||
lp_string;
|
lp_string;
|
||||||
|
|||||||
@@ -218,6 +218,11 @@ do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME,
|
|||||||
#define STACK_DECR_ELEMENT(NAME, I) \
|
#define STACK_DECR_ELEMENT(NAME, I) \
|
||||||
do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME, I) - 1)); } while (0)
|
do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME, I) - 1)); } while (0)
|
||||||
|
|
||||||
|
#define STACK_ITERATE(NAME, FUNC, FROM) \
|
||||||
|
do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \
|
||||||
|
FUNC (STACK_ELEMENT (NAME, i)); \
|
||||||
|
} } while (0)
|
||||||
|
|
||||||
#define STACK_ITERATE_VARG(NAME, FUNC, FROM, ...) \
|
#define STACK_ITERATE_VARG(NAME, FUNC, FROM, ...) \
|
||||||
do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \
|
do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \
|
||||||
FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__); \
|
FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__); \
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ add_current_token_to_string_cache (void)
|
|||||||
}
|
}
|
||||||
__strncpy ((char *) (strings_cache + strings_cache_used_size), token_start, res.length);
|
__strncpy ((char *) (strings_cache + strings_cache_used_size), token_start, res.length);
|
||||||
res.str = strings_cache + strings_cache_used_size;
|
res.str = strings_cache + strings_cache_used_size;
|
||||||
res.str[res.length] = '\0';
|
(strings_cache + strings_cache_used_size)[res.length] = '\0';
|
||||||
strings_cache_used_size = (size_t) (((size_t) res.length + 1) * sizeof (ecma_char_t) + strings_cache_used_size);
|
strings_cache_used_size = (size_t) (((size_t) res.length + 1) * sizeof (ecma_char_t) + strings_cache_used_size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -788,6 +788,7 @@ parse_number (void)
|
|||||||
c = LA (0);
|
c = LA (0);
|
||||||
if (is_fp && c == '.')
|
if (is_fp && c == '.')
|
||||||
{
|
{
|
||||||
|
FIXME (/* This is wrong: 1..toString (). */)
|
||||||
PARSE_ERROR ("Integer literal shall not contain more than one dot character", buffer - buffer_start);
|
PARSE_ERROR ("Integer literal shall not contain more than one dot character", buffer - buffer_start);
|
||||||
}
|
}
|
||||||
if (is_exp && (c == 'e' || c == 'E'))
|
if (is_exp && (c == 'e' || c == 'E'))
|
||||||
|
|||||||
+198
-90
@@ -50,6 +50,29 @@ typedef struct
|
|||||||
}
|
}
|
||||||
intrinsic_dumper;
|
intrinsic_dumper;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PROP_DATA,
|
||||||
|
PROP_SET,
|
||||||
|
PROP_GET,
|
||||||
|
VARG
|
||||||
|
}
|
||||||
|
prop_type;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
lp_string str;
|
||||||
|
bool was_num;
|
||||||
|
}
|
||||||
|
allocatable_string;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
prop_type type;
|
||||||
|
allocatable_string str;
|
||||||
|
}
|
||||||
|
prop_as_str_or_varg;
|
||||||
|
|
||||||
#define NESTING_ITERATIONAL 1
|
#define NESTING_ITERATIONAL 1
|
||||||
#define NESTING_SWITCH 2
|
#define NESTING_SWITCH 2
|
||||||
#define NESTING_FUNCTION 3
|
#define NESTING_FUNCTION 3
|
||||||
@@ -174,6 +197,18 @@ enum
|
|||||||
};
|
};
|
||||||
STATIC_STACK (rewritable_break, uint8_t, uint16_t)
|
STATIC_STACK (rewritable_break, uint8_t, uint16_t)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
strings_global_size
|
||||||
|
};
|
||||||
|
STATIC_STACK (strings, uint8_t, allocatable_string)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
props_global_size
|
||||||
|
};
|
||||||
|
STATIC_STACK (props, uint8_t, prop_as_str_or_varg)
|
||||||
|
|
||||||
#ifndef JERRY_NDEBUG
|
#ifndef JERRY_NDEBUG
|
||||||
#define STACK_CHECK_USAGE_LHS() \
|
#define STACK_CHECK_USAGE_LHS() \
|
||||||
JERRY_ASSERT (IDX.current == IDX_current + 1);
|
JERRY_ASSERT (IDX.current == IDX_current + 1);
|
||||||
@@ -684,6 +719,84 @@ name_to_native_call_id (idx_t obj)
|
|||||||
JERRY_UNREACHABLE ();
|
JERRY_UNREACHABLE ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_allocatable_string (prop_as_str_or_varg p)
|
||||||
|
{
|
||||||
|
if (p.str.was_num)
|
||||||
|
{
|
||||||
|
mem_heap_free_block ((uint8_t *) p.str.str.str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static allocatable_string
|
||||||
|
create_allocatable_string_from_num_uid (idx_t uid)
|
||||||
|
{
|
||||||
|
ecma_char_t *str = mem_heap_alloc_block (ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER * sizeof (ecma_char_t),
|
||||||
|
MEM_HEAP_ALLOC_SHORT_TERM);
|
||||||
|
ecma_number_to_zt_string (lexer_get_num_by_id (uid), str,
|
||||||
|
ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER * sizeof (ecma_char_t));
|
||||||
|
|
||||||
|
return (allocatable_string)
|
||||||
|
{
|
||||||
|
.was_num = true,
|
||||||
|
.str = (lp_string)
|
||||||
|
{
|
||||||
|
.length = ecma_zt_string_length (str),
|
||||||
|
.str = str
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static allocatable_string
|
||||||
|
create_allocatable_string_from_literal (idx_t uid)
|
||||||
|
{
|
||||||
|
return (allocatable_string)
|
||||||
|
{
|
||||||
|
.was_num = false,
|
||||||
|
.str = lexer_get_string_by_id (uid)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static allocatable_string
|
||||||
|
create_allocatable_string_from_small_int (idx_t uid)
|
||||||
|
{
|
||||||
|
const uint8_t chars_need = 4; /* Max is 255. */
|
||||||
|
uint8_t index = 0;
|
||||||
|
ecma_char_t *str = mem_heap_alloc_block (chars_need * sizeof (ecma_char_t),
|
||||||
|
MEM_HEAP_ALLOC_SHORT_TERM);
|
||||||
|
if (uid >= 100)
|
||||||
|
{
|
||||||
|
str[index++] = (ecma_char_t) (uid/100 + '0');
|
||||||
|
uid %= 100;
|
||||||
|
}
|
||||||
|
if (uid >= 10)
|
||||||
|
{
|
||||||
|
str[index++] = (ecma_char_t) (uid/10 + '0');
|
||||||
|
}
|
||||||
|
str[index++] = (ecma_char_t) (uid%10 + '0');
|
||||||
|
str[index] = ECMA_CHAR_NULL;
|
||||||
|
|
||||||
|
return (allocatable_string)
|
||||||
|
{
|
||||||
|
.was_num = true,
|
||||||
|
.str = (lp_string)
|
||||||
|
{
|
||||||
|
.length = index,
|
||||||
|
.str = str
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static prop_as_str_or_varg
|
||||||
|
create_prop_as_str_or_varg (allocatable_string str, prop_type type)
|
||||||
|
{
|
||||||
|
return (prop_as_str_or_varg)
|
||||||
|
{
|
||||||
|
.type = type,
|
||||||
|
.str = str
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/* property_name
|
/* property_name
|
||||||
: Identifier
|
: Identifier
|
||||||
| StringLiteral
|
| StringLiteral
|
||||||
@@ -701,18 +814,21 @@ parse_property_name (void)
|
|||||||
{
|
{
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, token_data ());
|
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_STRING, token_data ());
|
||||||
|
STACK_PUSH (strings, create_allocatable_string_from_literal (token_data ()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOK_NUMBER:
|
case TOK_NUMBER:
|
||||||
{
|
{
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_NUMBER, token_data ());
|
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_NUMBER, token_data ());
|
||||||
|
STACK_PUSH (strings, create_allocatable_string_from_num_uid (token_data ()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOK_SMALL_INT:
|
case TOK_SMALL_INT:
|
||||||
{
|
{
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_SMALLINT, token_data ());
|
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_SMALLINT, token_data ());
|
||||||
|
STACK_PUSH (strings, create_allocatable_string_from_small_int (token_data ()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -740,6 +856,9 @@ parse_property_name_and_value (void)
|
|||||||
|
|
||||||
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_VARG_PROP_DATA, STACK_HEAD(IDX, 2), STACK_HEAD(IDX, 1));
|
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_VARG_PROP_DATA, STACK_HEAD(IDX, 2), STACK_HEAD(IDX, 1));
|
||||||
|
|
||||||
|
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_DATA));
|
||||||
|
STACK_DROP (strings, 1);
|
||||||
|
|
||||||
STACK_DROP (IDX, 2);
|
STACK_DROP (IDX, 2);
|
||||||
STACK_CHECK_USAGE (IDX);
|
STACK_CHECK_USAGE (IDX);
|
||||||
}
|
}
|
||||||
@@ -793,6 +912,7 @@ parse_property_assignment (void)
|
|||||||
STACK_DECLARE_USAGE (U16)
|
STACK_DECLARE_USAGE (U16)
|
||||||
STACK_DECLARE_USAGE (toks)
|
STACK_DECLARE_USAGE (toks)
|
||||||
STACK_DECLARE_USAGE (U8)
|
STACK_DECLARE_USAGE (U8)
|
||||||
|
STACK_DECLARE_USAGE (strings)
|
||||||
|
|
||||||
if (!token_is (TOK_NAME))
|
if (!token_is (TOK_NAME))
|
||||||
{
|
{
|
||||||
@@ -814,6 +934,8 @@ parse_property_assignment (void)
|
|||||||
STACK_DROP (toks, 1);
|
STACK_DROP (toks, 1);
|
||||||
// name, lhs
|
// name, lhs
|
||||||
parse_property_name (); // push name
|
parse_property_name (); // push name
|
||||||
|
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_GET));
|
||||||
|
STACK_DROP (strings, 1);
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs
|
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs
|
||||||
@@ -859,6 +981,8 @@ parse_property_assignment (void)
|
|||||||
STACK_DROP (toks, 1);
|
STACK_DROP (toks, 1);
|
||||||
// name, lhs
|
// name, lhs
|
||||||
parse_property_name (); // push name
|
parse_property_name (); // push name
|
||||||
|
STACK_PUSH (props, create_prop_as_str_or_varg (STACK_TOP (strings), PROP_SET));
|
||||||
|
STACK_DROP (strings, 1);
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs
|
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs
|
||||||
@@ -895,6 +1019,7 @@ simple_prop:
|
|||||||
parse_property_name_and_value ();
|
parse_property_name_and_value ();
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
STACK_CHECK_USAGE (strings);
|
||||||
STACK_CHECK_USAGE (U8);
|
STACK_CHECK_USAGE (U8);
|
||||||
STACK_CHECK_USAGE (toks);
|
STACK_CHECK_USAGE (toks);
|
||||||
STACK_CHECK_USAGE (U16);
|
STACK_CHECK_USAGE (U16);
|
||||||
@@ -925,109 +1050,86 @@ check_for_eval_and_arguments_in_strict_mode (idx_t id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
/* 13.1, 15.3.2 */
|
||||||
find_assignment_to (opcode_counter_t from, idx_t tmp_id, opcode_t *res)
|
static void
|
||||||
|
check_for_syntax_errors_in_formal_param_list (uint8_t from)
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (res != NULL);
|
if (STACK_SIZE (props) - from < 2 || !parser_strict_mode ())
|
||||||
JERRY_ASSERT (tmp_id >= lexer_get_reserved_ids_count ());
|
|
||||||
for (opcode_counter_t oc = from; oc > 0; oc = (opcode_counter_t) (oc - 1))
|
|
||||||
{
|
{
|
||||||
*res = deserialize_opcode (oc);
|
return;
|
||||||
if (OPCODE_IS ((*res), assignment))
|
}
|
||||||
|
for (uint8_t i = (uint8_t) (from + 1); i < STACK_SIZE (props); i = (uint8_t) (i + 1))
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (STACK_ELEMENT (props, i).type == VARG);
|
||||||
|
for (uint8_t j = from; j < i; j = (uint8_t) (j + 1))
|
||||||
{
|
{
|
||||||
if (res->data.assignment.var_left == tmp_id)
|
if (lp_string_equal (STACK_ELEMENT (props, i).str.str, STACK_ELEMENT (props, j).str.str))
|
||||||
{
|
{
|
||||||
return true;
|
EMIT_ERROR_VARG ("Duplication of literal '%s' in FormalParameterList is not allowed in strict mode",
|
||||||
|
STACK_ELEMENT (props, j).str.str.str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 11.1.5 */
|
||||||
static void
|
static void
|
||||||
check_for_duplication_of_param (opcode_counter_t from, uint8_t metas_num)
|
check_for_syntax_errors_in_obj_decl (uint8_t from)
|
||||||
{
|
{
|
||||||
if (!parser_strict_mode () || metas_num < 2)
|
if (STACK_SIZE (props) - from < 2)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
STACK_DECLARE_USAGE (IDX);
|
for (uint8_t i = (uint8_t) (from + 1); i < STACK_SIZE (props); i = (uint8_t) (i + 1))
|
||||||
STACK_DECLARE_USAGE (U8);
|
|
||||||
STACK_DECLARE_USAGE (ops);
|
|
||||||
|
|
||||||
STACK_PUSH (U8, 0); // seen metas
|
|
||||||
STACK_PUSH (U8, STACK_SIZE (IDX));
|
|
||||||
|
|
||||||
for (opcode_counter_t oc = from; oc < OPCODE_COUNTER (); oc = (opcode_counter_t) (oc + 1))
|
|
||||||
{
|
{
|
||||||
STACK_PUSH (ops, deserialize_opcode (oc));
|
JERRY_ASSERT (STACK_ELEMENT (props, i).type == PROP_DATA
|
||||||
if (OPCODE_IS (STACK_TOP (ops), meta))
|
|| STACK_ELEMENT (props, i).type == PROP_GET
|
||||||
|
|| STACK_ELEMENT (props, i).type == PROP_SET);
|
||||||
|
for (uint8_t j = from; j < i; j = (uint8_t) (j + 1))
|
||||||
{
|
{
|
||||||
switch (STACK_TOP (ops).data.meta.type)
|
/*4*/
|
||||||
|
const lp_string previous = STACK_ELEMENT (props, j).str.str;
|
||||||
|
const prop_type prop_type_previous = STACK_ELEMENT (props, j).type;
|
||||||
|
const lp_string prop_id_desc = STACK_ELEMENT (props, i).str.str;
|
||||||
|
const prop_type prop_type_prop_id_desc = STACK_ELEMENT (props, i).type;
|
||||||
|
if (lp_string_equal (previous, prop_id_desc))
|
||||||
{
|
{
|
||||||
case OPCODE_META_TYPE_VARG:
|
/*a*/
|
||||||
|
if (parser_strict_mode () && prop_type_previous == PROP_DATA && prop_type_prop_id_desc == PROP_DATA)
|
||||||
{
|
{
|
||||||
for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (IDX); i = (uint8_t) (i + 1))
|
EMIT_ERROR_VARG ("Duplication of parameter name '%s' in ObjectDeclaration is not allowed in strict mode",
|
||||||
{
|
previous.str);
|
||||||
if (STACK_ELEMENT (IDX, i) == STACK_TOP (ops).data.meta.data_1)
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (STACK_ELEMENT (IDX, i) < lexer_get_strings_count ());
|
|
||||||
EMIT_ERROR ("Duplication of identifier as parameter is not allowed in strict mode.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
STACK_PUSH (IDX, STACK_TOP (ops).data.meta.data_1);
|
|
||||||
STACK_INCR_HEAD (U8, 2);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case OPCODE_META_TYPE_VARG_PROP_DATA:
|
/*b*/
|
||||||
|
if (prop_type_previous == PROP_DATA
|
||||||
|
&& (prop_type_prop_id_desc == PROP_SET || prop_type_prop_id_desc == PROP_GET))
|
||||||
{
|
{
|
||||||
opcode_t res;
|
EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor",
|
||||||
if (find_assignment_to (oc, STACK_TOP (ops).data.meta.data_1, &res))
|
previous.str);
|
||||||
{
|
|
||||||
for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (IDX); i = (uint8_t) (i + 1))
|
|
||||||
{
|
|
||||||
if (STACK_ELEMENT (IDX, i) == res.data.assignment.value_right)
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (STACK_ELEMENT (IDX, i) < lexer_get_strings_count ());
|
|
||||||
EMIT_ERROR ("Duplication of identifier as parameter is not allowed in strict mode.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
STACK_PUSH (IDX, res.data.assignment.value_right);
|
|
||||||
}
|
|
||||||
/* FALLTHRU. */
|
|
||||||
}
|
}
|
||||||
case OPCODE_META_TYPE_THIS_ARG:
|
/*c*/
|
||||||
case OPCODE_META_TYPE_VARG_PROP_GETTER:
|
if (prop_type_prop_id_desc == PROP_DATA
|
||||||
case OPCODE_META_TYPE_VARG_PROP_SETTER:
|
&& (prop_type_previous == PROP_SET || prop_type_previous == PROP_GET))
|
||||||
{
|
{
|
||||||
STACK_INCR_HEAD (U8, 2);
|
EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor",
|
||||||
break;
|
previous.str);
|
||||||
}
|
}
|
||||||
default:
|
/*d*/
|
||||||
|
if ((prop_type_previous == PROP_SET && prop_type_prop_id_desc == PROP_SET)
|
||||||
|
|| (prop_type_previous == PROP_GET && prop_type_prop_id_desc == PROP_GET))
|
||||||
{
|
{
|
||||||
break;
|
EMIT_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be accessor of same type",
|
||||||
|
previous.str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STACK_DROP (ops, 1);
|
|
||||||
if (STACK_HEAD (U8, 2) == metas_num)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STACK_DROP (IDX, STACK_SIZE (IDX) - STACK_TOP (U8));
|
|
||||||
STACK_DROP (U8, 2);
|
|
||||||
|
|
||||||
STACK_CHECK_USAGE (ops);
|
|
||||||
STACK_CHECK_USAGE (U8);
|
|
||||||
STACK_CHECK_USAGE (IDX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Parse list of identifiers, assigment expressions or properties, splitted by comma.
|
/** Parse list of identifiers, assigment expressions or properties, splitted by comma.
|
||||||
For each ALT dumps appropriate bytecode. Uses OBJ during dump if neccesary.
|
For each ALT dumps appropriate bytecode. Uses OBJ during dump if neccesary.
|
||||||
Returns temp var if expression has lhs, or 0 otherwise. */
|
Returns number of arguments. */
|
||||||
static uint8_t
|
static uint8_t
|
||||||
parse_argument_list (argument_list_type alt, idx_t obj)
|
parse_argument_list (argument_list_type alt, idx_t obj)
|
||||||
{
|
{
|
||||||
@@ -1038,38 +1140,35 @@ parse_argument_list (argument_list_type alt, idx_t obj)
|
|||||||
STACK_DECLARE_USAGE (U16)
|
STACK_DECLARE_USAGE (U16)
|
||||||
STACK_DECLARE_USAGE (IDX)
|
STACK_DECLARE_USAGE (IDX)
|
||||||
STACK_DECLARE_USAGE (temp_names)
|
STACK_DECLARE_USAGE (temp_names)
|
||||||
uint8_t args_num = 0;
|
STACK_DECLARE_USAGE (props)
|
||||||
|
|
||||||
|
STACK_PUSH (U8, STACK_SIZE (props));
|
||||||
|
STACK_PUSH (U8, TOK_OPEN_PAREN);
|
||||||
|
STACK_PUSH (U8, TOK_CLOSE_PAREN);
|
||||||
|
STACK_PUSH (U8, 0);
|
||||||
|
|
||||||
STACK_PUSH (U16, OPCODE_COUNTER ());
|
STACK_PUSH (U16, OPCODE_COUNTER ());
|
||||||
switch (alt)
|
switch (alt)
|
||||||
{
|
{
|
||||||
case AL_FUNC_DECL:
|
case AL_FUNC_DECL:
|
||||||
{
|
{
|
||||||
STACK_PUSH (U8, TOK_OPEN_PAREN); // Openning token;
|
|
||||||
STACK_PUSH (U8, TOK_CLOSE_PAREN); // Ending token;
|
|
||||||
DUMP_OPCODE_2 (func_decl_n, obj, INVALID_VALUE);
|
DUMP_OPCODE_2 (func_decl_n, obj, INVALID_VALUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AL_FUNC_EXPR:
|
case AL_FUNC_EXPR:
|
||||||
{
|
{
|
||||||
STACK_PUSH (U8, TOK_OPEN_PAREN);
|
|
||||||
STACK_PUSH (U8, TOK_CLOSE_PAREN);
|
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
DUMP_OPCODE_3 (func_expr_n, ID(1), obj, INVALID_VALUE);
|
DUMP_OPCODE_3 (func_expr_n, ID(1), obj, INVALID_VALUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AL_CONSTRUCT_EXPR:
|
case AL_CONSTRUCT_EXPR:
|
||||||
{
|
{
|
||||||
STACK_PUSH (U8, TOK_OPEN_PAREN);
|
|
||||||
STACK_PUSH (U8, TOK_CLOSE_PAREN);
|
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
DUMP_OPCODE_3 (construct_n, ID(1), obj, INVALID_VALUE);
|
DUMP_OPCODE_3 (construct_n, ID(1), obj, INVALID_VALUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AL_CALL_EXPR:
|
case AL_CALL_EXPR:
|
||||||
{
|
{
|
||||||
STACK_PUSH (U8, TOK_OPEN_PAREN);
|
|
||||||
STACK_PUSH (U8, TOK_CLOSE_PAREN);
|
|
||||||
if (is_intrinsic (obj))
|
if (is_intrinsic (obj))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -1089,16 +1188,16 @@ parse_argument_list (argument_list_type alt, idx_t obj)
|
|||||||
}
|
}
|
||||||
case AL_ARRAY_DECL:
|
case AL_ARRAY_DECL:
|
||||||
{
|
{
|
||||||
STACK_PUSH (U8, TOK_OPEN_SQUARE);
|
STACK_SET_HEAD (U8, 3, TOK_OPEN_SQUARE);
|
||||||
STACK_PUSH (U8, TOK_CLOSE_SQUARE);
|
STACK_SET_HEAD (U8, 2, TOK_CLOSE_SQUARE);
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
DUMP_OPCODE_2 (array_decl, ID(1), INVALID_VALUE);
|
DUMP_OPCODE_2 (array_decl, ID(1), INVALID_VALUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AL_OBJ_DECL:
|
case AL_OBJ_DECL:
|
||||||
{
|
{
|
||||||
STACK_PUSH (U8, TOK_OPEN_BRACE);
|
STACK_SET_HEAD (U8, 3, TOK_OPEN_BRACE);
|
||||||
STACK_PUSH (U8, TOK_CLOSE_BRACE);
|
STACK_SET_HEAD (U8, 2, TOK_CLOSE_BRACE);
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
DUMP_OPCODE_2 (obj_decl, ID(1), INVALID_VALUE);
|
DUMP_OPCODE_2 (obj_decl, ID(1), INVALID_VALUE);
|
||||||
break;
|
break;
|
||||||
@@ -1109,8 +1208,6 @@ parse_argument_list (argument_list_type alt, idx_t obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STACK_PUSH (U8, 0);
|
|
||||||
|
|
||||||
current_token_must_be (STACK_HEAD (U8, 3));
|
current_token_must_be (STACK_HEAD (U8, 3));
|
||||||
|
|
||||||
switch (alt)
|
switch (alt)
|
||||||
@@ -1140,6 +1237,9 @@ parse_argument_list (argument_list_type alt, idx_t obj)
|
|||||||
{
|
{
|
||||||
current_token_must_be (TOK_NAME);
|
current_token_must_be (TOK_NAME);
|
||||||
STACK_PUSH (IDX, token_data ());
|
STACK_PUSH (IDX, token_data ());
|
||||||
|
STACK_PUSH (props,
|
||||||
|
create_prop_as_str_or_varg (create_allocatable_string_from_literal (token_data ()),
|
||||||
|
VARG));
|
||||||
check_for_eval_and_arguments_in_strict_mode (STACK_TOP (IDX));
|
check_for_eval_and_arguments_in_strict_mode (STACK_TOP (IDX));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1206,13 +1306,13 @@ next:
|
|||||||
{
|
{
|
||||||
case AL_FUNC_DECL:
|
case AL_FUNC_DECL:
|
||||||
{
|
{
|
||||||
check_for_duplication_of_param (STACK_TOP (U16), STACK_TOP (U8));
|
check_for_syntax_errors_in_formal_param_list (STACK_HEAD (U8, 4));
|
||||||
REWRITE_OPCODE_2 (STACK_TOP (U16), func_decl_n, obj, STACK_TOP (U8));
|
REWRITE_OPCODE_2 (STACK_TOP (U16), func_decl_n, obj, STACK_TOP (U8));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AL_FUNC_EXPR:
|
case AL_FUNC_EXPR:
|
||||||
{
|
{
|
||||||
check_for_duplication_of_param (STACK_TOP (U16), STACK_TOP (U8));
|
check_for_syntax_errors_in_formal_param_list (STACK_HEAD (U8, 4));
|
||||||
REWRITE_OPCODE_3 (STACK_TOP (U16), func_expr_n, ID(1), obj, STACK_TOP (U8));
|
REWRITE_OPCODE_3 (STACK_TOP (U16), func_expr_n, ID(1), obj, STACK_TOP (U8));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1246,7 +1346,7 @@ next:
|
|||||||
}
|
}
|
||||||
case AL_OBJ_DECL:
|
case AL_OBJ_DECL:
|
||||||
{
|
{
|
||||||
check_for_duplication_of_param (STACK_TOP (U16), STACK_TOP (U8));
|
check_for_syntax_errors_in_obj_decl (STACK_HEAD (U8, 4));
|
||||||
REWRITE_OPCODE_2 (STACK_TOP (U16), obj_decl, ID(1), STACK_TOP (U8));
|
REWRITE_OPCODE_2 (STACK_TOP (U16), obj_decl, ID(1), STACK_TOP (U8));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1256,11 +1356,15 @@ next:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
args_num = STACK_TOP (U8);
|
const uint8_t args_num = STACK_TOP (U8);
|
||||||
|
|
||||||
STACK_DROP (U8, 3);
|
STACK_ITERATE (props, free_allocatable_string, STACK_HEAD (U8, 4));
|
||||||
|
|
||||||
|
STACK_DROP (props, (uint8_t) (STACK_SIZE (props) - STACK_HEAD (U8, 4)));
|
||||||
|
STACK_DROP (U8, 4);
|
||||||
STACK_DROP (U16, 1);
|
STACK_DROP (U16, 1);
|
||||||
|
|
||||||
|
STACK_CHECK_USAGE (props);
|
||||||
STACK_CHECK_USAGE (U8);
|
STACK_CHECK_USAGE (U8);
|
||||||
STACK_CHECK_USAGE (U16);
|
STACK_CHECK_USAGE (U16);
|
||||||
STACK_CHECK_USAGE (temp_names);
|
STACK_CHECK_USAGE (temp_names);
|
||||||
@@ -4006,6 +4110,8 @@ parser_init (const char *source, size_t source_size, bool show_opcodes)
|
|||||||
STACK_INIT (rewritable_break);
|
STACK_INIT (rewritable_break);
|
||||||
STACK_INIT (locs);
|
STACK_INIT (locs);
|
||||||
STACK_INIT (scopes);
|
STACK_INIT (scopes);
|
||||||
|
STACK_INIT (props);
|
||||||
|
STACK_INIT (strings);
|
||||||
|
|
||||||
HASH_INIT (intrinsics, 1);
|
HASH_INIT (intrinsics, 1);
|
||||||
|
|
||||||
@@ -4066,6 +4172,8 @@ parser_free (void)
|
|||||||
STACK_FREE (rewritable_break);
|
STACK_FREE (rewritable_break);
|
||||||
STACK_FREE (locs);
|
STACK_FREE (locs);
|
||||||
STACK_FREE (scopes);
|
STACK_FREE (scopes);
|
||||||
|
STACK_FREE (props);
|
||||||
|
STACK_FREE (strings);
|
||||||
|
|
||||||
HASH_FREE (intrinsics);
|
HASH_FREE (intrinsics);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2014 Samsung Electronics Co., Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
var a = {a:1, get a() {return 1}}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2014 Samsung Electronics Co., Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
var a = {get a() {return undefined}, get a() {return undefined}}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2014 Samsung Electronics Co., Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
var a = {get a(){return undefined}, set a(b){}}
|
||||||
|
|
||||||
|
// var b = {if:0, else:1, try:2, catch:3, finally:4}
|
||||||
Reference in New Issue
Block a user