Skip to content

Commit

Permalink
feat: call dictu from native code
Browse files Browse the repository at this point in the history
This uses a stack loaded piece of code to interrupt the current
vm execution in order to invoke a function called by native code.

It creates a new callframe for that and then makes sure the vm loop
breaks after that frame was reached again, this way the result is
returned tp the caller. It then resets the vm state and continues
normally.
  • Loading branch information
liz3 committed Nov 13, 2024
1 parent 643f2c9 commit 3d26296
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/vm/datatypes/strings.c
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,13 @@ static Value isValidUtf8(DictuVM *vm, int argCount, Value *args) {
return BOOL_VAL(string->character_len != -1);
}

static Value testThing(DictuVM *vm, int argCount, Value *args) {
int argC = argCount-1;
Value func = args[1];
Value* func_args = args +2;
return executeDirect(vm, func, argC, func_args);
}

void declareStringMethods(DictuVM *vm) {
// Note(Liz3): We need functions from the c stdlib for iswalpha, iswlower,
// iswupper(the utf8.c library functions do not work)
Expand Down Expand Up @@ -916,4 +923,5 @@ void declareStringMethods(DictuVM *vm) {
defineNative(vm, &vm->stringMethods, "collapseSpaces",
collapseSpacesString);
defineNative(vm, &vm->stringMethods, "wrap", wrapString);
defineNative(vm, &vm->stringMethods, "testThing", testThing);
}
32 changes: 31 additions & 1 deletion src/vm/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "datatypes/enums.h"
#include "natives.h"
#include "../optionals/optionals.h"
#include "value.h"

static void resetStack(DictuVM *vm) {
vm->stackTop = vm->stack;
Expand Down Expand Up @@ -866,7 +867,9 @@ static void copyAnnotations(DictuVM *vm, ObjDict *superAnnotations, ObjDict *kla
}
}

static DictuInterpretResult run(DictuVM *vm) {


static DictuInterpretResult runWithBreakFrame(DictuVM *vm, int breakFrame) {
CallFrame *frame = &vm->frames[vm->frameCount - 1];
register uint8_t* ip = frame->ip;

Expand All @@ -877,6 +880,7 @@ static DictuInterpretResult run(DictuVM *vm) {
#define READ_CONSTANT() \
(frame->closure->function->chunk.constants.values[READ_BYTE()])


#define READ_STRING() AS_STRING(READ_CONSTANT())

#define UNSUPPORTED_OPERAND_TYPE_ERROR(op) \
Expand Down Expand Up @@ -2253,6 +2257,7 @@ static DictuInterpretResult run(DictuVM *vm) {
}

CASE_CODE(RETURN): {

Value result = pop(vm);

// Close any upvalues still in scope.
Expand All @@ -2270,6 +2275,10 @@ static DictuInterpretResult run(DictuVM *vm) {

frame = &vm->frames[vm->frameCount - 1];
ip = frame->ip;
if (breakFrame != -1 && vm->frameCount == breakFrame) {
return INTERPRET_OK;
}

DISPATCH();
}

Expand Down Expand Up @@ -2435,6 +2444,9 @@ static DictuInterpretResult run(DictuVM *vm) {

return INTERPRET_RUNTIME_ERROR;
}
static DictuInterpretResult run(DictuVM *vm) {
return runWithBreakFrame(vm, -1);
}

DictuInterpretResult dictuInterpret(DictuVM *vm, char *moduleName, char *source) {
ObjString *name = copyString(vm, moduleName, strlen(moduleName));
Expand All @@ -2457,3 +2469,21 @@ DictuInterpretResult dictuInterpret(DictuVM *vm, char *moduleName, char *source)

return result;
}
Value executeDirect(DictuVM* vm, Value function, int argCount, Value* args) {
if(!IS_FUNCTION(function) && !IS_CLOSURE(function))
return NIL_VAL;
int currentFrameCount = vm->frameCount;
Value* currentStack = vm->stackTop;
CallFrame *frame = &vm->frames[vm->frameCount++];
uint8_t code[4] = {OP_CALL, argCount, 0, OP_RETURN};
frame->ip = code;
push(vm, function);
for(int i = argCount -1; i >= 0; i--) {
push(vm, args[i]);
}
runWithBreakFrame(vm, currentFrameCount+1);
Value v = pop(vm);
vm->stackTop = currentStack;
vm->frameCount--;
return v;
}
2 changes: 2 additions & 0 deletions src/vm/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ bool isFalsey(Value value);

ObjClosure *compileModuleToClosure(DictuVM *vm, char *name, char *source);

Value executeDirect(DictuVM* vm, Value function, int argCount, Value* args);

#endif

0 comments on commit 3d26296

Please sign in to comment.