Very minimal implementations:
* getOwnPropertyDescriptor trap: works enough to support virtualization
of enumeration, but doesn't provide 'value', 'get', or 'set'.
* defineProperty: just pass-through so far, no actual trap implementation.
* Invalidate the literal cache on every mark-and-sweep round, and allow
collection of pinned literals. This approach still allows the literal
cache to be simplistic and without an invalidation mechanism in normal
operation (between mark-and-sweep rounds), but still allows eventual
collection of pinned literals if they stop occurring.
* Log level fixes.
* Automatically pin C literals interned into heap strings. Or if the
literal maps to an already interned string, pin it too. Pinning is
implemented using a duk_hstring flag and a one-off refcount bump.
Mark-and-sweep avoids sweeping pinned strings based on the flag.
* Add a lookup cache for quickly mapping a C literal address (which is
assumed stable) into a duk_hstring pointer. Once a mapping has been
formed, it never needs to be invalidated because the duk_hstring is
always pinned if the cache is used. Only heap destruction will free
the pinned duk_hstrings.
* More internal call site conversion for literals.
* Wording trivia.
The align trick used in duk_hbuffer_fixed uses a union which includes an
IEEE double for align-by-8. Also include a duk_uint64_t if available in
case double/integer align requirements differ.
* Convert memory helpers like duk_memcmp() to macros where possible: for some
reason automatic inlining with -Os doesn't do the right thing and the
footprint impact is over 1kB. The duk_memcmp() helper is an inlined
function because it returns a value and assertions would otherwise lead
to multiple evaluation of arguments.
* Differentiate between C99+ and "unsafe" call sites. For example, use
duk_memcpy() when the call site obeys C99+ restrictions, and
duk_memcpy_unsafe() when either pointer may be NULL when the size is zero.
Same for all helpers.
* Add internal wrappers also to DUK_MEMMOVE(), DUK_MEMSET(), and
DUK_MEMZERO().
* Use the wrappers everywhere for consistency: the zero-size cases will then
always be safe, and if the target is fine with invalid pointers in the zero
size case, the whole check can be omitted easily.
* Remove a few zero size checks as they're no longer necessary.
Add internal helpers to deal with undefined behavior cases explicitly.
When DUK_USE_ALLOW_UNDEFINED_BEHAVIOR is set, skip the (almost always
unnecessary) explicit checks to improve footprint and performance.
Also split duk_util_misc.c into a few better scoped files.
The cast from duk_hbuffer to duk_hbuffer_fixed seemingly increases alignment
requirement from 4 to 8 because duk_hbuffer_fixed is forced to pack to 8 bytes
(so that data following the buffer is properly aligned). However, because the
struct base pointer is always aligned by 8 when the platform requires alignment
by 8, the warning is harmless and can be avoided by casting through a void *.
When noreturn attribute is not available, avoid warnings by e.g. returning
dummy values (never actually used because of e.g. a longjmp) with the
DUK_WO_NORETURN() macro.
In duk_bi_date_windows.c, the function duk__convert_filetime_to_ularge
is a static function called only from duk_bi_date_get_now_windows_subms,
which is wrapped in a #define.
This change wraps duk__convert_filetime_to_ularge in the same #define
to prevent compiler warnings about unused functions.
Clang warns about tmp being used uninitialized, but it is always assigned to
because the for-loop preceding the assignment runs from 1 to 3 and assigns to
tmp unconditionally on the first round. Work around the warning by assigning
tmp to zero unnecessarily.
* Keep .prototype value on stack while holding the 'proto' pointer, in case the
value is virtualized and comes from a getter or a Proxy.
* Improve error message for the case where the rval has no .prototype property.
This case comes up often with Duktape/C function constructors because they
don't have a .prototype property by default.
Use a single pause flags field to implement Resume, StepInto, StepOver,
and StepOut. This opens up possibilities for more Resume options, like
explicit control over whether to pause on caught vs. uncaught error.
Change StepOver, StepInto, and StepOut behavior when current activation
has no line information. Previously the commands were silently ignored
in this tate. The updated behavior is to ignore the line-based pause
trigger but obey the others, e.g. StepInto will pause on function entry,
function exit, and an error thrown past the current function.