Just like to_size_t() - which was already removed in f369229 - this is
non-standard, use to_length() instead. One remaining use was removed,
and I'm glad it's gone. :^)
toGMTString() is deprecated but is kept for compatibility's sake, but because
HTTP Dates are always expressed in GMT, it should be safe to call toUTCString()
in toGMTString().
As @nico pointed out, 0.0 == -0.0 in C++, even though they are not
bitwise identical. Use the same trick as Value::is_negative_zero() to
really check for it.
This allows JS::Value(0.0) to correctly become an Int32-backed 0 value.
We now store 32-bit integers as 32-bit integers directly which avoids
having to convert them from doubles when they're only used as 32-bit
integers anyway. :^)
This patch feels a bit incomplete and there's a lot of opportunities
to take advantage of this information. We'll have to find and exploit
them eventually.
This patch rethinks the way indexed property storage works:
Instead of having a cut-off point at 200 elements where we always move
to generic property storage, we now allow arrays to stay in simple mode
as long as we don't create a gap/hole larger than 200 elements.
We also simplify generic storage to only have a hash map (for now)
instead of juggling both a vector and a hash map. This is mostly fine
since the vast majority of arrays get to stay simple now.
This is a huge speedup on anything that uses basic JS arrays with more
than 200 elements in them. :^)
Otherwise we continuously lose the first sparse element (at index
SPARSE_ARRAY_THRESHOLD) without noticing, as we overwrite all indices
with the value at index+1.
Fixes#5884.
Instead of counting the number of call frames on the VM stack, we now
always fake the "arguments" object when the current call frame has
a callee value.
This fixes an issue with DOM event handlers in LibWeb not being able
to access "arguments" since they were called without an outer frame.
Checking for the existence of a call frame is not enough to check if
we're in a function call, as the global execution context is a regular
call frame as well.
Found by OSS-Fuzz, where simply accessing "arguments" in the global
scope would crash due to call_frame().callee being an empty value
(https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=32115).
https://tc39.es/ecma262/#sec-function.prototype.tostring - this is how
the spec wants us to do it. :^)
Also change the function name behaviour to only provide a name for
NativeFunctions, which matches other engines - presumably to not expose
Proxy objects, and to prevent "function bound foo() { [native code] }".
There are three JS::Function types that are not ScriptFunction:
NativeFunction, BoundFunction and ProxyObject. We were only checking for
the first two when determining whether to reconstruct the function's
source code, which was leading to a bad cast to ScriptFunction.
Since only ScriptFunction has the [[SourceText]] internal slot, I simply
swapped the branches here.
Fixes#5775.
- We were not passing the to_string()'d argument to the exec function
but the original argument
- We were leaking an empty value in two cases, which almost certainly
will crash something down the line
- We were not checking for exceptions after to_string() and get(), which
both may throw. If the getter is an accessor, it'll assert upon being
called with the VM already storing an exception.
This is basically just for consistency, it's quite strange to see
multiple AK container types next to each other, some with and some
without the namespace prefix - we're 'using AK::Foo;' a lot and should
leverage that. :^)
https://tc39.es/ecma262/#sec-properties-of-the-regexp-prototype-object
The RegExp prototype object:
- is an ordinary object.
- is not a RegExp instance and does not have a [[RegExpMatcher]]
internal slot or any of the other internal slots of RegExp instance
objects.
In other words: no need to have RegExpPrototype inherit from
RegExpObject (we weren't even calling its initialize()).