* Strings with 0xFF byte prefix are considered special symbols: they have
typeof "symbol" but still mostly behave as strings (e.g. allow ToString)
so that existing code dealing with internal keys, especially inside
Duktape, can work with fewer changes.
* Strings with 0x80 byte prefix are global symbols, e.g. Symbol.for('foo')
creates the byte representatio: 0x80 "foo"
* Strings with 0x81 byte prefix are unique symbols; the 0x81 byte is followed
by the Symbol description, and an internal string component ensuring
uniqueness is separated by a 0xFF byte (which can never appear anywhere in
an extended UTF-8 string). The unique suffix is up to Duktape internals,
currently two 32-bit counters are used. For example:
0x81 "mySymbol" 0xFF "0-17".
* Well-known symbols use the 0x81 prefix but lack a unique suffix, so their
format is 0x81 <description> 0xFF.
* ES6 distinguishes between an undefined symbol description and an empty
string symbol description. This distinction is not currently visible via
Ecmascript bindings but may be visible in the future. Append an extra
0xFF to the unique suffix when the description is undefined, i.e.
0x81 0xFF <unique suffix> 0xFF.
* Remove 'enumerate' trap.
* Use 'ownKeys' trap for "for-in" too, as specified in ES7.
* Add enumerability check for 'ownKeys' result when used in for-in or
Object.keys(). Because there's no support for 'getOwnPropertyDescriptor'
trap yet, the check will always operate directly on the target object.
Add minimal fast paths for Array.prototype operations like push() and pop(),
triggered when the 'this' binding is an Array which has its array part still
present. This is the most common case and user code will expect for example
Array.prototype.push() to be relatively fast.
The main purpose of this commit is to figure out the necessary internal
helpers for fast paths. More fast paths will be added separately.
These don't play well with the API currently: the Duktape specific error
codes don't have Ecmascript Error class counterparts so they don't get
represented usefully as Ecmascript objects (e.g. AllocError is a plain
Error from Ecmascript point of view).
There's no real need for Duktape specific error code. Some of the codes
had become unused; a couple were used but Ecmascript standard types can
be used instead.
Also minor error message tweaking.
Instead of having a separate panic concept which previously differed from
fatal error handling in that there was no context attached to the error,
use fatal errors also for call sites which previously used the panic handler.
Because these call sites are context-free (DUK_ASSERT() failures) simply call
the Duktape-wide default fatal error handler instead of the user fatal error
handler. For heap creation errors (self test failures) the udata is available;
for assertion it isn't and NULL is used instead.
Add a config option to replace the Duktape-wide fatal error handler; the
default one just segfaults on purpose, to avoid creating postability issues
by depending on e.g. abort().
Remove the error code from the fatal error function signature (it's mostly
pointless) and change the "ctx" argument to "udata" (heap userdata) which is
less confusing than an arbitrary context related to the heap (especially
because it's unsafe to actually use the "ctx" to e.g. call into the Duktape
API).
The fatal error signature change also affects the duk_fatal() API call, which
loses the error code argument.
* Use shared error macros and shared error handler to reduce the size of call
sites of common errors.
* Make zero argument DUK_ERROR() calls non-vararg calls to reduce call site
footprint. Non-vararg calls have smaller call sites and because there are
a lot of call sites, this turns out to be significant.
* Remove variadic macros from internal DUK_ERROR() macro set and add separate
macros for argument counts 0 to 4; this is more portable and requires less
conditional code, and works well when a non-vararg call is used for most
error call sites.
* Rework macro / function argument order for the error path, try to keep 'thr'
in the same argument slot to avoid unnecessary register moves.
* Pack linenumber and error code into a single 32-bit argument when possible,
removes one more constant load from the call site.
* Convert some internal errors to RangeErrors when the underlying cause is an
implementation limit (such as a compiler temp limit) rather than an actual
unexpected internal situation.
* Simplify and share a few error messages to reduce string count.
Add API calls:
- duk_error_va()
- duk_push_error_object_va()
- duk_log_va()
Also fix return value issue for duk_push_error_object() when variadic macros
are not available (i.e. legacy environments). The comma expression used by
the macro wasn't parenthesized which doesn't work correctly when the return
value is assigned to a variable.
When doing a single file build, drop DUK_INTERNAL_DECL declarations which
would otherwise be mapped to "static". This avoids the problem with C++
where a static data symbol is both forward declared and defined.
With this change static definitions must appear before their first use in
the single file build. This requires a change in combine_src.py which is
done in a separate commit.