Commit graph

11 commits

Author SHA1 Message Date
Andreas Kling
ff8bb962b6 LibJS: Always keep a reference to the global object in Shape
We need to move towards supporting multiple global objects, which will
be a large refactoring. To keep it manageable, let's do it in steps,
starting with giving Object a way to find the GlobalObject it lives
inside by asking its Shape for it.
2020-06-08 12:15:58 +02:00
Matthew Olsson
39ad42defd LibJS: Add Proxy objects
Includes all traps except the following: [[Call]], [[Construct]],
[[OwnPropertyKeys]].

An important implication of this commit is that any call to any virtual
Object method has the potential to throw an exception. These methods
were not checked in this commit -- a future commit will have to protect
these various method calls throughout the codebase.
2020-06-06 22:13:01 +02:00
Matthew Olsson
5ad5322f6a LibJS: Distinguish between omitted descriptor attributes and false ones
When calling Object.defineProperty, there is now a difference between
omitting a descriptor attribute and specifying that it is false. For
example, "{}" and "{ configurable: false }" will have different
attribute values.
2020-06-06 22:13:01 +02:00
mattco98
95abcc3722 LibJS: Implement correct object property ordering
This commit introduces a way to get an object's own properties in the
correct order. The "correct order" for JS object properties is first all
array-like index properties (numeric keys) sorted by insertion order,
followed by all string properties sorted by insertion order.

Objects also now print correctly in the repl! Before this commit:

courage ~/js-tests $ js
> ({ foo: 1, bar: 2, baz: 3 })
{ bar: 2, foo: 1, baz: 3 }

After:

courage ~/js-tests $ js
> ({ foo: 1, bar: 2, baz: 3 })
{ foo: 1, bar: 2, baz: 3 }
2020-04-29 18:47:03 +02:00
Andreas Kling
f897c41092 LibJS: Implement basic support for the "delete" operator
It turns out "delete" is actually a unary op :)
This patch implements deletion of object properties, it doesn't yet
work for casually deleting properties from the global object.

When deleting a property from an object, we switch that object to
having a unique shape, no longer sharing shapes with others.
Once an object has a unique shape, it no longer needs to care about
shape transitions.
2020-04-26 15:51:07 +02:00
Andreas Kling
1b391d78ae LibJS: Allow cells to mark null pointers
This simplifies the cell visiting functions by letting them not worry
about the pointers they pass to the visitor being null.
2020-04-16 16:10:38 +02:00
Andreas Kling
0fea525373 LibJS: Key shape transitions on both property name and attributes
This allows us to cache forward transitions that reconfigure existing
properties as well, leading to better shape reuse.
2020-04-10 16:33:44 +02:00
Andreas Kling
8286f8b996 LibJS: Add property configuration transitions
Object.defineProperty() can now change the attributes of a property
already on the object. Internally this becomes a shape transition with
the TransitionType::Configure. Such transitions don't expand the
property storage capacity, but rather simply keep attributes up to date
when generating a property table.
2020-04-10 00:36:06 +02:00
Andreas Kling
e6d920d87d LibJS: Add Object.defineProperty() and start caring about attributes
We now care (a little bit) about the "configurable" and "writable"
property attributes.

Property attributes are stored together with the property name in
the Shape object. Forward transitions are not attribute-savvy and will
cause poor Shape reuse in the case of multiple same-name properties
with different attributes.

Oh, and this patch also adds Object.getOwnPropertyDescriptor() :^)
2020-04-10 00:36:06 +02:00
Andreas Kling
e323246517 Meta: Add missing copyright headers 2020-04-06 11:09:01 +02:00
Andreas Kling
5e6e1fd482 LibJS: Start implementing object shapes
This patch adds JS::Shape, which implements a transition tree for our
Object class. Object property keys, prototypes and attributes are now
stored in a Shape, and each Object has a Shape.

When adding a property to an Object, we make a transition from the old
Shape to a new Shape. If we've made the same exact transition in the
past (with another Object), we reuse the same transition and both
objects may now share a Shape.

This will become the foundation of inline caching and other engine
optimizations in the future. :^)
2020-04-02 19:32:21 +02:00