Files
wren/embedding-api.html
Bob Nystrom 0387e95df4 Fresh docs!
2016-02-20 09:25:27 -08:00

219 lines
11 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>Embedding API &ndash; 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">
<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">
<ul>
<li><a href="getting-started.html">Getting Started</a></li>
<li><a href="contributing.html">Contributing</a></li>
</ul>
<section>
<h2>language guide</h2>
<ul>
<li><a href="syntax.html">Syntax</a></li>
<li><a href="values.html">Values</a></li>
<li><a href="lists.html">Lists</a></li>
<li><a href="maps.html">Maps</a></li>
<li><a href="method-calls.html">Method Calls</a></li>
<li><a href="control-flow.html">Control Flow</a></li>
<li><a href="variables.html">Variables</a></li>
<li><a href="functions.html">Functions</a></li>
<li><a href="classes.html">Classes</a></li>
<li><a href="concurrency.html">Concurrency</a></li>
<li><a href="error-handling.html">Error Handling</a></li>
<li><a href="modularity.html">Modularity</a></li>
</ul>
</section>
<section>
<h2>reference</h2>
<ul>
<li><a href="modules">Modules</a></li>
<li><a href="embedding-api.html">Embedding API</a></li>
<li><a href="performance.html">Performance</a></li>
<li><a href="qa.html">Q &amp; A</a></li>
</ul>
</section>
</nav>
<nav class="small">
<table>
<tr>
<td><a href="getting-started.html">Getting Started</a></td>
<td><a href="contributing.html">Contributing</a></td>
</tr>
<tr>
<td colspan="2"><h2>language guide</h2></td>
<td><h2>reference</h2></td>
</tr>
<tr>
<td>
<ul>
<li><a href="syntax.html">Syntax</a></li>
<li><a href="values.html">Values</a></li>
<li><a href="lists.html">Lists</a></li>
<li><a href="maps.html">Maps</a></li>
<li><a href="method-calls.html">Method Calls</a></li>
<li><a href="control-flow.html">Control Flow</a></li>
</ul>
</td>
<td>
<ul>
<li><a href="variables.html">Variables</a></li>
<li><a href="functions.html">Functions</a></li>
<li><a href="classes.html">Classes</a></li>
<li><a href="concurrency.html">Concurrency</a></li>
<li><a href="error-handling.html">Error Handling</a></li>
<li><a href="modularity.html">Modularity</a></li>
</ul>
</td>
<td>
<ul>
<li><a href="modules">Modules</a></li>
<li><a href="embedding-api.html">Embedding API</a></li>
<li><a href="performance.html">Performance</a></li>
<li><a href="qa.html">Q &amp; A</a></li>
</ul>
</td>
</tr>
</table>
</nav>
<main>
<h1>Embedding API</h1>
<p>Wren is designed to be a scripting language, so the embedding API is as
important as any of its language features. There are two (well, three) ways to
get Wren into your application: </p>
<ol>
<li>
<p><strong>Link to static or dynamic library.</strong> When you <a href="getting-started.html">build Wren</a>, it
generates both shared and static libraries in <code>lib</code> that you can link to. </p>
</li>
<li>
<p><strong>Include the source directly in your application.</strong> If you want to include
the source directly in your program, you don&rsquo;t need to run any build steps.
Just add the source files in <code>src/vm</code> to your project. They should compile
cleanly as C99 or C++89 or anything later. </p>
</li>
</ol>
<p>In either case, you also want to add <code>src/include</code> to your include path so you
can get to the <a href="https://github.com/munificent/wren/blob/master/src/include/wren.h">public header for Wren</a>: </p>
<div class="codehilite"><pre><span class="cp">#include &quot;wren.h&quot;</span>
</pre></div>
<h2>Creating a Wren VM <a href="#creating-a-wren-vm" name="creating-a-wren-vm" class="header-anchor">#</a></h2>
<p>Once you&rsquo;ve integrated the code into your executable, you need to create a
virtual machine. To do that, you first fill in a <code>WrenConfiguration</code>: </p>
<div class="codehilite"><pre><span class="n">WrenConfiguration</span> <span class="n">config</span><span class="p">;</span>
<span class="n">wrenInitConfiguration</span><span class="p">(</span><span class="o">&amp;</span><span class="n">config</span><span class="p">);</span>
</pre></div>
<p>This gives you a basic configuration that has reasonable defaults for
everything. If you don&rsquo;t need to tweak stuff, you can leave it at that. If you
do want to turn some knobs and dials, it exposes some fields you can set: </p>
<div class="codehilite"><pre><span class="n">config</span><span class="p">.</span><span class="n">reallocateFn</span> <span class="o">=</span> <span class="p">...;</span>
</pre></div>
<p>The <code>reallocateFn</code> is a callback you can provide to control how Wren allocates
and frees memory. If you leave that to the default, it uses <code>malloc()</code> and
<code>free()</code>. </p>
<div class="codehilite"><pre><span class="n">config</span><span class="p">.</span><span class="n">loadModuleFn</span> <span class="o">=</span> <span class="p">...;</span>
<span class="n">config</span><span class="p">.</span><span class="n">bindForeignMethodFn</span> <span class="o">=</span> <span class="p">...;</span>
<span class="n">config</span><span class="p">.</span><span class="n">bindForeignClassFn</span> <span class="o">=</span> <span class="p">...;</span>
</pre></div>
<p>These three callbacks are how Wren talks back to your program. We&rsquo;ll cover
them in detail later. </p>
<div class="codehilite"><pre><span class="n">config</span><span class="p">.</span><span class="n">initialHeapSize</span> <span class="o">=</span> <span class="p">...;</span>
<span class="n">config</span><span class="p">.</span><span class="n">minHeapSize</span> <span class="o">=</span> <span class="p">...;</span>
<span class="n">config</span><span class="p">.</span><span class="n">heapGrowthPercent</span> <span class="o">=</span> <span class="p">...;</span>
</pre></div>
<p>These let you tune how the garbage collector runs. You can tweak these if you
want, but the defaults are usually fine. </p>
<p>With this ready, you can create the VM: </p>
<div class="codehilite"><pre><span class="n">WrenVM</span><span class="o">*</span> <span class="n">vm</span> <span class="o">=</span> <span class="n">wrenNewVM</span><span class="p">(</span><span class="o">&amp;</span><span class="n">config</span><span class="p">);</span>
</pre></div>
<p>This allocates memory for a new VM using the same <code>reallocateFn</code> you provided.
The Wren C implementation has no global state, so every single bit of data Wren
uses is bundled up inside a <code>WrenVM</code>. You can have multiple Wren VMs running
independently from each other without any problems. </p>
<p><code>wrenNewVM()</code> stores its own copy of the configuration, so after calling it, you
can discard the <code>WrenConfiguration</code> struct you filled in. Now you have a live
VM, waiting to run some code! </p>
<h2>Executing Wren code <a href="#executing-wren-code" name="executing-wren-code" class="header-anchor">#</a></h2>
<p>You can tell the VM to execute a string of Wren source code like so: </p>
<div class="codehilite"><pre><span class="n">WrenInterpretResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">wrenInterpret</span><span class="p">(</span><span class="n">vm</span><span class="p">,</span> <span class="s">&quot;System.print(</span><span class="se">\&quot;</span><span class="s">Hi!</span><span class="se">\&quot;</span><span class="s">)&quot;</span><span class="p">);</span>
</pre></div>
<p>The first string is the chunk of code to execute&mdash;a series of one or more
statements separated by newlines. Wren runs this code in a special &ldquo;main&rdquo;
module. Each time you call this, the code is run in the same module. This way,
top-level names defined in one call can be accessed in later ones. </p>
<p>When you call <code>wrenInterpret()</code>, Wren first compiles your source to bytecode. If
an error occurs here, it returns immediately with <code>WREN_RESULT_COMPILE_ERROR</code>.
Otherwise, Wren spins up a new <a href="concurrency.html">fiber</a> and executes the code in that. Your
code can in turn spawn whatever other fibers it wants. It keeps running fibers
until they all complete. </p>
<p>If a <a href="error-handling.html">runtime error</a> occurs (and another fiber doesn&rsquo;t catch it), it will
abort fibers all the way back to the main one and then return <code>WREN_RESULT_RUNTIME_ERROR</code>. Otherwise, when the last fiber successfully
returns, it returns <code>WREN_RESULT_SUCCESS</code>. </p>
<h2>Calling a C function from Wren <a href="#calling-a-c-function-from-wren" name="calling-a-c-function-from-wren" class="header-anchor">#</a></h2>
<p><strong>TODO</strong> </p>
<h2>Calling a Wren method from C <a href="#calling-a-wren-method-from-c" name="calling-a-wren-method-from-c" class="header-anchor">#</a></h2>
<p><strong>TODO</strong> </p>
<h2>Storing a reference to a Wren object in C <a href="#storing-a-reference-to-a-wren-object-in-c" name="storing-a-reference-to-a-wren-object-in-c" class="header-anchor">#</a></h2>
<p><strong>TODO</strong> </p>
<h2>Storing C data in a Wren object <a href="#storing-c-data-in-a-wren-object" name="storing-c-data-in-a-wren-object" class="header-anchor">#</a></h2>
<p><strong>TODO</strong> </p>
<h2>Shutting down a VM <a href="#shutting-down-a-vm" name="shutting-down-a-vm" class="header-anchor">#</a></h2>
<p>Once the party is over and you&rsquo;re ready to end your relationship with a VM, you
need to free any memory it allocated. You do that like so: </p>
<div class="codehilite"><pre><span class="n">wrenFreeVM</span><span class="p">(</span><span class="n">vm</span><span class="p">);</span>
</pre></div>
<p>After calling that, you obviously cannot use the <code>WrenVM*</code> you passed to it
again. It&rsquo;s dead. </p>
<p>Note that Wren will yell at you if you still have any live <code>WrenValue</code> objects
when you call this. This makes sure you haven&rsquo;t lost track of any of them (which
leaks memory) and you don&rsquo;t try to use any of them after the VM has been freed. </p>
</main>
</div>
<footer>
<div class="page">
<div class="main-column">
<p>Wren lives
<a href="https://github.com/munificent/wren">on GitHub</a>
&mdash; Made with &#x2764; 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>