[NTLK] NEWT/0 set-aref bug
simonbell at me.com
Tue Dec 16 10:51:41 EST 2014
> On 16 Dec 2014, at 10:45, Matej Horvat <matej.horvat at guest.arnes.si> wrote:
> What did you use to compile that code? I compiled the same function with NTK and it gives me this:
Ooh, interesting! I should have tried that.
My compiler is reverse-engineered from the Newton ROM and runs in a Mac OS X application. I was (overly, as it turns out) confident my implementation is faithful to the original.
I know there are differences between the ROM and NTK (no constant folding and no native functions where the ROM compiler is concerned, for example) but calling Compile() on a MessagePad gives the same byte code as NTK so I have obviously slipped up somewhere. I can’t explain where the push-constant nil comes from, and that should have been a clue!
>> the Newton interpreter unwinds the stack on function return to leave just the return value on it.
> Does it?
Here’s what I think the interpreter does when it encounters the return bytecode:
. . .
case 002: // return
// unwind stack and leave return value on top
var1 = *(dataStack.top-1);
dataStack.top = dataStack.base + (RVALUE(vm->stackFrame) >> kStackFrameFlagBits) + 3 + 1;
*(dataStack.top-1) = var1;
// restore VM state of caller
vm = ctrlStack.pop();
instructionOffset = RVALUE(vm->pc);
// if we had any exception handlers, pop them
if (STACKINDEX(ctrlStack) < exceptionStackIndex)
. . .
dataStack is a stack of Refs
ctrlStack is a stack of virtual machine state
vm is the current virtual machine state
the exception handlers are held in a global linked list
and that approach might help your interpreter, but doesn’t solve the “set-aref in a loop” problem.
Clearly I need to investigate my compiler implementation. I think it is a code generation problem rather than the set-aref instruction per se, and I wonder whether there are more examples where unused results are not popped off the stack. Curious that it has the same bug as NEWT/0!
More information about the NewtonTalk