|
|
|
=========================
|
|
|
|
Duktape 2.0 release notes
|
|
|
|
=========================
|
|
|
|
|
|
|
|
Release overview
|
|
|
|
================
|
|
|
|
|
|
|
|
Main changes in this release (see RELEASES.rst for full details):
|
|
|
|
|
|
|
|
* Improve buffer bindings: plain buffers now behave like ArrayBuffers,
|
|
|
|
and Duktape.Buffer has been removed with ArrayBuffer taking its place.
|
|
|
|
|
|
|
|
* FIXME
|
|
|
|
|
|
|
|
The release has API incompatible changes, see upgrading notes below.
|
|
|
|
|
|
|
|
Upgrading from Duktape 1.5.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.5.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.x 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 = ArrayBuffer.plainOf(bufferObject);
|
|
|
|
} else {
|
|
|
|
plainBuffer = Duktape.Buffer(bufferObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
Or you can detect features specifically::
|
|
|
|
|
|
|
|
var plainBuffer = (typeof ArrayBuffer.plainOf === 'function' ?
|
|
|
|
ArrayBuffer.plainOf : Duktape.Buffer)(bufferObject);
|
|
|
|
|
|
|
|
DUK_OPT_xxx feature option support removed
|
|
|
|
------------------------------------------
|
|
|
|
|
|
|
|
Duktape 2.x 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 remove your custom header and add the equivalent options
|
|
|
|
to ``tools/configure.py`` when possible.
|
|
|
|
|
|
|
|
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 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``, check the path; correct path is now
|
|
|
|
``tools/genconfig.py``. Consider replacing genconfig.py with configure.py.
|
|
|
|
|
|
|
|
* If you're using ROM built-ins via ``make_dist.py``, change your build to
|
|
|
|
use ``tools/configure.py`` instead, and rename ``--user-builtins-metadata``
|
|
|
|
options to ``--builtin-file``.
|
|
|
|
|
|
|
|
Dist package file changes
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
* Configuration metadata is now in unpacked form in ``dist/config`` to match
|
|
|
|
the Duktape master repo and 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.x release; see detailed
|
|
|
|
changes below. Here's a summary of changes:
|
|
|
|
|
|
|
|
* Plain buffers now behave like ArrayBuffer instances (to the extent possible)
|
|
|
|
for Ecmascript code, and ``Duktape.Buffer`` has been removed, with
|
|
|
|
``ArrayBuffer`` taking its place. There are numerous small changes to how
|
|
|
|
plain buffers are treated by standard built-ins as a result.
|
|
|
|
|
|
|
|
* Plain buffer and ArrayBuffer have numeric indices (e.g. ``arrayBuf[6]``) as
|
|
|
|
before, but the properties are not enumerable so that they won't be e.g.
|
|
|
|
JSON serialized.
|
|
|
|
|
|
|
|
* Plain buffer string coercion (``String(plainBuffer)``) now mimics ArrayBuffer
|
|
|
|
and usually results in the string ``[object ArrayBuffer]``.
|
|
|
|
|
|
|
|
* Default built-in bindings 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 (see https://github.com/svaarala/duktape/issues/1005).
|
|
|
|
C code can still do so using ``duk_buffer_to_string()`` (or by direct buffer
|
|
|
|
and string operations) 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
|
|
|
|
will still inherit from ``ArrayBuffer.prototype``, but all ArrayBuffer, typed
|
|
|
|
array, and Node.js Buffer methods will be non-functional. Plain buffers
|
|
|
|
won't object coerce. 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:
|
|
|
|
|
|
|
|
- Typed array ``.subarray()`` handling of arguments inheriting from a typed
|
|
|
|
array (rather than being a direct instance) has been fixed so that the result
|
|
|
|
has the default prototype for the result type (e.g. ``Uint8Array.prototype``)
|
|
|
|
rather than being copied from the argument.
|
|
|
|
|
|
|
|
* If you're using the Node.js Buffer binding, review the following:
|
|
|
|
|
|
|
|
- Node.js Buffer ``.slice()`` handling of arguments inheriting from a Buffer
|
|
|
|
(rather than being a direct instance) has been fixed so that the result has
|
|
|
|
the default prototype (``Buffer.prototype``) rather than being copied from
|
|
|
|
the argument.
|
|
|
|
|
|
|
|
- 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.hs 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.
|
|
|
|
|
|
|
|
- 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 ArrayBuffer 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):
|
|
|
|
|
|
|
|
- ``ArrayBuffer.allocPlain()``: to allocate a new (fixed) plain buffer
|
|
|
|
|
|
|
|
- ``ArrayBuffer.plainOf()``: to get the underlying plain buffer of any
|
|
|
|
buffer object (without making a copy)
|
|
|
|
|
|
|
|
Some detailed changes (see ``tests/ecmascript/test-dev-plain-buffer.js)`` for
|
|
|
|
even more detail):
|
|
|
|
|
|
|
|
* ``typeof plainBuffer`` is now ``object`` instead of ``buffer``.
|
|
|
|
|
|
|
|
- ``plainBuffer instanceof ArrayBuffer`` is true.
|
|
|
|
|
|
|
|
* Plain buffer Object.prototype.toString() now usually (assuming no overridden
|
|
|
|
.toString()) yields ``[object ArrayBuffer]`` instead of ``[object Buffer]``.
|
|
|
|
|
|
|
|
* Plain buffer inherits from ArrayBuffer.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 ArrayBuffer]`` 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 ArrayBuffer]']``.
|
|
|
|
``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 plain buffer: always true, even if buffer is zero
|
|
|
|
length.
|
|
|
|
|
|
|
|
* ``duk_to_primitive()`` for plain buffer: plain buffer now not considered a
|
|
|
|
primitive value (same as for a full ArrayBuffer object) and usually coerces
|
|
|
|
to the string ``[object ArrayBuffer]``.
|
|
|
|
|
|
|
|
* ``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 ArrayBuffer 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 an ArrayBuffer
|
|
|
|
argument is handled in ``new ArrayBuffer()``.
|
|
|
|
|
|
|
|
- ``new Buffer(plainBuffer)`` no longer special cases plain buffer and gets
|
|
|
|
treated like an ArrayBuffer: a fresh Buffer with matching ``.length`` is
|
|
|
|
created and index elements are copied into the result buffer (in effect
|
|
|
|
making an actual buffer copy).
|
|
|
|
|
|
|
|
* XXX: This will most likely change with Node.js Buffer binding version
|
|
|
|
update, as Node.js Buffer constructor also recognizes ArrayBuffers now.
|
|
|
|
|
|
|
|
- ``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 coerce
|
|
|
|
the argument plain buffer into an ArrayBuffer instance which is then used
|
|
|
|
as the result ``.buffer``. The coerced ArrayBuffer shares the same
|
|
|
|
underlying plain buffer (storage).
|
|
|
|
|
|
|
|
* XXX: This may still change.
|
|
|
|
|
|
|
|
* ``new DataView(plainBuffer)`` is now accepted (Duktape 1.x would reject with
|
|
|
|
TypeError) and gets treated like for typed arrays: the plain buffer is coerced
|
|
|
|
into an ArrayBuffer with the same underlying plain buffer (storage).
|
|
|
|
|
|
|
|
* ``ArrayBuffer.prototype.slice()`` accepts a plain buffer and the resulting slice
|
|
|
|
(which is a copy) is also a plain buffer.
|
|
|
|
|
|
|
|
* ``typedarray.prototype.subarray()`` accepts a plain buffer and the resulting slice
|
|
|
|
is an ArrayBuffer because plain buffers cannot represent a view offset/length.
|
|
|
|
(This could arguably also be a Uint8Array because ES6 doesn't recognize
|
|
|
|
ArrayBuffers which have a view offset. However, as custom behavior, .subarray()
|
|
|
|
also returns an ArrayBuffer when called with an ArrayBuffer instance, so the
|
|
|
|
current plain buffer behavior is consistent with that.)
|
|
|
|
|
|
|
|
* 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 ArrayBuffer.
|
|
|
|
This matches normal ``Object.prototype.valueOf()`` behavior, e.g. plain string is
|
|
|
|
coerced into a String object.
|
|
|
|
|
|
|
|
- ``JSON.stringify()`` now recognizes plain buffers like ArrayBuffer instances;
|
|
|
|
the result is typically ``{}`` without a ``.toJSON()`` implementation.
|
|
|
|
|
|
|
|
* XXX: JX/JC treatment may still change.
|
|
|
|
|
|
|
|
* ``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.
|
|
|
|
|
|
|
|
* XXX: this (and other buffer mixing) may still change.
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
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()``). ES6 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/ES6 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 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.
|
|
|
|
|
|
|
|
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).
|
|
|
|
|
|
|
|
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``
|
|
|
|
|
|
|
|
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 cause an intentional
|
|
|
|
segfault; 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 ES6/ES7 ``[[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 ES6/ES7, 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.
|
|
|
|
|
|
|
|
Other incompatible changes
|
|
|
|
--------------------------
|
|
|
|
|
|
|
|
* 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_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.
|
|
|
|
|
|
|
|
* Legacy octal literal handling has been improved to match more closely with
|
|
|
|
ES6 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 ES6 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).
|
|
|
|
|
|
|
|
Known issues
|
|
|
|
============
|
|
|
|
|
|
|
|
FIXME.
|
|
|
|
|
|
|
|
Raw issues from test runs
|
|
|
|
=========================
|
|
|
|
|
|
|
|
API tests
|
|
|
|
---------
|
|
|
|
|
|
|
|
FIXME.
|
|
|
|
|
|
|
|
Ecmascript tests
|
|
|
|
----------------
|
|
|
|
|
|
|
|
FIXME.
|
|
|
|
|
|
|
|
test262
|
|
|
|
-------
|
|
|
|
|
|
|
|
FIXME.
|