mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-14 23:58:03 +01:00
235 lines
14 KiB
HTML
235 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
|
<title>Configuring the VM – Wren</title>
|
|
<link rel="stylesheet" type="text/css" href="../style.css" />
|
|
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
|
|
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
|
|
the viewport. -->
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
|
|
</head>
|
|
<body id="top" class="embedding">
|
|
<header>
|
|
<div class="page">
|
|
<div class="main-column">
|
|
<h1><a href="../">wren</a></h1>
|
|
<h2>a classy little scripting language</h2>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
<div class="page">
|
|
<nav class="big">
|
|
<section>
|
|
<h2>embedding</h2>
|
|
<ul>
|
|
<li><a href="./">Introduction</a></li>
|
|
<li><a href="slots-and-handles.html">Slots and Handles</a></li>
|
|
<li><a href="calling-wren-from-c.html">Calling Wren from C</a></li>
|
|
<li><a href="calling-c-from-wren.html">Calling C from Wren</a></li>
|
|
<li><a href="storing-c-data.html">Storing C Data</a></li>
|
|
<li><a href="configuring-the-vm.html">Configuring the VM</a></li>
|
|
</ul>
|
|
</section>
|
|
</nav>
|
|
<nav class="small">
|
|
<table>
|
|
<tr>
|
|
<td><h2>embedding</h2></td>
|
|
<td><h2>?</h2></td>
|
|
<td><h2>?</h2></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<ul>
|
|
<li><a href="./">Introduction</a></li>
|
|
<li><a href="slots-and-handles.html">Slots and Handles</a></li>
|
|
<li><a href="calling-wren-from-c.html">Calling Wren from C</a></li>
|
|
<li><a href="calling-c-from-wren.html">Calling C from Wren</a></li>
|
|
<li><a href="storing-c-data.html">Storing C Data</a></li>
|
|
<li><a href="configuring-the-vm.html">Configuring the VM</a></li>
|
|
</ul>
|
|
</td>
|
|
<td>
|
|
<ul>
|
|
</ul>
|
|
</td>
|
|
<td>
|
|
<ul>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</nav>
|
|
<main>
|
|
<h1>Configuring the VM</h1>
|
|
<p>When you create a Wren VM, you tweak it by passing in a pointer to a
|
|
WrenConfiguration structure. Since Wren has no global state, you can configure
|
|
each VM differently if your application happens to run multiple. </p>
|
|
<p>The struct looks like: </p>
|
|
<div class="codehilite"><pre><span></span><span class="k">typedef</span> <span class="k">struct</span>
|
|
<span class="p">{</span>
|
|
<span class="n">WrenReallocateFn</span> <span class="n">reallocateFn</span><span class="p">;</span>
|
|
<span class="n">WrenLoadModuleFn</span> <span class="n">loadModuleFn</span><span class="p">;</span>
|
|
<span class="n">WrenBindForeignMethodFn</span> <span class="n">bindForeignMethodFn</span><span class="p">;</span>
|
|
<span class="n">WrenBindForeignClassFn</span> <span class="n">bindForeignClassFn</span><span class="p">;</span>
|
|
<span class="n">WrenWriteFn</span> <span class="n">writeFn</span><span class="p">;</span>
|
|
<span class="n">WrenErrorFn</span> <span class="n">errorFn</span><span class="p">;</span>
|
|
<span class="kt">size_t</span> <span class="n">initialHeapSize</span><span class="p">;</span>
|
|
<span class="kt">size_t</span> <span class="n">minHeapSize</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">heapGrowthPercent</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="n">WrenConfiguration</span><span class="p">;</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Most fields have useful defaults, which you can (and should) initialize by
|
|
calling: </p>
|
|
<div class="codehilite"><pre><span></span><span class="n">wrenInitConfiguration</span><span class="p">(</span><span class="o">&</span><span class="n">configuration</span><span class="p">);</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Calling this ensures that your VM doesn’t get uninitialized configuration when
|
|
new fields are added to WrenConfiguration. Here is what each field does, roughly
|
|
categorized: </p>
|
|
<h2>Binding <a href="#binding" name="binding" class="header-anchor">#</a></h2>
|
|
<p>The VM is isolated from the outside world. These callbacks let the VM request
|
|
access to imported code and foreign functionality. </p>
|
|
<h3><code>loadModuleFn</code> <a href="#loadmodulefn" name="loadmodulefn" class="header-anchor">#</a></h3>
|
|
<p>This is the callback Wren uses to load an imported module. The VM itself does
|
|
not know how to talk to the file system, so when an <code>import</code> statement is
|
|
executed, it relies on the host application to locate and read the source code
|
|
for a module. </p>
|
|
<p>The signature of this function is: </p>
|
|
<div class="codehilite"><pre><span></span><span class="kt">char</span><span class="o">*</span> <span class="n">loadModule</span><span class="p">(</span><span class="n">WrenVM</span><span class="o">*</span> <span class="n">vm</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">name</span><span class="p">)</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>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. </p>
|
|
<p>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. </p>
|
|
<p>If your host application isn’t able to load a module with some name, it should
|
|
return <code>NULL</code> and Wren will report that as a runtime error. </p>
|
|
<p>If you don’t use any <code>import</code> statements, you can leave this <code>NULL</code>. </p>
|
|
<h3><code>bindForeignMethodFn</code> <a href="#bindforeignmethodfn" name="bindforeignmethodfn" class="header-anchor">#</a></h3>
|
|
<p>The callback Wren uses to find a foreign method and bind it to a class. See
|
|
<a href="/embedding/calling-c-from-wren.html">this page</a> for details. If your application defines no foreign
|
|
methods, you can leave this <code>NULL</code>. </p>
|
|
<h3><code>bindForeignClassFn</code> <a href="#bindforeignclassfn" name="bindforeignclassfn" class="header-anchor">#</a></h3>
|
|
<p>The callback Wren uses to find a foreign class and get its foreign methods. See
|
|
<a href="/embedding/storing-c-data.html">this page</a> for details. If your application defines no foreign
|
|
classes, you can leave this <code>NULL</code>. </p>
|
|
<h2>Diagnostics <a href="#diagnostics" name="diagnostics" class="header-anchor">#</a></h2>
|
|
<p>These let you wire up some minimal output so you can tell if your code is doing
|
|
what you expect. </p>
|
|
<h3><code>writeFn</code> <a href="#writefn" name="writefn" class="header-anchor">#</a></h3>
|
|
<p>This is the callback Wren uses to output text when <code>System.print()</code> or the other
|
|
related functions are called. This is the minimal connection the VM has with the
|
|
outside world and lets you do rudimentary “printf debugging”. Its signature is: </p>
|
|
<div class="codehilite"><pre><span></span><span class="kt">void</span> <span class="n">write</span><span class="p">(</span><span class="n">WrenVM</span><span class="o">*</span> <span class="n">vm</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">text</span><span class="p">)</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Wren does <em>not</em> have a default implementation for this. It’s up to you to wire
|
|
it up to <code>printf()</code> or some other way to show the text. If you leave it <code>NULL</code>,
|
|
calls to <code>System.print()</code> and others silently do nothing. </p>
|
|
<h3><code>errorFn</code> <a href="#errorfn" name="errorfn" class="header-anchor">#</a></h3>
|
|
<p>Wren uses this callback to report compile time and runtime errors. Its signature
|
|
is: </p>
|
|
<div class="codehilite"><pre><span></span><span class="kt">void</span> <span class="n">error</span><span class="p">(</span>
|
|
<span class="n">WrenErrorType</span> <span class="n">type</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">module</span><span class="p">,</span>
|
|
<span class="kt">int</span> <span class="n">line</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">message</span><span class="p">)</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>The <code>type</code> parameter is one of: </p>
|
|
<div class="codehilite"><pre><span></span><span class="k">typedef</span> <span class="k">enum</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// A syntax or resolution error detected at compile time.</span>
|
|
<span class="n">WREN_ERROR_COMPILE</span><span class="p">,</span>
|
|
|
|
<span class="c1">// The error message for a runtime error.</span>
|
|
<span class="n">WREN_ERROR_RUNTIME</span><span class="p">,</span>
|
|
|
|
<span class="c1">// One entry of a runtime error's stack trace.</span>
|
|
<span class="n">WREN_ERROR_STACK_TRACE</span>
|
|
<span class="p">}</span> <span class="n">WrenErrorType</span><span class="p">;</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>When a compile error occurs, <code>errorFn</code> is called once with type
|
|
<code>WREN_ERROR_COMPILE</code>, the name of the module and line where the error occurs,
|
|
and the error message. </p>
|
|
<p>Runtime errors include stack traces. To handle this, Wren first calls <code>errorFn</code>
|
|
with <code>WREN_ERROR_RUNTIME</code>, no module or line, and the runtime error’s message.
|
|
After that, it calls <code>errorFn</code> again using type <code>WREN_ERROR_STACK_TRACE</code>, once
|
|
for each line in the stack trace. Each of those calls has the module and line
|
|
where the method or function is defined and <code>message</code> is the name of the method
|
|
or function. </p>
|
|
<p>If you leave this <code>NULL</code>, Wren does not report any errors. </p>
|
|
<h2>Memory Management <a href="#memory-management" name="memory-management" class="header-anchor">#</a></h2>
|
|
<p>These fields control how the VM allocates and manages memory. </p>
|
|
<h3><code>reallocateFn</code> <a href="#reallocatefn" name="reallocatefn" class="header-anchor">#</a></h3>
|
|
<p>This lets you provide a custom memory allocation function. Its signature is: </p>
|
|
<div class="codehilite"><pre><span></span><span class="kt">void</span><span class="o">*</span> <span class="n">reallocate</span><span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">memory</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">newSize</span><span class="p">)</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Wren uses this one function to allocate, grow, shrink, and deallocate memory.
|
|
When called, <code>memory</code> is the existing pointer to the block of memory if an
|
|
allocation is being changed or freed. If Wren is requesting new memory, then
|
|
<code>memory</code> is <code>NULL</code>. </p>
|
|
<p><code>newSize</code> is the number of bytes of memory being requested. If memory is being
|
|
freed, this is zero. Your callback should allocate the proper amount of memory
|
|
and return it. </p>
|
|
<p>If you don’t provide a custom allocator, the VM uses a default one that relies
|
|
on <code>realloc</code> and <code>free</code>. </p>
|
|
<h3><code>initialHeapSize</code> <a href="#initialheapsize" name="initialheapsize" class="header-anchor">#</a></h3>
|
|
<p>This defines the total number of bytes of memory the VM will allocate before
|
|
triggering the first garbage collection. Setting this to a smaller number
|
|
reduces the amount of memory Wren will have allocated at one time, but causes it
|
|
to collect garbage more frequently. </p>
|
|
<p>If you set this to zero, Wren uses a default size of 10MB. </p>
|
|
<h3><code>minHeapSize</code> <a href="#minheapsize" name="minheapsize" class="header-anchor">#</a></h3>
|
|
<p>After a garbage collection occurs, the threshold for the <em>next</em> collection is
|
|
determined based on the number of bytes remaining in use. This allows Wren to
|
|
grow or shrink its memory usage automatically based on how much memory is
|
|
actually needed. </p>
|
|
<p>This can be used to ensure that the heap does not get <em>too</em> small, which can
|
|
in turn lead to a large number of collections afterwards as the heap grows
|
|
back to a usable size. </p>
|
|
<p>If zero, this defaults to 1MB. </p>
|
|
<h3><code>heapGrowthPercent</code> <a href="#heapgrowthpercent" name="heapgrowthpercent" class="header-anchor">#</a></h3>
|
|
<p>Wren tunes the rate of garbage collection based on how much memory is still in
|
|
use after a collection. This number controls that. It determines the amount of
|
|
additional memory Wren will use after a collection, as a percentage of the
|
|
current heap size. </p>
|
|
<p>For example, say that this is 50. After a garbage collection, there are 400
|
|
bytes of memory still in use. That means the next collection will be triggered
|
|
after a total of 600 bytes are allocated (including the 400 already in use.) </p>
|
|
<p>Setting this to a smaller number wastes less memory, but triggers more
|
|
frequent garbage collections. </p>
|
|
<p>If set to zero, the VM uses a default of 50. </p>
|
|
<p><a href="storing-c-data.html">← Storing C Data</a> </p>
|
|
</main>
|
|
</div>
|
|
<footer>
|
|
<div class="page">
|
|
<div class="main-column">
|
|
<p>Wren lives
|
|
<a href="https://github.com/munificent/wren">on GitHub</a>
|
|
— Made with ❤ by
|
|
<a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
|
|
<a href="https://github.com/munificent/wren/blob/master/AUTHORS">friends</a>.
|
|
</p>
|
|
<div class="main-column">
|
|
</div>
|
|
</footer>
|
|
</body>
|
|
</html>
|