1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-22 19:45:08 +00:00
Commit graph

244 commits

Author SHA1 Message Date
Linus Groh
8137f40b73 LibJS: Add Value::is_integer() 2020-05-08 20:06:49 +02:00
Matthew Olsson
532d4bc0ab LibJS: Spec-compliant equality comparisons
The ECMAScript spec defines multiple equality operations which are used
all over the spec; this patch introduces them. Of course, the two
primary equality operations are AbtractEquals ('==') and StrictEquals
('==='), which have been renamed to 'abstract_eq' and 'strict_eq' in
this patch.

In support of the two operations mentioned above, the following have
also been added: SameValue, SameValueZero, and SameValueNonNumeric.
These are important to have, because they are used elsewhere in the spec
aside from the two primary equality comparisons.
2020-05-08 09:49:20 +02:00
Matthew Olsson
ab652fa1ee LibJS: Add String.raw 2020-05-07 23:05:55 +02:00
Matthew Olsson
838390171c LibJS: Function.length respects default and rest parameters
"[Function.length is] the number of formal parameters. This number
excludes the rest parameter and only includes parameters before
the first one with a default value." - MDN
2020-05-06 17:40:56 +02:00
Andreas Kling
025cdfdce8 LibJS: Simplify a Value type check in Object::to_string() 2020-05-06 16:40:08 +02:00
Linus Groh
eea62dd365 LibJS: Add Value::{is, as}_function() 2020-05-06 14:49:53 +02:00
Andreas Kling
fc5d0a1bd2 LibJS: Switch objects to unique shape after 100 property additions
At that point, it seems unlikely that the shape is gonna be shared with
other objects, and we avoid getting stuck holding a big bag of shapes.
2020-05-05 18:49:45 +02:00
Emanuele Torre
8bd9f7e50e LibJS: run clang-format on all the files 2020-05-05 09:15:16 +02:00
Emanuele Torre
30519c22f6 LibJS: Re-implement console functions as wrappers around Console methods
Console methods are now Value(void) functions.

JavaScript functions in the JavaScript ConsoleObject are now implemented
as simple wrappers around Console methods.

This will make it possible for LibJS users to easily override the
default behaviour of JS console functions (even their return value!)
once we add a way to override Console behaviour.
2020-05-05 09:15:16 +02:00
Emanuele Torre
73bead5ae9 LibJS: Move join_args() in Interpreter
It can be useful outside of Runtime/ConsoleObject.cpp.
join_args() => Interpreter::join_arguments()
2020-05-05 09:15:16 +02:00
Linus Groh
454c1e6bbe LibJS: Implement rest parameters 2020-05-04 23:30:52 +02:00
Linus Groh
25cf0da2fb LibJS: Set name of anonymous functions during assignment 2020-05-03 11:41:56 +02:00
Matthew Olsson
5e66f1900b LibJS: Add function default arguments
Adds the ability for function arguments to have default values. This
works for standard functions as well as arrow functions. Default values
are not printed in a <function>.toString() call, as nodes cannot print
their source string representation.
2020-05-03 00:44:57 +02:00
Andreas Kling
c00ff4ba62 LibJS: Fix build (GlobalObject::add_constructor not visible in LibWeb) 2020-05-02 20:43:44 +02:00
Linus Groh
99be27b4a1 LibJS: Add "name" property to functions 2020-05-02 20:41:31 +02:00
Linus Groh
d007e8d00f LibJS: Set correct "length" of Object constructor 2020-05-02 20:41:31 +02:00
Linus Groh
85582953c6 LibJS: Minor formatting changes in Function.cpp 2020-05-02 20:41:31 +02:00
Linus Groh
ae05dc8abc LibJS: Name functions created by "Function" "anonymous"
...as it is supposed to be.
2020-05-02 20:41:31 +02:00
Emanuele Torre
be1a5bf3f7 LibJS: Add ConsoleMessage concept
A ConsoleMessage is a struct cointaining:
 * AK::String text;         represents the text of the message sent
                             to the console.
 * ConsoleMessageKind kind; represents the kind of JS `console` function
                             from which the message was sent.

Now, Javascript `console` functions only send a ConsoleMessage to the
Interpreter's Console instead of printing text directly to stdout.
The Console then stores the recived ConsoleMessage in
Console::m_messages; the Console does not print to stdout by default.

You can set Console::on_new_message to a void(ConsoleMessage&); this
function will get call everytime a new message is added to the Console's
messages and can be used, for example, to print ConsoleMessages to
stdout or to color the output based on the kind of ConsoleMessage.

In this patch, I also:
  * Re-implement all the previously implemented functions in the
     JavaScript ConsoleObject, as wrappers around Console functions
     that add new message to the Console.
  * Implement console.clear() like so:
    - m_messages get cleared;
    - a new_message with kind set ConsoleMessageKind::Clear gets added
       to m_messages, its text is an empty AK::String;
  * Give credit to linusg in Console.cpp since I used his
     console.trace() algorithm in Console::trace().

I think that having this abstration will help us in the implementation
of a browser console or a JS debugger. We could also add more MetaData
to ConsoleMessage, e.g. Object IDs of the arguments passed to console
functions in order to make hyperlinks, Timestamps, ecc.; which could be
interesting to see.

This will also help in implementing a `/bin/js` option to make, for
example, return a ConsoleMessageWrapper to console functions instead of
undefined. This will be useful to make tests for functions like
console.count() and console.countClear(). :^)
2020-05-02 11:41:35 +02:00
Emanuele Torre
e9c7d4524a LibJS: Implement ConsoleObject::count() as a Console::count() wrapper
Also implement ConsoleObject::count_clear() as a wrapper for
Console::count_clear()
2020-05-02 11:41:35 +02:00
Emanuele Torre
2e92c2e5e1 LibJS: Start implementing a Console class for the interpreter
The goal is to start factoring out core ConsoleObject functionality and
to make ConsoleObject only a JS wrapper around Console.
2020-05-02 11:41:35 +02:00
Linus Groh
79b829637e LibJS: Implement most of the Reflect object 2020-05-01 16:54:01 +02:00
Linus Groh
1ba2e6768d LibJS: Implement indexed access for StringObject 2020-05-01 16:54:01 +02:00
Linus Groh
a81bce8c2a LibJS: Make Array.length non-configurable
This was incorrect, it's only writable.
2020-05-01 16:54:01 +02:00
Linus Groh
65dbe17dd7 LibJS: Add Value::to_size_t() 2020-05-01 16:54:01 +02:00
Linus Groh
62671bea68 LibJS: Add Object::has_property()
Like Object::has_own_property() but going down the prototype chain.
2020-05-01 16:54:01 +02:00
Linus Groh
4cdd802927 LibJS: Return a bool from Object::put* to indicate success 2020-05-01 16:54:01 +02:00
Kesse Jones
6dbb5df81f LibJS: Add String.prototype.lastIndexOf 2020-05-01 16:50:37 +02:00
Emanuele Torre
46b79eaad9 LibJS: Implement console.countReset()
I chose to also make it print "<counter_name>: 0\n" when a counter gets
reset, similarly to how firefox behaves.
2020-05-01 13:02:01 +02:00
Emanuele Torre
8c60ba1e42 LibJS: Implement console.count() 2020-05-01 13:02:01 +02:00
mattco98
683a0696f3 LibJS: Add Object.{keys,values,entries}() 2020-04-30 09:53:16 +02:00
Linus Groh
8159f45f6e LibJS: Make String.prototype.slice() generic 2020-04-29 19:14:36 +02:00
Linus Groh
cfdb7b8806 LibJS: Make (most) String.prototype functions generic
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.
2020-04-29 18:53:21 +02:00
Linus Groh
4bdb6daac5 LibJS: Handle non-string primitive values in Object::to_string() 2020-04-29 18:53:21 +02:00
Linus Groh
2c6e7dbd07 LibJS: Throw error in Object::to_string() if string conversion fails 2020-04-29 18:53:21 +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
Kesse Jones
58f6f50de4 LibJS: Add String.prototype.slice 2020-04-29 18:35:18 +02:00
Andreas Kling
aaf35112a4 LibJS: Pass JS::Function around by reference more 2020-04-29 13:43:57 +02:00
Andreas Kling
a38658dc88 LibJS: Don't use Optional<Value> for bound |this| values
Just use a plain Value since it already has an empty state.
2020-04-29 12:41:58 +02:00
Andreas Kling
698652a548 LibJS: Make Value::as_string() return a PrimitiveString reference 2020-04-29 12:35:39 +02:00
Andreas Kling
75f246dde8 LibJS: Make StringObject::primitive_string() return a reference 2020-04-29 12:33:28 +02:00
Linus Groh
d4ec38097f LibJS: Return undefined in Array.prototype.{pop,shift} for empty values 2020-04-29 09:38:25 +02:00
mattco98
18cfb9218a LibJS: Set Array length attributes to "Configurable | Writable" 2020-04-29 09:02:29 +02:00
Linus Groh
da0ab16f01 LibJS: Don't handle arrays separately in Value::to_number()
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
2020-04-29 01:30:59 +02:00
Linus Groh
6d6cd64689 LibJS: Skip undefined and null in join_array_with_separator()
This it being used in Array.prototype.{join,toString}() - and now
adhering to the spec: [undefined, null].join() === ","
2020-04-29 01:30:59 +02:00
Linus Groh
3152559422 LibJS: Call Array.prototype.findIndex() callback for empty elements
If the array value at the current index is empty, the callback will
be called with undefined as value.
2020-04-28 20:15:38 +02:00
Linus Groh
823cc7bc1c LibJS: Call Array.prototype.find() callback for empty elements
If the array value at the current index is empty, the callback will
be called with undefined as value.
2020-04-28 20:15:38 +02:00
Linus Groh
ad8abce8a5 LibJS: Let Array.prototype.map() resize new array before loop
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]
2020-04-28 20:15:38 +02:00
Linus Groh
0a0ba64383 LibJS: Handle Object.prototype.hasOwnProperty() with no arg correctly
I.e. the same as hasOwnProperty(undefined) or
hasOwnProperty("undefined") :^)
2020-04-28 20:03:50 +02:00
Andreas Kling
24cce3674b LibJS: Support o.f++ :^)
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.
2020-04-28 15:07:08 +02:00