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