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.
 
 
 
 
 
 

135 lines
5.1 KiB

<h1 id="limitations">Limitations</h1>
<p>The following is a list of known limitations of the current implementation.
Limitations include shortcomings from a semantics perspective, performance
limitations, and implementation limits (which are inevitable).</p>
<p>Trivial bugs are not listed unless they are "long term bugs".</p>
<h2>No re-entrancy</h2>
<p>A single Duktape heap, i.e. contexts sharing the same garbage collector,
is <b>not re-entrant</b>. Only one C/C++ thread can call Duktape APIs
at a time for a particular Duktape heap (although the calling thread
can change over time).</p>
<h2>String and buffer limits</h2>
<p>The internal representation allows a maximum length of 2**31-1 (0x7fffffff)
<i>bytes</i> (not characters) for strings. 16-bit codepoints encode into 3
bytes of UTF-8 in the worst case, so the maximum string length which is
guaranteed to work is about 0.7G characters.</p>
<p>Buffer values are also limited to 2**31-1 (0x7fffffff) bytes.</p>
<h2>Property limits</h2>
<p>An object can have at most <code>DUK_HOBJECT_MAX_PROPERTIES</code> (an
internal define). Currently this limit is 0x7ffffffff.</p>
<h2>Regexp infinite loop</h2>
<p>The regexp engine gets stuck when a quantifier is used over an
empty match. For instance, the following should produce a "no match"
result but hits an internal recursion limit instead:</p>
<pre>
$ duk
duk&gt; t = /(x*)*/.exec('y');
Error: Error: regexp executor recursion limit reached (rc=1) [ignored]
</pre>
<h2>Regexp dollar escape</h2>
<p>The Duktape RegExp syntax allows dollar escaping (e.g. <code>/\$/</code>)
even though it is not allowed by the E5.1 specification. RegExp dollar
escapes are used in existing Ecmascript code quite widely.</p>
<h2>Invalid stack indices</h2>
<p>The internal implementation for some stack operations (like
<code>duk_set_top()</code> uses pointer arithmetic. On 32-bit platforms
the pointer arithmetic may wrap and work in unexpected ways if stack
index values are large enough (e.g. 0x20000000 on a 32-bit platform
with 8-byte packed value type).</p>
<h2>Error handler model incomplete</h2>
<p>The model for error handlers is incomplete. Use <code>DUK_INVALID_INDEX</code>
as the error handler index for now.</p>
<h2>Unicode case conversion is not locale or context sensitive</h2>
<p>E5 Sections 15.5.4.16 to 15.5.4.19 require context and locale processing
of Unicode SpecialCasing.txt. However, we don't currently have a notion
of "current locale".</p>
<h2>Array performance when using non-default property attributes</h2>
<p>All array elements are expected to be writable, enumerable, and configurable
(default property attributes for new properties). If this assumption is violated,
even temporarily, the entire "array part" of an object is abandoned permanently
and array entries are moved to the "entry part". This involves interning all used
array indices as explicit string keys (e.g. "0", "1", etc). This is not a
compliance concern, but degrades performance.</p>
<h2>Compiler performance for inner functions</h2>
<p>Compiler needs multiple passes over the same function. Inner functions
are scanned <code>2**n</code> times, where <code>n</code> is the function level
(0, 1, ...).</p>
<h2>Global/eval code is slower than function code</h2>
<p>Bytecode generated for global and eval code cannot assign variables
statically to registers, and will use explicit name-based variable
read/write accesses. Bytecode generated for function code doesn't
have this limitation; most variables are assigned statically to registers
and direct register references are used used to access them.</p>
<p>This is a minor issue unless you spend a lot of time running top-level
global/eval code. The workaround is simple: put code in a function which
you call from the top level; for instance:</p>
<pre class="ecmascript-code">
function main() {
// ...
}
main();
</pre>
<p>There is also a common idiom of using an anonymous function for this
purpose:</p>
<pre class="ecmascript-code">
(function () {
// ...
})();
</pre>
<h2>Function temporaries may be live for garbage collection longer than expected</h2>
<p>Ecmascript functions are compiled into bytecode with a fixed set of
registers. Some registers are reserved for arguments and variable
bindings while others are used as temporaries. All registers are
considered live from a garbage collection perspective, even temporary
registers containing old values which the function actually cannot
reference any more. Such temporaries are considered reachable until they
are overwritten by the evaluation of another expression or until the
function exits. Function exit is the only easily predicted condition to
ensure garbage collection.</p>
<p>If you have a function which remains running for a very long time, it
should contain the bare minimum of variables and temporaries that could
remain live. For instance, you can structure code like:</p>
<pre class="ecmascript-code">
function runOnce() {
// run one iteration, lots of temporaries
}
function foreverLoop() {
for (;;) {
runOnce();
}
}
</pre>
<p>This is typically not an issue if there are no long-running functions.</p>