Merge branch 'geppetto'

This commit is contained in:
Ilmir Usmanov
2014-08-11 23:18:06 +04:00
5 changed files with 1734 additions and 1174 deletions
+86 -86
View File
@@ -36,114 +36,114 @@ OPCODE;
typedef ecma_completion_value_t (*opfunc)(OPCODE, struct __int_data *); typedef ecma_completion_value_t (*opfunc)(OPCODE, struct __int_data *);
#define OP_CALLS_AND_ARGS(op) \ #define OP_CALLS_AND_ARGS(op) \
op(call_0) \ op (call_0) \
op(call_1) \ op (call_1) \
op(call_n) \ op (call_n) \
op(construct_0) \ op (construct_0) \
op(construct_1) \ op (construct_1) \
op(construct_n) \ op (construct_n) \
op(func_decl_0) \ op (func_decl_0) \
op(func_decl_1) \ op (func_decl_1) \
op(func_decl_2) \ op (func_decl_2) \
op(func_decl_n) \ op (func_decl_n) \
op(func_expr_0) \ op (func_expr_0) \
op(func_expr_1) \ op (func_expr_1) \
op(func_expr_n) \ op (func_expr_n) \
op(varg_1_end) \ op (varg_1_end) \
op(varg_2_end) \ op (varg_2_end) \
op(varg_3) \ op (varg_3) \
op(varg_3_end) \ op (varg_3_end) \
op(exitval) \ op (exitval) \
op(retval) \ op (retval) \
op(ret) op (ret)
#define OP_INITS(op) \ #define OP_INITS(op) \
op(array_0) \ op (array_0) \
op(array_1) \ op (array_1) \
op(array_2) \ op (array_2) \
op(array_n) \ op (array_n) \
op(prop) \ op (prop) \
op(prop_access) \ op (prop_access) \
op(prop_get_decl) \ op (prop_get_decl) \
op(prop_set_decl) \ op (prop_set_decl) \
op(obj_0) \ op (obj_0) \
op(obj_1) \ op (obj_1) \
op(obj_2) \ op (obj_2) \
op(obj_n) \ op (obj_n) \
op(this) \ op (this) \
op(delete) \ op (delete) \
op(typeof) \ op (typeof) \
op(with) \ op (with) \
op(end_with) op (end_with)
#define OP_ASSIGNMENTS(op) \ #define OP_ASSIGNMENTS(op) \
op(assignment) op (assignment)
#define OP_B_SHIFTS(op) \ #define OP_B_SHIFTS(op) \
op(b_shift_left) \ op (b_shift_left) \
op(b_shift_right) \ op (b_shift_right) \
op(b_shift_uright) op (b_shift_uright)
#define OP_B_BITWISE(op) \ #define OP_B_BITWISE(op) \
op(b_and) \ op (b_and) \
op(b_or) \ op (b_or) \
op(b_xor) \ op (b_xor) \
op(b_not) op (b_not)
#define OP_B_LOGICAL(op) \ #define OP_B_LOGICAL(op) \
op(logical_and) \ op (logical_and) \
op(logical_or) \ op (logical_or) \
op(logical_not) op (logical_not)
#define OP_EQUALITY(op) \ #define OP_EQUALITY(op) \
op(equal_value) \ op (equal_value) \
op(not_equal_value) \ op (not_equal_value) \
op(equal_value_type) \ op (equal_value_type) \
op(not_equal_value_type) op (not_equal_value_type)
#define OP_RELATIONAL(op) \ #define OP_RELATIONAL(op) \
op(less_than) \ op (less_than) \
op(greater_than) \ op (greater_than) \
op(less_or_equal_than) \ op (less_or_equal_than) \
op(greater_or_equal_than) \ op (greater_or_equal_than) \
op(instanceof) \ op (instanceof) \
op(in) op (in)
#define OP_ARITHMETIC(op) \ #define OP_ARITHMETIC(op) \
op(post_incr) \ op (post_incr) \
op(post_decr) \ op (post_decr) \
op(pre_incr) \ op (pre_incr) \
op(pre_decr) \ op (pre_decr) \
op(addition) \ op (addition) \
op(substraction) \ op (substraction) \
op(division) \ op (division) \
op(multiplication) \ op (multiplication) \
op(remainder) op (remainder)
#define OP_UNCONDITIONAL_JUMPS(op) \ #define OP_UNCONDITIONAL_JUMPS(op) \
op(jmp) \ op (jmp) \
op(jmp_up) \ op (jmp_up) \
op(jmp_down) \ op (jmp_down) \
op(nop) op (nop)
#define OP_UNARY_OPS(op) \ #define OP_UNARY_OPS(op) \
op(is_true_jmp) \ op (is_true_jmp) \
op(is_false_jmp) op (is_false_jmp)
#define OP_LIST(op) \ #define OP_LIST(op) \
OP_CALLS_AND_ARGS(op) \ OP_CALLS_AND_ARGS (op) \
OP_INITS(op) \ OP_INITS (op) \
OP_ASSIGNMENTS(op) \ OP_ASSIGNMENTS (op) \
OP_B_LOGICAL(op) \ OP_B_LOGICAL (op) \
OP_B_BITWISE(op) \ OP_B_BITWISE (op) \
OP_B_SHIFTS(op) \ OP_B_SHIFTS (op) \
OP_EQUALITY(op) \ OP_EQUALITY (op) \
OP_RELATIONAL(op) \ OP_RELATIONAL (op) \
OP_ARITHMETIC(op) \ OP_ARITHMETIC (op) \
OP_UNCONDITIONAL_JUMPS(op) \ OP_UNCONDITIONAL_JUMPS (op) \
OP_UNARY_OPS(op) \ OP_UNARY_OPS (op) \
op(var_decl) \ op (var_decl) \
op(reg_var_decl) op (reg_var_decl)
#include "opcode-structures.h" #include "opcode-structures.h"
+487 -62
View File
@@ -57,7 +57,9 @@ static char
get_char (size_t i) get_char (size_t i)
{ {
if ((buffer + i) >= (buffer_start + buffer_size)) if ((buffer + i) >= (buffer_start + buffer_size))
{
return '\0'; return '\0';
}
return *(buffer + i); return *(buffer + i);
} }
@@ -73,7 +75,7 @@ increase_strings_cache (void)
char *new_cache; char *new_cache;
size_t new_cache_size; size_t new_cache_size;
// if strings_cache_size == 0, allocator recommend minimum size that is more than 0 // if strings_cache_size == 0, allocator recommends minimum size that is more than 0
new_cache_size = mem_heap_recommend_allocation_size (strings_cache_size * 2); new_cache_size = mem_heap_recommend_allocation_size (strings_cache_size * 2);
new_cache = (char *) mem_heap_alloc_block (new_cache_size, MEM_HEAP_ALLOC_SHORT_TERM); new_cache = (char *) mem_heap_alloc_block (new_cache_size, MEM_HEAP_ALLOC_SHORT_TERM);
@@ -84,8 +86,10 @@ increase_strings_cache (void)
new_cache = (char *) mem_heap_alloc_block (new_cache_size, MEM_HEAP_ALLOC_SHORT_TERM); new_cache = (char *) mem_heap_alloc_block (new_cache_size, MEM_HEAP_ALLOC_SHORT_TERM);
if (!new_cache) if (!new_cache)
{
parser_fatal (ERR_MEMORY); parser_fatal (ERR_MEMORY);
} }
}
if (strings_cache) if (strings_cache)
{ {
@@ -104,12 +108,16 @@ dump_current_line (void)
const char *i; const char *i;
if (!allow_dump_lines) if (!allow_dump_lines)
{
return; return;
}
__printf ("// "); __printf ("// ");
for (i = buffer; *i != '\n' && *i != 0; i++) for (i = buffer; *i != '\n' && *i != 0; i++)
{
__putchar (*i); __putchar (*i);
}
__putchar ('\n'); __putchar ('\n');
} }
#endif #endif
@@ -118,9 +126,13 @@ static bool
current_token_equals_to (const char *str) current_token_equals_to (const char *str)
{ {
if (__strlen (str) != (size_t) (buffer - token_start)) if (__strlen (str) != (size_t) (buffer - token_start))
{
return false; return false;
}
if (!__strncmp (str, token_start, (size_t) (buffer - token_start))) if (!__strncmp (str, token_start, (size_t) (buffer - token_start)))
{
return true; return true;
}
return false; return false;
} }
@@ -131,95 +143,365 @@ static token
decode_keyword (void) decode_keyword (void)
{ {
if (current_token_equals_to ("break")) if (current_token_equals_to ("break"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_BREAK }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_BREAK
};
}
if (current_token_equals_to ("case")) if (current_token_equals_to ("case"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_CASE }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_CASE
};
}
if (current_token_equals_to ("catch")) if (current_token_equals_to ("catch"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_CATCH }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_CATCH
};
}
if (current_token_equals_to ("class")) if (current_token_equals_to ("class"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("const")) if (current_token_equals_to ("const"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("continue")) if (current_token_equals_to ("continue"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_CONTINUE }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_CONTINUE
};
}
if (current_token_equals_to ("debugger")) if (current_token_equals_to ("debugger"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_DEBUGGER }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_DEBUGGER
};
}
if (current_token_equals_to ("default")) if (current_token_equals_to ("default"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_DEFAULT }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_DEFAULT
};
}
if (current_token_equals_to ("delete")) if (current_token_equals_to ("delete"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_DELETE }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_DELETE
};
}
if (current_token_equals_to ("do")) if (current_token_equals_to ("do"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_DO }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_DO
};
}
if (current_token_equals_to ("else")) if (current_token_equals_to ("else"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_ELSE }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_ELSE
};
}
if (current_token_equals_to ("enum")) if (current_token_equals_to ("enum"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("export")) if (current_token_equals_to ("export"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("extends")) if (current_token_equals_to ("extends"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("false")) if (current_token_equals_to ("false"))
return (token) { .type = TOK_BOOL, .data.uid = false }; {
return (token)
{
.type = TOK_BOOL,
.data.uid = false
};
}
if (current_token_equals_to ("finally")) if (current_token_equals_to ("finally"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_FINALLY }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_FINALLY
};
}
if (current_token_equals_to ("for")) if (current_token_equals_to ("for"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_FOR }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_FOR
};
}
if (current_token_equals_to ("function")) if (current_token_equals_to ("function"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_FUNCTION }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_FUNCTION
};
}
if (current_token_equals_to ("if")) if (current_token_equals_to ("if"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_IF }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_IF
};
}
if (current_token_equals_to ("instanceof")) if (current_token_equals_to ("instanceof"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_INSTANCEOF }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_INSTANCEOF
};
}
if (current_token_equals_to ("interface")) if (current_token_equals_to ("interface"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("in")) if (current_token_equals_to ("in"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_IN }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_IN
};
}
if (current_token_equals_to ("import")) if (current_token_equals_to ("import"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("implements")) if (current_token_equals_to ("implements"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("let")) if (current_token_equals_to ("let"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("new")) if (current_token_equals_to ("new"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_NEW }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_NEW
};
}
if (current_token_equals_to ("null")) if (current_token_equals_to ("null"))
return (token) { .type = TOK_NULL, .data.uid = 0 }; {
return (token)
{
.type = TOK_NULL,
.data.uid = 0
};
}
if (current_token_equals_to ("package")) if (current_token_equals_to ("package"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("private")) if (current_token_equals_to ("private"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("protected")) if (current_token_equals_to ("protected"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("public")) if (current_token_equals_to ("public"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("return")) if (current_token_equals_to ("return"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RETURN }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RETURN
};
}
if (current_token_equals_to ("static")) if (current_token_equals_to ("static"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("super")) if (current_token_equals_to ("super"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
if (current_token_equals_to ("switch")) if (current_token_equals_to ("switch"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_SWITCH }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_SWITCH
};
}
if (current_token_equals_to ("this")) if (current_token_equals_to ("this"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_THIS }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_THIS
};
}
if (current_token_equals_to ("throw")) if (current_token_equals_to ("throw"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_THROW }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_THROW
};
}
if (current_token_equals_to ("true")) if (current_token_equals_to ("true"))
return (token) { .type = TOK_BOOL, .data.uid = true }; {
return (token)
{
.type = TOK_BOOL,
.data.uid = true
};
}
if (current_token_equals_to ("try")) if (current_token_equals_to ("try"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_TRY }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_TRY
};
}
if (current_token_equals_to ("typeof")) if (current_token_equals_to ("typeof"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_TYPEOF }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_TYPEOF
};
}
if (current_token_equals_to ("var")) if (current_token_equals_to ("var"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_VAR }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_VAR
};
}
if (current_token_equals_to ("void")) if (current_token_equals_to ("void"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_VOID }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_VOID
};
}
if (current_token_equals_to ("while")) if (current_token_equals_to ("while"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_WHILE }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_WHILE
};
}
if (current_token_equals_to ("with")) if (current_token_equals_to ("with"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_WITH }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_WITH
};
}
if (current_token_equals_to ("yield")) if (current_token_equals_to ("yield"))
return (token) { .type = TOK_KEYWORD, .data.kw = KW_RESERVED }; {
return (token)
{
.type = TOK_KEYWORD,
.data.kw = KW_RESERVED
};
}
return empty_token; return empty_token;
} }
@@ -235,7 +517,11 @@ convert_seen_name_to_token (token_type tt, const char *string)
if ((string == NULL && current_token_equals_to (current_string)) if ((string == NULL && current_token_equals_to (current_string))
|| (string != NULL && !__strcmp (current_string, string))) || (string != NULL && !__strcmp (current_string, string)))
{ {
return (token) { .type = tt, .data.uid = i }; return (token)
{
.type = tt,
.data.uid = i
};
} }
current_string += __strlen (current_string) + 1; current_string += __strlen (current_string) + 1;
@@ -254,7 +540,9 @@ add_token_to_seen_names (token_type tt, const char *string)
// Go to unused memory of cache // Go to unused memory of cache
for (i = 0; i < seen_names_count; i++) for (i = 0; i < seen_names_count; i++)
{
current_string += __strlen (current_string) + 1; current_string += __strlen (current_string) + 1;
}
required_size = (size_t) (current_string - strings_cache) + len + 1; required_size = (size_t) (current_string - strings_cache) + len + 1;
if (required_size > strings_cache_size) if (required_size > strings_cache_size)
@@ -278,7 +566,11 @@ add_token_to_seen_names (token_type tt, const char *string)
__memcpy (current_string, string, __strlen (string) + 1); __memcpy (current_string, string, __strlen (string) + 1);
} }
return (token) { .type = tt, .data.uid = seen_names_count++ }; return (token)
{
.type = tt,
.data.uid = seen_names_count++
};
} }
static token static token
@@ -289,8 +581,10 @@ convert_seen_num_to_token (int num)
for (i = 0; i < seen_nums_count; i++) for (i = 0; i < seen_nums_count; i++)
{ {
if (seen_nums[i].num == num) if (seen_nums[i].num == num)
{
return seen_nums[i].tok; return seen_nums[i].tok;
} }
}
return empty_token; return empty_token;
} }
@@ -334,7 +628,9 @@ lexer_get_string_by_id (uint8_t id)
JERRY_ASSERT (id < seen_names_count); JERRY_ASSERT (id < seen_names_count);
for (i = 0 ; i < id; i++) for (i = 0 ; i < id; i++)
{
current_string += __strlen (current_string) + 1; current_string += __strlen (current_string) + 1;
}
return current_string; return current_string;
} }
@@ -345,10 +641,14 @@ lexer_get_nums (int32_t *nums)
int i; int i;
if (!nums) if (!nums)
{
return seen_nums_count; return seen_nums_count;
}
for (i = 0; i < seen_nums_count; i++) for (i = 0; i < seen_nums_count; i++)
{
nums[i] = seen_nums[i].num; nums[i] = seen_nums[i].num;
}
return seen_nums_count; return seen_nums_count;
} }
@@ -359,7 +659,9 @@ lexer_adjust_num_ids (void)
size_t i; size_t i;
for (i = 0; i < seen_nums_count; i++) for (i = 0; i < seen_nums_count; i++)
{
seen_nums[i].tok.data.uid = (uint8_t) (seen_nums[i].tok.data.uid + seen_names_count); seen_nums[i].tok.data.uid = (uint8_t) (seen_nums[i].tok.data.uid + seen_names_count);
}
} }
static void static void
@@ -380,7 +682,11 @@ consume_char (void)
do \ do \
{ \ { \
buffer += NUM; \ buffer += NUM; \
return (token) { .type = TOK, .data.uid = 0 }; \ return (token) \
{ \
.type = TOK, \
.data.uid = 0 \
}; \
} \ } \
while (0) while (0)
@@ -390,10 +696,14 @@ consume_char (void)
do \ do \
{ \ { \
if (LA (NUM) == CHAR) \ if (LA (NUM) == CHAR) \
{ \
RETURN_PUNC_EX (THEN_TOK, NUM + 1); \ RETURN_PUNC_EX (THEN_TOK, NUM + 1); \
} \
else \ else \
{ \
RETURN_PUNC_EX (ELSE_TOK, NUM); \ RETURN_PUNC_EX (ELSE_TOK, NUM); \
} \ } \
} \
while (0) while (0)
#define IF_LA_IS(CHAR, THEN_TOK, ELSE_TOK) \ #define IF_LA_IS(CHAR, THEN_TOK, ELSE_TOK) \
@@ -403,12 +713,18 @@ consume_char (void)
do \ do \
{ \ { \
if (LA (1) == CHAR1) \ if (LA (1) == CHAR1) \
{ \
RETURN_PUNC_EX (THEN1_TOK, 2); \ RETURN_PUNC_EX (THEN1_TOK, 2); \
} \
else if (LA (1) == CHAR2) \ else if (LA (1) == CHAR2) \
{ \
RETURN_PUNC_EX (THEN2_TOK, 2); \ RETURN_PUNC_EX (THEN2_TOK, 2); \
} \
else \ else \
{ \
RETURN_PUNC (ELSE_TOK); \ RETURN_PUNC (ELSE_TOK); \
} \ } \
} \
while (0) while (0)
static token static token
@@ -426,11 +742,17 @@ parse_name (void)
{ {
c = LA (0); c = LA (0);
if (c == '\0') if (c == '\0')
{
break; break;
}
if (!__isalpha (c) && !__isdigit (c) && c != '$' && c != '_') if (!__isalpha (c) && !__isdigit (c) && c != '$' && c != '_')
{
break; break;
}
if (every_char_islower && (!__islower (c))) if (every_char_islower && (!__islower (c)))
{
every_char_islower = false; every_char_islower = false;
}
consume_char (); consume_char ();
} }
@@ -438,12 +760,16 @@ parse_name (void)
{ {
known_token = decode_keyword (); known_token = decode_keyword ();
if (!is_empty (known_token)) if (!is_empty (known_token))
{
goto end; goto end;
} }
}
known_token = convert_seen_name_to_token (TOK_NAME, NULL); known_token = convert_seen_name_to_token (TOK_NAME, NULL);
if (!is_empty (known_token)) if (!is_empty (known_token))
{
goto end; goto end;
}
known_token = add_token_to_seen_names (TOK_NAME, NULL); known_token = add_token_to_seen_names (TOK_NAME, NULL);
@@ -499,8 +825,12 @@ parse_number (void)
JERRY_ASSERT (__isdigit (c) || c == '.'); JERRY_ASSERT (__isdigit (c) || c == '.');
if (c == '0') if (c == '0')
{
if (LA (1) == 'x' || LA (1) == 'X') if (LA (1) == 'x' || LA (1) == 'X')
{
is_hex = true; is_hex = true;
}
}
if (c == '.') if (c == '.')
{ {
@@ -518,26 +848,40 @@ parse_number (void)
{ {
c = LA (0); c = LA (0);
if (!__isxdigit (c)) if (!__isxdigit (c))
{
break; break;
}
consume_char (); consume_char ();
} }
if (__isalpha (c) || c == '_' || c == '$') if (__isalpha (c) || c == '_' || c == '$')
{
parser_fatal (ERR_INT_LITERAL); parser_fatal (ERR_INT_LITERAL);
}
tok_length = (size_t) (buffer - token_start); tok_length = (size_t) (buffer - token_start);
// OK, I know that integer overflow can occur here // OK, I know that integer overflow can occur here
for (i = 0; i < tok_length; i++) for (i = 0; i < tok_length; i++)
{
res = (res << 4) + hex_to_int (token_start[i]); res = (res << 4) + hex_to_int (token_start[i]);
}
token_start = NULL; token_start = NULL;
known_token = convert_seen_num_to_token (res); known_token = convert_seen_num_to_token (res);
if (!is_empty (known_token)) if (!is_empty (known_token))
{
return known_token; return known_token;
}
known_token = (token) { .type = TOK_INT, .data.uid = seen_nums_count }; known_token = (token)
add_num_to_seen_tokens ((num_and_token) { .num = res, .tok = known_token }); {
.type = TOK_INT, .data.uid = seen_nums_count
};
add_num_to_seen_tokens ((num_and_token)
{
.num = res, .tok = known_token
});
return known_token; return known_token;
} }
@@ -547,20 +891,28 @@ parse_number (void)
// Eat up '.' // Eat up '.'
if (is_fp) if (is_fp)
{
consume_char (); consume_char ();
}
while (true) while (true)
{ {
c = LA (0); c = LA (0);
if (is_fp && c == '.') if (is_fp && c == '.')
{
parser_fatal (ERR_INT_LITERAL); parser_fatal (ERR_INT_LITERAL);
}
if (is_exp && (c == 'e' || c == 'E')) if (is_exp && (c == 'e' || c == 'E'))
{
parser_fatal (ERR_INT_LITERAL); parser_fatal (ERR_INT_LITERAL);
}
if (c == '.') if (c == '.')
{ {
if (__isalpha (LA (1)) || LA (1) == '_' || LA (1) == '$') if (__isalpha (LA (1)) || LA (1) == '_' || LA (1) == '$')
{
parser_fatal (ERR_INT_LITERAL); parser_fatal (ERR_INT_LITERAL);
}
is_fp = true; is_fp = true;
consume_char (); consume_char ();
continue; continue;
@@ -569,19 +921,27 @@ parse_number (void)
if (c == 'e' || c == 'E') if (c == 'e' || c == 'E')
{ {
if (LA (1) == '-' || LA (1) == '+') if (LA (1) == '-' || LA (1) == '+')
{
consume_char (); consume_char ();
}
if (!__isdigit (LA (1))) if (!__isdigit (LA (1)))
{
parser_fatal (ERR_INT_LITERAL); parser_fatal (ERR_INT_LITERAL);
}
is_exp = true; is_exp = true;
consume_char (); consume_char ();
continue; continue;
} }
if (__isalpha (c) || c == '_' || c == '$') if (__isalpha (c) || c == '_' || c == '$')
{
parser_fatal (ERR_INT_LITERAL); parser_fatal (ERR_INT_LITERAL);
}
if (!__isdigit (c)) if (!__isdigit (c))
{
break; break;
}
consume_char (); consume_char ();
} }
@@ -596,16 +956,26 @@ parse_number (void)
tok_length = (size_t) (buffer - token_start);; tok_length = (size_t) (buffer - token_start);;
for (i = 0; i < tok_length; i++) for (i = 0; i < tok_length; i++)
{
res = res * 10 + hex_to_int (token_start[i]); res = res * 10 + hex_to_int (token_start[i]);
}
token_start = NULL; token_start = NULL;
known_token = convert_seen_num_to_token (res); known_token = convert_seen_num_to_token (res);
if (!is_empty (known_token)) if (!is_empty (known_token))
{
return known_token; return known_token;
}
known_token = (token) { .type = TOK_INT, .data.uid = seen_nums_count }; known_token = (token)
add_num_to_seen_tokens ((num_and_token) { .num = res, .tok = known_token }); {
.type = TOK_INT, .data.uid = seen_nums_count
};
add_num_to_seen_tokens ((num_and_token)
{
.num = res, .tok = known_token
});
return known_token; return known_token;
} }
@@ -650,14 +1020,20 @@ parse_string (void)
{ {
c = LA (0); c = LA (0);
if (c == '\0') if (c == '\0')
{
parser_fatal (ERR_UNCLOSED); parser_fatal (ERR_UNCLOSED);
}
if (c == '\n') if (c == '\n')
{
parser_fatal (ERR_STRING); parser_fatal (ERR_STRING);
}
if (c == '\\') if (c == '\\')
{ {
/* Only single escape character is allowed. */ /* Only single escape character is allowed. */
if (LA (1) == 'x' || LA (1) == 'u' || __isdigit (LA (1))) if (LA (1) == 'x' || LA (1) == 'u' || __isdigit (LA (1)))
{
parser_fatal (ERR_STRING); parser_fatal (ERR_STRING);
}
if ((LA (1) == '\'' && !is_double_quoted) if ((LA (1) == '\'' && !is_double_quoted)
|| (LA (1) == '"' && is_double_quoted) || (LA (1) == '"' && is_double_quoted)
|| LA (1) == '\n') || LA (1) == '\n')
@@ -669,7 +1045,9 @@ parse_string (void)
} }
else if ((c == '\'' && !is_double_quoted) else if ((c == '\'' && !is_double_quoted)
|| (c == '"' && is_double_quoted)) || (c == '"' && is_double_quoted))
{
break; break;
}
consume_char (); consume_char ();
} }
@@ -704,7 +1082,9 @@ parse_string (void)
known_token = convert_seen_name_to_token (TOK_STRING, tok); known_token = convert_seen_name_to_token (TOK_STRING, tok);
if (!is_empty (known_token)) if (!is_empty (known_token))
{
goto end; goto end;
}
known_token = add_token_to_seen_names (TOK_STRING, tok); known_token = add_token_to_seen_names (TOK_STRING, tok);
@@ -734,9 +1114,9 @@ lexer_set_source (const char * source)
} }
static void static void
lexer_rewind( void) lexer_rewind (void)
{ {
JERRY_ASSERT( buffer_start != NULL ); JERRY_ASSERT (buffer_start != NULL);
buffer = buffer_start; buffer = buffer_start;
} }
@@ -760,20 +1140,30 @@ replace_comment_by_newline (void)
{ {
c = LA (0); c = LA (0);
if (!multiline && (c == '\n' || c == '\0')) if (!multiline && (c == '\n' || c == '\0'))
{
return false; return false;
}
if (multiline && c == '*' && LA (1) == '/') if (multiline && c == '*' && LA (1) == '/')
{ {
consume_char (); consume_char ();
consume_char (); consume_char ();
if (was_newlines) if (was_newlines)
{
return true; return true;
}
else else
{
return false; return false;
} }
}
if (multiline && c == '\n') if (multiline && c == '\n')
{
was_newlines = true; was_newlines = true;
}
if (multiline && c == '\0') if (multiline && c == '\0')
{
parser_fatal (ERR_UNCLOSED); parser_fatal (ERR_UNCLOSED);
}
consume_char (); consume_char ();
} }
} }
@@ -793,22 +1183,38 @@ lexer_next_token_private (void)
JERRY_ASSERT (token_start == NULL); JERRY_ASSERT (token_start == NULL);
if (__isalpha (c) || c == '$' || c == '_') if (__isalpha (c) || c == '$' || c == '_')
{
return parse_name (); return parse_name ();
}
if (__isdigit (c) || (c == '.' && __isdigit (LA (1)))) if (__isdigit (c) || (c == '.' && __isdigit (LA (1))))
{
return parse_number (); return parse_number ();
}
if (c == '\n') if (c == '\n')
{ {
consume_char (); consume_char ();
return (token) { .type = TOK_NEWLINE, .data.uid = 0 }; return (token)
{
.type = TOK_NEWLINE,
.data.uid = 0
};
} }
if (c == '\0') if (c == '\0')
return (token) { .type = TOK_EOF, .data.uid = 0 };; {
return (token)
{
.type = TOK_EOF,
.data.uid = 0
};
}
if (c == '\'' || c == '"') if (c == '\'' || c == '"')
{
return parse_string (); return parse_string ();
}
if (__isspace (c)) if (__isspace (c))
{ {
@@ -819,10 +1225,18 @@ lexer_next_token_private (void)
if (c == '/' && LA (1) == '*') if (c == '/' && LA (1) == '*')
{ {
if (replace_comment_by_newline ()) if (replace_comment_by_newline ())
return (token) { .type = TOK_NEWLINE, .data.uid = 0 }; {
return (token)
{
.type = TOK_NEWLINE,
.data.uid = 0
};
}
else else
{
return lexer_next_token_private (); return lexer_next_token_private ();
} }
}
if (c == '/' && LA (1) == '/') if (c == '/' && LA (1) == '/')
{ {
@@ -879,18 +1293,25 @@ lexer_next_token_private (void)
case '=': case '=':
if (LA (1) == '=') if (LA (1) == '=')
{
IF_LA_N_IS ('=', TOK_TRIPLE_EQ, TOK_DOUBLE_EQ, 2); IF_LA_N_IS ('=', TOK_TRIPLE_EQ, TOK_DOUBLE_EQ, 2);
}
else else
{
RETURN_PUNC (TOK_EQ); RETURN_PUNC (TOK_EQ);
}
case '!': case '!':
if (LA (1) == '=') if (LA (1) == '=')
{
IF_LA_N_IS ('=', TOK_NOT_DOUBLE_EQ, TOK_NOT_EQ, 2); IF_LA_N_IS ('=', TOK_NOT_DOUBLE_EQ, TOK_NOT_EQ, 2);
}
else else
{
RETURN_PUNC (TOK_NOT); RETURN_PUNC (TOK_NOT);
}
default: default: JERRY_UNREACHABLE ();
JERRY_UNREACHABLE ();
} }
parser_fatal (ERR_NON_CHAR); parser_fatal (ERR_NON_CHAR);
} }
@@ -900,7 +1321,9 @@ lexer_next_token (void)
{ {
#ifdef __TARGET_HOST_x64 #ifdef __TARGET_HOST_x64
if (buffer == buffer_start) if (buffer == buffer_start)
{
dump_current_line (); dump_current_line ();
}
#endif /* __TARGET_HOST_x64 */ #endif /* __TARGET_HOST_x64 */
token tok = lexer_next_token_private (); token tok = lexer_next_token_private ();
@@ -938,13 +1361,15 @@ lexer_init (const char *source, size_t source_size, bool show_opcodes)
} }
void void
lexer_run_first_pass( void) lexer_run_first_pass (void)
{ {
token tok = lexer_next_token (); token tok = lexer_next_token ();
while (tok.type != TOK_EOF) while (tok.type != TOK_EOF)
{
tok = lexer_next_token (); tok = lexer_next_token ();
}
lexer_rewind(); lexer_rewind ();
} }
void void
+2 -2
View File
@@ -147,9 +147,9 @@ typedef struct
} __packed } __packed
token; token;
void lexer_init(const char *, size_t, bool); void lexer_init (const char *, size_t, bool);
void lexer_free (void); void lexer_free (void);
void lexer_run_first_pass( void); void lexer_run_first_pass (void);
token lexer_next_token (void); token lexer_next_token (void);
void lexer_save_token (token); void lexer_save_token (token);
void lexer_dump_buffer_state (void); void lexer_dump_buffer_state (void);
+118 -18
View File
@@ -88,7 +88,9 @@ static void
reset_temp_name (void) reset_temp_name (void)
{ {
if (max_temp_name < temp_name) if (max_temp_name < temp_name)
{
max_temp_name = temp_name; max_temp_name = temp_name;
}
temp_name = min_temp_name; temp_name = min_temp_name;
} }
@@ -115,20 +117,26 @@ must_be_inside_but_not_in (uint8_t inside[], uint8_t insides_count, uint8_t not_
int8_t i; int8_t i;
if (nestings_head == 0) if (nestings_head == 0)
{
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
}
for (i = (int8_t) (nestings_head - 1); i >= 0; i--) for (i = (int8_t) (nestings_head - 1); i >= 0; i--)
{ {
int8_t j; int8_t j;
if (nestings[i] == not_in) if (nestings[i] == not_in)
{
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
}
for (j = 0; j < insides_count; j++) for (j = 0; j < insides_count; j++)
{ {
if (nestings[i] == inside[j]) if (nestings[i] == inside[j])
{
return; return;
} }
} }
}
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
} }
@@ -168,7 +176,9 @@ skip_newlines (void)
{ {
tok = lexer_next_token (); tok = lexer_next_token ();
while (tok.type == TOK_NEWLINE) while (tok.type == TOK_NEWLINE)
{
tok = lexer_next_token (); tok = lexer_next_token ();
}
} }
static void static void
@@ -189,7 +199,9 @@ token_after_newlines_must_be (token_type tt)
{ {
skip_newlines (); skip_newlines ();
if (tok.type != tt) if (tok.type != tt)
{
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
}
} }
static inline void static inline void
@@ -197,7 +209,9 @@ token_after_newlines_must_be_keyword (keyword kw)
{ {
skip_newlines (); skip_newlines ();
if (!is_keyword (kw)) if (!is_keyword (kw))
{
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
}
} }
#if 0 #if 0
@@ -206,7 +220,9 @@ insert_semicolon (void)
{ {
tok = lexer_next_token (); tok = lexer_next_token ();
if (tok.type != TOK_NEWLINE && tok.type != TOK_SEMICOLON) if (tok.type != TOK_NEWLINE && tok.type != TOK_SEMICOLON)
{
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
}
} }
#endif #endif
@@ -483,7 +499,9 @@ parse_property_assignment (void)
return lhs; return lhs;
} }
else else
{
return parse_property_name_and_value (); return parse_property_name_and_value ();
}
} }
static void static void
@@ -636,7 +654,9 @@ parse_argument_list (argument_list_type alt, T_IDX obj)
} }
} }
else else
{
dump_varg_3 (current_arg, args); dump_varg_3 (current_arg, args);
}
switch (alt) switch (alt)
{ {
@@ -733,11 +753,15 @@ parse_argument_list (argument_list_type alt, T_IDX obj)
} }
} }
else else
{
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
} }
}
else else
{
dump_varg_end (current_arg, args); dump_varg_end (current_arg, args);
} }
}
else else
{ {
switch (alt) switch (alt)
@@ -825,7 +849,9 @@ parse_function_expression (void)
skip_newlines (); skip_newlines ();
if (tok.type == TOK_NAME) if (tok.type == TOK_NAME)
{
name = tok.data.uid; name = tok.data.uid;
}
else else
{ {
lexer_save_token (tok); lexer_save_token (tok);
@@ -924,14 +950,22 @@ parse_primary_expression (void)
return lhs; return lhs;
} }
else if (tok.type == TOK_NAME) else if (tok.type == TOK_NAME)
{
return tok.data.uid; return tok.data.uid;
}
else if (tok.type == TOK_NULL || tok.type == TOK_BOOL else if (tok.type == TOK_NULL || tok.type == TOK_BOOL
|| tok.type == TOK_INT || tok.type == TOK_STRING) || tok.type == TOK_INT || tok.type == TOK_STRING)
{
return parse_literal (); return parse_literal ();
}
else if (tok.type == TOK_OPEN_SQUARE) else if (tok.type == TOK_OPEN_SQUARE)
{
return parse_array_literal (); return parse_array_literal ();
}
else if (tok.type == TOK_OPEN_BRACE) else if (tok.type == TOK_OPEN_BRACE)
{
return parse_object_literal (); return parse_object_literal ();
}
else if (tok.type == TOK_OPEN_PAREN) else if (tok.type == TOK_OPEN_PAREN)
{ {
skip_newlines (); skip_newlines ();
@@ -1001,11 +1035,15 @@ parse_member_expression (void)
{ {
skip_newlines (); skip_newlines ();
if (tok.type != TOK_NAME) if (tok.type != TOK_NAME)
{
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
}
prop = tok.data.uid; prop = tok.data.uid;
} }
else else
{
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
}
DUMP_OPCODE_3 (prop_access, lhs, obj, prop); DUMP_OPCODE_3 (prop_access, lhs, obj, prop);
obj = lhs; obj = lhs;
@@ -1115,7 +1153,9 @@ parse_postfix_expression (void)
DUMP_OPCODE_2 (post_decr, lhs, expr); DUMP_OPCODE_2 (post_decr, lhs, expr);
} }
else else
{
lexer_save_token (tok); lexer_save_token (tok);
}
return expr; return expr;
} }
@@ -1176,7 +1216,9 @@ parse_unary_expression (void)
return lhs; return lhs;
} }
if (is_keyword (KW_VOID)) if (is_keyword (KW_VOID))
{
JERRY_UNIMPLEMENTED (); JERRY_UNIMPLEMENTED ();
}
if (is_keyword (KW_TYPEOF)) if (is_keyword (KW_TYPEOF))
{ {
lhs = next_temp_name (); lhs = next_temp_name ();
@@ -1213,9 +1255,12 @@ parse_multiplicative_expression (void)
{ {
switch (tok.type) switch (tok.type)
{ {
case TOK_MULT: DUMP_OF (multiplication, unary_expression) case TOK_MULT:
case TOK_DIV: DUMP_OF (division, unary_expression) DUMP_OF (multiplication, unary_expression)
case TOK_MOD: DUMP_OF (remainder, unary_expression) case TOK_DIV:
DUMP_OF (division, unary_expression)
case TOK_MOD:
DUMP_OF (remainder, unary_expression)
default: default:
lexer_save_token (tok); lexer_save_token (tok);
@@ -1241,8 +1286,10 @@ parse_additive_expression (void)
{ {
switch (tok.type) switch (tok.type)
{ {
case TOK_PLUS: DUMP_OF (addition, multiplicative_expression); case TOK_PLUS:
case TOK_MINUS: DUMP_OF (substraction, multiplicative_expression); DUMP_OF (addition, multiplicative_expression);
case TOK_MINUS:
DUMP_OF (substraction, multiplicative_expression);
default: default:
lexer_save_token (tok); lexer_save_token (tok);
@@ -1268,9 +1315,12 @@ parse_shift_expression (void)
{ {
switch (tok.type) switch (tok.type)
{ {
case TOK_LSHIFT: DUMP_OF (b_shift_left, additive_expression) case TOK_LSHIFT:
case TOK_RSHIFT: DUMP_OF (b_shift_right, additive_expression) DUMP_OF (b_shift_left, additive_expression)
case TOK_RSHIFT_EX: DUMP_OF (b_shift_uright, additive_expression) case TOK_RSHIFT:
DUMP_OF (b_shift_right, additive_expression)
case TOK_RSHIFT_EX:
DUMP_OF (b_shift_uright, additive_expression)
default: default:
lexer_save_token (tok); lexer_save_token (tok);
@@ -1296,10 +1346,14 @@ parse_relational_expression (void)
{ {
switch (tok.type) switch (tok.type)
{ {
case TOK_LESS: DUMP_OF (less_than, shift_expression) case TOK_LESS:
case TOK_GREATER: DUMP_OF (greater_than, shift_expression) DUMP_OF (less_than, shift_expression)
case TOK_LESS_EQ: DUMP_OF (less_or_equal_than, shift_expression) case TOK_GREATER:
case TOK_GREATER_EQ: DUMP_OF (greater_or_equal_than, shift_expression) DUMP_OF (greater_than, shift_expression)
case TOK_LESS_EQ:
DUMP_OF (less_or_equal_than, shift_expression)
case TOK_GREATER_EQ:
DUMP_OF (greater_or_equal_than, shift_expression)
case TOK_KEYWORD: case TOK_KEYWORD:
if (is_keyword (KW_INSTANCEOF)) if (is_keyword (KW_INSTANCEOF))
{ {
@@ -1335,10 +1389,14 @@ parse_equality_expression (void)
{ {
switch (tok.type) switch (tok.type)
{ {
case TOK_DOUBLE_EQ: DUMP_OF (equal_value, relational_expression) case TOK_DOUBLE_EQ:
case TOK_NOT_EQ: DUMP_OF (not_equal_value, relational_expression) DUMP_OF (equal_value, relational_expression)
case TOK_TRIPLE_EQ: DUMP_OF (equal_value_type, relational_expression) case TOK_NOT_EQ:
case TOK_NOT_DOUBLE_EQ: DUMP_OF (not_equal_value_type, relational_expression) DUMP_OF (not_equal_value, relational_expression)
case TOK_TRIPLE_EQ:
DUMP_OF (equal_value_type, relational_expression)
case TOK_NOT_DOUBLE_EQ:
DUMP_OF (not_equal_value_type, relational_expression)
default: default:
lexer_save_token (tok); lexer_save_token (tok);
@@ -1529,7 +1587,9 @@ parse_expression (void)
{ {
skip_newlines (); skip_newlines ();
if (tok.type == TOK_COMMA) if (tok.type == TOK_COMMA)
{
NEXT (expr, assignment_expression); NEXT (expr, assignment_expression);
}
else else
{ {
lexer_save_token (tok); lexer_save_token (tok);
@@ -1560,7 +1620,9 @@ parse_variable_declaration (void)
DUMP_OPCODE_3 (assignment, name, OPCODE_ARG_TYPE_VARIABLE, expr); DUMP_OPCODE_3 (assignment, name, OPCODE_ARG_TYPE_VARIABLE, expr);
} }
else else
{
lexer_save_token (tok); lexer_save_token (tok);
}
} }
/* variable_declaration_list /* variable_declaration_list
@@ -1583,8 +1645,10 @@ parse_variable_declaration_list (bool *several_decls)
skip_newlines (); skip_newlines ();
if (several_decls) if (several_decls)
{
*several_decls = true; *several_decls = true;
} }
}
} }
/* for_statement /* for_statement
@@ -1618,7 +1682,9 @@ parse_for_or_for_in_statement (void)
skip_newlines (); skip_newlines ();
if (tok.type == TOK_SEMICOLON) if (tok.type == TOK_SEMICOLON)
{
goto plain_for; goto plain_for;
}
/* Both for_statement_initialiser_part and for_in_statement_initialiser_part /* Both for_statement_initialiser_part and for_in_statement_initialiser_part
contains 'var'. Check it first. */ contains 'var'. Check it first. */
if (is_keyword (KW_VAR)) if (is_keyword (KW_VAR))
@@ -1635,24 +1701,36 @@ parse_for_or_for_in_statement (void)
{ {
skip_newlines (); skip_newlines ();
if (tok.type == TOK_SEMICOLON) if (tok.type == TOK_SEMICOLON)
{
goto plain_for; goto plain_for;
}
else if (is_keyword (KW_IN)) else if (is_keyword (KW_IN))
{
goto for_in; goto for_in;
}
else else
{
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
} }
} }
}
/* expression contains left_hand_side_expression. */ /* expression contains left_hand_side_expression. */
parse_expression (); parse_expression ();
skip_newlines (); skip_newlines ();
if (tok.type == TOK_SEMICOLON) if (tok.type == TOK_SEMICOLON)
{
goto plain_for; goto plain_for;
}
else if (is_keyword (KW_IN)) else if (is_keyword (KW_IN))
{
goto for_in; goto for_in;
}
else else
{
parser_fatal (ERR_PARSER); parser_fatal (ERR_PARSER);
}
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
@@ -1692,7 +1770,9 @@ plain_for:
next_token_must_be (TOK_SEMICOLON); next_token_must_be (TOK_SEMICOLON);
} }
else else
{
stop = integer_one (); stop = integer_one ();
}
end_oc = opcode_counter; end_oc = opcode_counter;
DUMP_OPCODE_2 (is_false_jmp, stop, INVALID_VALUE); DUMP_OPCODE_2 (is_false_jmp, stop, INVALID_VALUE);
@@ -1786,7 +1866,9 @@ parse_if_statement (void)
parse_statement (); parse_statement ();
} }
else else
{
lexer_save_token (tok); lexer_save_token (tok);
}
} }
/* do_while_statement /* do_while_statement
@@ -2002,7 +2084,10 @@ parse_statement (void)
} }
if (is_keyword (KW_CONTINUE)) if (is_keyword (KW_CONTINUE))
{ {
must_be_inside_but_not_in ((uint8_t[]){NESTING_ITERATIONAL, NESTING_SWITCH}, 2, must_be_inside_but_not_in ((uint8_t[])
{
NESTING_ITERATIONAL, NESTING_SWITCH
}, 2,
NESTING_FUNCTION); NESTING_FUNCTION);
add_to_rewritable_opcodes (REWRITABLE_CONTINUE, opcode_counter); add_to_rewritable_opcodes (REWRITABLE_CONTINUE, opcode_counter);
DUMP_OPCODE_1 (jmp_up, INVALID_VALUE); DUMP_OPCODE_1 (jmp_up, INVALID_VALUE);
@@ -2010,7 +2095,10 @@ parse_statement (void)
} }
if (is_keyword (KW_BREAK)) if (is_keyword (KW_BREAK))
{ {
must_be_inside_but_not_in ((uint8_t[]){NESTING_ITERATIONAL, NESTING_SWITCH}, 2, must_be_inside_but_not_in ((uint8_t[])
{
NESTING_ITERATIONAL, NESTING_SWITCH
}, 2,
NESTING_FUNCTION); NESTING_FUNCTION);
add_to_rewritable_opcodes (REWRITABLE_BREAK, opcode_counter); add_to_rewritable_opcodes (REWRITABLE_BREAK, opcode_counter);
DUMP_OPCODE_1 (jmp_down, INVALID_VALUE); DUMP_OPCODE_1 (jmp_down, INVALID_VALUE);
@@ -2026,7 +2114,9 @@ parse_statement (void)
DUMP_OPCODE_1 (retval, expr); DUMP_OPCODE_1 (retval, expr);
} }
else else
{
DUMP_VOID_OPCODE (ret); DUMP_VOID_OPCODE (ret);
}
return; return;
} }
if (is_keyword (KW_WITH)) if (is_keyword (KW_WITH))
@@ -2080,9 +2170,13 @@ static void
parse_source_element (void) parse_source_element (void)
{ {
if (is_keyword (KW_FUNCTION)) if (is_keyword (KW_FUNCTION))
{
parse_function_declaration (); parse_function_declaration ();
}
else else
{
parse_statement (); parse_statement ();
}
} }
/* source_element_list /* source_element_list
@@ -2104,11 +2198,17 @@ parse_source_element_list (void)
} }
lexer_save_token (tok); lexer_save_token (tok);
if (max_temp_name > min_temp_name) if (max_temp_name > min_temp_name)
{
REWRITE_OPCODE_2 (reg_var_decl_loc, reg_var_decl, min_temp_name, max_temp_name - 1); REWRITE_OPCODE_2 (reg_var_decl_loc, reg_var_decl, min_temp_name, max_temp_name - 1);
}
else if (max_temp_name == min_temp_name) else if (max_temp_name == min_temp_name)
{
REWRITE_OPCODE_2 (reg_var_decl_loc, reg_var_decl, min_temp_name, max_temp_name); REWRITE_OPCODE_2 (reg_var_decl_loc, reg_var_decl, min_temp_name, max_temp_name);
}
else else
{
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
}
finish_scope (); finish_scope ();
optimizer_reorder_scope ((uint16_t) (reg_var_decl_loc + 1), opcode_counter); optimizer_reorder_scope ((uint16_t) (reg_var_decl_loc + 1), opcode_counter);
} }
+35
View File
@@ -0,0 +1,35 @@
// 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 i = 0;
for (; i < 100; i++) {}
assert (i == 100);
for (var j = 0; j < 100; j++) {}
assert (i == 100);
// for (i = 0;;) {
// if (i == 100) {
// // break;
// // assert (0);
// }
// i++;
// }
assert (i == 100);
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {}
}
assert (i == 100);
assert (j == 100);