fixed some issues regarding goto handling
This commit is contained in:
parent
c299101781
commit
11b2629680
@ -117,20 +117,30 @@ ex resume.
|
|||||||
ex resume: value.
|
ex resume: value.
|
||||||
ex return: value.
|
ex return: value.
|
||||||
|
|
||||||
|
### return from context(method/block)
|
||||||
|
|
||||||
|
explicit return operators
|
||||||
|
```
|
||||||
|
^ return_stacktop
|
||||||
|
^^ local_return
|
||||||
|
```
|
||||||
|
|
||||||
|
implicit return when the end of the context is reached
|
||||||
|
* a method context returns the receiver.
|
||||||
|
* a block context returns the last evaluated value. if nothing has been evaluated, nil is returned.
|
||||||
|
|
||||||
### goto
|
### goto
|
||||||
|
|
||||||
```
|
```
|
||||||
goto jump_label.
|
goto jump_label.
|
||||||
|
|
||||||
jump_label:
|
jump_label:
|
||||||
a + b;
|
a + b.
|
||||||
```
|
```
|
||||||
|
|
||||||
useful to make a block return
|
goto inside a block context.
|
||||||
can i deprecate the ^^ operator?
|
|
||||||
|
|
||||||
```
|
```
|
||||||
[ 1 + 2. goto r. 3 + 4. r:]
|
[ 1 + 2. goto r. 3 + 4. r: 99 ]
|
||||||
```
|
```
|
||||||
|
|
||||||
goto must not cross the boundary of the block context.
|
goto must not cross the boundary of the block context.
|
||||||
|
@ -52,6 +52,24 @@ class MyObject(Object)
|
|||||||
].
|
].
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
method(#class) local_return_001
|
||||||
|
{
|
||||||
|
| a b c d|
|
||||||
|
a := 10.
|
||||||
|
c := 2.
|
||||||
|
d := 3.
|
||||||
|
b := ([
|
||||||
|
[
|
||||||
|
a := a + 3.
|
||||||
|
if (a > 10) { ^^77 } // ^^ must return to the calling method despite 2 blocks nested.
|
||||||
|
] value.
|
||||||
|
d := 99. // this is skipped because of ^^77 above.
|
||||||
|
] ensure: [ c := 88 ]). // however, the ensured block must be executed.
|
||||||
|
|
||||||
|
^a == 13 and b == 77 and c == 88 and d == 3.
|
||||||
|
}
|
||||||
|
|
||||||
method(#class) q
|
method(#class) q
|
||||||
{
|
{
|
||||||
| v |
|
| v |
|
||||||
@ -90,11 +108,23 @@ start:
|
|||||||
[([] isKindOf: MethodContext) == false],
|
[([] isKindOf: MethodContext) == false],
|
||||||
[([] isKindOf: Context) == true],
|
[([] isKindOf: Context) == true],
|
||||||
|
|
||||||
// 15-20
|
// 15-19
|
||||||
[("string" isKindOf: String) == true],
|
[("string" isKindOf: String) == true],
|
||||||
[(#symbol isKindOf: String) == true],
|
[(#symbol isKindOf: String) == true],
|
||||||
[("string" isKindOf: Symbol) == false],
|
[("string" isKindOf: Symbol) == false],
|
||||||
[(#symbol isKindOf: Symbol) == true]
|
[(#symbol isKindOf: Symbol) == true],
|
||||||
|
[ [] value == nil ],
|
||||||
|
|
||||||
|
// 20-24
|
||||||
|
[ self local_return_001 ],
|
||||||
|
[ (if (1 > 2) { } else { }) == nil. ],
|
||||||
|
[ (if (1 < 2) { } else { }) == nil. ],
|
||||||
|
[ (if (1 > 2) { } else { goto A01. A01: }) == nil ],
|
||||||
|
[ (if (1 > 2) { } else { 9876. goto A02. A02: }) == 9876 ],
|
||||||
|
|
||||||
|
// 25-29
|
||||||
|
[ [ | a3 | a3:= 20. if (a3 == 21) { a3 := 4321. goto L03 } else { a3 := 1234. goto L03 }. a3 := 8888. L03: a3 ] value == 1234 ],
|
||||||
|
[ [ | a4 | a4:= 21. if (a4 == 21) { a4 := 4321. goto L04 } else { a4 := 1234. goto L04 }. a4 := 8888. L04: a4 ] value == 4321 ]
|
||||||
).
|
).
|
||||||
|
|
||||||
limit := tc size.
|
limit := tc size.
|
||||||
@ -104,11 +134,16 @@ start:
|
|||||||
tb := tc at: idx.
|
tb := tc at: idx.
|
||||||
System log(System.Log.INFO, idx asString, (if (tb value) { " PASS" } else { " FAIL" }), "\n").
|
System log(System.Log.INFO, idx asString, (if (tb value) { " PASS" } else { " FAIL" }), "\n").
|
||||||
].
|
].
|
||||||
(if (true) { a: 10. b: 1p1000. c: 20000 }) dump.
|
|
||||||
[goto B02. A01: 10. B02: 1000. ] value class dump.
|
|
||||||
|
// (if (true) { a: 10. b: 1p1000. c: 20000 }) dump.
|
||||||
|
// [goto B02. A01: 10. B02: 1000. ] value class dump.
|
||||||
self q.
|
self q.
|
||||||
|
|
||||||
[ | a | a := 21. if (a = 21) { goto X02 }. X02: ] value dump. // this causes a stack depletion problem... TODO:
|
//[ | a | a := 21. if (a = 21) { goto X02 }. X02: ] value dump. // this causes a stack depletion problem... TODO:
|
||||||
|
|
||||||
|
//[ a := 4. while (1) { X44: goto X33 }. X33: 1233 dump. if (a < 10) { a := a + 1. 'X44' dump. goto X44 } else { 'ELSE' dump. a := a * 10}. ] value dump.
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
this is horrible... the stack won't be cleared when goto is made...
|
this is horrible... the stack won't be cleared when goto is made...
|
||||||
|
262
moo/lib/comp.c
262
moo/lib/comp.c
@ -4911,132 +4911,6 @@ static int compile_block_expression (moo_t* moo)
|
|||||||
if (emit_single_param_instruction(moo, BCODE_JUMP_FORWARD, MAX_CODE_JUMP, &block_loc) <= -1) return -1;
|
if (emit_single_param_instruction(moo, BCODE_JUMP_FORWARD, MAX_CODE_JUMP, &block_loc) <= -1) return -1;
|
||||||
|
|
||||||
/* compile statements inside a block */
|
/* compile statements inside a block */
|
||||||
#if 0
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
|
||||||
{
|
|
||||||
/* the block is empty */
|
|
||||||
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int empty = 1, n;
|
|
||||||
|
|
||||||
while (TOKEN_TYPE(moo) != MOO_IOTOK_EOF)
|
|
||||||
{
|
|
||||||
n = compile_block_statement(moo);
|
|
||||||
if (n <= -1) return -1;
|
|
||||||
if (n == 8888)
|
|
||||||
{
|
|
||||||
/* compile_block_statement() processed non-statement item like a jump label. */
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
|
||||||
{
|
|
||||||
if (empty && emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* a proper statement has been processed in compile_block_statemnt */
|
|
||||||
empty = 0;
|
|
||||||
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK) break;
|
|
||||||
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
|
||||||
{
|
|
||||||
moo_ioloc_t period_loc = *TOKEN_LOC(moo);
|
|
||||||
GET_TOKEN (moo);
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK) break;
|
|
||||||
if (emit_byte_instruction(moo, BCODE_POP_STACKTOP, &period_loc) <= -1) return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elif 0
|
|
||||||
code_start = cc->mth.code.len;
|
|
||||||
|
|
||||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACK)
|
|
||||||
{
|
|
||||||
moo_oow_t pop_stacktop_pos = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_EOF)
|
|
||||||
{
|
|
||||||
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = compile_block_statement(moo);
|
|
||||||
if (n <= -1) return -1;
|
|
||||||
if (n == 8888)
|
|
||||||
{
|
|
||||||
/* compile_block_statement() processed non-statement item like a jump label. */
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
|
||||||
{
|
|
||||||
/* eliminate BCODE_POP_STACKTOP produced in the else block below
|
|
||||||
* becuase the non-steatemnt item is the last item before the closing bracket */
|
|
||||||
if (pop_stacktop_pos > 0) eliminate_instructions (moo, pop_stacktop_pos, cc->mth.code.len - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (n == 7777)
|
|
||||||
{
|
|
||||||
/* goto statement -
|
|
||||||
* the goto statement looks like a normal statement, but it never pushes a value.
|
|
||||||
* so no pop_stacktop instruction needs to get injected */
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
|
||||||
{
|
|
||||||
/* eliminate BCODE_POP_STACKTOP produced in the else block below
|
|
||||||
* because the non-steatemnt item is the last item before the closing bracket */
|
|
||||||
if (pop_stacktop_pos > 0) eliminate_instructions (moo, pop_stacktop_pos, cc->mth.code.len - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
|
||||||
{
|
|
||||||
GET_TOKEN (moo);
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK) break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* a proper statement has been processed in compile_block_statemnt */
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK) break;
|
|
||||||
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
|
||||||
{
|
|
||||||
moo_ioloc_t period_loc = *TOKEN_LOC(moo);
|
|
||||||
GET_TOKEN (moo);
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK) break;
|
|
||||||
|
|
||||||
pop_stacktop_pos = cc->mth.code.len;
|
|
||||||
if (emit_byte_instruction(moo, BCODE_POP_STACKTOP, &period_loc) <= -1) return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cc->mth.code.len == code_start)
|
|
||||||
{
|
|
||||||
/* the block is empty */
|
|
||||||
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
code_start = cc->mth.code.len;
|
code_start = cc->mth.code.len;
|
||||||
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
|
|
||||||
@ -5130,19 +5004,16 @@ static int compile_block_expression (moo_t* moo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
MOO_ASSERT (moo, cc->mth.code.len > code_start);
|
||||||
if (cc->mth.code.len > 2 && cc->mth.code.len - 2 == code_start)
|
if (cc->mth.code.len - code_start >= 2 &&
|
||||||
|
cc->mth.code.ptr[code_start] == BCODE_PUSH_NIL &&
|
||||||
|
cc->mth.code.ptr[code_start + 1] == BCODE_POP_STACKTOP)
|
||||||
{
|
{
|
||||||
if (cc->mth.code.ptr[code_start] == BCODE_PUSH_NIL &&
|
/* elminnate the block prologue */
|
||||||
cc->mth.code.ptr[code_start + 1] == BCODE_POP_STACKTOP &&
|
eliminate_instructions(moo, code_start, code_start + 1);
|
||||||
no goto found... <--- it's a bit tricy since goto can be inside other expressions like 'if' expression.
|
}
|
||||||
{
|
|
||||||
eliminate_instructions(moo, code_start, code_start + 2);
|
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -6177,6 +6048,7 @@ static int compile_braced_block (moo_t* moo)
|
|||||||
|
|
||||||
GET_TOKEN (moo);
|
GET_TOKEN (moo);
|
||||||
|
|
||||||
|
#if 0
|
||||||
code_start = cc->mth.code.len;
|
code_start = cc->mth.code.len;
|
||||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
|
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
|
||||||
{
|
{
|
||||||
@ -6244,6 +6116,122 @@ static int compile_braced_block (moo_t* moo)
|
|||||||
/* the block doesn't contain an instruction at all */
|
/* the block doesn't contain an instruction at all */
|
||||||
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
code_start = cc->mth.code.len;
|
||||||
|
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
|
||||||
|
{
|
||||||
|
moo_oow_t pop_stacktop_pos;
|
||||||
|
|
||||||
|
pop_stacktop_pos = cc->mth.code.len;
|
||||||
|
if (emit_byte_instruction(moo, BCODE_POP_STACKTOP, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_EOF)
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = compile_block_statement(moo);
|
||||||
|
if (n <= -1) return -1;
|
||||||
|
if (n == 8888)
|
||||||
|
{
|
||||||
|
/* compile_block_statement() processed non-statement item like a jump label. */
|
||||||
|
MOO_ASSERT (moo, cc->mth._label != MOO_NULL);
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
/* the last label inside {} must be followed by a valid statement */
|
||||||
|
moo_oocs_t labname;
|
||||||
|
labname.ptr = (moo_ooch_t*)(cc->mth._label + 1);
|
||||||
|
labname.len = moo_count_oocstr(labname.ptr);
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_LABELATEND, &cc->mth._label->loc, &labname, "label at end of braced block");
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
/* unlike in [], a label can be placed at the back of the block.
|
||||||
|
* to keep the last evaluated value, eliminate the pop_stacktop instruction */
|
||||||
|
if (pop_stacktop_pos > 0) eliminate_instructions (moo, pop_stacktop_pos, pop_stacktop_pos);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (n == 7777)
|
||||||
|
{
|
||||||
|
/* goto statement */
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE)
|
||||||
|
{
|
||||||
|
/* jumping somewhere inside {} is different from inside [].
|
||||||
|
* [] needs to leave a return value when leaving the block.
|
||||||
|
* {} doesn't need to because {} can only be used as part of 'if', 'while', 'until', 'do'.
|
||||||
|
* that means, the last evaluated value inside {} before exit is used
|
||||||
|
* as a lvalue but the jump target can't be break into an assignment statement.
|
||||||
|
*
|
||||||
|
* a : 3.
|
||||||
|
* a := if (1) { goto L30 }. // if jump to L30 is made inside {}, assignment to 'a' is skipped.
|
||||||
|
* // so the evaluation result of the 'if' statement goes unused.
|
||||||
|
* L30: b := a + 1. // therefore, 'a' holds 3.
|
||||||
|
*
|
||||||
|
* it is not allowed to place label inside "b := a + 1".
|
||||||
|
* so the pop_stacktop produced must not be eliminated.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||||
|
{
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pop_stacktop_pos = cc->mth.code.len; /* remember the position of the last POP_STACKTOP for elimination */
|
||||||
|
if (emit_byte_instruction(moo, BCODE_POP_STACKTOP, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE)
|
||||||
|
{
|
||||||
|
eliminate_instructions (moo, pop_stacktop_pos, pop_stacktop_pos);
|
||||||
|
pop_stacktop_pos = INVALID_IP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||||
|
{
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE)
|
||||||
|
{
|
||||||
|
eliminate_instructions(moo, pop_stacktop_pos, pop_stacktop_pos);
|
||||||
|
pop_stacktop_pos = INVALID_IP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
MOO_ASSERT (moo, cc->mth.code.len > code_start);
|
||||||
|
if (cc->mth.code.len - code_start >= 2 &&
|
||||||
|
cc->mth.code.ptr[code_start] == BCODE_PUSH_NIL &&
|
||||||
|
cc->mth.code.ptr[code_start + 1] == BCODE_POP_STACKTOP)
|
||||||
|
{
|
||||||
|
/* elminnate the block prologue */
|
||||||
|
eliminate_instructions(moo, code_start, code_start + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
|
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
|
||||||
{
|
{
|
||||||
@ -7123,7 +7111,7 @@ static int compile_method_statements (moo_t* moo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* a proper statement has been processed */
|
/* a proper statement or a goto statement(if n == 7777) has been processed */
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||||
{
|
{
|
||||||
/* period after a statement */
|
/* period after a statement */
|
||||||
|
@ -5102,8 +5102,6 @@ static MOO_INLINE int do_return (moo_t* moo, moo_oob_t bcode, moo_oop_t return_v
|
|||||||
|
|
||||||
static MOO_INLINE void do_return_from_block (moo_t* moo)
|
static MOO_INLINE void do_return_from_block (moo_t* moo)
|
||||||
{
|
{
|
||||||
LOG_INST0 (moo, "return_from_block");
|
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->active_context) == moo->_block_context);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->active_context) == moo->_block_context);
|
||||||
|
|
||||||
if (moo->active_context == moo->processor->active->initial_context)
|
if (moo->active_context == moo->processor->active->initial_context)
|
||||||
@ -5974,7 +5972,7 @@ static int __execute (moo_t* moo)
|
|||||||
handle_return:
|
handle_return:
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
if ((n = do_return (moo, bcode, return_value)) <= -1) return -1;
|
if ((n = do_return(moo, bcode, return_value)) <= -1) return -1;
|
||||||
if (n == 0) EXIT_DISPATCH_LOOP();
|
if (n == 0) EXIT_DISPATCH_LOOP();
|
||||||
}
|
}
|
||||||
NEXT_INST();
|
NEXT_INST();
|
||||||
@ -5986,6 +5984,7 @@ static int __execute (moo_t* moo)
|
|||||||
goto handle_return;
|
goto handle_return;
|
||||||
|
|
||||||
ON_INST(BCODE_RETURN_FROM_BLOCK)
|
ON_INST(BCODE_RETURN_FROM_BLOCK)
|
||||||
|
LOG_INST0 (moo, "return_from_block");
|
||||||
do_return_from_block (moo);
|
do_return_from_block (moo);
|
||||||
NEXT_INST();
|
NEXT_INST();
|
||||||
|
|
||||||
|
@ -1047,4 +1047,5 @@ typedef struct moo_t moo_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MOO_STATIC_ASSERT_EXPR(expr) ((void)MOO_SIZEOF(char[(expr)? 1: -1]))
|
#define MOO_STATIC_ASSERT_EXPR(expr) ((void)MOO_SIZEOF(char[(expr)? 1: -1]))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user