I.e. they don't require the |this| value to be a string object and
"can be transferred to other kinds of objects for use as a method" as
the spec describes it.
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 }
Now that Array.prototype.join() is producing the correct results we
can remove the separate code path for arrays in Value::to_number()
and treat them like all other objects - using to_primitive() with
number as the preferred type and then calling to_number() on the
result.
This is how the spec descibes it.
This also means we don't crash anymore when trying to coerce
[<empty>] to a number - it now does the following:
[<empty>] - to string - "" - to number - 0
[<empty>, <empty>] - to string - "," - to number - NaN
Currently we would create an empty array of size 0 and appening results
of the callback function while skipping empty values.
This is incorrect, we should be initializing a full array of the correct
size beforehand and then inserting the results while still skipping
empty values.
Wrong: new Array(5).map(() => {}) // []
Right: new Array(5).map(() => {}) // [<empty> * 5]
This patch teaches UpdateExpression how to use a Reference. Some other
changes were necessary to keep tests working:
A Reference can now also refer to a local or global variable. This is
not fully aligned with the spec since we don't have a Record concept.
Expression nodes can now be asked to produce a Reference. We then use
this to implement the "delete" operator without downcasting the child
node to a MemberExpression manually.
The number of iterations is limited to the initial array size, but we
still need to check if the array did shrink since then before accessing
each element.
Fixes#1992.
Added the ability to include a u8 attributes parameter with all of the
various put methods in the Object class. They can be omitted, in which
case it defaults to "Writable | Enumerable | Configurable", just like
before this commit.
All of the attribute values for each property were gathered from
SpiderMonkey in the Firefox console. Some properties (e.g. all of the
canvas element properties) have undefined property descriptors... not
quite sure what that means. Those were left as the default specified
above.
Normally the storage would be expanded by set_shape() upon transition
to a new shape, but if the shape is already unique, there is no new
transition so we have to expand the storage manually.
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.
JS::Value already has the empty state ({} or Value() gives you one.)
Use this instead of wrapping Value in Optional in some places.
I've also added Value::value_or(Value) so you can easily provide a
fallback value when one is not present.
This is a special kind of byte array that clamps its values to 0...255
It will be used for HTML ImageData objects.
I made Object::put_by_index() and get_by_index() virtual for this.
We'll probably need to make non-numeric property name lookups virtual
as well, but this solves my current problem well enough.