mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
5.5 KiB
128 lines
5.5 KiB
<h1 id="comparisontolua">Comparison to Lua</h1>
|
|
|
|
<p>Duktape borrows a lot from Lua conceptually. Below are a few notes on
|
|
what's different in Duktape compared to Lua. This may be useful if you're
|
|
already familiar with Lua.</p>
|
|
|
|
<h2>Array and stack indices are zero-based</h2>
|
|
|
|
<p>All array and stack indices are zero-based, not one-based as in Lua. So,
|
|
bottom of stack is 0, second element from bottom is 1, and top element is -1.
|
|
Because 0 is no longer available to denote an invalid/non-existent element,
|
|
the constant <code>DUK_INVALID_INDEX</code> is used instead in Duktape.</p>
|
|
|
|
<p>String indices are also zero-based, and slices are indicated with an
|
|
inclusive start index and an exclusive end index (i.e. [start,end[).
|
|
In Lua, slices are indicated with inclusive indices (i.e. [start,end]).</p>
|
|
|
|
<h2>Object type represents functions and threads</h2>
|
|
|
|
<p>In Lua functions and threads are a separate type from objects.
|
|
In Duktape the object type is used for plain objects, Ecmascript and
|
|
native functions, and threads (coroutines). As a result, all of these
|
|
have a mutable and extensible set of properties.</p>
|
|
|
|
<h2>Lua userdata and lightuserdata</h2>
|
|
|
|
<p>The concept closest to Lua <code>userdata</code> is the Duktape <code>buffer</code>
|
|
type, with the following differences:</p>
|
|
|
|
<ul>
|
|
<li>Duktape buffers can be resizable, Lua userdata values cannot. If a
|
|
Duktape buffer is resizable, its data pointer is no longer guaranteed
|
|
to be stable.</li>
|
|
<li>Duktape buffers are raw byte arrays without any properties, Lua userdata
|
|
objects can store an environment reference.</li>
|
|
</ul>
|
|
|
|
<p>Lua <code>lightuserdata</code> and Duktape <code>pointer</code> are essentially
|
|
the same.</p>
|
|
|
|
<p>If you need to associate properties with a Duktape buffer, you can use
|
|
an actual object and have the buffer as its property. You can then add a
|
|
finalizer to the object to free any resources related to the buffer. This
|
|
works reasonably well as long as nothing else holds a reference to the buffer.
|
|
If this were the case, the buffer could get used after the object had already
|
|
been finalized. To safeguard against this, the native C structure should
|
|
have a flag indicating whether the data structure is open or closed. This
|
|
is good practice anyway for robust native code.</p>
|
|
|
|
<h2>Garbage collection</h2>
|
|
|
|
<p>Duktape has a combined reference counting and non-incremental mark-and-sweep
|
|
garbage collector (mark-and-sweep is needed only for reference cycles). Collection
|
|
pauses can be avoided by disabling voluntary mark-and-sweep passes
|
|
(<code>DUK_OPT_NO_VOLUNTARY_GC</code>). Lua has an incremental collector with no
|
|
pauses, but has no reference counting.</p>
|
|
|
|
<p>Duktape has an emergency garbage collector. Lua 5.2 has an emergency
|
|
garbage collector while Lua 5.1 does not (there is an emergency GC patch
|
|
though).</p>
|
|
|
|
<h2>Finalizers</h2>
|
|
|
|
<p>Duktape has finalizer supported. Lua 5.2 has finalizer support while
|
|
Lua 5.1 does not.</p>
|
|
|
|
<h2>duk_safe_call() vs. lua_cpcall()</h2>
|
|
|
|
<p><code>duk_safe_call()</code> is a protected C function call which
|
|
operates in the existing value stack frame. The function call is
|
|
not visible on the call stack all.</p>
|
|
|
|
<p><code>lua_cpcall()</code> creates a new stack frame.</p>
|
|
|
|
<h2>Bytecode use</h2>
|
|
|
|
<p>Duktape Ecmascript function bytecode is currently a purely internal
|
|
matter. Code cannot currently be loaded from an external pre-compiled
|
|
bytecode file. Similarly, there is no equivalent to e.g. <code>lua_dump()</code>.</p>
|
|
|
|
<h2>Metatables</h2>
|
|
|
|
<p>There is currently no equivalent of Lua metatables in Duktape (or
|
|
Ecmascript). The
|
|
<a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-8.5">ES6 proxy object</a>
|
|
concept will most likely provide similar functionality at some point.</p>
|
|
|
|
<h2>lua_next() vs. duk_next()</h2>
|
|
|
|
<p><code>lua_next()</code> replaces the previous key and value with a new pair,
|
|
while <code>duk_next()</code> does not; the caller needs to explicitly pop the
|
|
key and/or value.</p>
|
|
|
|
<h2>Raw accessors</h2>
|
|
|
|
<p>There is no equivalent to Lua raw table access functions like
|
|
<code>lua_rawget</code>. One can use the following Ecmascript built-ins
|
|
for a similar effect (though not with respect to performance):
|
|
<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.3">Object.getOwnPropertyDescriptor ( O, P )</a>,
|
|
<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.6">Object.defineProperty ( O, P, Attributes )</a>.</p>
|
|
|
|
<h2>Coroutines</h2>
|
|
|
|
<p>There are no primitives for coroutine control in the Duktape API
|
|
(Lua API has e.g. <code>lua_resume</code>). Coroutines can only be controlled
|
|
using the functions exposed by the <code>Duktape</code> built-in. Further,
|
|
Duktape has quite many coroutine yield restrictions now; for instance,
|
|
coroutines cannot yield from inside constructor calls or getter/setter calls.</p>
|
|
|
|
<h2>Multiple return values</h2>
|
|
|
|
<p>Lua supports multiple return values, Duktape (or Ecmascript) currently
|
|
doesn't. This may change with Ecmascript E6, which has a syntax for
|
|
multiple value returns. The Duktape/C API reserves return values above 1
|
|
so that they may be later used for multiple return values.</p>
|
|
|
|
<h2>Unicode</h2>
|
|
|
|
<p>Lua has no built-in Unicode support (strings are byte strings), while
|
|
Duktape has support for 16-bit Unicode as part of Ecmascript compliance.</p>
|
|
|
|
<h2>Streaming compilation</h2>
|
|
|
|
<p>Lua has a streaming compilation API which is good when code is read from
|
|
the disk or perhaps decompressed on-the-fly. Duktape currently does not
|
|
support streaming compilation because it needs multiple passes over the
|
|
source code.</p>
|
|
|
|
|