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.

1256 lines
54 KiB

=========================
Duktape 2.0 release notes
=========================
Release overview
================
Main changes in this release (see RELEASES.rst for full details):
* New tools/configure.py frontend tool replaces genconfig.py for configuring
and preparing Duktape sources for build.
* Buffer handling has been simplified: Duktape.Buffer has been removed and is
replaced by Uint8Array, plain buffers now behave like Uint8Array objects.
Node.js Buffer behavior aligned with more recent Node.js Buffer API.
* Implement more ES2015 and ES2016 functionality, and align some ES5.1
semantics with ES2015/ES2016. Implement WHATWG Encoding API with
TextEncoder() and TextDecoder() bindings.
* Some incompatible API changes, and several API additions. API and config
changes to avoid I/O dependencies (such as printf() and fopen()) in core
Duktape code to simplify porting.
* More configuration flexibility in dropping Duktape specific functionality
from build, e.g. coroutines and finalization.
* Disabled ECMAScript bindings are no longer present (instead of being present
but throwing a TypeError).
* Built-in functionality moved to optional extras: print/alert bindings,
logging, and module loader. New optional extras include a Node.js-like
module loader and a 'console' binding.
* Bug fixes, performance and footprint improvements.
The release has API incompatible changes, see upgrading notes below.
Upgrading from Duktape 1.x
==========================
There are API incompatible changes in this release. Whenever possible the
incompatible changes cause a compilation error (or warning) so that fixing
call sites should be straightforward. Below are instructions on how to
migrate from 1.x to 2.0.0. There are also bug fixes and other minor
behavioral changes which may affect some applications, see ``RELEASES.rst``
for details.
There are backwards compatible providers for some removed/modified API calls
in ``extras/duk-v1-compat``.
Supporting Duktape 1.x and Duktape 2.x simultaneously
-----------------------------------------------------
For C code you can use the ``DUK_VERSION`` define to support both Duktape 1.x
and 2.x in the same application. For example::
#if (DUK_VERSION >= 20000)
rc = duk_safe_call(ctx, my_safe_call, NULL, 1 /*nargs*/, 1 /*nrets*/);
#else
rc = duk_safe_call(ctx, my_safe_call, 1 /*nargs*/, 1 /*nrets*/);
#endif
If you're developing against Duktape master before 2.0 release, ``DUK_VERSION``
is set to 19999 so that you can use::
#if (DUK_VERSION >= 19999)
rc = duk_safe_call(ctx, my_safe_call, NULL, 1 /*nargs*/, 1 /*nrets*/);
#else
rc = duk_safe_call(ctx, my_safe_call, 1 /*nargs*/, 1 /*nrets*/);
#endif
Similarly for ECMAScript code you can::
var plainBuffer;
if (Duktape.version >= 19999) {
plainBuffer = Uint8Array.plainOf(bufferObject);
} else {
plainBuffer = Duktape.Buffer(bufferObject);
}
Or you can detect features specifically::
var plainBuffer = (typeof Uint8Array.plainOf === 'function' ?
Uint8Array.plainOf : Duktape.Buffer)(bufferObject);
DUK_OPT_xxx feature option support removed
------------------------------------------
Duktape 2.0 no longer supports ``DUK_OPT_xxx`` options given via the compiler
command line. Instead, all options are encoded in ``duk_config.h``.
To use custom Duktape options, use the ``tools/configure.py`` tool to create
a customized ``duk_config.h`` and prepared Duktape sources matching the
configuration. For example to enable assertions and fastint support::
$ python2 tools/configure.py \
--output-directory /tmp/output \
--source-directory src-input \
--config-metadata config \
-DDUK_USE_FASTINT \
-DDUK_USE_ASSERTIONS
# Prepared duk_config.h header and Duktape sources (duktape.h and
# duktape.c) are in /tmp/output. Compile normally with your application.
$ gcc -std=c99 -Wall -o/tmp/test -I/tmp/output /tmp/output/duktape.c \
my_application.c -lm
See http://wiki.duktape.org/Configuring.html for details and examples.
To upgrade:
* If you're using the Duktape default configuration and no ``DUK_OPT_xxx``
compiler options, no actions are needed.
* Otherwise, remove ``DUK_OPT_xxx`` options from the compilation command and
add a ``tools/configure.py`` pre-step to your build. Add the equivalent
``DUK_USE_xxx`` options to ``tools/configure.py`` argument list; for example
``-DDUK_USE_FASTINT``.
* If you're using a ``duk_custom.h`` header there are three simple approaches:
- To embed your custom header into ``duk_config.h`` statically, use
``--fixup-file duk_custom.h`` in ``tools/configure.py`` options.
- To include your custom header at compilation time, similarly to
``DUK_OPT_HAVE_CUSTOM_H``, use ``--fixup-line '#include "duk_custom.h"'``
in ``tools/configure.py`` options.
- Finally, you can in some cases remove your custom header and use
equivalent config options for ``tools/configure.py``.
Config option changes
---------------------
There are several new config options and some existing config options have
been removed.
To upgrade:
* Review any ``DUK_OPT_xxx`` or ``DUK_USE_xxx`` options in use against
``config/config-options/*.yaml``.
Built-ins disabled in configuration are now absent
--------------------------------------------------
If a built-in is disabled when running ``configure.py``, it won't be present
in the ECMAScript environment. For example, with ``-UDUK_USE_ES6_PROXY``::
duk> new Proxy()
ReferenceError: identifier 'Proxy' undefined
at [anon] (duk_js_var.c:1262) internal
at global (input:1) preventsyield
duk> typeof Proxy
= "undefined"
In Duktape 1.x the binding was present but would just throw an Error when
invoked::
duk> new Proxy()
Error: unknown error (rc -1)
at Proxy () native strict construct preventsyield
at global (input:1) preventsyield
duk> typeof Proxy
= "function"
The revised behavior saves footprint and allows scripts to detect
supported built-ins reliably using e.g.::
if (typeof Proxy === 'function') {
// supported
}
To upgrade:
* In most cases no action is needed. If your code relies on the builtins
being present but throwing an error (which seems unlikely), such call
sites need to be fixed.
Tooling changes
---------------
There are some tooling changes in this release:
* The distributable now includes raw sources in ``src-input/`` and some
tooling in ``tools/``. This allows Duktape sources to be modified and
re-amalgamated directly from the distributable. The distributable still
includes sources prepared using default configuration (``src/``,
``src-noline/``, and ``src-separate``) and some configuration examples.
* The tooling includes a new ``tools/configure.py`` tool which creates
a ``duk_config.h`` and matching prepared sources simultaneously. This
allows use of ROM built-ins from the distributable. Previously ROM
built-ins required a manual ``dist.py --rom-support ...`` command.
* The ``make_dist.py`` utility in Duktape main repo has been renamed to
``dist.py`` and no longer supports ``--rom-support``,
``--rom-auto-lightfunc``, and ``--user-builtin-metadata`` options. Use
the ``tools/configure.py`` tool instead, which supports these options.
However, ``--user-builtin-metadata`` has been renamed ``--builtin-file``.
* The ``config/genconfig.py`` has been relocated to ``tools/genconfig.py`` in
the distributable. It can still be used as a standalone tool, but using
configure.py is recommended instead.
To upgrade:
* If you're just using the default sources and ``duk_config.h`` in the
distributable, no changes are needed.
* If you're using ``genconfig.py`` considering using ``tools/configure.py``
instead. If you keep on using ``genconfig.py``, update path to
``tools/genconfig.py``.
* If you're using ROM built-ins via ``make_dist.py``, change your build to
use ``tools/configure.py`` instead, and change ``--user-builtins-metadata``
option argument(s) to ``--builtin-file``.
Dist package file changes
-------------------------
* Configuration metadata is now in unpacked form in ``dist/config`` to match
the Duktape master repo and to make config files more convenient to patch.
The ``dist/tools/genconfig.py`` tool no longer accepts a tar.gz metadata
argument.
* The pre-built ``duk_config.h`` examples have been removed as somewhat
useless. Use ``dist/tools/configure.py`` (or ``dist/tools/genconfig.py)``
to generate ``duk_config.h`` files.
* ``dist/duk_build_meta.json`` has been renamed to ``dist/duk_dist_meta.json``
for clarity. It no longer contains string data scanned from source files.
This metadata is now in source directories, e.g.
``dist/src/duk_source_meta.json`` as the string set potentially depends
on options used to prepare sources.
* Source metadata, e.g. ``dist/src/metadata.json``, has been renamed to
``dist/src/duk_source_meta.json`` for clarity. The metadata contains
Duktape version information, strings scanned from source files, and for
combined (amalgamated) sources the line number metadata.
Buffer behavior changes
-----------------------
There are a lot of buffer behavior changes in the 2.0 release; see detailed
changes below and in RELEASES.rst. Here's a summary of changes:
* ``Duktape.Buffer`` has been removed. Plain buffers now behave like
``Uint8Array`` instances to the extent possible. They don't have a property
table, however, which causes some limitations. Plain buffers ToObject()
coerce to an actual Uint8Array object with the same backing buffer. There
are many small changes to how plain buffers are treated by standard built-ins
as a result. For example, string coercion (``String(plainBuffer)``) now
mimics Uint8Array and usually results in the string ``[object Uint8Array]``.
* Plain buffers have an inherited ``.buffer`` getter property which returns an
ArrayBuffer object backing to the same underlying plain buffer. Because
there is no property table for plain buffers, each ``.buffer`` access creates
a new ArrayBuffer instance.
* When ``duk_push_buffer_object()`` creates an automatic ArrayBuffer for a
view (such as Uint8Array), the ArrayBuffer's .byteOffset will be set to 0
and its .byteLength will be set to view.byteOffset + view.byteLength. This
ensures that accessing the ArrayBuffer at view.byteOffset returns the same
value as when accessing view at index 0, which is the usual relationship
between a view and its backing ArrayBuffer. Up to Duktape 1.6.x the
ArrayBuffer's .byteOffset and .byteLength would be the same as the view's.
* Non-standard properties, such as virtual indices and ``.length`` have been
removed from ArrayBuffer and DataView. The ``.byteOffset``, ``.byteLength``,
``.BYTES_PER_ELEMENT``, and ``.buffer`` properties of view objects are now
inherited getters to match ES2015. The ``.length`` property remains a virtual
own property, however (it is a getter in ES2015).
* Default ECMAScript built-ins no longer provide the ability to do a 1:1
buffer-to-string coercion where the buffer bytes are used directly as the
internal string bytes. Instead, an encoding (usually UTF-8) is always
involved, and U+FFFD replacement characters are used when invalid inputs
are encountered. See https://github.com/svaarala/duktape/issues/1005.
C code can still do 1:1 conversions using ``duk_buffer_to_string()`` or
by pushing a raw string directly, and can expose such a binding to
ECMAScript code.
* Node.js Buffer binding has been aligned more with Node.js v6.9.1 (from
Node.js v0.12.1) and some (but not all) behavior differences to actual
Node.js have been fixed.
* Disabling ``DUK_USE_BUFFEROBJECT_SUPPORT`` allows use of plain buffers in
the C API, and allows manipulation of plain buffers in ECMAScript code via
their virtual properties (index properties, ``.length``, etc). Plain buffers
still inherit from ``Uint8Array.prototype``, but won't Object coerce. All
ArrayBuffer, typed array, and Node.js Buffer methods will be missing, including
``Uint8Array.allocPlain()``. Duktape custom built-ins operating on plain
buffers (like Duktape.dec() with hex or base-64 encoding) continue to work.
(This behavior is not guaranteed and may change even in minor versions.)
To upgrade:
* If you're using buffers in general, review http://wiki.duktape.org/HowtoBuffers.html
which has been updated for Duktape 2.0.
* If you're using standard ArrayBuffers and typed arrays, no changes should
normally be necessary, however see technical changes in RELEASES.rst.
* If you're using the Node.js Buffer binding, review the following:
- Node.js Buffer ``.concat()`` always returns a buffer copy, even for a
one-element input array which had special handling in Node.js v0.12.1.
- Node.js Buffer.prototype ``.toString()`` now decodes the input buffer
using UTF-8, emitting replacement characters for invalid UTF-8 sequences.
- Review Buffer code for Node.js Buffer changes between Node.js versions
v0.12.1 and v6.9.1 in general.
* If you're using plain buffers, review their usage especially in ECMAScript
code, in particular:
- Because plain buffers now mimic Uint8Array (a view), they are treated as
initializer values when used as typed array constructor arguments. For
example, ``new Uint32Array(plainBuffer)`` will create a new Uint32Array
rather than a view into the plain buffer.
- To create a view into the plain buffer, use the same approach as with a
Uint8Array, e.g. ``new Uint32Array(plainBuffer.buffer)``.
* Regardless of buffer type(s) in use:
- One important change is that ``String(plainBuffer)`` and ``duk_to_string()``
for a buffer does not work as before, use new ``duk_buffer_to_string()``
C API call instead. There's no equivalent function for the default
ECMAScript built-ins.
- Another important change is that plain buffers, like Uint8Array objects,
boolean coerce to ``true`` regardless of buffer size (zero or larger) and
contents.
* If you're using ``Duktape.Buffer``, the following new built-ins replace its
functionality (and more):
- ``Uint8Array.allocPlain()``: to allocate a new (fixed) plain buffer
- ``Uint8Array.plainOf()``: to get the underlying plain buffer of any
buffer object (without making a copy)
- However, these bindings are intentionally missing if buffer object support
has been disabled in Duktape configuration.
Some detailed changes, not exhaustive; see ``RELEASES.rst`` and
``tests/ecmascript/test-bi-plain-buffer-*.js`` for even more detail:
* ``typeof plainBuffer`` is now ``object`` instead of ``buffer``.
- ``plainBuffer instanceof Uint8Array`` is true.
* Plain buffer Object.prototype.toString() now usually, assuming no overridden
.toString(), yields ``[object Uint8Array]`` instead of ``[object Buffer]``.
* Plain buffer inherits from Uint8Array.prototype instead of
Duktape.Buffer.prototype.
* For a plain buffer ``duk_to_string()`` no longer creates a string with the
same underlying bytes, but results in ``[object Uint8Array]`` instead
(unless ``.toString()`` or ``.valueOf()`` has been overridden); in
particular, using a plain buffer as an object property key is misleading
as ``obj[buf]`` is (usually) equivalent to ``obj['[object Uint8Array]']``.
``duk_to_buffer()`` for a string still results in a plain buffer with the
same underlying bytes as before.
* A new ``duk_buffer_to_string()`` API call converts any buffer value to a
string with the same underlying bytes as in the buffer (like
``duk_to_string()`` did in Duktape 1.x). ECMAScript built-ins no longer
have this ability directly.
* ``duk_to_boolean()`` for a plain buffer: always true, even if the buffer
has zero length.
* ``duk_to_primitive()`` for plain buffer: usually coerces to the string
``[object Uint8Array]`` because plain buffers are not considered a primitive
value.
* ``duk_is_primitive()`` for a plain buffer is now false to match how
``duk_to_primitive()`` deals with plain buffers (i.e. coerces them rather
than returning them as is).
* When a plain buffer is used as the "this" binding of a function call, it is
ToObject() coerced to an actual Uint8Array if the call target is non-strict.
This mimics what happens to e.g. plain strings. Lightfuncs have also been
revised to behave the same way (in Duktape 1.x they would not be ToObject()
coerced in this situation).
* ``new ArrayBuffer(plainBuffer)`` no longer creates a new ArrayBuffer with
the same underlying plain buffer; instead, the plain buffer gets coerced to
zero and creates a zero-length ArrayBuffer. This matches how a Uint8Array
argument is handled in ``new ArrayBuffer()``.
- ``new Buffer(plainBuffer)`` no longer special cases plain buffer and gets
treated like an Uint8Array: a fresh Buffer with matching ``.length`` is
created and index elements are copied into the result buffer (in effect
making an actual buffer copy).
- ``ArrayBuffer.isView(nodejsBuffer)`` is now true to reflect the fact that
Node.js Buffers are Uint8Arrays in newer Node.js versions.
* ``new Uint32Array(plainBuffer)`` and other typed array constructors use the
argument plain buffer as an initializer (like Uint8Array), which causes a
copy to be created.
* ``new DataView(plainBuffer)`` is rejected and DataView() in general rejects
any other argument than an actual ArrayBuffer.
* ``typedarray.prototype.subarray()`` accepts a plain buffer and the resulting slice
is a Uint8Array because plain buffers cannot represent a view offset/length.
* Node.js ``Buffer.prototype.slice()`` accepts a plain buffer and the result is a
Node.js Buffer (which itself is a special Uint8Array instance).
* ``plainBuffer.valueOf()`` ordinarily backed by ``Object.prototype.valueOf()``
returns ``Object(plainBuffer)``, i.e. converts plain buffer to an actual
Uint8Array. This matches normal ``Object.prototype.valueOf()`` behavior, e.g.
plain string is coerced into a String object.
- ``JSON.stringify()`` now recognizes plain buffers like Uint8Array instances;
the result is typically ``{"0":XXX,"1":XXX,....}`` without a ``.toJSON()``
implementation, as the virtual index properties are enumerable for Uint8Arrays.
* ``Object.freeze()`` not allowed for plain buffers or buffer objects (Duktape
1.x allowed silently) because array index elements cannot be made non-writable.
This is an internal limitation and failing with a TypeError signals this to the
caller (and matches how e.g. V8 handles ``Object.freeze(new Uint8Array(4))``).
- Typed array ``.subarray()`` and Node.js Buffer ``.slice()`` result internal
prototype is now set to the default prototype of the result type (e.g. initial
value of ``Uint8Array.prototype`` if the input is an Uint8Array) rather than
being copied from the argument.
* Node.js ``Buffer`` and ``Buffer.prototype`` methods now accept plain buffers.
* A plain buffer is accepted as a constructor "replacement value".
Pointer behavior changes
------------------------
There are very minor changes to pointer value behavior:
* ``plainPointer instanceof Duktape.Pointer`` now evaluates to ``true``
(``false`` in Duktape 1.x).
To upgrade:
* If you're using pointer values in ECMAScript code, check pointer handling.
Lightfunc behavior changes
--------------------------
There are very minor changes to lightfunc value behavior:
* ``duk_is_primitive()`` now returns false for lightfuncs; this is more in
line with how lightfuncs behave in ECMAScript ToPrimitive() coercion and
matches how plain buffers work in Duktape 2.x.
* ``[[DefaultValue]]`` coercion now considers lightfuncs non-primitive
(previously considered primitive and thus accepted as ``[[DefaultValue]]``
result).
* When a lightfunc is used as the "this" binding of a function call, it is
ToObject() coerced to a full function when the call target is non-strict.
Duktape 1.x would not coerce the lightfunc to an object in this situation;
the change was made to match plain buffer behavior. Note that because
lightfuncs themselves are considered strict functions, this only happens
when the call target is not a lightfunc but the "this" binding is.
* A lightfunc is accepted as a constructor "replacement value".
To upgrade:
* If you're using lightfuncs, review their handling.
print() and alert() globals removed
-----------------------------------
The ``print()`` and ``alert()`` globals were removed because they depended on
stdout/stderr which is a portability issue on some platforms. Further, even
if stdout/stderr is available, it's not always the appropriate place for debug
printouts, so it's cleaner if the application provides its own debug/console
logging functions.
To upgrade:
* If you don't use ``print()`` or ``alert()`` no action is needed; they simply
won't be a part of the global object anymore.
* If a simple ``print()`` and/or ``alert()`` suffices, you can use something
like this::
static duk_ret_t my_print(duk_context *ctx) {
duk_push_string(ctx, " ");
duk_insert(ctx, 0);
duk_join(ctx, duk_get_top(ctx) - 1);
fprintf(stdout, "%s\n", duk_to_string(ctx, -1)); /* 'stderr' for alert() */
fflush(stdout); /* may or may not want to flush, depends on application */
return 0;
}
/* And after Duktape heap creation (or after each new thread with a
* fresh global environment):
*/
duk_push_c_function(ctx, my_print, DUK_VARARGS);
duk_put_global_string(ctx, "print");
* If you do need ``print()`` and/or ``alert()`` with the Duktape 1.x
semantics you can include the following extra into your compilation:
``extras/print-alert``.
Built-in CommonJS module framework removed
------------------------------------------
The built-in CommonJS module loading framework consisting of ``require()``,
``Duktape.modSearch()`` and ``Duktape.modLoaded`` was removed; a module
framework isn't always needed, and when it is, it's difficult for a single
framework to match the very different use cases.
To upgrade:
* If you don't use the built-in module loading framework, no action is needed.
* If you do use the built-in module loading framework and want to continue
using a module loader with Duktape 1.x semantics, you can include the
following extra into your compilation: ``extras/module-duktape``.
* If you're upgrading, there are also other alternatives to module loading.
For example, the ``extras/module-node`` module loader provides Node.js-like
semantics with a more flexible module resolution and loading process.
Duktape.Logger, duk_log(), and duk_log_va() removed
---------------------------------------------------
The built-in logging framework consisting of ``Duktape.Logger``, ``duk_log()``,
and ``duk_log_va()`` were removed because they depended on stdout/stderr which
is a portability issue on some platforms. The logging framework also didn't
always match user expectations: for some uses it was too simple (lacking e.g.
expressive backend configuration); for other uses it was too complex (too
high a ROM/RAM footprint for some embedded uses). Sometimes an existing API
like ``console.log()`` was preferred while in other cases a platform specific
logging binding was more appropriate.
To upgrade:
* If you don't need ``Duktape.Logger`` or the C logging API calls, no action
is needed.
* If you do need ``Duktape.Logger`` and/or the C logging API calls with
Duktape 1.x semantics, you can include the following extra into your
compilation: ``extras/logging``.
duk_safe_call() userdata
------------------------
There's a new userdata argument for ``duk_safe_call()``::
/* Duktape 1.x */
typedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx);
duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, duk_idx_t nargs, duk_idx_t nrets);
/* Duktape 2.x */
typedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx, void *udata);
duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets);
The additional userdata argument makes it easier to pass a C pointer to the
safe-called function without the need to push a pointer onto the value stack.
Multiple C values can be passed by packing them into a stack-allocated struct
and passing a pointer to the struct as the userdata.
To upgrade:
* Add a userdata argument to duk_safe_call() call sites. If no relevant
userdata exists, pass a NULL.
* Add a userdata argument to safe call targets. If no relevant userdata
exists, just ignore the argument.
* If a call site needs to support both Duktape 1.x and Duktape 2.x, use
a DUK_VERSION preprocessor check::
#if (DUK_VERSION >= 20000)
duk_ret_t my_safe_call(duk_context *ctx, void *udata) {
#else
duk_ret_t my_safe_call(duk_context *ctx) {
#endif
/* Ignore 'udata'. */
}
/* ... */
#if (DUK_VERSION >= 20000)
rc = duk_safe_call(ctx, my_safe_call, NULL, 1 /*nargs*/, 1 /*nrets*/);
#else
rc = duk_safe_call(ctx, my_safe_call, 1 /*nargs*/, 1 /*nrets*/);
#endif
Duktape specific error codes removed from API
---------------------------------------------
Duktape specific error codes were removed from the public API and from
internals. These error codes were not very widely used, and they didn't
have an ECMAScript counterpart (for example, a ``DUK_ERR_API_ERROR`` mapped
to a plain ``Error`` object) which was confusing. The removed error codes
and defines are:
* ``DUK_ERR_UNIMPLEMENTED_ERROR`` / ``DUK_RET_UNIMPLEMENTED_ERROR``
* ``DUK_ERR_UNSUPPORTED_ERROR`` / ``DUK_RET_UNSUPPORTED_ERROR``
* ``DUK_ERR_INTERNAL_ERROR`` / ``DUK_RET_INTERNAL_ERROR``
* ``DUK_ERR_ALLOC_ERROR`` / ``DUK_RET_ALLOC_ERROR``
* ``DUK_ERR_ASSERTION_ERROR`` / ``DUK_RET_ASSERTION_ERROR``
* ``DUK_ERR_API_ERROR`` / ``DUK_RET_API_ERROR``
* ``DUK_ERR_UNCAUGHT_ERROR`` / ``DUK_RET_UNCAUGHT_ERROR``
Duktape API related errors were also changed to map to either a ``TypeError``
or ``RangeError`` instead of a plain ``Error``:
* A ``RangeError`` is used when an argument is out of bounds; for example:
a value stack index is out of bounds, pop count is too large, not enough
value stack items for call argument count.
* A ``TypeError`` is used when a value has incorrect type, and is thrown by
for example ``duk_require_boolean()``. ``TypeError`` is also typically
used when nothing else applies.
To upgrade:
* If you use the custom error codes (``DUK_ERR_INTERNAL_ERROR`` etc) in your
code, convert to using standard error codes (``DUK_ERR_TYPE_ERROR``, etc).
* If you depend on API errors mapping to a plain ``Error``, revise such code
to accept also ``TypeError`` or ``RangeError``. (In general depending on a
specific error type should be only be done when it's absolute necessary.)
duk_error(), duk_error_va(), duk_throw(), duk_fatal() have a return value
-------------------------------------------------------------------------
The prototype return value for these error throwers was changed from ``void``
to ``duk_ret_t`` which allows for idioms like::
if (argvalue < 0) {
return duk_error(ctx, DUK_ERR_TYPE_ERROR,
"invalid arg: %d", (int) argvalue);
}
To upgrade:
* Without an explicit cast to ``(void) duk_error(...)`` you may get some new
compiler warnings. Fix by adding the void cast, or convert the call sites
to use the ``return duk_error(...)`` idiom where applicable.
duk_dump_context_stdout() and duk_dump_context_stderr() removed
---------------------------------------------------------------
These two API calls were helpers based on ``duk_push_context_dump()`` which
would write the context dump directly to stdout/stderr. Having a dependency
on stdout/stderr is a portability concern so the calls were removed in
Duktape 2.x.
To upgrade:
* Replace ``duk_dump_context_stdout()`` with an explicit call sequence like::
duk_push_context_dump(ctx);
printf("%s\n", duk_to_string(ctx, -1));
duk_pop(ctx);
Similarly for ``duk_dump_context_stderr()``.
* Alternatively, include extras/duk-v1-compat into your compilation to add back
the removed API calls.
duk_to_defaultvalue() removed
-----------------------------
The ``duk_to_defaultvalue()`` API call was rather technical: it invoked the
internal ``[[DefaultValue]]`` algorithm which is used in ES5.1 as part of
the ToPrimitive() coercion (``duk_to_primitive()``). ES2015 no longer specifies
``[[DefaultValue]]`` which has been folded into ToPrimitive(). The API call
thus no longer makes much sense.
To upgrade:
* If you're using ``duk_to_defaultvalue()`` (which is unlikely), you can in
most cases replace it with ``duk_to_primitive()``. The main difference
is that ``duk_to_primitive()`` accepts all argument types (returning
those considered primitive as is) while ``duk_to_defaultvalue()`` rejects
primitive value arguments. See the ES5.1/ES2015 specifications for exact
differences between the two.
* Here's an example replacement. Replace this::
duk_to_defaultvalue(ctx, idx, hint);
with::
duk_require_type_mask(ctx, idx, DUK_TYPE_MASK_OBJECT |
DUK_TYPE_MASK_BUFFER |
DUK_TYPE_MASK_LIGHTFUNC);
duk_to_primitive(ctx, idx, hint);
* Alternatively, include extras/duk-v1-compat into your compilation to add back
the removed API call.
File I/O Duktape C API calls were removed
-----------------------------------------
Some platform don't have file I/O API calls (even ANSI), while on others they
are present but don't actually map to the file system (instead, a platform
specific API is used to access the actual file system). Finally, there are
character encoding issues with ANSI C file I/O APIs e.g. on Windows, so that
the built-in file I/O support didn't always work as expected.
To improve portability, the following Duktape C API calls depending on
platform file I/O (fopen() etc) were removed (moved to extras):
* duk_push_string_file()
* duk_compile_file()
* duk_pcompile_file()
* duk_eval_file()
* duk_eval_file_noresult()
* duk_peval_file()
* duk_peval_file_noresult()
To upgrade:
* If you don't use these API calls, no action is needed.
* If you use these API calls you can e.g. implement a helper to push a file
as a string (like ``duk_push_string_file()``) and then implement any needed
compile/eval helpers based on that.
* Alternatively, you can include the following extra into your compilation:
``extras/duk-v1-compat``. The extra provides Duktape 1.x compatible
file-related API call bindings.
duk_debugger_attach() and duk_debugger_attach_custom() merged
-------------------------------------------------------------
The ``duk_debugger_attach_custom()`` API call in Duktape 1.x has been renamed
to ``duk_debugger_attach()`` to eliminate an unnecessary API call variant from
the public API. The remaining debugger attach call always includes an
AppRequest callback argument.
To upgrade:
* ``duk_debugger_attach_custom()`` call sites: rename API call to
``duk_debugger_attach()``; no argument changes are needed.
* ``duk_debugger_attach()`` call sites: add a NULL ``request_cb`` callback
argument.
* If a call site needs to support both Duktape 1.x and Duktape 2.x::
/* Alternative #1: conditional call name. */
#if (DUK_VERSION >= 20000)
duk_debugger_attach(
#else
duk_debugger_attach_custom(
#endif
read_cb,
write_cb,
peek_cb,
read_flush_cb,
write_flush_cb,
request_cb, /* NULL OK if not necessary */
detached_cb,
udata);
/* Alternative #2: conditional request_cb argument. */
duk_debugger_attach(
read_cb,
write_cb,
peek_cb,
read_flush_cb,
write_flush_cb,
#if (DUK_VERSION >= 20000)
request_cb, /* NULL OK if not necessary */
#endif
detached_cb,
udata);
Debug protocol version bumped from 1 to 2
-----------------------------------------
Because there are small incompatible changes in the debug protocol in this
release, the debug protocol version has been bumped from 1 to 2. The version
is provided by the ``DUK_DEBUG_PROTOCOL_VERSION`` constant, and also appears
in the debug protocol version identification string.
To upgrade:
* Review the debug protocol changes and ensure debug client has corresponding
changes.
* Update debug client code to support both versions 1 and 2, or version 2 only.
Debugger detached callback has a duk_context pointer argument
-------------------------------------------------------------
The debugger detached callback is allowed to immediately reattach the debugger
session. However, the detached callback didn't have a ``duk_context *``
argument in Duktape 1.x so that the relevant context pointer needed to be passed
e.g. via the udata argument which is awkward.
In Duktape 2.x an explicit context argument was added::
/* Duktape 1.x */
typedef void (*duk_debug_detached_function) (void *udata);
/* Duktape 2.x */
typedef void (*duk_debug_detached_function) (duk_context *ctx, void *udata);
To upgrade:
* If you're using ``duk_debugger_attach()``, add an additional ``duk_context *``
argument to the detached callback.
* If support for both Duktape 1.x and 2.x is desired, use::
#if DUK_VERSION >= 20000
void my_detached_cb(duk_context *ctx, void *udata) {
#else
void my_detached_cb(void *udata) {
#end
/* ... */
}
Debugger command callstack index changes
----------------------------------------
Debug command callstack indexes have been made mandatory where appropriate to
simplify the protocol. Affected commands are: GetVar, PutVar, GetLocals, and
Eval.
To upgrade:
* Review debug client handling of callstack indices when sending affected
commands.
Debugger print/alert and logger forwarding removed
--------------------------------------------------
Forwarding of ``print()``, ``alert()``, and log writes, enabled using config
options ``DUK_USE_DEBUGGER_FWD_PRINTALERT`` and ``DUK_USE_DEBUGGER_FWD_LOGGING``,
was removed as part of removing the bindings themselves. Also debugger
notifications Print (0x02), Alert (0x03), Log (0x04) were deprecated.
To upgrade:
* No changes are needed, but print/alert and logger notification support can
be removed from a debug client.
* If you rely on print/alert or logger forwarding in your debugger setup, you
can add custom print/alert or logger forwarding by implementing print/alert
or logging yourself and using AppNotify (``duk_debugger_notify()``) to
forward print/alert or logger text.
Internal duk_harray affects debugger array inspection
-----------------------------------------------------
Duktape 2.x introduces an internal ``duk_harray`` type to represent arrays.
The array ``.length`` property is no longer stored in the property table of
the array but is a C struct field in ``duk_harray`` and the property visible
to ECMAScript code is virtual.
As a result, array ``.length`` is not visible when inspecting ordinary array
properties using e.g. GetObjPropDesc or GetObjPropDescRange. Instead, array
``.length`` is an artificial property ``"length"`` returned by GetHeapObjInfo.
To upgrade:
* If the debug client uses array ``.length`` for e.g. UI purposes, ensure
the artificial property ``"length"`` is used instead.
Other debugger changes
----------------------
* Artificial properties renamed for consistency with internal renaming:
- ``compiledfunction`` -> ``compfunc``
- ``nativefunction`` -> ``natfunc``
- ``bufferobject`` -> ``bufobj``
- ``bound`` -> ``boundfunc``
Debug print config options changed
----------------------------------
Debug print related config options were reworked as follows:
* Debug prints no longer automatically go to ``stderr``. Instead, an
application must define ``DUK_USE_DEBUG_WRITE()`` in ``duk_config.h``
when ``DUK_USE_DEBUG`` is enabled. The macro is called to write debug log
lines; there's no default provider to avoid platform I/O dependencies.
Using a user-provided macro removes a dependency on platform I/O and also
allows debug logs to be filtered and redirected in whatever manner is most
useful for the application. Example provider::
#define DUK_USE_DEBUG_WRITE(level,file,line,func,msg) do { \
fprintf(stderr, "D%ld %s:%ld (%s): %s\n", \
(long) (level), (file), (long) (line), (func), (msg)); \
} while (0)
See http://wiki.duktape.org/HowtoDebugPrints.html for more information.
* Debug level options ``DUK_USE_DPRINT``, ``DUK_USE_DDPRINT``, and
``DUK_DDDPRINT`` were replaced with a single config option
``DUK_USE_DEBUG_LEVEL`` with a numeric value:
- 0 is minimal logging (matches ``DUK_USE_DPRINT``)
- 1 is verbose logging (matches ``DUK_USE_DDPRINT``)
- 2 is very verbose logging (matches ``DUK_USE_DDDPRINT``)
To upgrade:
* If you're not using debug prints, no action is needed.
* If you're using debug prints:
- Add a ``DUK_USE_DEBUG_WRITE()`` to your ``duk_config.h``. By itself it
won't enable debug prints so it's safe to add even when debug prints are
disabled.
- Convert debug level options from ``DUK_USE_{D,DD,DDD}PRINT`` to the
equivalent ``DUK_USE_DEBUG_LEVEL`` (0, 1, or 2).
Fatal error and panic handling reworked
---------------------------------------
The following changes were made to fatal error and panic handling:
* Fatal error function signature was simplied from::
/* Duktape 1.x */
void func(duk_context *ctx, duk_errcode_t code, const char *msg);
to::
/* Duktape 2.x */
void func(void *udata, const char *msg);
where the ``udata`` argument is the userdata argument given in heap creation.
* ``duk_fatal()`` error code argument was removed to match the signature
change.
* The entire concept of "panic errors" was removed and replaced with calls to
the fatal error mechanism. There's a user-registered (optional) fatal error
handler in heap creation, and a built-in default fatal error handler which
is called if user code doesn't provide a fatal error handler.
Some fatal errors, currently assertion failures, happen without a Duktape
heap/thread context so that a user-registered handler cannot be called
(there's no heap reference to look it up). For these errors the default
fatal error handler is always called, with the userdata argument as ``NULL``.
The default fatal error handler can be replaced by editing ``duk_config.h``.
To upgrade:
* If you're not providing a fatal error handler nor using a custom panic
handler, no action is needed -- however, providing a fatal error handler
in heap creation is **strongly recommended**, see
http://wiki.duktape.org/HowtoFatalErrors.html for instructions.
The default fatal error handler will by default call ``abort()`` with no
error message to ``stdout`` or ``stderr``. To improve this behavior define
``DUK_USE_FATAL_HANDLER()`` in your ``duk_config.h``.
* If you have a fatal error handler, update its signature::
/* Duktape 1.x */
void my_fatal(duk_context *ctx, duk_errcode_t error_code, const char *msg) {
/* ... */
}
/* Duktape 2.x */
void my_fatal(void *udata, const char *msg) {
/* ... */
}
* If you're using ``duk_fatal()`` API calls, remove the error code argument::
/* Duktape 1.x */
duk_fatal(ctx, DUK_ERR_INTERNAL_ERROR, "assumption failed");
/* Duktape 2.x */
duk_fatal(ctx, "assumption failed");
* If you have a custom panic handler in your ``duk_config.h``, convert it to
a default fatal error handler, also provided by ``duk_config.h``. Both
Duktape 1.x panic handler and Duktape 2.x default fatal error handler apply
to all Duktape heaps (rather than a specific Duktape heap).
InitJS support removed
----------------------
Both Duktape InitJS (``DUK_USE_BUILTIN_INITJS``) and user InitJS
(``DUK_USE_USER_INITJS``) were removed. Duktape built-in InitJS is no
longer needed (and was never used for very much). User InitJS was rarely
used and it's not a full solution because custom environment initialization
may also involve native initialization code which isn't supported by the
mechanism.
To upgrade:
* Duktape built-in InitJS removal requires no user code changes.
* If you're using the user InitJS option, call sites need to be modified to
run the init code explicitly on heap/thread creation.
Enumeration order changes
-------------------------
Enumeration order for ``Object.getOwnPropertyNames()`` has been changed to
match ES2015/ES2016 ``[[OwnPropertyKeys]]`` enumeration order, which is:
* Array indices in ascending order
* Normal (non-array-index) property keys in insertion order
* Symbols in insertion order
While not required by ES2015/ES2016, the same enumeration order is also used in
Duktape 2.x for ``for-in``, ``Object.keys()``, and ``duk_enum()``. A related
change is that ``duk_enum()`` flags ``DUK_ENUM_ARRAY_INDICES_ONLY`` and
``DUK_ENUM_SORT_ARRAY_INDICES`` can now be used independently.
The revised enumeration order makes enumeration behavior more predictable
and matches other modern engines. In particular, sparse arrays (arrays
without an internal array part) now enumerate identically to dense arrays.
To upgrade:
* Check application code for enumeration assumptions.
Symbol support related changes
------------------------------
Small changes related to adding symbol support:
* Symbols are represented as strings with an invalid UTF-8 representation (like
internal keys in Duktape 1.x), and they behave like strings in the C API just
like internal keys did in Duktape 1.x. For example, ``duk_is_string()`` is
true for symbols. Symbols can be distinguished using ``duk_is_symbol()``.
* Symbol support is currently **experimental**. The core semantics have been
implemented but it's likely some of the internal details will change in future
releases. The C API may also need changes (for example to the typing model)
in future releases; in its current form symbols behave just like internal
strings in the C API.
* Being experimental, the ``Symbol`` built-in is disabled by default; enable via
config option ``DUK_USE_SYMBOL_BUILTIN``. Symbols can be created from C code
even when the ``Symbol`` built-in is disabled, and symbol semantics (like
``typeof`` and coercion behavior) are currently enabled.
* Internal properties are now called "hidden symbols" and adopt some ES2015 Symbol
behaviors, e.g. ``typeof internalKey === 'symbol`` and ``"" + internalKey``
is now a TypeError. Internal keys are different from normal ES2015 Symbols in
that they can't be enumerated from ECMAScript code even with
``Object.getOwnPropertySymbols()``.
* The ``DUK_ENUM_INCLUDE_INTERNAL`` C API flag has been renamed
``DUK_ENUM_INCLUDE_HIDDEN``.
Other incompatible changes
--------------------------
Incompatible changes (not exhaustive, also see RELEASES.rst):
* Normal and constructor function call argument limit is now 255, down from
the previous 511.
* If a user function is called using the identifier 'eval', such a call won't
get tailcall optimized even if otherwise possible.
* ``duk_gc()`` no longer accepts a NULL context pointer for consistence with
other API calls. A NULL pointer not causes memory unsafe behavior, as with
all other API calls.
* ``duk_def_prop()`` now ToPropertyKey() coerces its argument rather than
requiring the key to be a string. This allows e.g. numbers to be used as
property keys.
* ``duk_char_code_at()`` and ``String.charCodeAt()`` now return 0xFFFD (Unicode
replacement character) if the string cannot be decoded as extended UTF-8,
previously an error was thrown. This situation never occurs for standard
ECMAScript strings or valid UTF-8 strings.
* ``duk_get_length()`` now allows the ``size_t`` rather than the unsigned 32-bit
integer range for the target value's ``.length``.
* Legacy octal literal handling has been improved to match more closely with
ES2015 Annex B. Octal look-alike decimal literals like "0778" and "0778.123"
are now allowed.
* Legacy octal escape handling in string literals has been improved to match
more closely with ES2015 Annex B and other engines: "\078" is not accepted and
is the same as "\u00078", "\8" and "\9" are accepted as literal "8" and "9"
(even in strict mode).
* The NetBSD pow() workaround option ``DUK_USE_POW_NETBSD_WORKAROUND`` has been
generalized and renamed to ``DUK_USE_POW_WORKAROUNDS``.
* When using a Proxy as a for-in target the "ownKeys" trap is invoked instead
of the "enumerate" trap in ES2016. Duktape now follows this behavior. The
"enumerate" trap has been obsoleted. Key enumerability is also now checked
when "ownKeys" trap is used in Object.keys() and for-in.
* Bound function internal prototype is copied from the target function to match
ES2015 requirements; in ES5 (and Duktape 1.x) bound function internal prototype
is always set to Function.prototype.
* Function.prototype.toString() output has been changed to match ES2015
requirements. For example ``function foo() {"ecmascript"}`` is now
``function foo() { [ecmascript code] }``.
* Function ``.name`` and ``.length`` properties are now non-writable,
non-enumerable, but configurable, to match revised ES2015 semantics. Previously
the properties were also non-configurable.
* Function ``.fileName`` property is now non-writable, non-enumerable, and
configurable. Previously it was writable, non-enumerable, and configurable.
While this is not required by ES2015 (as the property is non-standard), it has
been aligned with ``.name``. Direct assignment to the property will be
rejected, but you can set it using e.g.
``Object.defineProperty(func, 'fileName', { value: 'myFilename.js' });``.
* Error instance ``.fileName`` and ``.lineNumber`` property attributes are
also non-writable, non-enumerable, but configurable. This only matters when
tracebacks are disabled and concrete properties are used instead of the
inherited accessors.
* Object constructor methods like Object.keys(), Object.freeze(), etc now
follow more lenient ES2015 coercion semantics: non-object arguments are either
coerced to objects or treated like non-extensible objects with no own
properties.
* RegExp.prototype follows ES2015 behavior more closely: it is no longer a RegExp
instance, .source, .global, .ignoreCase, and .multiline are now inherited
getters, etc. However, leniency to allow e.g. RegExp.prototype.source (from
ES2017 draft) is supported for real world code compatibility.
* Duktape.info() now returns an object rather than an array. The object has
named properties like ``.type`` and ``.enext`` for the internal fields which
is easier to version and work with. The names of the properties are not
under version guarantees and may change in an incompatible fashion in even a
minor release.
* Memory management without mark-and-sweep is no longer supported; relying on
only refcounting was error prone because reference cycles or debugger use
could result in leaked garbage that would only get collected on heap
destruction.
Known issues
============
* Some non-compliant behavior for array indices near 2G or 4G elements.
* RegExp parser is strict and won't accept some real world RegExps which
are technically not compliant with ECMAScript E5/E5.1 specification
but allowed in ES2015 Annex B.
* Final mantissa bit rounding issues in the internal number-to-string
conversion.
Raw issues from test runs
=========================
API tests
---------
::
test-to-number.c: fail; 15 diff lines; known issue: number parsing bug for strings containing NUL characters (e.g. '\u0000')
ECMAScript tests
----------------
::
test-bi-array-proto-push: fail; 30 diff lines; known issue: array length above 2^32-1 not supported
test-bi-array-push-maxlen: fail; 17 diff lines; known issue: array length above 2^32-1 not supported
test-bi-date-tzoffset-brute-fi: fail; 12 diff lines; known issue: year 1970 deviates from expected, Duktape uses equiv. year for 1970 on purpose at the moment; requires special feature options: test case has been written for Finnish locale
test-bi-function-nonstd-caller-prop: fail; 175 diff lines; requires special feature options: DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
test-bi-global-parseint: fail; 89 diff lines; known issue: rounding differences for parsing integers larger than 2^53
test-bi-json-enc-proplist-dups: fail; 8 diff lines; known issue: JSON.stringify() can be given a property list to serialize; duplicates should be eliminated but Duktape (and other engines) will happily serialize a property multiple times
test-bi-json-enc-proxy: fail; 13 diff lines; known issue: JSON enumeration behavior for Proxy targets is incomplete and uses 'enumerate' trap instead of 'ownKeys' trap
test-bi-number-proto-toexponential: fail; 75 diff lines; known issue: corner case rounding errors in toExponential()
test-bi-number-proto-tostring: fail; 46 diff lines; known issue: expect strings to be checked, but probably Duktape rounding issues
test-bi-proxy-object-tostring: fail; 6 diff lines; known issue: Object class handling for Proxy objects is incomplete
test-bi-regexp-gh39: fail; 7 diff lines; known issue: requires leniency for non-standard regexps
test-bi-symbol-coercion: fail; 9 diff lines; known issue: no @@toPrimitive coercion yet
test-bi-typedarray-misc-inherited-accessors: fail; 21 diff lines; known issue: typed array .length etc not yet inherited accessors (ES2015 requirement)
test-bug-date-timeval-edges: fail; 17 diff lines; known issue: test case depends on current timezone offset
test-bug-enum-shadow-nonenumerable: fail; 12 diff lines; known issue: corner case enumeration semantics, not sure what correct behavior is (test262 ch12/12.6/12.6.4/12.6.4-2)
test-bug-json-parse-__proto__: fail; 18 diff lines; known issue: when ES2015 __proto__ enabled, JSON.parse() parses '__proto__' property incorrectly when a specially crafted reviver is used
test-bug-numconv-1e23: fail; 10 diff lines; known issue: corner case in floating point parse rounding
test-bug-numconv-denorm-toprec: fail; 7 diff lines; known issue: in a denormal corner case toPrecision() can output a zero leading digit
test-bug-tonumber-u0000: fail; 7 diff lines; known issue: '\u0000' should ToNumber() coerce to NaN, but now coerces to zero like an empty string
test-dev-16bit-overflows: fail; 11 diff lines; requires special feature options: requires 16-bit field options
test-dev-func-cons-args: fail; 18 diff lines; known issue: corner cases for 'new Function()' when arguments and code are given as strings
test-dev-func-varmap-drop: fail; 46 diff lines; requires special feature options: debugger support must be disabled
test-dev-lightfunc-accessor: fail; 50 diff lines; requires special feature options: DUK_USE_LIGHTFUNC_BUILTINS
test-dev-lightfunc-finalizer: fail; 8 diff lines; requires special feature options: DUK_USE_LIGHTFUNC_BUILTINS
test-dev-lightfunc: fail; 518 diff lines; requires special feature options: DUK_USE_LIGHTFUNC_BUILTINS
test-dev-object-literal-method-computed: fail; 8 diff lines; known issue: computed name for object literal method shorthand not yet implemented
test-dev-yield-after-callapply: fail; 8 diff lines; known issue: yield() not allowed when function called via Function.prototype.(call|apply)()
test-lex-unterminated-hex-uni-escape: fail; 29 diff lines; known issue: unterminated hex escapes should be parsed leniently, e.g. '\uX' -> 'uX' but Duktape now refuses to parse them
test-numconv-parse-misc: fail; 12 diff lines; known issue: rounding corner case for 1e+23 (parses/prints as 1.0000000000000001e+23)
test-numconv-tostring-gen: fail; 257 diff lines; known issue: rounding corner cases in number-to-string coercion
test-numconv-tostring-misc: fail; 6 diff lines; known issue: rounding corner case, 1e+23 string coerces to 1.0000000000000001e+23
test-regexp-empty-quantified: fail; 16 diff lines; known issue: a suitable empty quantified (e.g. '(x*)*') causes regexp parsing to terminate due to step limit
test-regexp-invalid-charclass: fail; 7 diff lines; known issue: some invalid character classes are accepted (e.g. '[\d-z]' and '[z-x]')
test-stmt-for-in-lhs: fail; 29 diff lines; known issue: for-in allows some invalid left-hand-side expressions which cause a runtime ReferenceError instead of a compile-time SyntaxError (e.g. 'for (a+b in [0,1]) {...}')
test262
-------
::
ch12/12.6/12.6.4/12.6.4-2 in non-strict mode // diagnosed: enumeration corner case issue, see test-bug-enum-shadow-nonenumerable.js
ch15/15.10/15.10.2/15.10.2.5/S15.10.2.5_A1_T5 in non-strict mode // diagnosed: Duktape bug, matching /(a*)b\1+/ against 'baaaac' causes first capture to match the empty string; the '\1+' part will then use the '+' quantifier over the empty string. As there is no handling to empty quantified now, Duktape bails out with a RangeError.
ch15/15.10/15.10.2/15.10.2.9/S15.10.2.9_A1_T5 in non-strict mode // diagnosed: Duktape bug, matching /(a*)b\1+/ against 'baaac' causes first capture to be empty, the '\1+' part will then quantify over an empty string leading to Duktape RangeError (there is no proper handling for an empty quantified now)
ch15/15.4/15.4.4/15.4.4.10/S15.4.4.10_A3_T3 in non-strict mode // diagnosed: probably Duktape bug related to long array corner cases or 'length' sign handling (C typing?)
ch15/15.4/15.4.4/15.4.4.12/S15.4.4.12_A3_T3 in non-strict mode // diagnosed: probably Duktape bug related to long array corner cases or 'length' sign handling (C typing?)
ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-5-12 in non-strict mode // diagnosed: Array length over 2G, not supported right now
ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-5-16 in non-strict mode // diagnosed: Array length over 2G, not supported right now
ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-9-9 in non-strict mode // diagnosed: a.indexOf(<n>,4294967290) returns -1 for all indices n=2,3,4,5 but is supposed to return 4294967294 for n=2. The cause is long array corner case handling, possibly signed length handling (C typing?)
ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-5-12 in non-strict mode // diagnosed: probably Duktape bug: long array corner cases (C typing?)
ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-5-16 in non-strict mode // diagnosed: probably Duktape bug: long array corner cases (C typing?)
ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-8-9 in non-strict mode // diagnosed: probably Duktape bug: long array corner cases (C typing?)
ch15/15.4/15.4.4/15.4.4.6/S15.4.4.6_A4_T1 in non-strict mode // diagnosed: Array .pop() fast path (can be disabled) ignores inherited array index properties