1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-22 18:55:07 +00:00
Commit graph

3776 commits

Author SHA1 Message Date
Idan Horowitz
6787e86a3a LibJS: Add and use the CreateNonEnumerableDataPropertyOrThrow AO 2021-07-06 14:20:30 +01:00
Idan Horowitz
6da7f43580 LibJS: Bring String.prototype.split closer to the specification
Specifically, add a couple of missing exception checks and use the
CreateDataPropertyOrThrow abstract operation.
2021-07-06 14:20:30 +01:00
Idan Horowitz
28172fde10 LibJS: Add missing exception check to the ArraySpeciesCreate AO 2021-07-06 14:20:30 +01:00
Luke
d89f539d16 LibJS: Add %TypedArray%.prototype.reverse
This fixes 13 test262 cases.
2021-07-06 13:40:27 +01:00
Luke
99cb54670f LibJS: Add missing exception check in internalize_json_property
The call to enumerable_own_property_names in the non-array case was
missing an exception check.

Fixes 1 test262 case (JSON/parse/reviver-object-own-keys-err.js)
2021-07-06 01:33:52 +01:00
Timothy Flynn
e0c9f58b0c LibJS: Implement and use the GetSubstitution abstract operation
Used by String.prototype.replace, String.prototype.replaceAll, and
RegExp.prototype [ @@replace ].
2021-07-05 23:26:41 +01:00
Timothy Flynn
4985d3ef42 LibJS: Fix linked specification of String.prototype.concat 2021-07-05 23:26:41 +01:00
Linus Groh
339ccba354 LibJS: Make Object.prototype.toString() fully spec compliant
- Fix evaluation order: IsArray(O) should always be called and before
  Get(O, @@toStringTag), previously it was the other way around and
  IsArray would only be called if @@toStringTag is not a string
- Add missing exception checks to both function calls
- Add missing builtin tag for arguments object

Also, while we're here:
- Update variable names to match spec
- Add spec step comments
2021-07-05 20:21:26 +01:00
Linus Groh
598842c5b7 LibJS: Fix bogus target.[[OwnPropertyKeys]]() call in Proxy 2021-07-05 18:19:45 +01:00
Linus Groh
34c28b981a LibJS: Add a missing exception check in Object.assign() 2021-07-05 18:19:45 +01:00
Linus Groh
2e94fa25d0 LibJS: Add spec step comments to Object.assign() 2021-07-05 18:19:45 +01:00
Linus Groh
4f2af65836 LibJS: Add spec step comments to Object.hasOwn() 2021-07-05 18:19:45 +01:00
Idan Horowitz
8195c31965 LibJS: Remove the non-standard get_own_property_descriptor helper 2021-07-05 18:19:39 +01:00
Idan Horowitz
557424a141 LibJS: Remove usage of define_native_property in OrdinaryFunctionObject
The length & name properties are supposed to be normal data properties.
2021-07-05 17:26:31 +01:00
davidot
f998cc156f LibJS: Remove PropertyName::to_value since it is not used anymore :^) 2021-07-05 16:04:52 +01:00
davidot
ce59e49e27 LibJS: Use a custom property_name_to_value method instead of to_value 2021-07-05 16:04:52 +01:00
davidot
721238f41c LibJS: Use the direct formatter of PropertyName instead of via to_value 2021-07-05 16:04:52 +01:00
davidot
c52d515028 LibJS: Make AbstractOperations::canonical_num... take a PropertyName
This allows us to hide the fact that it could be a number and means we
no longer need to check for this optimization in string and typedarray
2021-07-05 16:04:52 +01:00
Linus Groh
073071c634 LibJS: Fix Promise constructor reject function argument
If calling the executor function throws an exception, the return value
of `vm.call()` will be an empty value, which we then passed as an
argument to the reject function, which is incorrect - what it actually
needs is the exception value. This stems from a misunderstanding of the
spec I had at the time of implementing this - in their case, the
exception value is part of the completion record returned by Call().

This error was previously masked as we would use a fallback
(`value_or(js_undefined())` for the empty value argument, but that was
removed in 57f7e6e.

Fixes #8447.
2021-07-05 14:14:54 +01:00
Linus Groh
fe9dc47320 LibJS: Make FunctionObject's m_home_object an Object*, not Value
As the name implies (and the spec confirms), this is only ever going to
be an object or "nothing", or "undefined" in the spec. By taking this
literally and updating a check to check for `is_undefined()`, we
introduced a bug - the value was still initialized as an empty value.
Instead, use a pointer to an Object - either we have one, or we don't.

Fixes #8448.
2021-07-05 13:53:30 +01:00
Idan Horowitz
d713a84851 LibJS: Stop masking non-RangeError exceptions in TypedArray creation
Non-RangeError exceptions can be thrown by user implementations of
valueOf (which are called by to_index), and the specification
disallows changing the type of the thrown error.
2021-07-05 12:16:24 +01:00
Idan Horowitz
3b81a7420e LibJS: Use the GetMethod AO for creating a TypedArray from an iterable 2021-07-05 12:16:24 +01:00
Idan Horowitz
086b6f11c4 LibJS: Enforce a 2GB "Excessive Length" limit for TypedArrays 2021-07-05 12:16:24 +01:00
Idan Horowitz
56335dab6c LibJS: Use the GetPrototypeFromConstructor AO for TypedArrays creation 2021-07-05 12:16:24 +01:00
Andreas Kling
7fdeb0ec74 LibJS: Fix logic typo in ArgumentsObject.[[Set]]
Thanks to Linus for spotting this! :^)
2021-07-05 02:53:57 +02:00
Andreas Kling
a0acb6f058 LibJS: Fix accidental west-const in ArgumentsObject 2021-07-05 02:49:55 +02:00
Andreas Kling
77fa33e61a LibJS: Finish implementing mapped arguments exotic objects :^)
Now that the Object rewrite is in place, we have enough tools to
implement the mapped `arguments` propreties according to spec.

The basic mechanism is that the `arguments` object installs a hidden
parameter mapping object that property accesses get filtered through.
This is how accessing numeric properties on `arguments` are proxied
to the named identifier in the function scope.

When `arguments` is instantiated, getters and setters are created
for all the numeric properties on the object that correspond to
function arguments. These getters and setters can be deleted from the
object. This is all pretty intricate, so refer to the spec for details.

Note that the `arguments` object itself is still lazily instantiated
on first access within a function. This is non-conforming, and we'll
have to revisit this once we get around to improving function calls.
2021-07-05 02:38:31 +02:00
Timothy Flynn
9f0aef6051 LibJS: Implement most of String.prototype.replaceAll
This also renames ErrorType::StringMatchAllNonGlobalRegExp to
ErrorType::StringNonGlobalRegExp (removes "MatchAll") because this error
is now used in the same way from multiple operations.
2021-07-05 01:10:43 +01:00
Linus Groh
cb20baebae LibJS: Make ObjectPrototype an immutable prototype exotic object
To make this happen, this patch implements the SetImmutablePrototype
abstract operation (as a method on Object) and then overrides
[[SetPrototypeOf]] on ObjectPrototype.
2021-07-05 00:53:57 +01:00
Idan Horowitz
fac8f9a94d LibJS: Add the TypedArray.from() method 2021-07-05 00:27:03 +01:00
Linus Groh
9fe363eaad LibJS: Remove now unused IndexedPropertyIterator::value_and_attributes() 2021-07-05 00:03:25 +02:00
Linus Groh
9555ca99a0 LibJS: Remove unnecessary value_or() from get()
Object::get() never returns an empty value anymore, as per the spec, so
having a value_or() fallback is no longer needed.
2021-07-05 00:03:25 +02:00
Linus Groh
57f7e6e775 LibJS: Remove two unnecessary 'vm.argument(0).value_or(js_undefined())'
VM::argument() never returns an empty value.
2021-07-05 00:03:25 +02:00
Linus Groh
09bd5f8772 LibJS: Rewrite most of Object for spec compliance :^)
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.

This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.

What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.

Key changes include:

- 1:1 matching function names and parameters of all object-related
  functions, to avoid ambiguity. Previously we had things like put(),
  which the spec doesn't have - as a result it wasn't always clear which
  need to be used.
- Better separation between object abstract operations and internal
  methods - the former are always the same, the latter can be overridden
  (and are therefore virtual). The internal methods (i.e. [[Foo]] in the
  spec) are now prefixed with 'internal_' for clarity - again, it was
  previously not always clear which AO a certain method represents,
  get() could've been both Get and [[Get]] (I don't know which one it
  was closer to right now).
  Note that some of the old names have been kept until all code relying
  on them is updated, but they are now simple wrappers around the
  closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
  storage are now prefixed with 'storage_' to make their purpose clear,
  and as they are not part of the spec they should not contain any steps
  specified by it. Much functionality is now covered by the layers above
  it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
  by PropertyDescriptor - a concept similar to the current
  implementation, but more aligned with the actual spec. See the commit
  message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
  introduced more inline comments with the exact steps from the spec -
  this makes it super easy to verify correctness.
- East-const all the things.

As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.

Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)

Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
2021-07-04 22:07:36 +01:00
Linus Groh
777a93918f LibJS: Handle invalid and symbol PropertyName in its AK::Formatter
This would previously crash as we used to_string() without checking the
type first. Circumvent that by handling invalid and numeric ones
separately and then using to_string_or_symbol().
2021-07-04 22:07:36 +01:00
Linus Groh
c81001f920 LibJS: Add Value::operator==()
This is needed for MarkedValueList::contains_slow() to work.
2021-07-04 22:07:36 +01:00
Linus Groh
bb1a98d809 LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:

- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor

It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.

Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.

Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.

Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-04 22:07:36 +01:00
Linus Groh
a3c8ebd709 LibJS: VERIFY() that property name is valid in Value::get{,_method}() 2021-07-04 22:07:36 +01:00
Idan Horowitz
301c1a3a58 Everywhere: Fix incorrect usages of AK::Checked
Specifically, explicitly specify the checked type, use the resulting
value instead of doing the same calculation twice, and break down
calculations to discrete operations to ensure no intermediary overflows
are missed.
2021-07-04 20:08:28 +01:00
Idan Horowitz
e480d69130 LibJS: Bring ArrayCreate and ArrayConstructor closer to spec
Specifically, this now explicitly takes the length, adds missing
exceptions checks to calls with user-supplied lengths, takes and uses
the prototype argument, and fixes some spec non-conformance in
ArrayConstructor and its native functions around the use of ArrayCreate
2021-07-04 00:51:43 +01:00
Idan Horowitz
5ee1ae37b2 LibJS: Add the IteratorStep abstract iterator operation
As well as add 2 missing exception checks in the IteratorComplete and
IteratorValue abstract iterator operations.
2021-07-04 00:51:43 +01:00
Andreas Kling
e8430cf0d3 LibJS: Don't allow delete super.property
This should throw a ReferenceError, since `delete` is not allowed
on super references.
2021-07-03 01:30:30 +02:00
Andreas Kling
1270df257b LibJS: Bring the super keyword in line with the spec
This patch implements spec-compliant runtime semantics for the following
constructs:

- super.property
- super[property]

The MakeSuperPropertyReference AO is added to support this. :^)
2021-07-03 01:12:12 +02:00
Andreas Kling
fd43d1e205 LibJS: Improve ResolveBinding + add GetIdentifierReference
ResolveBinding now matches the spec, while the non-conforming parts
are moved to GetIdentifierReference.

Implementing this properly requires variable bindings.
2021-07-02 22:22:21 +02:00
Andreas Kling
5ce9305c5f LibJS: Implement the PrepareForOrdinaryCall abstract operation
This is used by VM::call_internal() and VM::construct() which roughly
map to function objects' [[Call]] and [[Construct]] slots in the spec.

Reorganizing this code revealed something weird: NativeFunction gets
its strictness by checking VM::in_strict_mode(). In other words,
it inherits the strict flag from the caller context. This is quite
weird, but many test-js tests rely on it, so let's preserve it until
we can think of something nicer.
2021-07-02 21:44:08 +02:00
Idan Horowitz
f8f3ff65fe LibJS: Bring %TypedArray%.prototype.set slightly closer to spec
Specifically, instead of using the internal {get, put}_by_index methods
we now use the GetValueFromBuffer and SetValueInBuffer abstract
operations, as required by the specification.

While i was here i also replaced a couple custom detached array buffer
error messages with the existing ErrorType::DetachedArrayBuffer.
2021-07-02 15:53:51 +01:00
Ali Mohammad Pur
62ca81fdcc LibJS: Implement the %TypedArray%.set() function 2021-07-02 04:53:01 +04:30
Andreas Kling
a4897ed7b2 LibJS: Throw on failed PutValue into an environment reference
This should really be handled at a different layer of the stack, but
this allows us to make progress on the Object rewrite without breaking
strict mode assignment tests.
2021-07-02 00:32:23 +02:00
Andreas Kling
80170887db LibJS: Make Environment::put_into_environment() return a success bool
This code is non-conforming and will eventually get cleaned out once
we implement proper variable bindings. However, this will aid us in
improving other parts of the code right now.
2021-07-02 00:26:31 +02:00
Andreas Kling
57db058652 LibJS: Make ResolveBinding() produce strict References in strict mode 2021-07-02 00:25:52 +02:00