enhanced compile_if_expression() not to eliminate blocks containing one or more labels
This commit is contained in:
parent
b2ac09072b
commit
3e1aded8a8
@ -94,7 +94,7 @@ int main (int argc, char* argv[])
|
|||||||
{ ":input-charset", '\0' },
|
{ ":input-charset", '\0' },
|
||||||
{ ":log-charset", '\0' },
|
{ ":log-charset", '\0' },
|
||||||
#if defined(MOO_BUILD_DEBUG)
|
#if defined(MOO_BUILD_DEBUG)
|
||||||
{ ":debug", '\0' }, /* NOTE: there is no short option for --debug */
|
{ ":debug", '\0' }, /* [NOTE] there is no short option for --debug */
|
||||||
#endif
|
#endif
|
||||||
{ MOO_NULL, '\0' }
|
{ MOO_NULL, '\0' }
|
||||||
};
|
};
|
||||||
|
@ -250,7 +250,7 @@ extend MethodContext
|
|||||||
|
|
||||||
if (self isExceptionContext)
|
if (self isExceptionContext)
|
||||||
{
|
{
|
||||||
/* NOTE: the following loop scans all parameters to the on:do: method.
|
/* [NOTE] the following loop scans all parameters to the on:do: method.
|
||||||
* if the on:do: method contains local temporary variables,
|
* if the on:do: method contains local temporary variables,
|
||||||
* you must change this function to skip scanning local variables.
|
* you must change this function to skip scanning local variables.
|
||||||
* the current on:do: method has 1 local variable declared.
|
* the current on:do: method has 1 local variable declared.
|
||||||
|
@ -109,8 +109,8 @@ class MyObject(Object)
|
|||||||
'too many arguments'
|
'too many arguments'
|
||||||
'too many block temporaries'
|
'too many block temporaries'
|
||||||
'too many block arguments'
|
'too many block arguments'
|
||||||
'too large block'
|
'array expression too large'
|
||||||
'too large array expression'
|
'instruction data too large'
|
||||||
'wrong primitive function number'
|
'wrong primitive function number'
|
||||||
'wrong primitive function identifier'
|
'wrong primitive function identifier'
|
||||||
'wrong primitive function argument definition'
|
'wrong primitive function argument definition'
|
||||||
|
190
moo/lib/comp.c
190
moo/lib/comp.c
@ -908,7 +908,7 @@ static void fini_oow_pool (moo_t* moo, moo_oow_pool_t* pool)
|
|||||||
* to reuse it */
|
* to reuse it */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_to_oow_pool (moo_t* moo, moo_oow_pool_t* pool, moo_oow_t v)
|
static int add_to_oow_pool (moo_t* moo, moo_oow_pool_t* pool, moo_oow_t v, const moo_ioloc_t* loc)
|
||||||
{
|
{
|
||||||
moo_oow_t idx;
|
moo_oow_t idx;
|
||||||
|
|
||||||
@ -925,7 +925,8 @@ static int add_to_oow_pool (moo_t* moo, moo_oow_pool_t* pool, moo_oow_t v)
|
|||||||
pool->tail = chunk;
|
pool->tail = chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
pool->tail->buf[idx] = v;
|
pool->tail->buf[idx].v = v;
|
||||||
|
pool->tail->buf[idx].loc = *loc;
|
||||||
pool->count++;
|
pool->count++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2703,7 +2704,7 @@ static MOO_INLINE int emit_backward_jump_instruction (moo_t* moo, int cmd, moo_o
|
|||||||
return emit_single_param_instruction(moo, cmd, offset + adj, srcloc);
|
return emit_single_param_instruction(moo, cmd, offset + adj, srcloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int patch_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_oow_t jt, moo_ioloc_t* errloc)
|
static int patch_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_oow_t jt)
|
||||||
{
|
{
|
||||||
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
|
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
|
||||||
moo_oow_t code_size;
|
moo_oow_t code_size;
|
||||||
@ -2739,8 +2740,7 @@ static int patch_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_oow_t
|
|||||||
|
|
||||||
if (code_size > MAX_CODE_JUMP * 2)
|
if (code_size > MAX_CODE_JUMP * 2)
|
||||||
{
|
{
|
||||||
/* TODO: change error code or get it as a parameter */
|
moo_seterrnum (moo, MOO_ERANGE);
|
||||||
moo_setsynerr (moo, MOO_SYNERR_BLKFLOOD, errloc, MOO_NULL);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2796,8 +2796,12 @@ static int update_loop_jumps (moo_t* moo, moo_oow_pool_t* pool, moo_oow_t jt)
|
|||||||
{
|
{
|
||||||
for (j = 0; j < MOO_COUNTOF(pool->static_chunk.buf) && i < pool->count; j++)
|
for (j = 0; j < MOO_COUNTOF(pool->static_chunk.buf) && i < pool->count; j++)
|
||||||
{
|
{
|
||||||
if (chunk->buf[j] != INVALID_IP &&
|
if (chunk->buf[j].v != INVALID_IP &&
|
||||||
patch_forward_jump_instruction(moo, chunk->buf[j], jt, MOO_NULL) <= -1) return -1;
|
patch_forward_jump_instruction(moo, chunk->buf[j].v, jt) <= -1)
|
||||||
|
{
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_INSTFLOOD, &chunk->buf[j].loc, MOO_NULL, "unable to patch conditional loop jump");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2815,17 +2819,17 @@ static void adjust_loop_jumps_for_elimination (moo_t* moo, moo_oow_pool_t* pool,
|
|||||||
{
|
{
|
||||||
for (j = 0; j < MOO_COUNTOF(pool->static_chunk.buf) && i < pool->count; j++)
|
for (j = 0; j < MOO_COUNTOF(pool->static_chunk.buf) && i < pool->count; j++)
|
||||||
{
|
{
|
||||||
if (chunk->buf[j] != INVALID_IP)
|
if (chunk->buf[j].v != INVALID_IP)
|
||||||
{
|
{
|
||||||
if (chunk->buf[j] >= start && chunk->buf[j] <= end)
|
if (chunk->buf[j].v >= start && chunk->buf[j].v <= end)
|
||||||
{
|
{
|
||||||
/* invalidate the instruction position */
|
/* invalidate the instruction position */
|
||||||
chunk->buf[j] = INVALID_IP;
|
chunk->buf[j].v = INVALID_IP;
|
||||||
}
|
}
|
||||||
else if (chunk->buf[j] > end && chunk->buf[j] < ((moo_cunit_class_t*)moo->c->cunit)->mth.code.len)
|
else if (chunk->buf[j].v > end && chunk->buf[j].v < ((moo_cunit_class_t*)moo->c->cunit)->mth.code.len)
|
||||||
{
|
{
|
||||||
/* decrement the instruction position */
|
/* decrement the instruction position */
|
||||||
chunk->buf[j] -= end - start + 1;
|
chunk->buf[j].v -= end - start + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@ -2930,7 +2934,7 @@ static MOO_INLINE void pop_loop (moo_t* moo)
|
|||||||
static MOO_INLINE int inject_break_to_loop (moo_t* moo, const moo_ioloc_t* srcloc)
|
static MOO_INLINE int inject_break_to_loop (moo_t* moo, const moo_ioloc_t* srcloc)
|
||||||
{
|
{
|
||||||
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
|
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
|
||||||
if (add_to_oow_pool(moo, &cc->mth.loop->break_ip_pool, cc->mth.code.len) <= -1 ||
|
if (add_to_oow_pool(moo, &cc->mth.loop->break_ip_pool, cc->mth.code.len, srcloc) <= -1 ||
|
||||||
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD, MAX_CODE_JUMP, srcloc) <= -1) return -1;
|
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD, MAX_CODE_JUMP, srcloc) <= -1) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2940,7 +2944,7 @@ static MOO_INLINE int inject_continue_to_loop (moo_t* moo, const moo_ioloc_t* sr
|
|||||||
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
|
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
|
||||||
/* used for a do-while loop. jump forward because the conditional
|
/* used for a do-while loop. jump forward because the conditional
|
||||||
* is at the end of the do-while loop */
|
* is at the end of the do-while loop */
|
||||||
if (add_to_oow_pool(moo, &cc->mth.loop->continue_ip_pool, cc->mth.code.len) <= -1 ||
|
if (add_to_oow_pool(moo, &cc->mth.loop->continue_ip_pool, cc->mth.code.len, srcloc) <= -1 ||
|
||||||
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD, MAX_CODE_JUMP, srcloc) <= -1) return -1;
|
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD, MAX_CODE_JUMP, srcloc) <= -1) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -5017,7 +5021,11 @@ static int compile_block_expression (moo_t* moo)
|
|||||||
|
|
||||||
if (emit_byte_instruction(moo, BCODE_RETURN_FROM_BLOCK, TOKEN_LOC(moo)) <= -1) return -1;
|
if (emit_byte_instruction(moo, BCODE_RETURN_FROM_BLOCK, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
|
|
||||||
if (patch_forward_jump_instruction(moo, jump_inst_pos, cc->mth.code.len, &block_loc) <= -1) return -1;
|
if (patch_forward_jump_instruction(moo, jump_inst_pos, cc->mth.code.len) <= -1)
|
||||||
|
{
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_INSTFLOOD, &block_loc, MOO_NULL, "unable to patch block jump");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* restore the temporary count */
|
/* restore the temporary count */
|
||||||
cc->mth.tmprs.len = saved_tmprs_len;
|
cc->mth.tmprs.len = saved_tmprs_len;
|
||||||
@ -5712,9 +5720,9 @@ static int compile_unary_message (moo_t* moo, int to_super)
|
|||||||
|
|
||||||
GET_TOKEN(moo);
|
GET_TOKEN(moo);
|
||||||
|
|
||||||
/* NOTE: since the actual method may not be known at the compile time,
|
/* [NOTE] since the actual method may not be known at the compile time,
|
||||||
* i can't check if nargs will match the number of arguments
|
* i can't check if nargs will match the number of arguments
|
||||||
* expected by the method */
|
* expected by the method */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emit_double_param_instruction(moo, send_message_cmd[to_super], nargs, index, &sel_loc) <= -1) return -1;
|
if (emit_double_param_instruction(moo, send_message_cmd[to_super], nargs, index, &sel_loc) <= -1) return -1;
|
||||||
@ -5987,7 +5995,7 @@ start_over:
|
|||||||
int bcode;
|
int bcode;
|
||||||
bcode = (TOKEN_TYPE(moo) == MOO_IOTOK_AND)? BCODE_JUMP_FORWARD_IF_FALSE: BCODE_JUMP_FORWARD_IF_TRUE;
|
bcode = (TOKEN_TYPE(moo) == MOO_IOTOK_AND)? BCODE_JUMP_FORWARD_IF_FALSE: BCODE_JUMP_FORWARD_IF_TRUE;
|
||||||
/* TODO: optimization if the expression is a known constant that can be determined to be boolean */
|
/* TODO: optimization if the expression is a known constant that can be determined to be boolean */
|
||||||
if (add_to_oow_pool(moo, &jumptoend, cc->mth.code.len) <= -1 ||
|
if (add_to_oow_pool(moo, &jumptoend, cc->mth.code.len, TOKEN_LOC(moo)) <= -1 ||
|
||||||
emit_single_param_instruction(moo, bcode, MAX_CODE_JUMP, TOKEN_LOC(moo)) <= -1 ||
|
emit_single_param_instruction(moo, bcode, MAX_CODE_JUMP, TOKEN_LOC(moo)) <= -1 ||
|
||||||
emit_byte_instruction(moo, BCODE_POP_STACKTOP, TOKEN_LOC(moo)) <= -1) goto oops;
|
emit_byte_instruction(moo, BCODE_POP_STACKTOP, TOKEN_LOC(moo)) <= -1) goto oops;
|
||||||
GET_TOKEN (moo);
|
GET_TOKEN (moo);
|
||||||
@ -6011,15 +6019,17 @@ start_over:
|
|||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch instructions that jumps to the end of if expression */
|
/* patch instructions that jumps to the end of logical expression for short-circuited evaluation */
|
||||||
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)
|
||||||
{
|
{
|
||||||
/* pass expr_loc to every call to patch_forward_jump_instruction().
|
|
||||||
* it's harmless because if the first call doesn't flood, the subseqent
|
|
||||||
* call will never flood either. */
|
|
||||||
for (j = 0; j < MOO_COUNTOF(jumptoend.static_chunk.buf) && i < jumptoend.count; j++)
|
for (j = 0; j < MOO_COUNTOF(jumptoend.static_chunk.buf) && i < jumptoend.count; j++)
|
||||||
{
|
{
|
||||||
if (patch_forward_jump_instruction (moo, jumptoend_chunk->buf[j], cc->mth.code.len, &expr_loc) <= -1) goto oops;
|
if (patch_forward_jump_instruction (moo, jumptoend_chunk->buf[j].v, cc->mth.code.len) <= -1)
|
||||||
|
{
|
||||||
|
/* the logical expression is too large to patch the jump instruction */
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_INSTFLOOD, &expr_loc, MOO_NULL, "unable to patch logical operator jump");
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6274,6 +6284,7 @@ static int compile_if_expression (moo_t* moo)
|
|||||||
moo_oow_t jumptonext, precondpos, postcondpos, endoftrueblock;
|
moo_oow_t jumptonext, precondpos, postcondpos, endoftrueblock;
|
||||||
moo_ioloc_t if_loc, brace_loc;
|
moo_ioloc_t if_loc, brace_loc;
|
||||||
int jmpop_inst, push_true_inst, push_false_inst;
|
int jmpop_inst, push_true_inst, push_false_inst;
|
||||||
|
moo_label_t* la, * lb;
|
||||||
|
|
||||||
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_IF || TOKEN_TYPE(moo) == MOO_IOTOK_IFNOT);
|
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_IF || TOKEN_TYPE(moo) == MOO_IOTOK_IFNOT);
|
||||||
if_loc = *TOKEN_LOC(moo);
|
if_loc = *TOKEN_LOC(moo);
|
||||||
@ -6299,46 +6310,48 @@ static int compile_if_expression (moo_t* moo)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
enum { COND_NORMAL, COND_TRUE, COND_FALSE } cond_type = COND_NORMAL; /* normal condition */
|
|
||||||
|
|
||||||
GET_TOKEN (moo); /* get ( */
|
GET_TOKEN (moo); /* get ( */
|
||||||
precondpos = cc->mth.code.len;
|
precondpos = cc->mth.code.len;
|
||||||
|
|
||||||
if (jumptonext != INVALID_IP &&
|
if (jumptonext != INVALID_IP &&
|
||||||
patch_forward_jump_instruction(moo, jumptonext, precondpos, &brace_loc) <= -1) goto oops;
|
patch_forward_jump_instruction(moo, jumptonext, precondpos) <= -1)
|
||||||
|
{
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_INSTFLOOD, &brace_loc, MOO_NULL, "unable to patch conditional branching jump");
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
if (compile_conditional(moo) <= -1) goto oops;
|
if (compile_conditional(moo) <= -1) goto oops;
|
||||||
postcondpos = cc->mth.code.len;
|
postcondpos = cc->mth.code.len;
|
||||||
|
|
||||||
if (precondpos + 1 == postcondpos && cc->mth.code.ptr[precondpos] == push_true_inst)
|
/* remember position of the jmpop_forward_if_false instruction to be generated */
|
||||||
{
|
jumptonext = cc->mth.code.len;
|
||||||
/* got 'if (true)' or 'ifnot (false)' */
|
/* BCODE_JMPOP_FORWARD_IF_FALSE is always a long jump instruction.
|
||||||
jumptonext = INVALID_IP; /* indicate that the jump has not been emitted */
|
* just specify MAX_CODE_JUMP for consistency with short jump variants */
|
||||||
cond_type = COND_TRUE;
|
if (emit_single_param_instruction(moo, jmpop_inst, MAX_CODE_JUMP, &if_loc) <= -1) goto oops;
|
||||||
}
|
|
||||||
else if (precondpos + 1 == postcondpos && cc->mth.code.ptr[precondpos] == push_false_inst)
|
|
||||||
{
|
|
||||||
/* got 'if (false)' or 'ifnot (true)' */
|
|
||||||
jumptonext = INVALID_IP; /* indicate that the jump has not been emitted */
|
|
||||||
cond_type = COND_FALSE; /* mark that the conditional is false. instructions will get eliminated below */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* remember position of the jmpop_forward_if_false instruction to be generated */
|
|
||||||
jumptonext = cc->mth.code.len;
|
|
||||||
/* BCODE_JMPOP_FORWARD_IF_FALSE is always a long jump instruction.
|
|
||||||
* just specify MAX_CODE_JUMP for consistency with short jump variants */
|
|
||||||
if (emit_single_param_instruction(moo, jmpop_inst, MAX_CODE_JUMP, &if_loc) <= -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;
|
|
||||||
|
|
||||||
switch (cond_type)
|
la = cc->mth._label;
|
||||||
|
if (compile_braced_block(moo) <= -1) goto oops;
|
||||||
|
lb = cc->mth._label;
|
||||||
|
|
||||||
|
/* [NOTE]
|
||||||
|
* it checks by comparing 'la' and 'b' if there has been a label found inside a braced block.
|
||||||
|
* the code below doesn't eliminate instructions emitted of a braced block containing one or
|
||||||
|
* more labels.
|
||||||
|
*
|
||||||
|
* the check is suboptimal and primitive. an optimizing compiler needs to check if the actual
|
||||||
|
* jump is to be made made into the blcok. TODO: optimize it further
|
||||||
|
*/
|
||||||
|
if (la == lb && precondpos + 1 == postcondpos)
|
||||||
{
|
{
|
||||||
case COND_TRUE:
|
if (cc->mth.code.ptr[precondpos] == push_true_inst)
|
||||||
MOO_ASSERT (moo, jumptonext == INVALID_IP);
|
{
|
||||||
|
/* got 'if (true)' or 'ifnot (false)' */
|
||||||
|
|
||||||
|
eliminate_instructions (moo, jumptonext, jumptonext + MOO_BCODE_LONG_PARAM_SIZE);
|
||||||
|
jumptonext = INVALID_IP;
|
||||||
|
|
||||||
/* eliminate PUSH_TRUE */
|
/* eliminate PUSH_TRUE */
|
||||||
eliminate_instructions (moo, precondpos, precondpos);
|
eliminate_instructions (moo, precondpos, precondpos);
|
||||||
@ -6349,25 +6362,30 @@ static int compile_if_expression (moo_t* moo)
|
|||||||
/* update the end position of the first true block */
|
/* update the end position of the first true block */
|
||||||
endoftrueblock = cc->mth.code.len;
|
endoftrueblock = cc->mth.code.len;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
else if (cc->mth.code.ptr[precondpos] == push_false_inst)
|
||||||
|
{
|
||||||
|
/* got 'if (false)' or 'ifnot (true)' */
|
||||||
|
|
||||||
case COND_FALSE:
|
eliminate_instructions (moo, jumptonext, jumptonext + MOO_BCODE_LONG_PARAM_SIZE);
|
||||||
MOO_ASSERT (moo, jumptonext == INVALID_IP);
|
jumptonext = INVALID_IP;
|
||||||
|
|
||||||
/* the conditional was false. eliminate instructions emitted
|
/* the conditional was false. eliminate instructions emitted
|
||||||
* for the block attached to the conditional */
|
* for the block attached to the conditional */
|
||||||
eliminate_instructions (moo, precondpos, cc->mth.code.len - 1);
|
eliminate_instructions (moo, precondpos, cc->mth.code.len - 1);
|
||||||
postcondpos = precondpos;
|
postcondpos = precondpos;
|
||||||
break;
|
}
|
||||||
|
else goto normal_cond;
|
||||||
case COND_NORMAL:
|
}
|
||||||
MOO_ASSERT (moo, jumptonext != INVALID_IP);
|
else
|
||||||
if (endoftrueblock == INVALID_IP)
|
{
|
||||||
{
|
normal_cond:
|
||||||
/* emit an instruction to jump to the end */
|
if (endoftrueblock == INVALID_IP)
|
||||||
if (add_to_oow_pool(moo, &jumptoend, cc->mth.code.len) <= -1 ||
|
{
|
||||||
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD, MAX_CODE_JUMP, TOKEN_LOC(moo)) <= -1) goto oops;
|
/* emit an instruction to jump to the end */
|
||||||
}
|
if (add_to_oow_pool(moo, &jumptoend, cc->mth.code.len, TOKEN_LOC(moo)) <= -1 ||
|
||||||
|
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD, MAX_CODE_JUMP, TOKEN_LOC(moo)) <= -1) goto oops;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_TOKEN (moo); /* get the next token after } */
|
GET_TOKEN (moo); /* get the next token after } */
|
||||||
@ -6390,8 +6408,13 @@ static int compile_if_expression (moo_t* moo)
|
|||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
if (jumptonext != INVALID_IP &&
|
if (jumptonext != INVALID_IP &&
|
||||||
patch_forward_jump_instruction(moo, jumptonext, cc->mth.code.len, &brace_loc) <= -1) goto oops;
|
patch_forward_jump_instruction(moo, jumptonext, cc->mth.code.len) <= -1)
|
||||||
|
{
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_INSTFLOOD, &brace_loc, MOO_NULL, "unable to patch conditional branching jump");
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
la = cc->mth._label;
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
|
||||||
{
|
{
|
||||||
GET_TOKEN (moo); /* get { */
|
GET_TOKEN (moo); /* get { */
|
||||||
@ -6403,8 +6426,9 @@ static int compile_if_expression (moo_t* moo)
|
|||||||
/* emit an instruction 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, TOKEN_LOC(moo)) <= -1) goto oops;
|
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
|
lb = cc->mth._label;
|
||||||
|
|
||||||
if (endoftrueblock != INVALID_IP)
|
if (la == lb && endoftrueblock != INVALID_IP)
|
||||||
{
|
{
|
||||||
/* eliminate all instructions after the end of the first true block found */
|
/* eliminate all instructions after the end of the first true block found */
|
||||||
eliminate_instructions (moo, endoftrueblock, cc->mth.code.len - 1);
|
eliminate_instructions (moo, endoftrueblock, cc->mth.code.len - 1);
|
||||||
@ -6413,12 +6437,13 @@ static int compile_if_expression (moo_t* moo)
|
|||||||
/* 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)
|
||||||
{
|
{
|
||||||
/* pass if_loc to every call to patch_forward_jump_instruction().
|
|
||||||
* it's harmless because if the first call doesn't flood, the subseqent
|
|
||||||
* call will never flood either. */
|
|
||||||
for (j = 0; j < MOO_COUNTOF(jumptoend.static_chunk.buf) && i < jumptoend.count; j++)
|
for (j = 0; j < MOO_COUNTOF(jumptoend.static_chunk.buf) && i < jumptoend.count; j++)
|
||||||
{
|
{
|
||||||
if (patch_forward_jump_instruction (moo, jumptoend_chunk->buf[j], cc->mth.code.len, &if_loc) <= -1) goto oops;
|
if (patch_forward_jump_instruction(moo, jumptoend_chunk->buf[j].v, cc->mth.code.len) <= -1)
|
||||||
|
{
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_INSTFLOOD, &jumptoend_chunk->buf[j].loc, MOO_NULL, "unable to patch conditional branching jump");
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6521,15 +6546,18 @@ static int compile_while_expression (moo_t* moo) /* or compile_until_expression
|
|||||||
{
|
{
|
||||||
/* the jump offset is out of the representable range by the offset
|
/* the jump offset is out of the representable range by the offset
|
||||||
* portion of the jump instruction */
|
* portion of the jump instruction */
|
||||||
moo_setsynerr (moo, MOO_SYNERR_BLKFLOOD, &while_loc, MOO_NULL);
|
moo_setsynerr (moo, MOO_SYNERR_INSTFLOOD, &while_loc, MOO_NULL);
|
||||||
}
|
}
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond_style != 1)
|
if (cond_style != 1)
|
||||||
{
|
{
|
||||||
/* patch the jump instruction */
|
if (patch_forward_jump_instruction(moo, postcondpos, cc->mth.code.len) <= -1)
|
||||||
if (patch_forward_jump_instruction(moo, postcondpos, cc->mth.code.len, &brace_loc) <= -1) goto oops;
|
{
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_INSTFLOOD, &brace_loc, MOO_NULL, "unable to patch conditional loop jump");
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond_style == -1)
|
if (cond_style == -1)
|
||||||
@ -6642,7 +6670,7 @@ static int compile_do_while_expression (moo_t* moo)
|
|||||||
{
|
{
|
||||||
/* the jump offset is out of the representable range by the offset
|
/* the jump offset is out of the representable range by the offset
|
||||||
* portion of the jump instruction */
|
* portion of the jump instruction */
|
||||||
moo_setsynerr (moo, MOO_SYNERR_BLKFLOOD, &do_loc, MOO_NULL);
|
moo_setsynerr (moo, MOO_SYNERR_INSTFLOOD, &do_loc, MOO_NULL);
|
||||||
}
|
}
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
@ -6841,7 +6869,11 @@ static MOO_INLINE int resolve_goto_label (moo_t* moo, moo_goto_t* _goto)
|
|||||||
MOO_ASSERT (moo, _goto->ip != INVALID_IP);
|
MOO_ASSERT (moo, _goto->ip != INVALID_IP);
|
||||||
MOO_ASSERT (moo, _goto->ip != _label->ip);
|
MOO_ASSERT (moo, _goto->ip != _label->ip);
|
||||||
|
|
||||||
if (patch_forward_jump_instruction(moo, _goto->ip, _label->ip, &_goto->loc) <= -1) return -1;
|
if (patch_forward_jump_instruction(moo, _goto->ip, _label->ip) <= -1)
|
||||||
|
{
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_INSTFLOOD, &_goto->loc, MOO_NULL, "unable to patch unconditional jump");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_label = _label->next;
|
_label = _label->next;
|
||||||
@ -8712,7 +8744,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
|
|||||||
* method-modifier := "(" (#class | #instance)? ")"
|
* method-modifier := "(" (#class | #instance)? ")"
|
||||||
* method-actual-definition := method-name "{" method-tempraries? method-pragma? method-statements* "}"
|
* method-actual-definition := method-name "{" method-tempraries? method-pragma? method-statements* "}"
|
||||||
*
|
*
|
||||||
* NOTE: when extending a class, class-module-import and variable-definition are not allowed.
|
* [NOTE] when extending a class, class-module-import and variable-definition are not allowed.
|
||||||
*/
|
*/
|
||||||
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
|
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
|
||||||
moo_oop_association_t ass;
|
moo_oop_association_t ass;
|
||||||
@ -8878,9 +8910,9 @@ static int __compile_class_definition (moo_t* moo, int class_type)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: I don't mandate that the parent and the child be of the same type.
|
/* [NOTE] I don't mandate that the parent and the child be of the same type.
|
||||||
* Say, for a parent class(#byte(4)), a child can be defined to be
|
* Say, for a parent class(#byte(4)), a child can be defined to be
|
||||||
* class(#word(4)). */
|
* class(#word(4)). */
|
||||||
|
|
||||||
if (cc->non_pointer_instsize < MOO_CLASS_SPEC_NAMED_INSTVARS(spec))
|
if (cc->non_pointer_instsize < MOO_CLASS_SPEC_NAMED_INSTVARS(spec))
|
||||||
{
|
{
|
||||||
|
@ -134,8 +134,8 @@ static moo_ooch_t synerrstr_58[] = {'t','o','o',' ','m','a','n','y',' ','t','e',
|
|||||||
static moo_ooch_t synerrstr_59[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
|
static moo_ooch_t synerrstr_59[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
|
||||||
static moo_ooch_t synerrstr_60[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
|
static moo_ooch_t synerrstr_60[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
|
||||||
static moo_ooch_t synerrstr_61[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'};
|
static moo_ooch_t synerrstr_61[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'};
|
||||||
static moo_ooch_t synerrstr_62[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
|
static moo_ooch_t synerrstr_62[] = {'a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n',' ','t','o','o',' ','l','a','r','g','e','\0'};
|
||||||
static moo_ooch_t synerrstr_63[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'};
|
static moo_ooch_t synerrstr_63[] = {'i','n','s','t','r','u','c','t','i','o','n',' ','d','a','t','a',' ','t','o','o',' ','l','a','r','g','e','\0'};
|
||||||
static moo_ooch_t synerrstr_64[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
|
static moo_ooch_t synerrstr_64[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
|
||||||
static moo_ooch_t synerrstr_65[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
|
static moo_ooch_t synerrstr_65[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
|
||||||
static moo_ooch_t synerrstr_66[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'};
|
static moo_ooch_t synerrstr_66[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'};
|
||||||
|
@ -1321,7 +1321,7 @@ static int delete_sem_from_sem_io_tuple (moo_t* moo, moo_oop_semaphore_t sem, in
|
|||||||
MOO_LOG3 (moo, MOO_LOG_WARN, "Failed to delete an IO semaphored handle %zd at index %zd for %hs\n", io_handle, index, io_type_str[io_type]);
|
MOO_LOG3 (moo, MOO_LOG_WARN, "Failed to delete an IO semaphored handle %zd at index %zd for %hs\n", io_handle, index, io_type_str[io_type]);
|
||||||
if (!force) return -1;
|
if (!force) return -1;
|
||||||
|
|
||||||
/* NOTE:
|
/* [NOTE]
|
||||||
* this means there could be some issue handling the file handles.
|
* this means there could be some issue handling the file handles.
|
||||||
* the file handle might have been closed before reaching here.
|
* the file handle might have been closed before reaching here.
|
||||||
* assuming the callback works correctly, it's not likely that the
|
* assuming the callback works correctly, it's not likely that the
|
||||||
@ -1649,7 +1649,7 @@ static MOO_INLINE moo_oop_method_t find_method_in_class (moo_t* moo, moo_oop_cla
|
|||||||
return (moo_oop_method_t)ass->value;
|
return (moo_oop_method_t)ass->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: moo_seterrXXX() is not called here */
|
/* [NOTE] moo_seterrXXX() is not called here */
|
||||||
return MOO_NULL;
|
return MOO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1665,7 +1665,7 @@ static MOO_INLINE moo_oop_method_t find_method_in_class_chain (moo_t* moo, moo_o
|
|||||||
}
|
}
|
||||||
while ((moo_oop_t)_class != moo->_nil);
|
while ((moo_oop_t)_class != moo->_nil);
|
||||||
|
|
||||||
/* NOTE: moo_seterrXXX() is not called here */
|
/* [NOTE] moo_seterrXXX() is not called here */
|
||||||
return MOO_NULL;
|
return MOO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2192,7 +2192,7 @@ static moo_pfrc_t pf_context_find_exception_handler (moo_t* moo, moo_mod_t* mod,
|
|||||||
size = MOO_OBJ_GET_SIZE(rcv);
|
size = MOO_OBJ_GET_SIZE(rcv);
|
||||||
for (i = MOO_CONTEXT_NAMED_INSTVARS; i < size; i += 2)
|
for (i = MOO_CONTEXT_NAMED_INSTVARS; i < size; i += 2)
|
||||||
{
|
{
|
||||||
/* NOTE: the following loop scans all parameters to the on:do: method.
|
/* [NOTE] the following loop scans all parameters to the on:do: method.
|
||||||
* if the on:do: method contains local temporary variables,
|
* if the on:do: method contains local temporary variables,
|
||||||
* you must change this function to skip scanning local variables.
|
* you must change this function to skip scanning local variables.
|
||||||
* the current on:do: method has 1 local variable declared.
|
* the current on:do: method has 1 local variable declared.
|
||||||
@ -4758,7 +4758,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
* there are other normal processes to run. check IO activities
|
* there are other normal processes to run. check IO activities
|
||||||
* before proceeding to handle normal process scheduling */
|
* before proceeding to handle normal process scheduling */
|
||||||
|
|
||||||
/* NOTE: the check with the multiplexer may happen too frequently
|
/* [NOTE] the check with the multiplexer may happen too frequently
|
||||||
* because this is called everytime process switching is requested.
|
* because this is called everytime process switching is requested.
|
||||||
* the actual callback implementation should try to avoid invoking
|
* the actual callback implementation should try to avoid invoking
|
||||||
* actual system calls too frequently for less overhead. */
|
* actual system calls too frequently for less overhead. */
|
||||||
@ -5071,7 +5071,7 @@ static MOO_INLINE int do_return (moo_t* moo, moo_oob_t bcode, moo_oop_t return_v
|
|||||||
MOO_ASSERT (moo, moo->active_context->origin == moo->processor->active->initial_context->origin);
|
MOO_ASSERT (moo, moo->active_context->origin == moo->processor->active->initial_context->origin);
|
||||||
MOO_ASSERT (moo, moo->active_context->origin == moo->active_context);
|
MOO_ASSERT (moo, moo->active_context->origin == moo->active_context);
|
||||||
|
|
||||||
/* NOTE: this condition is true for the processified block context also.
|
/* [NOTE] this condition is true for the processified block context also.
|
||||||
* moo->active_context->origin == moo->processor->active->initial_context->origin
|
* moo->active_context->origin == moo->processor->active->initial_context->origin
|
||||||
* however, the check here is done after context switching and the
|
* however, the check here is done after context switching and the
|
||||||
* processified block check has been done against the context before switching */
|
* processified block check has been done against the context before switching */
|
||||||
|
@ -670,7 +670,7 @@ static void compact_symbol_table (moo_t* moo, moo_oop_t _nil)
|
|||||||
if (tally <= 0) return;
|
if (tally <= 0) return;
|
||||||
|
|
||||||
bucket = moo->symtab->bucket;
|
bucket = moo->symtab->bucket;
|
||||||
/* NOTE: in theory, the bucket size can be greater than MOO_SMOOI_MAX
|
/* [NOTE] in theory, the bucket size can be greater than MOO_SMOOI_MAX
|
||||||
* as it is an internal header field and is of an unsigned type */
|
* as it is an internal header field and is of an unsigned type */
|
||||||
bucket_size = MOO_OBJ_GET_SIZE(bucket);
|
bucket_size = MOO_OBJ_GET_SIZE(bucket);
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ typedef moo_int32_t moo_uci_t;
|
|||||||
|
|
||||||
typedef moo_uint8_t moo_oob_t;
|
typedef moo_uint8_t moo_oob_t;
|
||||||
|
|
||||||
/* NOTE: sizeof(moo_oop_t) must be equal to sizeof(moo_oow_t) */
|
/* [NOTE] sizeof(moo_oop_t) must be equal to sizeof(moo_oow_t) */
|
||||||
typedef moo_uintptr_t moo_oow_t;
|
typedef moo_uintptr_t moo_oow_t;
|
||||||
typedef moo_intptr_t moo_ooi_t;
|
typedef moo_intptr_t moo_ooi_t;
|
||||||
#define MOO_SIZEOF_OOW_T MOO_SIZEOF_UINTPTR_T
|
#define MOO_SIZEOF_OOW_T MOO_SIZEOF_UINTPTR_T
|
||||||
|
@ -369,7 +369,11 @@ struct moo_code_t
|
|||||||
typedef struct moo_oow_pool_chunk_t moo_oow_pool_chunk_t;
|
typedef struct moo_oow_pool_chunk_t moo_oow_pool_chunk_t;
|
||||||
struct moo_oow_pool_chunk_t
|
struct moo_oow_pool_chunk_t
|
||||||
{
|
{
|
||||||
moo_oow_t buf[16];
|
struct
|
||||||
|
{
|
||||||
|
moo_oow_t v;
|
||||||
|
moo_ioloc_t loc;
|
||||||
|
} buf[16];
|
||||||
moo_oow_pool_chunk_t* next;
|
moo_oow_pool_chunk_t* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -795,7 +795,7 @@ moo_pfbase_t* moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidle
|
|||||||
/* add a new primitive method */
|
/* add a new primitive method */
|
||||||
int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, moo_method_type_t type, const moo_ooch_t* mthname, int variadic, const moo_ooch_t* pfname)
|
int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, moo_method_type_t type, const moo_ooch_t* mthname, int variadic, const moo_ooch_t* pfname)
|
||||||
{
|
{
|
||||||
/* NOTE: this function is a subset of add_compiled_method() in comp.c */
|
/* [NOTE] this function is a subset of add_compiled_method() in comp.c */
|
||||||
|
|
||||||
moo_oop_char_t mnsym, pfidsym;
|
moo_oop_char_t mnsym, pfidsym;
|
||||||
moo_oop_method_t mth;
|
moo_oop_method_t mth;
|
||||||
|
@ -221,7 +221,7 @@ enum moo_obj_type_t
|
|||||||
MOO_OBJ_TYPE_UINT32,
|
MOO_OBJ_TYPE_UINT32,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTE: you can have MOO_OBJ_SHORT, MOO_OBJ_INT
|
/* [NOTE] you can have MOO_OBJ_SHORT, MOO_OBJ_INT
|
||||||
* MOO_OBJ_LONG, MOO_OBJ_FLOAT, MOO_OBJ_DOUBLE, etc
|
* MOO_OBJ_LONG, MOO_OBJ_FLOAT, MOO_OBJ_DOUBLE, etc
|
||||||
* type type field being 6 bits long, you can have up to 64 different types.
|
* type type field being 6 bits long, you can have up to 64 different types.
|
||||||
|
|
||||||
@ -429,7 +429,7 @@ struct moo_obj_word_t
|
|||||||
#define MOO_OBJ_GET_WORD_VAL(oop,idx) ((((moo_oop_word_t)(oop))->slot)[idx])
|
#define MOO_OBJ_GET_WORD_VAL(oop,idx) ((((moo_oop_word_t)(oop))->slot)[idx])
|
||||||
#define MOO_OBJ_GET_LIWORD_VAL(oop,idx) ((((moo_oop_liword_t)(oop))->slot)[idx])
|
#define MOO_OBJ_GET_LIWORD_VAL(oop,idx) ((((moo_oop_liword_t)(oop))->slot)[idx])
|
||||||
|
|
||||||
#define MOO_OBJ_SET_OOP_VAL(oop,idx,val) ((((moo_oop_oop_t)(oop))->slot)[idx] = (val)) /* NOTE: MOO_STORE_OOP() */
|
#define MOO_OBJ_SET_OOP_VAL(oop,idx,val) ((((moo_oop_oop_t)(oop))->slot)[idx] = (val)) /* [NOTE] MOO_STORE_OOP() */
|
||||||
#define MOO_OBJ_SET_CHAR_VAL(oop,idx,val) ((((moo_oop_char_t)(oop))->slot)[idx] = (val))
|
#define MOO_OBJ_SET_CHAR_VAL(oop,idx,val) ((((moo_oop_char_t)(oop))->slot)[idx] = (val))
|
||||||
#define MOO_OBJ_SET_BYTE_VAL(oop,idx,val) ((((moo_oop_byte_t)(oop))->slot)[idx] = (val))
|
#define MOO_OBJ_SET_BYTE_VAL(oop,idx,val) ((((moo_oop_byte_t)(oop))->slot)[idx] = (val))
|
||||||
#define MOO_OBJ_SET_HALFWORD_VAL(oop,idx,val) ((((moo_oop_halfword_t)(oop))->slot)[idx] = (val))
|
#define MOO_OBJ_SET_HALFWORD_VAL(oop,idx,val) ((((moo_oop_halfword_t)(oop))->slot)[idx] = (val))
|
||||||
@ -665,9 +665,9 @@ struct moo_method_t
|
|||||||
#define MOO_METHOD_PREAMBLE_FLAG_DUAL (1 << 2)
|
#define MOO_METHOD_PREAMBLE_FLAG_DUAL (1 << 2)
|
||||||
#define MOO_METHOD_PREAMBLE_FLAG_LENIENT (1 << 3) /* lenient primitive method - no exception upon failure. return an error instead */
|
#define MOO_METHOD_PREAMBLE_FLAG_LENIENT (1 << 3) /* lenient primitive method - no exception upon failure. return an error instead */
|
||||||
|
|
||||||
/* NOTE: if you change the number of instance variables for moo_context_t,
|
/* [NOTE] if you change the number of instance variables for moo_context_t,
|
||||||
* you need to change the defintion of BlockContext and MethodContext.
|
* you need to change the defintion of BlockContext and MethodContext.
|
||||||
* plus, you need to update various exception handling code in MethodContext */
|
* plus, you need to update various exception handling code in MethodContext */
|
||||||
#define MOO_CONTEXT_NAMED_INSTVARS 8
|
#define MOO_CONTEXT_NAMED_INSTVARS 8
|
||||||
typedef struct moo_context_t moo_context_t;
|
typedef struct moo_context_t moo_context_t;
|
||||||
typedef struct moo_context_t* moo_oop_context_t;
|
typedef struct moo_context_t* moo_oop_context_t;
|
||||||
@ -1879,8 +1879,8 @@ enum moo_synerrnum_t
|
|||||||
MOO_SYNERR_ARGFLOOD, /* too many arguments */
|
MOO_SYNERR_ARGFLOOD, /* too many arguments */
|
||||||
MOO_SYNERR_BLKTMPRFLOOD, /* too many block temporaries */
|
MOO_SYNERR_BLKTMPRFLOOD, /* too many block temporaries */
|
||||||
MOO_SYNERR_BLKARGFLOOD, /* too many block arguments */
|
MOO_SYNERR_BLKARGFLOOD, /* too many block arguments */
|
||||||
MOO_SYNERR_BLKFLOOD, /* too large block */
|
|
||||||
MOO_SYNERR_ARREXPFLOOD, /* too large array expression */
|
MOO_SYNERR_ARREXPFLOOD, /* too large array expression */
|
||||||
|
MOO_SYNERR_INSTFLOOD, /* instruction too large */
|
||||||
MOO_SYNERR_PFNUMINVAL, /* wrong primitive function number */
|
MOO_SYNERR_PFNUMINVAL, /* wrong primitive function number */
|
||||||
MOO_SYNERR_PFIDINVAL, /* wrong primitive function identifier */
|
MOO_SYNERR_PFIDINVAL, /* wrong primitive function identifier */
|
||||||
MOO_SYNERR_PFARGDEFINVAL, /* wrong primitive function argument definition */
|
MOO_SYNERR_PFARGDEFINVAL, /* wrong primitive function argument definition */
|
||||||
|
@ -139,7 +139,7 @@ static int _equal_objects (moo_t* moo, moo_oop_t rcv, moo_oop_t arg)
|
|||||||
int n;
|
int n;
|
||||||
/* TODO: remove recursion */
|
/* TODO: remove recursion */
|
||||||
|
|
||||||
/* NOTE: even if the object implements the equality method,
|
/* [NOTE] even if the object implements the equality method,
|
||||||
* this primitive method doesn't honor it. */
|
* this primitive method doesn't honor it. */
|
||||||
n = _equal_objects(moo, MOO_OBJ_GET_OOP_VAL(rcv, i), MOO_OBJ_GET_OOP_VAL(arg, i));
|
n = _equal_objects(moo, MOO_OBJ_GET_OOP_VAL(rcv, i), MOO_OBJ_GET_OOP_VAL(arg, i));
|
||||||
if (n <= 0) return n;
|
if (n <= 0) return n;
|
||||||
|
@ -91,7 +91,7 @@ int moo_equal_uchars (const moo_uch_t* str1, const moo_uch_t* str2, moo_oow_t le
|
|||||||
{
|
{
|
||||||
moo_oow_t i;
|
moo_oow_t i;
|
||||||
|
|
||||||
/* NOTE: you should call this function after having ensured that
|
/* [NOTE] you should call this function after having ensured that
|
||||||
* str1 and str2 are in the same length */
|
* str1 and str2 are in the same length */
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
@ -106,8 +106,8 @@ int moo_equal_bchars (const moo_bch_t* str1, const moo_bch_t* str2, moo_oow_t le
|
|||||||
{
|
{
|
||||||
moo_oow_t i;
|
moo_oow_t i;
|
||||||
|
|
||||||
/* NOTE: you should call this function after having ensured that
|
/* [NOTE] you should call this function after having ensured that
|
||||||
* str1 and str2 are in the same length */
|
* str1 and str2 are in the same length */
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
|
@ -488,7 +488,7 @@ static moo_pfrc_t pf_read_socket (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
return MOO_PF_FAILURE;
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: on EWOULDBLOCK or EGAIN, -1 is returned */
|
/* [NOTE] on EWOULDBLOCK or EGAIN, -1 is returned */
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n));
|
MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n));
|
||||||
|
|
||||||
@ -561,7 +561,7 @@ static moo_pfrc_t pf_write_socket (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
return MOO_PF_FAILURE;
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: on EWOULDBLOCK or EGAIN, -1 is returned */
|
/* [NOTE] on EWOULDBLOCK or EGAIN, -1 is returned */
|
||||||
MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n));
|
MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n));
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(n));
|
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(n));
|
||||||
|
Loading…
Reference in New Issue
Block a user