1
0
forked from Mirror/wren

[0.4.0] Introduce WrenLoadModuleResult, fix unfreed strings from host. (#778)

This commit is contained in:
ruby
2020-12-03 09:27:54 -08:00
committed by GitHub
parent e7071fffa5
commit 6bd2f810e2
7 changed files with 99 additions and 35 deletions

View File

@ -47,22 +47,53 @@ for a module.
The signature of this function is:
<pre class="snippet" data-lang="c">
char* loadModule(WrenVM* vm, const char* name)
WrenLoadModuleResult loadModule(WrenVM* vm, const char* name)
</pre>
When a module is imported, Wren calls this and passes in the module's name. The
host should return the source code for that module. Memory for the source should
be allocated using the same allocator that the VM uses for other allocation (see
below). Wren will take ownership of the returned string and free it later.
host should return the source code for that module in a `WrenLoadModuleResult` struct.
<pre class="snippet" data-lang="c">
WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = {0};
result.source = getSourceForModule(name);
return result;
}
</pre>
The module loader is only be called once for any given module name. Wren caches
the result internally so subsequent imports of the same module use the
previously loaded code.
If your host application isn't able to load a module with some name, it should
return `NULL` and Wren will report that as a runtime error.
make sure the `source` value is `NULL` when returned. Wren will then report that as a runtime error.
If you don't use any `import` statements, you can leave this `NULL`.
If you don't use any `import` statements, you can leave the `loadModuleFn` field in
the configuration set to `NULL` (the default).
Additionally, the `WrenLoadModuleResult` allows us to add a callback for when Wren is
done with the `source`, so we can free the memory if needed.
<pre class="snippet" data-lang="c">
static void loadModuleComplete(WrenVM* vm,
const char* module,
WrenLoadModuleResult result)
{
if(result.source) {
//for example, if we used malloc to allocate
our source string, we use free to release it.
free((void*)result.source);
}
}
WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = {0};
result.onComplete = loadModuleComplete;
result.source = getSourceForModule(name);
return result;
}
</pre>
### **`bindForeignMethodFn`**

View File

@ -81,17 +81,17 @@ WrenVM* vm = wrenNewVM(&config);
That function has this signature:
<pre class="snippet" data-lang="c">
char* WrenLoadModuleFn(WrenVM* vm, const char* name);
WrenLoadModuleResult WrenLoadModuleFn(WrenVM* vm, const char* name);
</pre>
Whenever a module is imported, the VM calls this and passes it the name of the
module. The embedder is expected to return the source code contents of the
module. When you embed Wren in your app, you can handle this however you want:
reach out to the file system, look inside resources bundled into your app,
whatever.
module in a `WrenLoadModuleResult`. When you embed Wren in your app, you can handle
this however you want: reach out to the file system, look inside resources bundled
into your app, whatever.
You can return `NULL` from this function to indicate that a module couldn't be
found. When you do this, Wren will report it as a runtime error.
You can return the source field as `NULL` from this function to indicate that a module
couldn't be found. When you do this, Wren will report it as a runtime error.
### The command-line loader