-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: call dictu from native code #755
Conversation
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.
@Jason2605 would be super thrilled to get some feedback here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems really promising so far! A couple of comments to think about but this would be huge 😄
return NIL_VAL; | ||
int currentFrameCount = vm->frameCount; | ||
Value* currentStack = vm->stackTop; | ||
CallFrame *frame = &vm->frames[vm->frameCount++]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we need to be careful we actually have enough frames, we may need to reallocate if not
src/vm/vm.c
Outdated
@@ -2457,3 +2469,21 @@ DictuInterpretResult dictuInterpret(DictuVM *vm, char *moduleName, char *source) | |||
|
|||
return result; | |||
} | |||
Value callFunction(DictuVM* vm, Value function, int argCount, Value* args) { | |||
if(!IS_FUNCTION(function) && !IS_CLOSURE(function)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here it would be nice to return an EMPTY val and throw a runtime error (happy you're just testing so may not have put that in yet etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also be nice to handle natives here too, that should be a lot easier as we don't need to handle call frames
src/vm/vm.c
Outdated
for(int i = argCount -1; i >= 0; i--) { | ||
push(vm, args[i]); | ||
} | ||
runWithBreakFrame(vm, currentFrameCount+1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we would need to handle a runtime error as at the minute (without testing) I'm assuming this will probably dump
@Jason2605 I've addressed the review points. I am very thankful you do not seam against this approach because i was very uncertain whether this would have other side effects but it seams that it does give a good way to callback into dictu code from natives, the overhead is manageable i hope. |
added tests! |
I think we're almost there! I think the runtime stack trace does segfault out though if a runtime error is actually raised, so we will need to have a look into that |
@Jason2605 ive fixed the issue, i had to read the error logic to make sense of the issue but after that it appeared logical. |
Silencing should be fine too, it is not real code afterall. |
http test service returning 502 🫠 |
Aha yeah the tests rely on an external service (not great). I’ve re-ran them now |
It’s 1am for me right now so I’ll give this a proper look over tomorrow! Thank you again for this :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have the setUp
method we can use here that is implicitly called before each test run!
tests/ffi/ffi.du
Outdated
@@ -38,18 +38,51 @@ import FFI; | |||
import Path; | |||
|
|||
class TestFFIModule < UnitTest { | |||
var mod = nil; | |||
doSetup() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doSetup() { | |
setUp() { |
tests/ffi/ffi.du
Outdated
FFI.suffix | ||
)); | ||
const mod = FFI.load(path); | ||
this.doSetup(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.doSetup(); |
tests/ffi/ffi.du
Outdated
this.assertEquals(mod.test, "Dictu!"); | ||
for(var i = 0; i < 40; i+=2) { | ||
this.assertEquals(mod.dictuFFITestAdd(i, i), i+i); | ||
} | ||
this.assertEquals(mod.dictuFFITestStr(), "Hello From Dictu FFI module!"); | ||
} | ||
testFFIModuleCallback() { | ||
this.doSetup(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.doSetup(); |
done |
God damn HTTP tests 😠 |
It's getting merged. Good find with this! Thank you for the PR 😃 |
feat: call dictu from native code
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 to the caller. It then resets the vm state and continues normally.
Type of Change:
Housekeeping:
Screenshots (If Applicable):