Commit graph

11 commits

Author SHA1 Message Date
Matthew Olsson
7a1d485b19 LibJS: Integrate Symbols into objects as valid keys
This allows objects properties to be created for symbol keys in addition
to just plain strings/numbers
2020-07-09 23:33:00 +02:00
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
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
Matthew Olsson
5ae9419a06 LibJS: Object index properties have descriptors; Handle sparse indices
This patch adds an IndexedProperties object for storing indexed
properties within an Object. This accomplishes two goals: indexed
properties now have an associated descriptor, and objects now gracefully
handle sparse properties.

The IndexedProperties class is a wrapper around two other classes, one
for simple indexed properties storage, and one for general indexed
property storage. Simple indexed property storage is the common-case,
and is simply a vector of properties which all have attributes of
default_attributes (writable, enumerable, and configurable).

General indexed property storage is for a collection of indexed
properties where EITHER one or more properties have attributes other
than default_attributes OR there is a property with a large index (in
particular, large is '200' or higher).

Indexed properties are now treated relatively the same as storage within
the various Object methods. Additionally, there is a custom iterator
class for IndexedProperties which makes iteration easy. The iterator
skips empty values by default, but can be configured otherwise.
Likewise, it evaluates getters by default, but can be set not to.
2020-05-28 17:17:13 +02:00
Matthew Olsson
45dfa094e9 LibJS: Add getter/setter support
This patch adds a GetterSetterPair object. Values can now store pointers
to objects of this type. These objects are created when using
Object.defineProperty and providing an accessor descriptor.
2020-05-21 22:56:18 +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
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
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