Fix parsing of for-loops.
This commit is contained in:
@@ -371,47 +371,6 @@ OP_CODE_DECL_VOID (ret)
|
|||||||
|
|
||||||
OP_CODE_DECL_VOID (nop)
|
OP_CODE_DECL_VOID (nop)
|
||||||
|
|
||||||
// LOOPS
|
|
||||||
// Lately, all loops should be translated into different JMPs in an optimizer.
|
|
||||||
|
|
||||||
/** End of body of infinite loop should be ended with unconditional JMP
|
|
||||||
* to loop_root (ie. next op after loop condition) */
|
|
||||||
OP_CODE_DECL (loop_inf, T_IDX,
|
|
||||||
loop_root)
|
|
||||||
|
|
||||||
/** Numeric loop initialization.
|
|
||||||
* for (start,stop,step)
|
|
||||||
*/
|
|
||||||
OP_CODE_DECL (loop_init_num, T_IDX_IDX_IDX,
|
|
||||||
start,
|
|
||||||
stop,
|
|
||||||
step)
|
|
||||||
|
|
||||||
/** Check loop (condition).
|
|
||||||
* if (loop cond is true)
|
|
||||||
* { next_op }
|
|
||||||
* else
|
|
||||||
* { goto after_loop_op; }
|
|
||||||
*/
|
|
||||||
OP_CODE_DECL (loop_precond_begin_num, T_IDX_IDX,
|
|
||||||
condition,
|
|
||||||
after_loop_op)
|
|
||||||
|
|
||||||
/** i++;
|
|
||||||
* Increment iterator on step and JMP to PRECOND
|
|
||||||
*/
|
|
||||||
OP_CODE_DECL (loop_precond_end_num, T_IDX_IDX_IDX,
|
|
||||||
iterator,
|
|
||||||
step,
|
|
||||||
precond_begin)
|
|
||||||
|
|
||||||
/** do {...} while (cond);
|
|
||||||
* If condition is true, JMP to BODY_ROOT
|
|
||||||
*/
|
|
||||||
OP_CODE_DECL (loop_postcond, T_IDX_IDX,
|
|
||||||
condition,
|
|
||||||
body_root)
|
|
||||||
|
|
||||||
/** a = [] */
|
/** a = [] */
|
||||||
OP_CODE_DECL (array_0, T_IDX,
|
OP_CODE_DECL (array_0, T_IDX,
|
||||||
lhs)
|
lhs)
|
||||||
|
|||||||
@@ -318,10 +318,6 @@ do_number_arithmetic(struct __int_data *int_data, /**< interpreter context */
|
|||||||
#define OP_UNIMPLEMENTED_LIST(op) \
|
#define OP_UNIMPLEMENTED_LIST(op) \
|
||||||
op(is_true_jmp) \
|
op(is_true_jmp) \
|
||||||
op(is_false_jmp) \
|
op(is_false_jmp) \
|
||||||
op(loop_init_num) \
|
|
||||||
op(loop_precond_begin_num) \
|
|
||||||
op(loop_precond_end_num) \
|
|
||||||
op(loop_postcond) \
|
|
||||||
op(call_0) \
|
op(call_0) \
|
||||||
op(call_n) \
|
op(call_n) \
|
||||||
op(func_decl_1) \
|
op(func_decl_1) \
|
||||||
@@ -388,22 +384,6 @@ do_number_arithmetic(struct __int_data *int_data, /**< interpreter context */
|
|||||||
OP_UNIMPLEMENTED_LIST(DEFINE_UNIMPLEMENTED_OP)
|
OP_UNIMPLEMENTED_LIST(DEFINE_UNIMPLEMENTED_OP)
|
||||||
#undef DEFINE_UNIMPLEMENTED_OP
|
#undef DEFINE_UNIMPLEMENTED_OP
|
||||||
|
|
||||||
ecma_completion_value_t
|
|
||||||
opfunc_loop_inf (OPCODE opdata, struct __int_data *int_data)
|
|
||||||
{
|
|
||||||
#ifdef __HOST
|
|
||||||
__printf ("%d::loop_inf:idx:%d\n",
|
|
||||||
int_data->pos,
|
|
||||||
opdata.data.loop_inf.loop_root);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int_data->pos = opdata.data.loop_inf.loop_root;
|
|
||||||
|
|
||||||
return ecma_make_completion_value( ECMA_COMPLETION_TYPE_NORMAL,
|
|
||||||
ecma_make_simple_value( ECMA_SIMPLE_VALUE_EMPTY),
|
|
||||||
ECMA_TARGET_ID_RESERVED);
|
|
||||||
}
|
|
||||||
|
|
||||||
ecma_completion_value_t
|
ecma_completion_value_t
|
||||||
opfunc_call_1 (OPCODE opdata __unused, struct __int_data *int_data)
|
opfunc_call_1 (OPCODE opdata __unused, struct __int_data *int_data)
|
||||||
{
|
{
|
||||||
@@ -836,11 +816,6 @@ GETOP_IMPL_1 (exitval, status_code)
|
|||||||
GETOP_IMPL_1 (retval, ret_value)
|
GETOP_IMPL_1 (retval, ret_value)
|
||||||
GETOP_IMPL_0 (ret)
|
GETOP_IMPL_0 (ret)
|
||||||
GETOP_IMPL_0 (nop)
|
GETOP_IMPL_0 (nop)
|
||||||
GETOP_IMPL_1 (loop_inf, loop_root)
|
|
||||||
GETOP_IMPL_3 (loop_init_num, start, stop, step)
|
|
||||||
GETOP_IMPL_2 (loop_precond_begin_num, condition, after_loop_op)
|
|
||||||
GETOP_IMPL_3 (loop_precond_end_num, iterator, step, precond_begin)
|
|
||||||
GETOP_IMPL_2 (loop_postcond, condition, body_root)
|
|
||||||
GETOP_IMPL_1 (var_decl, variable_name)
|
GETOP_IMPL_1 (var_decl, variable_name)
|
||||||
GETOP_IMPL_2 (b_not, dst, var_right)
|
GETOP_IMPL_2 (b_not, dst, var_right)
|
||||||
GETOP_IMPL_2 (logical_not, dst, var_right)
|
GETOP_IMPL_2 (logical_not, dst, var_right)
|
||||||
|
|||||||
@@ -35,13 +35,6 @@ struct __int_data;
|
|||||||
OPCODE;
|
OPCODE;
|
||||||
typedef ecma_completion_value_t (*opfunc)(OPCODE, struct __int_data *);
|
typedef ecma_completion_value_t (*opfunc)(OPCODE, struct __int_data *);
|
||||||
|
|
||||||
#define OP_LOOPS(op) \
|
|
||||||
op(loop_inf) \
|
|
||||||
op(loop_init_num) \
|
|
||||||
op(loop_precond_begin_num) \
|
|
||||||
op(loop_precond_end_num) \
|
|
||||||
op(loop_postcond)
|
|
||||||
|
|
||||||
#define OP_CALLS_AND_ARGS(op) \
|
#define OP_CALLS_AND_ARGS(op) \
|
||||||
op(call_0) \
|
op(call_0) \
|
||||||
op(call_1) \
|
op(call_1) \
|
||||||
@@ -134,7 +127,6 @@ typedef ecma_completion_value_t (*opfunc)(OPCODE, struct __int_data *);
|
|||||||
op(is_false_jmp)
|
op(is_false_jmp)
|
||||||
|
|
||||||
#define OP_LIST(op) \
|
#define OP_LIST(op) \
|
||||||
OP_LOOPS(op) \
|
|
||||||
OP_CALLS_AND_ARGS(op) \
|
OP_CALLS_AND_ARGS(op) \
|
||||||
OP_INITS(op) \
|
OP_INITS(op) \
|
||||||
OP_ASSIGNMENTS(op) \
|
OP_ASSIGNMENTS(op) \
|
||||||
|
|||||||
+17
-5
@@ -119,12 +119,24 @@ dump_current_line (void)
|
|||||||
{
|
{
|
||||||
const char *i;
|
const char *i;
|
||||||
|
|
||||||
|
__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
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* If TOKEN represents a keyword, return decoded keyword,
|
/* If TOKEN represents a keyword, return decoded keyword,
|
||||||
if TOKEN represents a Future Reserved Word, return KW_RESERVED,
|
if TOKEN represents a Future Reserved Word, return KW_RESERVED,
|
||||||
otherwise return KW_NONE. */
|
otherwise return KW_NONE. */
|
||||||
@@ -136,7 +148,7 @@ decode_keyword (void)
|
|||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
if (!__strncmp (keyword_tokens[i].str, token_start, (size_t) (buffer - token_start)))
|
if (current_token_equals_to (keyword_tokens[i].str))
|
||||||
return keyword_tokens[i].tok;
|
return keyword_tokens[i].tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +162,7 @@ convert_seen_name_to_token (void)
|
|||||||
|
|
||||||
for (i = 0; i < seen_names_count; i++)
|
for (i = 0; i < seen_names_count; i++)
|
||||||
{
|
{
|
||||||
if (!__strncmp (seen_names[i].str, token_start, (size_t) (buffer - token_start)))
|
if (current_token_equals_to (seen_names[i].str))
|
||||||
return seen_names[i].tok;
|
return seen_names[i].tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,8 +250,8 @@ lexer_adjust_num_ids (void)
|
|||||||
|
|
||||||
for (i = 0; i < sizeof (keyword_tokens) / sizeof (string_and_token); i++)
|
for (i = 0; i < sizeof (keyword_tokens) / sizeof (string_and_token); i++)
|
||||||
{
|
{
|
||||||
if (!__strncmp ("true", keyword_tokens[i].str, 4)
|
if (!__strcmp ("true", keyword_tokens[i].str)
|
||||||
|| !__strncmp ("false", keyword_tokens[i].str, 5))
|
|| !__strcmp ("false", keyword_tokens[i].str))
|
||||||
keyword_tokens[i].tok.data.uid = (uint8_t) (keyword_tokens[i].tok.data.uid + seen_names_count);
|
keyword_tokens[i].tok.data.uid = (uint8_t) (keyword_tokens[i].tok.data.uid + seen_names_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -609,7 +621,7 @@ parse_string (void)
|
|||||||
|
|
||||||
for (num = 0; num < seen_names_count; num++)
|
for (num = 0; num < seen_names_count; num++)
|
||||||
{
|
{
|
||||||
if (!__strncmp (seen_names[num].str, tok, __strlen (tok)))
|
if (!__strcmp (seen_names[num].str, tok))
|
||||||
{
|
{
|
||||||
mem_heap_free_block ((uint8_t*) tok);
|
mem_heap_free_block ((uint8_t*) tok);
|
||||||
return seen_names[num].tok;
|
return seen_names[num].tok;
|
||||||
|
|||||||
+14
-15
@@ -20,9 +20,10 @@
|
|||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
#define MAX_OPCODES 10
|
#define MAX_OPCODES 10
|
||||||
|
#define INVALID_VALUE 255
|
||||||
|
|
||||||
static token tok;
|
static token tok;
|
||||||
static OPCODE opcode, opcodes_buffer[10];
|
static OPCODE opcode, opcodes_buffer[MAX_OPCODES];
|
||||||
static uint8_t current_opcode_in_buffer = 0;
|
static uint8_t current_opcode_in_buffer = 0;
|
||||||
static uint8_t opcode_counter = 0;
|
static uint8_t opcode_counter = 0;
|
||||||
|
|
||||||
@@ -136,7 +137,7 @@ insert_semicolon (void)
|
|||||||
do { opcode=getop_##GETOP (__VA_ARGS__); serializer_dump_opcode (&opcode); opcode_counter++; } while (0)
|
do { opcode=getop_##GETOP (__VA_ARGS__); serializer_dump_opcode (&opcode); opcode_counter++; } while (0)
|
||||||
|
|
||||||
#define REWRITE_OPCODE(OC, GETOP, ...) \
|
#define REWRITE_OPCODE(OC, GETOP, ...) \
|
||||||
do { opcode=getop_##GETOP (__VA_ARGS__); serializer_rewrite_opcode ((int8_t) (OC - opcode_counter), &opcode); } while (0)
|
do { opcode=getop_##GETOP (__VA_ARGS__); serializer_rewrite_opcode (OC, &opcode); } while (0)
|
||||||
|
|
||||||
static T_IDX
|
static T_IDX
|
||||||
integer_zero (void)
|
integer_zero (void)
|
||||||
@@ -624,23 +625,23 @@ parse_literal (void)
|
|||||||
{
|
{
|
||||||
case TOK_NULL:
|
case TOK_NULL:
|
||||||
lhs = next_temp_name ();
|
lhs = next_temp_name ();
|
||||||
DUMP_OPCODE (assignment, OPCODE_ARG_TYPE_SIMPLE, lhs, ECMA_SIMPLE_VALUE_NULL);
|
DUMP_OPCODE (assignment, lhs, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_NULL);
|
||||||
return lhs;
|
return lhs;
|
||||||
|
|
||||||
case TOK_BOOL:
|
case TOK_BOOL:
|
||||||
lhs = next_temp_name ();
|
lhs = next_temp_name ();
|
||||||
DUMP_OPCODE (assignment, OPCODE_ARG_TYPE_SIMPLE, lhs,
|
DUMP_OPCODE (assignment, lhs, OPCODE_ARG_TYPE_SIMPLE,
|
||||||
tok.data.uid ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
tok.data.uid ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
||||||
return lhs;
|
return lhs;
|
||||||
|
|
||||||
case TOK_INT:
|
case TOK_INT:
|
||||||
lhs = next_temp_name ();
|
lhs = next_temp_name ();
|
||||||
DUMP_OPCODE (assignment, OPCODE_ARG_TYPE_NUMBER, lhs, tok.data.uid);
|
DUMP_OPCODE (assignment, lhs, OPCODE_ARG_TYPE_NUMBER, tok.data.uid);
|
||||||
return lhs;
|
return lhs;
|
||||||
|
|
||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
lhs = next_temp_name ();
|
lhs = next_temp_name ();
|
||||||
DUMP_OPCODE (assignment, OPCODE_ARG_TYPE_STRING, lhs, tok.data.uid);
|
DUMP_OPCODE (assignment, lhs, OPCODE_ARG_TYPE_STRING, tok.data.uid);
|
||||||
return lhs;
|
return lhs;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1143,7 +1144,7 @@ parse_conditional_expression (bool *was_conditional)
|
|||||||
|
|
||||||
DUMP_OPCODE (is_true_jmp, expr, (uint8_t) (opcode_counter + 2));
|
DUMP_OPCODE (is_true_jmp, expr, (uint8_t) (opcode_counter + 2));
|
||||||
jmp_oc = opcode_counter;
|
jmp_oc = opcode_counter;
|
||||||
DUMP_OPCODE (jmp_down, 1);
|
DUMP_OPCODE (jmp_down, INVALID_VALUE);
|
||||||
|
|
||||||
NEXT (lhs, assignment_expression);
|
NEXT (lhs, assignment_expression);
|
||||||
DUMP_OPCODE (assignment, res, OPCODE_ARG_TYPE_VARIABLE, lhs);
|
DUMP_OPCODE (assignment, res, OPCODE_ARG_TYPE_VARIABLE, lhs);
|
||||||
@@ -1151,7 +1152,7 @@ parse_conditional_expression (bool *was_conditional)
|
|||||||
|
|
||||||
REWRITE_OPCODE (jmp_oc, jmp_down, (uint8_t) (opcode_counter - jmp_oc));
|
REWRITE_OPCODE (jmp_oc, jmp_down, (uint8_t) (opcode_counter - jmp_oc));
|
||||||
jmp_oc = opcode_counter;
|
jmp_oc = opcode_counter;
|
||||||
DUMP_OPCODE (jmp_down, 1);
|
DUMP_OPCODE (jmp_down, INVALID_VALUE);
|
||||||
|
|
||||||
NEXT (lhs, assignment_expression);
|
NEXT (lhs, assignment_expression);
|
||||||
DUMP_OPCODE (assignment, res, OPCODE_ARG_TYPE_VARIABLE, lhs);
|
DUMP_OPCODE (assignment, res, OPCODE_ARG_TYPE_VARIABLE, lhs);
|
||||||
@@ -1435,10 +1436,10 @@ plain_for:
|
|||||||
stop = integer_one ();
|
stop = integer_one ();
|
||||||
|
|
||||||
end_oc = opcode_counter;
|
end_oc = opcode_counter;
|
||||||
DUMP_OPCODE (is_false_jmp, stop, 1);
|
DUMP_OPCODE (is_false_jmp, stop, INVALID_VALUE);
|
||||||
|
|
||||||
body_oc = opcode_counter;
|
body_oc = opcode_counter;
|
||||||
DUMP_OPCODE (jmp_down, 1);
|
DUMP_OPCODE (jmp_down, INVALID_VALUE);
|
||||||
|
|
||||||
step_oc = opcode_counter;
|
step_oc = opcode_counter;
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
@@ -1450,10 +1451,8 @@ plain_for:
|
|||||||
DUMP_OPCODE (jmp_up, (uint8_t) (opcode_counter - cond_oc));
|
DUMP_OPCODE (jmp_up, (uint8_t) (opcode_counter - cond_oc));
|
||||||
REWRITE_OPCODE (body_oc, jmp_down, (uint8_t) (opcode_counter - body_oc));
|
REWRITE_OPCODE (body_oc, jmp_down, (uint8_t) (opcode_counter - body_oc));
|
||||||
|
|
||||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
parse_source_element_list ();
|
parse_statement ();
|
||||||
next_token_must_be (TOK_CLOSE_BRACE);
|
|
||||||
|
|
||||||
DUMP_OPCODE (jmp_up, (uint8_t) (opcode_counter - step_oc));
|
DUMP_OPCODE (jmp_up, (uint8_t) (opcode_counter - step_oc));
|
||||||
REWRITE_OPCODE (end_oc, is_false_jmp, stop, opcode_counter);
|
REWRITE_OPCODE (end_oc, is_false_jmp, stop, opcode_counter);
|
||||||
@@ -1506,7 +1505,7 @@ parse_if_statement (void)
|
|||||||
|
|
||||||
cond = parse_expression_inside_parens ();
|
cond = parse_expression_inside_parens ();
|
||||||
cond_oc = opcode_counter;
|
cond_oc = opcode_counter;
|
||||||
DUMP_OPCODE (is_false_jmp, cond, 1);
|
DUMP_OPCODE (is_false_jmp, cond, INVALID_VALUE);
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
parse_statement ();
|
parse_statement ();
|
||||||
@@ -1556,7 +1555,7 @@ parse_while_statement (void)
|
|||||||
cond_oc = opcode_counter;
|
cond_oc = opcode_counter;
|
||||||
cond = parse_expression_inside_parens ();
|
cond = parse_expression_inside_parens ();
|
||||||
jmp_oc = opcode_counter;
|
jmp_oc = opcode_counter;
|
||||||
DUMP_OPCODE (is_false_jmp, cond, 1);
|
DUMP_OPCODE (is_false_jmp, cond, INVALID_VALUE);
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
parse_statement ();
|
parse_statement ();
|
||||||
|
|||||||
@@ -26,6 +26,6 @@ void serializer_dump_nums (const int *, uint8_t, uint8_t, uint8_t);
|
|||||||
|
|
||||||
void serializer_dump_opcode (const void *);
|
void serializer_dump_opcode (const void *);
|
||||||
|
|
||||||
void serializer_rewrite_opcode (const int8_t, const void *);
|
void serializer_rewrite_opcode (const uint8_t, const void *);
|
||||||
|
|
||||||
#endif // SERIALIZER_H
|
#endif // SERIALIZER_H
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ __fseek(_FILE * fp, /**< stream pointer */
|
|||||||
_whence_t whence) /**< specifies position type
|
_whence_t whence) /**< specifies position type
|
||||||
to add offset to */
|
to add offset to */
|
||||||
{
|
{
|
||||||
int whence_real;
|
int whence_real = SEEK_CUR;
|
||||||
switch ( whence )
|
switch ( whence )
|
||||||
{
|
{
|
||||||
case __SEEK_SET:
|
case __SEEK_SET:
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ serializer_dump_opcode (const void *opcode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
serializer_rewrite_opcode (const int8_t offset, const void *opcode)
|
serializer_rewrite_opcode (const uint8_t loc, const void *opcode)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
__printf ("%03d: %20s ", opcode_counter + offset, massive[(int)((char*)opcode)[0]]);
|
__printf ("%03d: %20s ", loc, massive[(int)((char*)opcode)[0]]);
|
||||||
for (i = 1; i < 4; i++)
|
for (i = 1; i < 4; i++)
|
||||||
__printf ("%4d ", ((char*)opcode)[i]);
|
__printf ("%4d ", ((char*)opcode)[i]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user