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.
127 lines
5.5 KiB
127 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
|
|
a buffer object instead (or create your own object and store the plain 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
|
|
(disable <code>DUK_USE_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>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 dump/load</h2>
|
|
|
|
<p>Starting from Duktape 1.3 Duktape has a bytecode dump/load mechanism
|
|
similar to Lua <code>lua_dump()</code>. See
|
|
<a href="#bytecodedumpload">Bytecode dump/load</a>.</p>
|
|
|
|
<h2>Metatables</h2>
|
|
|
|
<p>There is no equivalent of Lua metatables in ECMAScript E5/E5.1, but
|
|
<a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-proxy-objects">ECMAScript ES2015 Proxy objects</a>
|
|
provide similar functionality. To allow property virtualization better than available in
|
|
E5/E5.1, Duktape implements an <a href="#es6-proxy">ES2015 Proxy subset</a>.</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 ES2015, 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>Weak references</h2>
|
|
|
|
<p>Lua supports weak references. Duktape currently doesn't.</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>
|
|
|
|
|