Skip to content

Commit

Permalink
Fix bug in apiStack setup during import callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
bamless committed Jul 20, 2024
1 parent 8e31014 commit 9c645a6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
10 changes: 5 additions & 5 deletions src/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,14 @@ ObjModule* importModule(JStarVM* vm, ObjString* name) {
return NULL;
}

// An import callback is similar to a native function call (could be re-entrant), so setup the
// apiStack to the current stack pointer, so that push/pop operations are relative to the
// current position
size_t savedApiStack = vm->sp - vm->apiStack;
// An import callback is similar to a native function call (can use the J* API and can be
// re-entrant), so setup the apiStack to the current stack pointer, so that push/pop operations
// are relative to the current position
size_t apiStackOffset = vm->apiStack - vm->stack;
vm->apiStack = vm->sp;

JStarImportResult res = vm->importCallback(vm, name->data);
vm->apiStack = vm->sp + savedApiStack;
vm->apiStack = vm->stack + apiStackOffset;

if(!res.code) {
return NULL;
Expand Down
17 changes: 11 additions & 6 deletions src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "profiler.h"

#if defined(JSTAR_DBG_PRINT_GC) || defined(JSTAR_DBG_PRINT_EXEC)
#include "disassemble.h"
#include "disassemble.h"
#endif

// Constant method names used in operator overloading
Expand Down Expand Up @@ -310,24 +310,29 @@ static bool callNative(JStarVM* vm, ObjNative* native, uint8_t argc) {
const Frame* frame = appendNativeFrame(vm, native);

ObjModule* oldModule = vm->module;
size_t savedApiStack = vm->apiStack - vm->stack;

// Save the current apiStack position relative to the base of the stack. This is saved
// in a relative way so that the apiStack can be restored to the correct position after
// a possible stack reallocation (for example, if the native function or any of its nested
// calls allocate more stack space than its currently available)
size_t apiStackOffset = vm->apiStack - vm->stack;

vm->module = native->proto.module;
vm->apiStack = frame->stack;

if(!native->fn(vm)) {
vm->module = oldModule;
vm->apiStack = vm->stack + savedApiStack;
vm->apiStack = vm->stack + apiStackOffset;
return false;
}

Value ret = pop(vm);
vm->frameCount--;
vm->sp = vm->apiStack;
vm->module = oldModule;
vm->apiStack = vm->stack + savedApiStack;

push(vm, ret);

vm->module = oldModule;
vm->apiStack = vm->stack + apiStackOffset;
return true;
}

Expand Down

0 comments on commit 9c645a6

Please sign in to comment.