Commit graph

271 commits

Author SHA1 Message Date
Linus Groh
d6cffb82a2 LibJS: Move 'typeof' string functionality from AST to Value
We should be able to get the 'typeof' string for any value directly, so
this is now a standalone Value::typeof() method instead of being part of
UnaryExpression::execute().
2021-04-02 22:24:30 +02:00
Linus Groh
f418115f1b LibJS: Add initial support for Promises
Almost a year after first working on this, it's finally done: an
implementation of Promises for LibJS! :^)

The core functionality is working and closely following the spec [1].
I mostly took the pseudo code and transformed it into C++ - if you read
and understand it, you will know how the spec implements Promises; and
if you read the spec first, the code will look very familiar.

Implemented functions are:

- Promise() constructor
- Promise.prototype.then()
- Promise.prototype.catch()
- Promise.prototype.finally()
- Promise.resolve()
- Promise.reject()

For the tests I added a new function to test-js's global object,
runQueuedPromiseJobs(), which calls vm.run_queued_promise_jobs().
By design, queued jobs normally only run after the script was fully
executed, making it improssible to test handlers in individual test()
calls by default [2].

Subsequent commits include integrations into LibWeb and js(1) -
pretty-printing, running queued promise jobs when necessary.

This has an unusual amount of dbgln() statements, all hidden behind the
PROMISE_DEBUG flag - I'm leaving them in for now as they've been very
useful while debugging this, things can get quite complex with so many
asynchronously executed functions.

I've not extensively explored use of these APIs for promise-based
functionality in LibWeb (fetch(), Notification.requestPermission()
etc.), but we'll get there in due time.

[1]: https://tc39.es/ecma262/#sec-promise-objects
[2]: https://tc39.es/ecma262/#sec-jobs-and-job-queues
2021-04-02 10:47:40 +02:00
Idan Horowitz
78f0cabb17 LibJS: Use Utf8View for string prefix checks
This commit replaces the usage of String::starts_with with
Utf8View::starts_with, which first decodes the utf8 encoded
string, and as such can take things like overlong encoded
sequences into account (which could otherwise cause the prefix
check to be inconsistent with the following code points check).
2021-03-25 10:59:34 +01:00
Linus Groh
40eab55e7d LibJS: Remove as_size_t()
Just like to_size_t() - which was already removed in f369229 - this is
non-standard, use to_length() instead. One remaining use was removed,
and I'm glad it's gone. :^)
2021-03-23 08:22:39 +01:00
Andreas Kling
6870349599 LibJS: Flatten Value::to_numeric()
The basic idea here is to inline to_primitive() to get rid of the
function call overhead.
2021-03-21 21:39:39 +01:00
Andreas Kling
00965e3dad LibJS: Add fast path for add() with two numeric JS::Values 2021-03-21 21:39:39 +01:00
Andreas Kling
37cd1a95fc LibJS: Only call GlobalObject::vm() once in add() 2021-03-21 21:39:39 +01:00
Andreas Kling
c8382c32e9 LibJS: Split Value::Type::Number into Int32 and Double
We now store 32-bit integers as 32-bit integers directly which avoids
having to convert them from doubles when they're only used as 32-bit
integers anyway. :^)

This patch feels a bit incomplete and there's a lot of opportunities
to take advantage of this information. We'll have to find and exploit
them eventually.
2021-03-21 21:39:39 +01:00
Linus Groh
88a3267e46 LibJS: Replace global_object.global_object() with just global_object
That's just silly...
2021-03-16 22:12:56 +01:00
Linus Groh
fa6bce5087 LibJS: Throw RangeError on BigInt exponentiation with negative exponent
https://tc39.es/ecma262/#sec-numeric-types-bigint-exponentiate
2021-03-16 21:54:51 +01:00
Linus Groh
11138f5c1f LibJS: Throw RangeError on BigInt division/modulo by zero
https://tc39.es/ecma262/#sec-numeric-types-bigint-divide
https://tc39.es/ecma262/#sec-numeric-types-bigint-remainder
2021-03-16 21:54:51 +01:00
Linus Groh
585123127e LibJS: Support @@toPrimitive in ToPrimitive abstract operation
Fixes #3961.
2021-03-03 11:04:06 +01:00
Linus Groh
e7ef729db3 LibJS: Use Value::get_method() a bunch 2021-03-02 19:20:29 +01:00
Linus Groh
1b43a6ef2d LibJS: Implement the GetMethod abstract operation
https://tc39.es/ecma262/#sec-getmethod

We have bunch of duplicated on-demand versions of this, let's do it
properly.
2021-03-02 19:20:29 +01:00
Andreas Kling
5d180d1f99 Everywhere: Rename ASSERT => VERIFY
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED)

Since all of these checks are done in release builds as well,
let's rename them to VERIFY to prevent confusion, as everyone is
used to assertions being compiled out in release.

We can introduce a new ASSERT macro that is specifically for debug
checks, but I'm doing this wholesale conversion first since we've
accumulated thousands of these already, and it's not immediately
obvious which ones are suitable for ASSERT.
2021-02-23 20:56:54 +01:00
Andreas Kling
ee1b58bf41 LibJS: Use all_of() in JS::Value's BigInt validation 2021-02-17 15:22:21 +01:00
Andreas Kling
9efd80f100 LibJS: Use fabs() instead of abs() in JS::Value
abs() takes an int, so this would only work correctly for numbers
smaller than INT_MAX.
2021-02-15 13:58:24 +01:00
Andreas Kling
16a0e7a66d LibJS: Improve correctness of rounding and bitwise operations
Patch from Anonymous
2021-02-05 09:38:45 +01:00
Linus Groh
50957ec78e LibJS: Fix variable name coding style int{Part => _part}
...and rename intpart_end to int_part_end for consistency.
2021-02-02 16:52:55 +01:00
Linus Groh
cab3049dcc LibJS: Rename ErrorType::ToObjectNullOr{Undef => Undefined}
This seems like an unnecessary and uncommon abbreviation.
2021-01-14 08:13:32 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Renamed from Libraries/LibJS/Runtime/Value.cpp (Browse further)