Commit graph

189 commits

Author SHA1 Message Date
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Idan Horowitz
9cfbbfd8d8 LibJS: Implement the EnumerateObjectProperties AO 2022-03-29 14:34:08 +03:00
Lenny Maiorani
d00b79568f Libraries: Use default constructors/destructors in LibJS
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules

"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
2022-03-16 16:19:40 +00:00
Linus Groh
47cdd90836 LibJS: Use new NativeFunction::create() in most places
Resolves one FIXME where we can now pass a realm, and sets the length
correctly in a bunch of places that previously didn't.
Also reduces the number of "format function name string from arbitrary
PropertyKey" implementations, although two more remain present in the
AST (used with ECMAScriptFunctionObjects, which is a different beast).
2022-02-20 23:21:40 +00:00
Linus Groh
368af9ad6e LibJS: Add Object constructor allowing null prototype 2022-02-09 23:31:34 +00:00
Linus Groh
bc183dbbcb LibJS: Replace uses of MarkedValueList with MarkedVector<Value>
This is effectively a drop-in replacement.
2022-02-09 12:25:27 +00:00
davidot
9264f9d24e LibJS+Everywhere: Remove VM::exception() and most related functions
This commit removes all exception related code:
Remove VM::exception(), VM::throw_exception() etc. Any leftover
throw_exception calls are moved to throw_completion.
The one method left is clear_exception() which is now a no-op. Most of
these calls are just to clear whatever exception might have been thrown
when handling a Completion. So to have a cleaner commit this will be
removed in a next commit.

It also removes the actual Exception and TemporaryClearException classes
since these are no longer used.

In any spot where the exception was actually used an attempt was made to
preserve that behavior. However since it is no longer tracked by the VM
we cannot access exceptions which were thrown in previous calls.
There are two such cases which might have different behavior:
- In Web::DOM::Document::interpreter() the on_call_stack_emptied hook
  used to print any uncaught exception but this is now no longer
  possible as the VM does not store uncaught exceptions.
- In js the code used to be interruptable by throwing an exception on
  the VM. This is no longer possible but was already somewhat fragile
  before as you could happen to throw an exception just before a VERIFY.
2022-02-08 09:12:42 +00:00
Linus Groh
6f20f49b21 Everywhere: Rename JS::PropertyKey variables from property_{name => key}
PropertyKey used to be called PropertyName, but got renamed. Let's
update all the variables of this type as well.
2022-02-06 22:02:45 +00:00
mjz19910
1ef633472b Everywhere: Convert VM::call() to JS::call() 2022-01-23 15:24:45 +00:00
Linus Groh
29e96eceeb LibJS: Convert PropertyKey::from_value() to ThrowCompletionOr
Lots of MUST() - perhaps we'll eventually come up with a better API for
the common case where it can't fail.
2022-01-04 23:37:26 +00:00
Timothy Flynn
d69f5ca128 LibJS: Update spec numbers for Operations on Objects AOs
The error cause proposal was merged, so some spec numbers were bumped.
2021-12-21 14:56:28 +01:00
Andreas Kling
212319b25e LibJS: Only allocate space for Object private elements if needed
Most JavaScript objects don't have private elements, so this reduces the
size of typical JS::Object instances by two pointers.
2021-12-08 10:29:54 +01:00
Linus Groh
a20b189eab LibJS: Fix incorrectly formatted section comments
A couple of missing URLs, spaces, and a stray comma.
2021-11-24 17:37:27 +00:00
Idan Horowitz
ba55d77665 LibJS: Remove leftover exception check in OrdinaryHasProperty 2021-11-09 20:32:51 +02:00
Idan Horowitz
2eaed880b1 LibJS: Remove old Native Functions
Now that all the usages were updated to the new ThrowCompletionOr based
version we can remove the legacy version.
2021-10-31 18:20:37 +02:00
Andreas Kling
7ccb8c8609 LibJS: Provide default hash traits for JS::PropertyKey
Let's not require people to use PropertyNameTraits everywhere when we
can just specialize AK::Traits<JS::PropertyKey> instead. :^)
2021-10-24 17:18:09 +02:00
Andreas Kling
398c181c79 LibJS: Rename PropertyName to PropertyKey
Let's use the same name as the spec. :^)
2021-10-24 17:18:07 +02:00
Linus Groh
0881f8160f LibJS: Use implicit ThrowCompletionOr<T> constructor where possible
Luckily this is not very widespread yet as most of it would happen in
the various JS functions instead of AOs.
2021-10-21 09:02:23 +01:00
davidot
d94b5e511f LibJS: Add slot [[PrivateElements]] and related methods to Object 2021-10-20 23:19:17 +01:00
Idan Horowitz
40eb3a39d4 LibJS: Rename define_native_function => define_old_native_function
This method will eventually be removed once all native functions are
converted to ThrowCompletionOr
2021-10-20 12:27:19 +01:00
Idan Horowitz
ca27e5eff5 LibJS: Convert NativeFunction callback to ThrowCompletionOr 2021-10-20 12:27:19 +01:00
Linus Groh
52976bfac6 LibJS: Convert to_object() to ThrowCompletionOr 2021-10-13 09:55:10 +01:00
Andreas Kling
6108bac606 LibJS: Only do a single property lookup in internal_get_own_property()
Instead of checking storage_has(), followed by storage_get(), we can do
storage_get() directly and avoid a redundant property lookup.

This exposed a bug in SimpleIndexedPropertyStorage::get() which would
previously succeed for array holes.
2021-10-05 15:15:29 +02:00
Linus Groh
d7d73f9100 LibJS: Convert to_property_descriptor() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-04 09:52:15 +01:00
Linus Groh
2f42675ebd LibJS: Convert ordinary_set_with_own_descriptor() to ThrowCompletionOr 2021-10-04 09:52:15 +01:00
Linus Groh
3b59a4577d LibJS: Convert define_properties() to ThrowCompletionOr 2021-10-04 09:52:15 +01:00
Linus Groh
0a49a2db60 LibJS: Convert set_immutable_prototype() to ThrowCompletionOr 2021-10-04 09:52:15 +01:00
Linus Groh
1f7068ace9 LibJS: Remove unused TemporaryChange include from Object.cpp 2021-10-03 21:40:07 +01:00
Linus Groh
e5b8544762 LibJS: Convert enumerable_own_property_names() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
3af559ee8a LibJS: Convert test_integrity_level() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
ed5a9aa038 LibJS: Convert set_integrity_level() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
3be26f56db LibJS: Convert has_own_property() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
f38a5957bf LibJS: Convert has_property() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
a29b7a3ec7 LibJS: Convert delete_property_or_throw() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
fe86b04b42 LibJS: Convert define_property_or_throw() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
ebf57df431 LibJS: Convert create_non_enum_data_p_or_throw() to ThrowCompletionOr
The actual name is a bit longer, but you know what I mean :^)
2021-10-03 20:14:03 +01:00
Linus Groh
364dd42fc8 LibJS: Convert create_data_property_or_throw() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
bb2499cd7a LibJS: Convert create_method_property() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
fb443b3fb4 LibJS: Convert create_data_property() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
1d45541278 LibJS: Convert Object::set() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
b7e5f08e56 LibJS: Convert Object::get() to ThrowCompletionOr
To no one's surprise, this patch is pretty big - this is possibly the
most used AO of all of them. Definitely worth it though.
2021-10-03 20:14:03 +01:00
Linus Groh
9b6c09e2c4 LibJS: Convert is_extensible() to ThrowCompletionOr 2021-10-03 20:14:03 +01:00
Linus Groh
fa2ac5b759 LibJS: Convert ordinary_to_primitive() to ThrowCompletionOr
Also add spec step comments to it while we're here.
2021-10-03 20:14:03 +01:00
Linus Groh
ba6e4c7ae1 LibJS+LibWeb: Use Object::set_prototype() in more places 2021-10-02 14:53:06 +01:00
Linus Groh
84c9f3e0d0 LibJS: Add Object::set_prototype()
This is just factoring out step "9. Set O.[[Prototype]] to V." of
10.1.2 [[SetPrototypeOf]] into its own method so that we don't have to
use internal_set_prototype_of() for setting an object prototype in all
cases.
2021-10-02 14:53:06 +01:00
Andreas Kling
14c57b4b7f LibJS: Remove transition avoidance & start caching prototype transitions
The way that transition avoidance (foo_without_transition) was
implemented led to shapes being unshareable and caused shape explosion
instead, precisely what we were trying to avoid.

This patch removes all the attempts to avoid transitioning shapes, and
instead *adds* transitions when changing an object's prototype.
This makes transitions flow naturally, and as a result we end up with
way fewer shape objects in real-world situations.

When we run out of big problems, we can get back to avoiding transitions
as an optimization, but for now, let's avoid ballooning our processes
with a unique shape for every object.
2021-10-01 02:59:29 +02:00
davidot
830ea0414c LibJS: Make scoping follow the spec
Before this we used an ad-hoc combination of references and 'variables'
stored in a hashmap. This worked in most cases but is not spec like.
Additionally hoisting, dynamically naming functions and scope analysis
was not done properly.

This patch fixes all of that by:
  - Implement BindingInitialization for destructuring assignment.
  - Implementing a new ScopePusher which tracks the lexical and var
    scoped declarations. This hoists functions to the top level if no
    lexical declaration name overlaps. Furthermore we do checking of
    redeclarations in the ScopePusher now requiring less checks all over
    the place.
  - Add methods for parsing the directives and statement lists instead
    of having that code duplicated in multiple places. This allows
    declarations to pushed to the appropriate scope more easily.
  - Remove the non spec way of storing 'variables' in
    DeclarativeEnvironment and make Reference follow the spec instead of
    checking both the bindings and 'variables'.
  - Remove all scoping related things from the Interpreter. And instead
    use environments as specified by the spec. This also includes fixing
    that NativeFunctions did not produce a valid FunctionEnvironment
    which could cause issues with callbacks and eval. All
    FunctionObjects now have a valid NewFunctionEnvironment
    implementation.
  - Remove execute_statements from Interpreter and instead use
    ASTNode::execute everywhere this simplifies AST.cpp as you no longer
    need to worry about which method to call.
  - Make ScopeNodes setup their own environment. This uses four
    different methods specified by the spec
    {Block, Function, Eval, Global}DeclarationInstantiation with the
    annexB extensions.
  - Implement and use NamedEvaluation where specified.

Additionally there are fixes to things exposed by these changes to eval,
{for, for-in, for-of} loops and assignment.

Finally it also fixes some tests in test-js which where passing before
but not now that we have correct behavior :^).
2021-09-30 08:16:32 +01:00
Linus Groh
ee8380edea LibJS: Convert internal_own_property_keys() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
fbfb0bb908 LibJS: Convert internal_delete() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
e5409c6ead LibJS: Convert internal_set() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
6c2b974db2 LibJS: Convert internal_get() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
d9895ec12d LibJS: Convert internal_has_property() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
5da210125e LibJS: Convert internal_define_own_property() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
0e69a6e487 LibJS: Convert internal_get_own_property() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
73bae7d779 LibJS: Convert internal_prevent_extensions() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
9b4362f10a LibJS: Convert internal_is_extensible() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
8c81c84c18 LibJS: Convert internal_set_prototype_of() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Linus Groh
5148150e1c LibJS: Convert internal_get_prototype_of() to ThrowCompletionOr 2021-09-29 23:49:53 +01:00
Luke Wilde
e06762f312 LibJS: Make Object::ordinary_set_with_own_descriptor non-static
This needs to be accessible for implementing IDL legacy platform
objects.
2021-09-26 18:59:56 +02:00
Idan Horowitz
ab594e5f2f LibJS: Convert Value::invoke and VM::call to ThrowCompletionOr 2021-09-23 23:59:13 +03:00
Linus Groh
31bc9565f8 LibJS: Avoid transitions for name/length of native functions/accessors 2021-08-28 23:17:01 +01:00
Linus Groh
47ab84ffd9 LibJS: Add define_direct_{property,accessor}_without_transition() 2021-08-28 23:17:01 +01:00
Linus Groh
222e518a53 LibJS: Avoid pointless transitions and metadata lookups in storage_set()
- Replace the misleading abuse of the m_transitions_enabled flag for the
  fast path without lookup with a new m_initialized boolean that's set
  either by Heap::allocate() after calling the Object's initialize(), or
  by the GlobalObject in its special initialize_global_object(). This
  makes it work regardless of the shape's uniqueness.
- When we're adding a new property past the initialization phase,
  there's no need to do a second metadata lookup to retrieve the storage
  value offset - it's known to always be the shape's property count
  minus one. Also, instead of doing manual storage resizing and
  assignment via indexing, just use Vector::append().
- When we didn't add a new property but are overwriting an existing one,
  the property count and therefore storage value offset doesn't change,
  so we don't have to retrieve it either.

As a result, Object::set_shape() is now solely responsible for updating
the m_shape pointer and is not resizing storage anymore, so I moved it
into the header.
2021-08-28 23:17:01 +01:00
davidot
151447bdf7 LibJS: Move Object::invoke to Value::invoke and fix it for primitives
This is a tiny difference and only changes anything for primitives in
strict mode. However this is tested in test262 and can be noticed by
overriding toString of primitive values.

This does now require one to wrap an object in a Value to call invoke
but all code using invoke has been migrated.
2021-08-09 17:33:14 +01:00
Linus Groh
312946059b LibJS+Spreadsheet: Use js_string(VM&, ...) overload more 2021-08-08 21:32:58 +01:00
Brian Gianforcaro
53166c10ca LibJS: Remove unused header includes 2021-08-01 08:10:16 +02:00
Idan Horowitz
8d01d43f5e LibJS: Replace the boolean argument of Object::set with an enum class
This is more serenity-esque and also makes pointing out missing
exception checks during reviews much easier.
2021-07-16 17:50:01 +01:00
Idan Horowitz
56d8098d13 LibJS: Use PropertyName instead of StringOrSymbol in Object::invoke()
This prevents the unnecessary PropertyName -> StringOrSymbol ->
PropertyName conversion.
2021-07-09 22:32:25 +01:00
Idan Horowitz
795786387b LibJS: Remove the NativeProperty mechanism from LibJS
These were an ad-hoc way to implement special behaviour when reading or
writing to specific object properties. Because these were effectively
replaced by the abillity to override the internal methods of Object,
they are no longer needed.
2021-07-07 21:47:22 +01:00
Idan Horowitz
a6b8291a9b LibJS: Add define_direct_property and remove the define_property helper
This removes all usages of the non-standard define_property helper
method and replaces all it's usages with the specification required
alternative or with define_direct_property where appropriate.
2021-07-06 14:20:30 +01:00
Idan Horowitz
6787e86a3a LibJS: Add and use the CreateNonEnumerableDataPropertyOrThrow AO 2021-07-06 14:20:30 +01: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
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
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
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
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
Andreas Kling
1bd52ce789 LibJS: Stop qualifying AK::Function
Now that JS function objects are JS::FunctionObject, we can stop
qualifying AK::Function and just say "Function" everywhere. Nice. :^)
2021-06-27 22:40:49 +02:00
Andreas Kling
ba9d5c4d54 LibJS: Rename Function => FunctionObject 2021-06-27 22:36:04 +02:00
Linus Groh
dbda5a9a4c LibJS: Move install_error_cause() from Object to Error
This is only used by Error and its subclasses, so it doesn't need to be
available to all objects.
2021-06-26 19:06:55 +01:00
davidot
83dd0164b2 Revert "LibJS: Fix this_value in native setters and getters"
This reverts commit f102b563
The reverted to behavior is not correct for example with a double proxy
But this change lead to problems with DOMNodes
2021-06-26 18:16:53 +01:00
davidot
19f505d320 LibJS: Fix propagation of setters and getters from prototypes
If we define a property with just a setter/getter (not both) we must:
- take the previous getter/setter if defined on the actual object
- overwrite the other to nullptr if it is from a prototype
2021-06-26 18:16:53 +01:00
Andreas Kling
c2ad599783 LibJS: Rename CallFrame => ExecutionContext
This struct represents what the ECMAScript specification calls an
"execution context" so let's use the same terminology. :^)
2021-06-24 19:28:00 +02:00
davidot
f102b56345 LibJS: Fix this_value in native setters and getters
This fixes getting values from double proxies:
var p = new Proxy(new Proxy([], {}), {});
p.length
2021-06-22 20:49:28 +01:00
davidot
91de1135a5 LibJS: Fix a number of regressions in the test262 tests
In get_own_properties:
Entries which are deleted while iterating need to be skipped

In PropertyDescriptor::from_dictionary
If the getter/setter is undefined it should still mark it as present
2021-06-22 20:49:28 +01:00
davidot
733e8472fa LibJS: Make put_own_property_by_index closer to spec
Most of the code is taken from put_own_property however the attributes
  need to be handled slightly differently it seems
2021-06-22 20:49:28 +01:00
davidot
15edad8202 LibJS: Make define_property always throw if specified
Now put uses is_strict_mode to determine define_property should throw
2021-06-22 20:49:28 +01:00
davidot
16b87b85e3 LibJS: Add parameter to delete_property since we need DeleteOrThrow 2021-06-22 20:49:28 +01:00
Ali Mohammad Pur
eb5c92d4e2 LibJS: Don't assert for empty reciever if AllowSideEffects::No is given
This parameter is only used if AllowSideEffects::Yes, so there's no
reason to pass anything to it if that's not used.
2021-06-22 00:26:25 +04:30
Andreas Kling
f86e241699 LibJS: Object.getOwnPropertyNames() should enumerate String's .length
We were incorrectly aborting property name enumeration after generating
names for all the indexable properties in the underlying string.
2021-06-19 11:46:08 +02:00
Idan Horowitz
b6a74b6bd9 LibJS: Use existing attributes if any are missing in the new descriptor
The specification defines that we should only change attributes that
exist in the incoming descriptor, but since we currently just overwrite
the existing descriptor with the new one, we can just set the missing
attributes to the existing values manually.
2021-06-18 10:22:09 +02:00
Idan Horowitz
dcb55db99b LibJS: Replace boolean without_side_effects parameters with an enum 2021-06-17 16:52:15 +02:00
Idan Horowitz
a85a95fe8d LibJS: Stop overwriting existing accessors in Object::define_property 2021-06-17 13:20:18 +01:00
Idan Horowitz
b9d9187feb LibJS: Automatically & lazily coerce PropertyNames into numbers
This commit expands on 5eef07d232 by
automatically trying to coerce Type::String PropertyNames into numbers
when a caller checks if the PropertyName is_number/is_string.
This has several benefits:
 - We no longer have to duplicate the number coercion code to every
   function that accepts a PropertyNumber. (Or more likely, forget to.)
 - This keeps the lazy nature of only doing the coercion when and if
   there is a semantic difference to the different PropertyName types,
   which means this shouldnt cause any performance drop.
 - Since this coercion changes the state of the PropertyName itself the
   result is essentially cached and can speed up any repeat uses of the
   same PropertyName instance.
2021-06-16 22:54:48 +01:00
Idan Horowitz
623eadb44e LibJS: Stop overwriting existing indexed accessors in define_accessor
The previous implementation only checked the shape, ignoring existing
accessors when using number property names.
2021-06-16 22:54:48 +01:00
Idan Horowitz
6352a33ed2 LibJS: Respect Object::get's without_side_effects parameter for numbers 2021-06-16 22:54:48 +01:00
Linus Groh
317b88a8c3 LibJS: Replace Object's create_empty() with create() taking a prototype
This now matches the spec's OrdinaryObjectCreate() across the board:
instead of implicitly setting the created object's prototype to
%Object.prototype% and then in many cases setting it to a nullptr right
away, it now has an 'Object* prototype' parameter with _no default
value_. This makes the code easier to compare with the spec, very clear
in terms of what prototype is being used as well as avoiding unnecessary
shape transitions.

Also fixes a couple of cases were we weren't setting the correct
prototype.

There's no reason to assume that the object would not be empty (as in
having own properties), so let's follow our existing pattern of
Type::create(...) and simply call it 'create'.
2021-06-16 22:49:04 +01:00
Idan Horowitz
07992c8da6 LibJS: Throw when delete-ing a non-configurable property in strict mode 2021-06-16 12:57:48 +01:00
Idan Horowitz
c619ad4fec LibJS: Allow no-op define property calls on non-configurable objects
This brings us slightly closer to the specification's 10.1.6.3
ValidateAndApplyPropertyDescriptor.
2021-06-16 12:57:48 +01:00
Andreas Kling
5eef07d232 LibJS: Avoid lots of string-to-int during global object construction
We were doing a *lot* of string-to-int conversion while creating a new
global object. This happened because Object::put() would try to convert
the property name (string) to an integer to see if it refers to an
indexed property.

Sidestep this issue by using PropertyName for the CommonPropertyNames
struct on VM (vm.names.foo), and giving PropertyName a flag that tells
us whether it's a string that *may be* a number.

All CommonPropertyNames are set up so they are known to not be numbers.
2021-06-13 19:11:29 +02:00
Linus Groh
7327a28ccc LibJS: Add ECMA-262 section/title/URL comments almost everywhere
As mentioned on Discord earlier, we'll add these to all new functions
going forward - this is the backfill. Reasons:

- It makes you look at the spec, implementing based on MDN or V8
  behavior is a no-go
- It makes finding the various functions that are non-compliant easier,
  in the future everything should either have such a comment or, if it's
  not from the spec at all, a comment explaining why that is the case
- It makes it easier to check whether a certain abstract operation is
  implemented in LibJS, not all of them use the same name as the spec.
  E.g. RejectPromise() is Promise::reject()
- It makes it easier to reason about vm.arguments(), e.g. when the
  function has a rest parameter
- It makes it easier to see whether a certain function is from a
  proposal or Annex B

Also:

- Add arguments to all functions and abstract operations that already
  had a comment
- Fix some outdated section numbers
- Replace some ecma-international.org URLs with tc39.es
2021-06-13 00:33:28 +01:00