implemented simple optimization in compiling an if expression
This commit is contained in:
parent
22013650bb
commit
07d8d0ea83
@ -176,7 +176,11 @@ class MyObject(Object)
|
|||||||
a := a + 100000000000000.
|
a := a + 100000000000000.
|
||||||
}.*)
|
}.*)
|
||||||
|
|
||||||
(*
|
|
||||||
|
a := if(false) { 10 } elsif (false) { 20 } elsif (false) { 30} else { 40}.
|
||||||
|
##a := if(false) { 999 } else { 888 }.
|
||||||
|
a dump.
|
||||||
|
|
||||||
a := 5.
|
a := 5.
|
||||||
a := while (true)
|
a := while (true)
|
||||||
{
|
{
|
||||||
@ -187,12 +191,12 @@ class MyObject(Object)
|
|||||||
}.
|
}.
|
||||||
a dump.
|
a dump.
|
||||||
}.
|
}.
|
||||||
a dump.*)
|
a dump.
|
||||||
a := 5.
|
a := 5.
|
||||||
do {
|
do {
|
||||||
a := do {
|
a := do {
|
||||||
('in loop.....' & a asString) dump.
|
('in loop.....' & a asString) dump.
|
||||||
if (a > 5) { break }.
|
##if (a > 5) { break }.
|
||||||
a := a + 1.
|
a := a + 1.
|
||||||
} while(a < 10).
|
} while(a < 10).
|
||||||
} while (false).
|
} while (false).
|
||||||
|
107
moo/lib/comp.c
107
moo/lib/comp.c
@ -4530,63 +4530,94 @@ static int compile_conditional (moo_t* moo)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INVALID_IP MOO_TYPE_MAX(moo_oow_t)
|
||||||
|
|
||||||
static int compile_if_expression (moo_t* moo)
|
static int compile_if_expression (moo_t* moo)
|
||||||
{
|
{
|
||||||
moo_oow_pool_t jumptoend;
|
moo_oow_pool_t jumptoend;
|
||||||
moo_oow_pool_chunk_t* jumptoend_chunk;
|
moo_oow_pool_chunk_t* jumptoend_chunk;
|
||||||
moo_oow_t i, j;
|
moo_oow_t i, j;
|
||||||
|
moo_oow_t jumptonext, precondpos, postcondpos, endoftrueblock;
|
||||||
moo_oow_t jumptonext;
|
int falseblock;
|
||||||
moo_ioloc_t if_loc, brace_loc;
|
moo_ioloc_t if_loc, brace_loc;
|
||||||
|
|
||||||
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_IF);
|
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_IF);
|
||||||
if_loc = *TOKEN_LOC(moo);
|
if_loc = *TOKEN_LOC(moo);
|
||||||
|
|
||||||
init_oow_pool (moo, &jumptoend);
|
init_oow_pool (moo, &jumptoend);
|
||||||
|
jumptonext = INVALID_IP;
|
||||||
|
endoftrueblock = INVALID_IP;
|
||||||
|
|
||||||
/* TODO: simple optimization to check if the conditional is true or false */
|
do
|
||||||
GET_TOKEN (moo); /* get ( */
|
|
||||||
if (compile_conditional (moo) <= -1) goto oops;
|
|
||||||
|
|
||||||
jumptonext = moo->c->mth.code.len;
|
|
||||||
/* specifying MAX_CODE_JUMP causes emit_single_param_instruction() to
|
|
||||||
* produce the long jump instruction (BCODE_JUMP_FORWARD_X) */
|
|
||||||
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_IF_FALSE_0, MAX_CODE_JUMP) <= -1) goto oops;
|
|
||||||
|
|
||||||
GET_TOKEN (moo); /* get { */
|
|
||||||
brace_loc = *TOKEN_LOC(moo);
|
|
||||||
if (compile_braced_block (moo) <= -1) goto oops;
|
|
||||||
|
|
||||||
/* emit code to jump to the end */
|
|
||||||
/*jumptoend[jumptoend_count++] = moo->c->mth.code.len;*/
|
|
||||||
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;
|
|
||||||
|
|
||||||
GET_TOKEN (moo);
|
|
||||||
while (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF)
|
|
||||||
{
|
{
|
||||||
if (patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
int falseblock = 0;
|
||||||
|
|
||||||
GET_TOKEN (moo); /* get ( */
|
GET_TOKEN (moo); /* get ( */
|
||||||
if (compile_conditional(moo) <= -1) goto oops;
|
precondpos = moo->c->mth.code.len;
|
||||||
|
|
||||||
/* emit code to jump to the next elsif or else */
|
if (jumptonext != INVALID_IP &&
|
||||||
jumptonext = moo->c->mth.code.len;
|
patch_long_forward_jump_instruction (moo, jumptonext, precondpos, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
||||||
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_IF_FALSE_0, MAX_CODE_JUMP) <= -1) goto oops;
|
|
||||||
|
if (compile_conditional(moo) <= -1) goto oops;
|
||||||
|
postcondpos = moo->c->mth.code.len;
|
||||||
|
|
||||||
|
if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_TRUE)
|
||||||
|
{
|
||||||
|
/* do not generate jump */
|
||||||
|
jumptonext = INVALID_IP;
|
||||||
|
falseblock = 0;
|
||||||
|
|
||||||
|
/* eliminate PUSH_TRUE as well */
|
||||||
|
moo->c->mth.code.len = precondpos;
|
||||||
|
postcondpos = precondpos;
|
||||||
|
}
|
||||||
|
else if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE)
|
||||||
|
{
|
||||||
|
jumptonext = INVALID_IP;
|
||||||
|
/* mark that the conditional is false. instructions will get eliminated below */
|
||||||
|
falseblock = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* remember position of the jump_forward_if_false instruction to be generated */
|
||||||
|
jumptonext = moo->c->mth.code.len;
|
||||||
|
/* specifying MAX_CODE_JUMP causes emit_single_param_instruction() to
|
||||||
|
* produce the long jump instruction (BCODE_JUMP_FORWARD_X) */
|
||||||
|
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_IF_FALSE_0, MAX_CODE_JUMP) <= -1) goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
GET_TOKEN (moo); /* get { */
|
GET_TOKEN (moo); /* get { */
|
||||||
brace_loc = *TOKEN_LOC(moo);
|
brace_loc = *TOKEN_LOC(moo);
|
||||||
if (compile_braced_block(moo) <= -1) goto oops;
|
if (compile_braced_block(moo) <= -1) goto oops;
|
||||||
|
|
||||||
/* emit code to jump to the end */
|
if (jumptonext == INVALID_IP)
|
||||||
/*jumptoend[jumptoend_count++] = moo->c->mth.code.len;*/
|
{
|
||||||
if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1) goto oops;
|
if (falseblock)
|
||||||
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) goto oops;
|
{
|
||||||
|
moo->c->mth.code.len = precondpos;
|
||||||
|
postcondpos = precondpos;
|
||||||
|
}
|
||||||
|
else if (endoftrueblock == INVALID_IP)
|
||||||
|
{
|
||||||
|
/* update the end position of the first true block */
|
||||||
|
endoftrueblock = moo->c->mth.code.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GET_TOKEN (moo); /* get the next token after } */
|
GET_TOKEN (moo); /* get the next token after } */
|
||||||
}
|
} while (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF);
|
||||||
|
|
||||||
if (patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
if (jumptonext != INVALID_IP &&
|
||||||
|
patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
||||||
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
|
||||||
{
|
{
|
||||||
@ -4596,10 +4627,16 @@ static int compile_if_expression (moo_t* moo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* emit code to push nil if no 'else' part exists */
|
/* emit an instruction to push nil if no 'else' part exists */
|
||||||
if (emit_byte_instruction (moo, BCODE_PUSH_NIL) <= -1) goto oops;
|
if (emit_byte_instruction (moo, BCODE_PUSH_NIL) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (endoftrueblock != INVALID_IP)
|
||||||
|
{
|
||||||
|
/* eliminate all instructions after the end of the first true block found */
|
||||||
|
moo->c->mth.code.len = endoftrueblock;
|
||||||
|
}
|
||||||
|
|
||||||
/* patch instructions that jumps to the end of if expression */
|
/* patch instructions that jumps to the end of if expression */
|
||||||
for (jumptoend_chunk = jumptoend.head, i = 0; jumptoend_chunk; jumptoend_chunk = jumptoend_chunk->next)
|
for (jumptoend_chunk = jumptoend.head, i = 0; jumptoend_chunk; jumptoend_chunk = jumptoend_chunk->next)
|
||||||
{
|
{
|
||||||
@ -4819,7 +4856,7 @@ skip_emitting_jump_backward:
|
|||||||
|
|
||||||
/* update jump instructions emitted for break */
|
/* update jump instructions emitted for break */
|
||||||
if (update_loop_jumps (moo, &loop->break_ip_pool, moo->c->mth.code.len) <= -1) return -1;
|
if (update_loop_jumps (moo, &loop->break_ip_pool, moo->c->mth.code.len) <= -1) return -1;
|
||||||
free_loop (moo, loop);
|
free_loop (moo, loop); /* destroy the unlinked loop information */
|
||||||
loop = MOO_NULL;
|
loop = MOO_NULL;
|
||||||
loop_pushed = 0;
|
loop_pushed = 0;
|
||||||
|
|
||||||
|
@ -3518,7 +3518,8 @@ int moo_execute (moo_t* moo)
|
|||||||
case BCODE_JUMP_BACKWARD_IF_TRUE_X:
|
case BCODE_JUMP_BACKWARD_IF_TRUE_X:
|
||||||
FETCH_PARAM_CODE_TO (moo, b1);
|
FETCH_PARAM_CODE_TO (moo, b1);
|
||||||
LOG_INST_1 (moo, "jump_backward_if_true %zu", b1);
|
LOG_INST_1 (moo, "jump_backward_if_true %zu", b1);
|
||||||
if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= b1;
|
/*if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= b1;*/
|
||||||
|
if (MOO_STACK_GETTOP(moo) != moo->_false) moo->ip -= b1;
|
||||||
MOO_STACK_POP (moo);
|
MOO_STACK_POP (moo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3527,7 +3528,8 @@ int moo_execute (moo_t* moo)
|
|||||||
case BCODE_JUMP_BACKWARD_IF_TRUE_2:
|
case BCODE_JUMP_BACKWARD_IF_TRUE_2:
|
||||||
case BCODE_JUMP_BACKWARD_IF_TRUE_3:
|
case BCODE_JUMP_BACKWARD_IF_TRUE_3:
|
||||||
LOG_INST_1 (moo, "jump_backward_if_true %zu", (moo_oow_t)(bcode & 0x3));
|
LOG_INST_1 (moo, "jump_backward_if_true %zu", (moo_oow_t)(bcode & 0x3));
|
||||||
if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= (bcode & 0x3); /* low 2 bits */
|
/*if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= (bcode & 0x3);*/ /* low 2 bits */
|
||||||
|
if (MOO_STACK_GETTOP(moo) != moo->_false) moo->ip -= (bcode & 0x3);
|
||||||
MOO_STACK_POP (moo);
|
MOO_STACK_POP (moo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3560,7 +3562,8 @@ int moo_execute (moo_t* moo)
|
|||||||
case BCODE_JUMP2_BACKWARD_IF_TRUE:
|
case BCODE_JUMP2_BACKWARD_IF_TRUE:
|
||||||
FETCH_PARAM_CODE_TO (moo, b1);
|
FETCH_PARAM_CODE_TO (moo, b1);
|
||||||
LOG_INST_1 (moo, "jump2_backward_if_true %zu", b1);
|
LOG_INST_1 (moo, "jump2_backward_if_true %zu", b1);
|
||||||
if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= MAX_CODE_JUMP + b1;
|
/* if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= MAX_CODE_JUMP + b1; */
|
||||||
|
if (MOO_STACK_GETTOP(moo) != moo->_false) moo->ip -= MAX_CODE_JUMP + b1;
|
||||||
MOO_STACK_POP (moo);
|
MOO_STACK_POP (moo);
|
||||||
break;
|
break;
|
||||||
/* -------------------------------------------------------- */
|
/* -------------------------------------------------------- */
|
||||||
|
@ -96,7 +96,7 @@ int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_oow_t heapsz, const moo_vmprim_t
|
|||||||
moo->option.dfl_sysdic_size = MOO_DFL_SYSDIC_SIZE;
|
moo->option.dfl_sysdic_size = MOO_DFL_SYSDIC_SIZE;
|
||||||
moo->option.dfl_procstk_size = MOO_DFL_PROCSTK_SIZE;
|
moo->option.dfl_procstk_size = MOO_DFL_PROCSTK_SIZE;
|
||||||
|
|
||||||
/* TODO: intoduct a permanent heap */
|
/* TODO: introduce a permanent heap */
|
||||||
/*moo->permheap = moo_makeheap (moo, what is the best size???);
|
/*moo->permheap = moo_makeheap (moo, what is the best size???);
|
||||||
if (!moo->permheap) goto oops; */
|
if (!moo->permheap) goto oops; */
|
||||||
moo->curheap = moo_makeheap (moo, heapsz);
|
moo->curheap = moo_makeheap (moo, heapsz);
|
||||||
|
Loading…
Reference in New Issue
Block a user