An array without holes and with only integer properties can be represented
with a "flat" array part that allows for O(1) property access.
If we ever add a non-integer property, create holes in the array,
the whole array is unpacked into a normal string-keyed object.
Also add fast integer indexing to be used on these arrays, before falling
back to converting the integer to a string property lookup.
Use JS_ARRAYLIMIT to restrict size of arrays to avoid integer overflows and out
of memory thrashing.
Since js_try can throw to its surrounding exception scope if it runs out
of space in the exception stack, we need to make sure to allocate
resources guarded by the try inside the try not outside it.
When a userdata object is garbage collected, we should invoke a callback
to client code to let it know that the associated userdata pointer is no
longer in use.
Revert 'add context and flag argument to js_newstate' commit.
The context argument just adds clutter. The flag which was intended
for JS_DEBUG and/or JS_STRICT shouldn't be necessary.
js_newcfunction and js_newcconstructor need an extra argument, the
name of the function to use in stack traces.
Any coercion between types may overwrite the stack slot with the coerced
value. This is usually not a problem, but if you need to preserve the
original value, you should copy it to another stack slot before running
any functions that may coerce the type (anything involving ToPrimitive).
This change lets us avoid interning the result of toString().
If we later add short strings (embedded in js_Value and js_Property
structs) then we can also avoid creating a garbage collected string or
interning the result of js_tostring on a number.
Separate literal/interned and garbage collected string types in js_Value.
js_pushintern/js_tointern are convenience functions to push/pop strings and
automatically intern them (so that the string pointers are guaranteed to be
stable).
js_pushliteral should push stable strings (either interned or actual literals).
js_pushstring will copy the string into garbage collected memory.
The pointer returned by js_tostring is guaranteed to be stable only for as long as
the stack slot it came from remains untouched.
Some uses will always cause a string to be interned:
* Using it as a property name.
* Wrapping it in a new String() object.
* Strings returned by toString().
ToPrimitive must not clobber the stack, so the result has to be unrooted.
* Numbers converted to strings (by js_tostring)
Likewise, we have nowhere to store the temporary string here.
Passing in a scratch buffer to js_tostring could help this problem.
Mostly an issue with array accesses (OP_GETPROP, etc) so an auxiliary
function and we don't have to clutter the API needlessly.
Add a separate js_loadeval for "eval code" scripts, and let
js_do/loadstring create "global code" scripts.
js_newscript called with the NULL scope is equivalent to 'eval code'.
js_newscript called with the J->GE scape is equivalent to 'global code'.
js_newfunction is created with the lexical scope, i.e. 'function code'.
clang incorrectly treats a default label as unreachable in a switch on
an enum that has all the cases covered. gcc and msvc complain about
missing return values if there is no default statement.
By making the default case fall through to the JS_TUNDEFINED case we
silence all the compilers and handle corrupt data (an enum that isn't
one of the enumerated values) safely.
Follow the spec more strictly, and don't rely on strtod's grammar.
GNU libc strtod accepts 0x prefixes, INF, INFINITY and much more which
we don't want, so pre-filter the string we pass to strtod.