First pass at implementing foreign classes.
Most of the pieces are there: - You can declare a foreign class. - It will call your C function to provide an allocator function. - Whenever a foreign object is created, it calls the allocator. - Foreign methods can access the foreign bytes of an object. - Most of the runtime checking is in place for things like subclassing foreign classes. There is still some loose ends to tie up: - Finalizers are not called. - Some of the error-handling could be better. - The GC doesn't track how much memory a marked foreign object uses.
This commit is contained in:
+2
-2
@@ -9,7 +9,7 @@
|
||||
|
||||
static int runRepl()
|
||||
{
|
||||
WrenVM* vm = createVM(NULL);
|
||||
WrenVM* vm = createVM();
|
||||
|
||||
printf("\\\\/\"-\n");
|
||||
printf(" \\_/ wren v0.0.0\n");
|
||||
@@ -50,7 +50,7 @@ int main(int argc, const char* argv[])
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
runFile(NULL, argv[1]);
|
||||
runFile(argv[1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+17
-10
@@ -4,25 +4,25 @@
|
||||
#include "io.h"
|
||||
#include "vm.h"
|
||||
|
||||
WrenVM* createVM(WrenBindForeignMethodFn bindForeign)
|
||||
static WrenBindForeignMethodFn bindMethodFn = NULL;
|
||||
static WrenBindForeignClassFn bindClassFn = NULL;
|
||||
|
||||
WrenVM* createVM()
|
||||
{
|
||||
WrenConfiguration config;
|
||||
|
||||
config.bindForeignMethodFn = bindForeign;
|
||||
wrenInitConfiguration(&config);
|
||||
|
||||
config.bindForeignMethodFn = bindMethodFn;
|
||||
config.bindForeignClassFn = bindClassFn;
|
||||
config.loadModuleFn = readModule;
|
||||
|
||||
// Since we're running in a standalone process, be generous with memory.
|
||||
config.initialHeapSize = 1024 * 1024 * 100;
|
||||
|
||||
// Use defaults for these.
|
||||
config.reallocateFn = NULL;
|
||||
config.minHeapSize = 0;
|
||||
config.heapGrowthPercent = 0;
|
||||
|
||||
return wrenNewVM(&config);
|
||||
}
|
||||
|
||||
void runFile(WrenBindForeignMethodFn bindForeign, const char* path)
|
||||
void runFile(const char* path)
|
||||
{
|
||||
// Use the directory where the file is as the root to resolve imports
|
||||
// relative to.
|
||||
@@ -43,7 +43,7 @@ void runFile(WrenBindForeignMethodFn bindForeign, const char* path)
|
||||
exit(66);
|
||||
}
|
||||
|
||||
WrenVM* vm = createVM(bindForeign);
|
||||
WrenVM* vm = createVM();
|
||||
|
||||
WrenInterpretResult result = wrenInterpret(vm, path, source);
|
||||
|
||||
@@ -55,3 +55,10 @@ void runFile(WrenBindForeignMethodFn bindForeign, const char* path)
|
||||
if (result == WREN_RESULT_COMPILE_ERROR) exit(65); // EX_DATAERR.
|
||||
if (result == WREN_RESULT_RUNTIME_ERROR) exit(70); // EX_SOFTWARE.
|
||||
}
|
||||
|
||||
void setForeignCallbacks(
|
||||
WrenBindForeignMethodFn bindMethod, WrenBindForeignClassFn bindClass)
|
||||
{
|
||||
bindMethodFn = bindMethod;
|
||||
bindClassFn = bindClass;
|
||||
}
|
||||
|
||||
+9
-2
@@ -4,11 +4,18 @@
|
||||
#include "wren.h"
|
||||
|
||||
// Creates a new Wren VM with the CLI's module loader and other configuration.
|
||||
WrenVM* createVM(WrenBindForeignMethodFn bindForeign);
|
||||
WrenVM* createVM();
|
||||
|
||||
// Executes the Wren script at [path] in a new VM.
|
||||
//
|
||||
// Exits if the script failed or could not be loaded.
|
||||
void runFile(WrenBindForeignMethodFn bindForeign, const char* path);
|
||||
void runFile(const char* path);
|
||||
|
||||
// Adds additional callbacks to use when binding foreign members from Wren.
|
||||
//
|
||||
// Used by the API test executable to let it wire up its own foreign functions.
|
||||
// This must be called before calling [createVM()].
|
||||
void setForeignCallbacks(WrenBindForeignMethodFn bindMethod,
|
||||
WrenBindForeignClassFn bindClass);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user