diff --git a/docs/opcodes.md b/docs/opcodes.md index 047ad09..ae8e4c8 100644 --- a/docs/opcodes.md +++ b/docs/opcodes.md @@ -1,22 +1,22 @@ # Opcodes -| Opcode | Description | -| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **MAKE_CLOSURE** _i (IS_LOCAL j)*_ | Push a ClosureAtom onto the stack, created from the FnAtom at `const[i]`. For each upvalue in the ClosureAtom, capture it from `stack[j]` if `IS_LOCAL` is `1`, capture from `upvalues[j]` otherwise. | -| **CALL** _argc_ | Call the function at **TOS** - `argc` with `argc` parameters. | -| **RETURN** | Return **TOS**. | -| **POP_TOP** | Pop **TOS**. | -| **POP** _argc_ | Pop **TOS** `argc` times. | -| **CLOSE_UPVALUE** | Close the free variables at **TOS**. | -| **LOAD_CONST** _idx_ | Push `const[idx]` onto the stack. | -| **LOAD_SYM** _idx_ | Push `globals[const[idx]]` onto the stack. | -| **DEF_SYM** _idx_ | Define `globals[const[idx]]` as **TOS**. | -| **SET_SYM** _idx_ | Set `globals[const[idx]]` as **TOS**. | -| **LOAD_UPVALUE** _idx_ | Push `upvalues[idx]` onto the stack. | -| **SET_UPVALUE** _idx_ | Set `upvalues[idx]` as **TOS**. | -| **LOAD_STACK** _idx_ | Push `upvalues[idx]` onto the stack. | -| **SET_STACK** _idx_ | Set `upvalues[idx]` to **TOS**. | -| **JUMP** _offset_ | Set `ip` of current frame to `offset`. | -| **POP_JUMP_IF_FALSE** _offset_ | Set `ip` of current frame to `offset` if **TOS** is not _truthy_. | -| **MAKE_LIST** _offset_ | Pop all elements from **BASE_PTR** + _offset_ to **TOS**, push those elements as cons list onto the stack. | -| **MAKE_NIL** | Push `'()` onto the stack | +| Opcode | Description | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **MAKE_CLOSURE** _i (IS_LOCAL j)*_ | Push a Closure onto the stack, created from the Prototype at `const[i]`. For each upvalue in the Closure, capture it from `stack[j]` if `IS_LOCAL` is `1`, capture from `upvalues[j]` otherwise. | +| **CALL** _argc_ | Call the function at **TOS** - `argc` with `argc` parameters. | +| **RETURN** | Return **TOS**. | +| **POP_TOP** | Pop **TOS**. | +| **POP** _argc_ | Pop **TOS** `argc` times. | +| **CLOSE_UPVALUE** | Close the free variables at **TOS**. | +| **LOAD_CONST** _idx_ | Push `const[idx]` onto the stack. | +| **LOAD_SYM** _idx_ | Push `globals[const[idx]]` onto the stack. | +| **DEF_SYM** _idx_ | Define `globals[const[idx]]` as **TOS**. | +| **SET_SYM** _idx_ | Set `globals[const[idx]]` as **TOS**. | +| **LOAD_UPVALUE** _idx_ | Push `upvalues[idx]` onto the stack. | +| **SET_UPVALUE** _idx_ | Set `upvalues[idx]` as **TOS**. | +| **LOAD_STACK** _idx_ | Push `upvalues[idx]` onto the stack. | +| **SET_STACK** _idx_ | Set `upvalues[idx]` to **TOS**. | +| **JUMP** _offset_ | Set `ip` of current frame to `offset`. | +| **POP_JUMP_IF_FALSE** _offset_ | Set `ip` of current frame to `offset` if **TOS** is not _truthy_. | +| **MAKE_LIST** _offset_ | Pop all elements from **BASE_PTR** + _offset_ to **TOS**, push those elements as cons list onto the stack. | +| **MAKE_NIL** | Push `'()` onto the stack | diff --git a/src/compile/Compiler.cpp b/src/compile/Compiler.cpp index 9eb8bdf..bf66e8c 100644 --- a/src/compile/Compiler.cpp +++ b/src/compile/Compiler.cpp @@ -556,15 +556,12 @@ void Compiler::emitRet() { handleTypeError(lambdaGrammar, te.expected, te.actual); } - emitCode(OpCode::SET_STACK, 0); - for (const auto &local : locals) { if (local.isCaptured) { emitCode(OpCode::CLOSE_UPVALUE, local.stackOffset); } } - emitCode(OpCode::POP, stackOffset); emitCode(OpCode::RETURN); } diff --git a/src/runtime/VM.cpp b/src/runtime/VM.cpp index a1d9548..ea73e2d 100644 --- a/src/runtime/VM.cpp +++ b/src/runtime/VM.cpp @@ -127,7 +127,7 @@ const SExpr *VM::exec() { MAKE_CLOSURE: { const auto proto = cast(readConst()); std::vector> upvalues; - for (unsigned int i{0}; i < proto->numUpvals; ++i) { + for (auto i = 0U; i < proto->numUpvals; ++i) { auto isLocal = readByte(); auto idx = readByte(); if (isLocal == 1) { @@ -144,15 +144,17 @@ CALL: { call(readByte()); } goto *dispatchTable[readByte()]; RETURN: { + const auto res = stack.back(); if (callFrames.size() == 1) [[unlikely]] { - const auto res = stack.back(); reset(); return res; } + stack.erase(stack.end() - (stack.size() - bp - 1), stack.end()); ip = callFrames.back().ip; bp = callFrames.back().bp; closure = callFrames.back().closure; callFrames.pop_back(); + stack.back() = res; } goto *dispatchTable[readByte()];