Add break

Don't use this instruction unless you know what you're doing. It does
*not* touch the if/call stacks, so the following code will behave in an
unexpected way (and cannot be fixed by inserting nops):

```
ifu true
    for ...
        ifu true
            break
        .end
    .end
.else
    ; will be executed since the inner if is still on the stack
.end
```

breakc has the same problem but does not require a separate condition.
This commit is contained in:
Tillmann Karras 2017-12-17 17:21:06 +00:00 committed by fincs
parent 89deb50e23
commit eeda288b29
3 changed files with 4 additions and 1 deletions

View File

@ -319,6 +319,7 @@ Syntax | Description
`cmp rSrc1, opx, opy, rSrc2` |
`call procName` |
`for iReg` |
`break` | (not recommended)
`breakc condExp` |
`callc condExp, procName` |
`ifc condExp` |

View File

@ -35,7 +35,7 @@ enum
MAESTRO_unk1E,
MAESTRO_unk1F,
MAESTRO_unk20,
MAESTRO_BREAK,
MAESTRO_NOP,
MAESTRO_END,
MAESTRO_BREAKC,

View File

@ -1242,6 +1242,7 @@ static const cmdTableType cmdTable[] =
DEC_COMMAND(NOP, format0),
DEC_COMMAND(END, format0),
DEC_COMMAND(EMIT, format0),
DEC_COMMAND(BREAK, format0),
DEC_COMMAND(ADD, format1),
DEC_COMMAND(DP3, format1),
@ -1373,6 +1374,7 @@ DEF_DIRECTIVE(end)
u32 lastOpcode = BUF[p-1] >> 26;
if (lastOpcode == MAESTRO_JMPC || lastOpcode == MAESTRO_JMPU
|| lastOpcode == MAESTRO_CALL || lastOpcode == MAESTRO_CALLC || lastOpcode == MAESTRO_CALLU
|| (elem.type == SE_FOR && lastOpcode == MAESTRO_BREAK)
|| (elem.type == SE_FOR && lastOpcode == MAESTRO_BREAKC)
|| (elem.type != SE_ARRAY && (p - elem.pos) < (elem.type != SE_PROC ? 2 : 1)))
insertPaddingNop();