in progress of fixing a bug in instruction elimination
This commit is contained in:
parent
60c38a1ecb
commit
62eb6db83d
@ -110,7 +110,8 @@ class MyObject(Object)
|
||||
|
||||
}
|
||||
|
||||
method(#class) main
|
||||
|
||||
method(#class) main_xx
|
||||
{
|
||||
|a k|
|
||||
|
||||
@ -214,6 +215,17 @@ class MyObject(Object)
|
||||
nil.
|
||||
## end of elimination.
|
||||
|
||||
## PROBLEM: the following double loop will exhaust the stack
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
##[:j :q | (j + q) dump] value: (if (true) { 20 }) value: (if (true) { break }).
|
||||
(1 + (if (false) {} else { break })) dump.
|
||||
}.
|
||||
}.
|
||||
|
||||
|
||||
a :=999.
|
||||
a := #{
|
||||
1,
|
||||
@ -228,19 +240,20 @@ class MyObject(Object)
|
||||
|
||||
(* Dictionary ???
|
||||
a := #{
|
||||
"a": 20,
|
||||
b : 30
|
||||
}.
|
||||
a := #{
|
||||
{ key, value },
|
||||
{ key, value },
|
||||
{ key, value },
|
||||
{ key, value }
|
||||
:( key, value ),
|
||||
:( key, value ),
|
||||
:( key, value ),
|
||||
:( key, value )
|
||||
}
|
||||
|
||||
a := :{
|
||||
:( key, value ),
|
||||
}
|
||||
*)
|
||||
|
||||
abc := { key, value }.
|
||||
{ key, value } dump.
|
||||
|
||||
(* abc := { key, value }.
|
||||
{ key, value } dump. *)
|
||||
|
||||
a do: [ :v | v dump].
|
||||
|
||||
@ -254,4 +267,22 @@ class MyObject(Object)
|
||||
'---------- END ------------' dump.
|
||||
##Processor sleepFor: 20.
|
||||
}
|
||||
|
||||
method(#class) main
|
||||
{
|
||||
## PROBLEM: the following double loop will exhaust the stack
|
||||
while (true)
|
||||
{
|
||||
##111 dump.
|
||||
while (true)
|
||||
{
|
||||
##[:j :q | (j + q) dump] value: (if (true) { 20 }) value: (if (true) { break }).
|
||||
(1 + (if (false) {} else { break })) dump.
|
||||
##break.
|
||||
##[:j :q | (j + q) dump] value: 10 value: 20.
|
||||
##if (false) {} else { break }.
|
||||
}.
|
||||
}.
|
||||
}
|
||||
##
|
||||
}
|
||||
|
105
moo/lib/comp.c
105
moo/lib/comp.c
@ -1508,6 +1508,16 @@ retry:
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_ASSIGN);
|
||||
ADD_TOKEN_CHAR (moo, c);
|
||||
}
|
||||
else if (c == '{')
|
||||
{
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_DICBRACE);
|
||||
ADD_TOKEN_CHAR (moo, c);
|
||||
}
|
||||
else if (c == '(')
|
||||
{
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_ASSPAREN);
|
||||
ADD_TOKEN_CHAR (moo, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
unget_char (moo, &moo->c->lxc);
|
||||
@ -1577,7 +1587,7 @@ retry:
|
||||
case '[':
|
||||
/* #[ - byte array literal */
|
||||
ADD_TOKEN_CHAR(moo, c);
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_BAPAREN);
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_BABRACK);
|
||||
break;
|
||||
|
||||
case '{':
|
||||
@ -2185,7 +2195,7 @@ static int patch_long_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_o
|
||||
code_size = jt - jip - (MOO_BCODE_LONG_PARAM_SIZE + 1);
|
||||
if (code_size > MAX_CODE_JUMP * 2)
|
||||
{
|
||||
/* TODO: change error code or get it as a parameter */
|
||||
/* TODO: change error code or get it as a parameter */
|
||||
set_syntax_error (moo, MOO_SYNERR_BLKFLOOD, errloc, MOO_NULL);
|
||||
return -1;
|
||||
}
|
||||
@ -2211,6 +2221,32 @@ static int patch_long_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_o
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void eliminate_instructions (moo_t* moo, moo_oow_t start, moo_oow_t end)
|
||||
{
|
||||
moo_oow_t last;
|
||||
|
||||
MOO_ASSERT (moo, moo->c->mth.code.len >= 1);
|
||||
|
||||
MOO_DEBUG2 (moo, "ELIMINATE INSTRUCTION FROM %zu TO %zu\n", start, end);
|
||||
last = moo->c->mth.code.len - 1;
|
||||
|
||||
if (end >= last)
|
||||
{
|
||||
/* eliminate all instructions starting from the start index.
|
||||
* setting the length to the start length will achieve this */
|
||||
moo->c->mth.code.len = start;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* eliminate a chunk in the middle of the instruction buffer.
|
||||
* some copying is required */
|
||||
if (end > last) end = last;
|
||||
MOO_MEMMOVE (&moo->c->mth.code.ptr[start], &moo->c->mth.code.ptr[end + 1], moo->c->mth.code.len - end - 1);
|
||||
moo->c->mth.code.len--;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Compiler
|
||||
* --------------------------------------------------------------------- */
|
||||
@ -3884,7 +3920,7 @@ if index is too large, switch to at:put? (or don't care as it's too large???).
|
||||
moo->c->mth.arlit_count = saved_arlit_count;
|
||||
break;
|
||||
|
||||
case MOO_IOTOK_BAPAREN: /* #[ */
|
||||
case MOO_IOTOK_BABRACK: /* #[ */
|
||||
/*case MOO_IOTOK_LBRACK:*/ /* [ */
|
||||
GET_TOKEN (moo);
|
||||
if (__read_byte_array_literal (moo, &lit) <= -1) return -1;
|
||||
@ -4218,7 +4254,7 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
|
||||
break;
|
||||
}
|
||||
|
||||
case MOO_IOTOK_BAPAREN: /* #[ */
|
||||
case MOO_IOTOK_BABRACK: /* #[ */
|
||||
/*GET_TOKEN (moo);*/
|
||||
if (compile_byte_array_literal(moo) <= -1) return -1;
|
||||
break;
|
||||
@ -4464,8 +4500,10 @@ static int compile_message_expression (moo_t* moo, int to_super)
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_BINSEL)
|
||||
{
|
||||
MOO_ASSERT (moo, moo->c->mth.code.len > noop_pos);
|
||||
MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1);
|
||||
moo->c->mth.code.len--;
|
||||
/*MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1);
|
||||
moo->c->mth.code.len--;*/
|
||||
/* eliminate the NOOP instruction */
|
||||
eliminate_instructions (moo, noop_pos, noop_pos);
|
||||
|
||||
noop_pos = moo->c->mth.code.len;
|
||||
if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1;
|
||||
@ -4475,8 +4513,10 @@ static int compile_message_expression (moo_t* moo, int to_super)
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_KEYWORD)
|
||||
{
|
||||
MOO_ASSERT (moo, moo->c->mth.code.len > noop_pos);
|
||||
MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1);
|
||||
moo->c->mth.code.len--;
|
||||
/*MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1);
|
||||
moo->c->mth.code.len--;*/
|
||||
/* eliminate the NOOP instruction */
|
||||
eliminate_instructions (moo, noop_pos, noop_pos);
|
||||
|
||||
noop_pos = moo->c->mth.code.len;
|
||||
if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1;
|
||||
@ -4492,8 +4532,10 @@ static int compile_message_expression (moo_t* moo, int to_super)
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_KEYWORD)
|
||||
{
|
||||
MOO_ASSERT (moo, moo->c->mth.code.len > noop_pos);
|
||||
MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1);
|
||||
moo->c->mth.code.len--;
|
||||
/*MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1);
|
||||
moo->c->mth.code.len--;*/
|
||||
/* eliminate the NOOP instruction */
|
||||
eliminate_instructions (moo, noop_pos, noop_pos);
|
||||
|
||||
noop_pos = moo->c->mth.code.len;
|
||||
if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1;
|
||||
@ -4521,10 +4563,11 @@ static int compile_message_expression (moo_t* moo, int to_super)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* delete the NOOP instruction inserted */
|
||||
MOO_ASSERT (moo, moo->c->mth.code.len > noop_pos);
|
||||
MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1);
|
||||
moo->c->mth.code.len--;
|
||||
/*MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1);
|
||||
moo->c->mth.code.len--;*/
|
||||
/* eliminate the NOOP instruction */
|
||||
eliminate_instructions (moo, noop_pos, noop_pos);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -4673,7 +4716,7 @@ static int compile_if_expression (moo_t* moo)
|
||||
falseblock = 0;
|
||||
|
||||
/* eliminate PUSH_TRUE as well */
|
||||
moo->c->mth.code.len = precondpos;
|
||||
eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
|
||||
postcondpos = precondpos;
|
||||
}
|
||||
else if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE)
|
||||
@ -4699,7 +4742,9 @@ static int compile_if_expression (moo_t* moo)
|
||||
{
|
||||
if (falseblock)
|
||||
{
|
||||
moo->c->mth.code.len = precondpos;
|
||||
/* the conditional was false. elimiate instructions emitted
|
||||
* for the block attached to the conditional */
|
||||
eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
|
||||
postcondpos = precondpos;
|
||||
}
|
||||
else if (endoftrueblock == INVALID_IP)
|
||||
@ -4713,8 +4758,8 @@ static int compile_if_expression (moo_t* moo)
|
||||
if (endoftrueblock == INVALID_IP)
|
||||
{
|
||||
/* emit an instruction to jump to the end */
|
||||
if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1) goto oops;
|
||||
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) goto oops;
|
||||
if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1 ||
|
||||
emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4739,7 +4784,7 @@ static int compile_if_expression (moo_t* moo)
|
||||
if (endoftrueblock != INVALID_IP)
|
||||
{
|
||||
/* eliminate all instructions after the end of the first true block found */
|
||||
moo->c->mth.code.len = endoftrueblock;
|
||||
eliminate_instructions (moo, endoftrueblock, moo->c->mth.code.len - 1);
|
||||
}
|
||||
|
||||
/* patch instructions that jumps to the end of if expression */
|
||||
@ -4777,6 +4822,7 @@ static int compile_while_expression (moo_t* moo)
|
||||
if (compile_conditional (moo) <= -1) goto oops;
|
||||
|
||||
postcondpos = moo->c->mth.code.len;
|
||||
#if 0
|
||||
if (precondpos + 1 == postcondpos)
|
||||
{
|
||||
/* simple optimization -
|
||||
@ -4786,7 +4832,7 @@ static int compile_while_expression (moo_t* moo)
|
||||
{
|
||||
/* the conditional is always true */
|
||||
cond_style = 1;
|
||||
moo->c->mth.code.len = precondpos;
|
||||
eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
|
||||
postcondpos = precondpos;
|
||||
}
|
||||
else if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE)
|
||||
@ -4795,6 +4841,7 @@ static int compile_while_expression (moo_t* moo)
|
||||
cond_style = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cond_style != 1)
|
||||
{
|
||||
@ -4819,7 +4866,7 @@ static int compile_while_expression (moo_t* moo)
|
||||
/* optimization -
|
||||
* the braced block is kind of empty as it only pushes nil.
|
||||
* get rid of this push instruction and don't generate the POP_STACKTOP */
|
||||
moo->c->mth.code.len = prebbpos;
|
||||
eliminate_instructions (moo, prebbpos, moo->c->mth.code.len - 1);
|
||||
}
|
||||
else if (prebbpos < postbbpos)
|
||||
{
|
||||
@ -4841,15 +4888,15 @@ static int compile_while_expression (moo_t* moo)
|
||||
|
||||
if (cond_style != 1)
|
||||
{
|
||||
/* patch the jump instruction. */
|
||||
/* patch the jump instruction */
|
||||
if (patch_long_forward_jump_instruction (moo, postcondpos, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
||||
}
|
||||
|
||||
if (cond_style == -1)
|
||||
{
|
||||
/* optimization - get rid of code generated for the while
|
||||
* loop including the conditional */
|
||||
moo->c->mth.code.len = precondpos;
|
||||
/* optimization - get rid of instructions generated for the while
|
||||
* loop including the conditional as the condition was false */
|
||||
eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
|
||||
}
|
||||
|
||||
/* patch the jump instructions for break */
|
||||
@ -4903,7 +4950,7 @@ static int compile_do_while_expression (moo_t* moo)
|
||||
/* optimization -
|
||||
* the braced block is kind of empty as it only pushes nil.
|
||||
* get rid of this push instruction and don't generate the POP_STACKTOP */
|
||||
moo->c->mth.code.len = prebbpos;
|
||||
eliminate_instructions (moo, prebbpos, moo->c->mth.code.len - 1);
|
||||
precondpos = prebbpos;
|
||||
}
|
||||
else if (prebbpos < postbbpos)
|
||||
@ -4932,14 +4979,14 @@ static int compile_do_while_expression (moo_t* moo)
|
||||
if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_TRUE)
|
||||
{
|
||||
/* the conditional is always true. eliminate PUSH_TRUE and emit an absolute jump */
|
||||
moo->c->mth.code.len = precondpos;
|
||||
eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
|
||||
postcondpos = precondpos;
|
||||
jbinst = BCODE_JUMP_BACKWARD_0;
|
||||
}
|
||||
else if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE)
|
||||
{
|
||||
/* the conditional is always false. eliminate PUSH_FALSE and don't emit jump */
|
||||
moo->c->mth.code.len = precondpos;
|
||||
eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
|
||||
postcondpos = precondpos;
|
||||
goto skip_emitting_jump_backward;
|
||||
}
|
||||
@ -5237,7 +5284,7 @@ static int compile_method_statement (moo_t* moo)
|
||||
case BCODE_PUSH_TWO:
|
||||
/* eliminate the unneeded push instruction */
|
||||
n = 0;
|
||||
moo->c->mth.code.len = preexprpos;
|
||||
eliminate_instructions (moo, preexprpos, moo->c->mth.code.len - 1);
|
||||
break;
|
||||
default:
|
||||
goto pop_stacktop;
|
||||
@ -6252,7 +6299,7 @@ static int __compile_pooldic_definition (moo_t* moo)
|
||||
if (!lit) return -1;
|
||||
goto add_literal;
|
||||
|
||||
case MOO_IOTOK_BAPAREN: /* #[ - byte array literal parenthesis */
|
||||
case MOO_IOTOK_BABRACK: /* #[ - byte array literal parenthesis */
|
||||
if (read_byte_array_literal(moo, &lit) <= -1) return -1;
|
||||
goto add_literal;
|
||||
|
||||
|
@ -323,9 +323,11 @@ struct moo_iotok_t
|
||||
MOO_IOTOK_RBRACK,
|
||||
MOO_IOTOK_LPAREN,
|
||||
MOO_IOTOK_RPAREN,
|
||||
MOO_IOTOK_APAREN, /* #( */
|
||||
MOO_IOTOK_BAPAREN, /* #[ */
|
||||
MOO_IOTOK_ABRACE, /* #{ */
|
||||
MOO_IOTOK_APAREN, /* #( - array literal */
|
||||
MOO_IOTOK_BABRACK, /* #[ - byte array literal */
|
||||
MOO_IOTOK_ABRACE, /* #{ - array expression */
|
||||
MOO_IOTOK_DICBRACE, /* :{ - dictionary expression */
|
||||
MOO_IOTOK_ASSPAREN, /* :( - association expression */
|
||||
MOO_IOTOK_PERIOD,
|
||||
MOO_IOTOK_COMMA,
|
||||
MOO_IOTOK_SEMICOLON,
|
||||
|
@ -979,11 +979,11 @@ struct moo_t
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/* TODO: stack bound check when pushing */
|
||||
/* TODO: proper stack bound check when pushing */
|
||||
#define MOO_STACK_PUSH(moo,v) \
|
||||
do { \
|
||||
(moo)->sp = (moo)->sp + 1; \
|
||||
MOO_ASSERT (moo, (moo)->sp < (unsigned int)(MOO_OBJ_GET_SIZE((moo)->processor->active) - MOO_PROCESS_NAMED_INSTVARS)); \
|
||||
(moo)->processor->active->slot[(moo)->sp] = v; \
|
||||
} while (0)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user