* Plain buffers still inherit from ArrayBuffer.prototype.
* Plain buffers won't object coerce, so Object(plainBuffer) fails.
* All buffer object related methods throw an error; their function bodies
are essentially empty. Note that this includes bindings such as
String.fromBuffer(), ArrayBuffer.allocPlain(), ArrayBuffer.plainOf(),
and so on. In essence, you can index plain buffers in Ecmascript but
the buffer values must be created via the C API.
* Duktape custom bindings like Duktape.dec('hex', 'deadbeef') still work
and produce plain buffers.
Duktape internal InitJS is no longer needed, and user InitJS is not really a
full solution: it's not possible to run native initialization code which would
often be necessary for custom bindings.
* Remove CSPROP(I) opcode. CSPROP usually leads to three opcodes, e.g.
LDREG + LDCONST + CSPROP. Direct loads for 'base[key]' and 'base' has
the same effect with one opcode shorter bytecode and no need for a
separate CSPROP opcode.
* Remove CSREGI (indirect) opcode, simplify CSREG opcode a bit. Extend
CSREG base register argument to be wider (BC) so that shuffling is not
needed in practice.
* Remove CSVARI (indirect) opcode and handle its equivalent by using explicit
shuffling in the compiler. This removes one opcode, and indirect target
check from CSVAR.
* Remove NEWI and extend base register argument of NEW to be wider (BC) so
that shuffling is not needed in practice.
* Remove CALLI, and split CALL into CALL, TAILCALL, and EVALCALL. This
eliminates the flags field (A) and allows the base register to be wider
(BC), eliminating the need for shuffling in practice.
* Maximum argument count to constructor and ordinary calls drops from 511
to 255 with this change.
This allows a native thread to suspend its Duktape thread while for
example calling out to an external blocking API, allowing other native
threads to cooperatively run code on the same heap in the meantime.
It is left up to the application to synchronize its native threads so
only a single native thread executes code at a time, each taking care to
use distinct Duktape threads while doing so.
Related to #834.
duk_require_heapptr() call now throws a TypeError instead of a RangeError for
an invalid index. This is not ideal, but is more consistent with other API
call behavior (at the moment; it'd be better if RangeErrors were used for
index errors in general).
The call returns a non-NULL duk_tval pointer to a static DUK_TAG_UNUSED so
that a call site can avoid an unnecessary NULL check. This is useful for
e.g. calls like duk_get_boolean().
Previous implementation avoided side effects during string table resize.
This is sufficient in most cases but not in the following:
- Caller pushes a string using duk_push_lstring(), with the data and
length referencing the data area of a dynamic or external buffer.
- When allocating a new duk_hstring a side effect triggers a finalizer.
- The finalizer resizes or reconfigures the dynamic/external buffer so
that the original duk_push_lstring() arguments are invalidated.
- When it's time to copy the data over into the duk_hstring, the pointer
and/or length are invalid and memory unsafe behavior follows.
Avoid this problem by preventing mark-and-sweep side effects for the duration
of the entire string intern processing.