1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-15 03:47:35 +00:00
serenity/Userland/Libraries/LibJS/Tests/builtins
Linus Groh a53542e0a3 LibJS: Clear exception after running each queued Promise job
It's not what the spec tells us to do. In fact, the spec tells us the
exact opposite:

    9.5 Jobs and Host Operations to Enqueue Jobs
    https://tc39.es/ecma262/#sec-jobs

    A Job is an Abstract Closure with no parameters that initiates an
    ECMAScript computation when no other ECMAScript computation is
    currently in progress.
    ...
    Their implementations must conform to the following requirements:
    - ...
    - The Abstract Closure must return a normal completion, implementing
      its own handling of errors.

However, this turned out to not be true in all cases. More specifically,
the NewPromiseReactionJob AO returns the completion result of calling a
user-provided function (PromiseCapability's [[Resolve]] / [[Reject]]),
which may be an abrupt completion:

    27.2.2.1 NewPromiseReactionJob ( reaction, argument )
    https://tc39.es/ecma262/#sec-newpromisereactionjob

    1. Let job be a new Job Abstract Closure with no parameters that
       captures reaction and argument and performs the following steps
       when called:
       ...
       h. If handlerResult is an abrupt completion, then
          i. Let status be Call(promiseCapability.[[Reject]],
             undefined, « handlerResult.[[Value]] »).
       i. Else,
          i. Let status be Call(promiseCapability.[[Resolve]],
             undefined, « handlerResult.[[Value]] »).
       j. Return Completion(status).

Interestingly, this case is explicitly handled in the HTML spec's
implementation of jobs as microtasks:

    8.1.5.3.3 HostEnqueuePromiseJob(job, realm)
    https://html.spec.whatwg.org/webappapis.html#hostenqueuepromisejob

    2. Queue a microtask on the surrounding agent's event loop to
       perform the following steps:
       ...
       5. If result is an abrupt completion, then report the exception
          given by result.[[Value]].

This is precisely what all the major engines do - but not only in
browsers; the provided code snippet in the test added in this commit
works just fine in Node.js, for example.

SpiderMonkey:
https://searchfox.org/mozilla-central/rev/25997ce8267ec9e3ea4b727e0973bd9ef02bba79/js/src/builtin/Promise.cpp#6292
https://searchfox.org/mozilla-central/rev/25997ce8267ec9e3ea4b727e0973bd9ef02bba79/js/src/builtin/Promise.cpp#1277
https://searchfox.org/mozilla-central/rev/25997ce8267ec9e3ea4b727e0973bd9ef02bba79/js/src/vm/JSContext.cpp#845

JavaScriptCore:
https://trac.webkit.org/browser/webkit/trunk/Source/JavaScriptCore/builtins/PromiseOperations.js?rev=273718#L562
https://trac.webkit.org/browser/webkit/trunk/Source/JavaScriptCore/runtime/JSMicrotask.cpp?rev=273718#L94

V8:
https://source.chromium.org/chromium/chromium/src/+/main:v8/src/builtins/promise-abstract-operations.tq;l=481;drc=a760f03a6e99bf4863d8d21c5f7896a74a0a39ea
https://source.chromium.org/chromium/chromium/src/+/main:v8/src/builtins/builtins-microtask-queue-gen.cc;l=331;drc=65c9257f1777731d6d0669598f6fe6fe65fa61d3

This should probably be fixed in the ECMAScript spec to relax the rule
that Jobs may not return an abrupt completion, just like in the HTML
spec. The important bit is that those are not surfaced to user code in
any way.
2021-11-12 15:35:03 +02:00
..
AggregateError LibJS: Implement the Error Cause proposal 2021-06-11 21:34:05 +01:00
Array LibJS: Prevent stack overflow in flatten_into_array() 2021-08-15 11:24:30 +01:00
ArrayBuffer LibJS: ArrayBuffer.prototype.slice 2021-04-03 16:24:44 +02:00
Atomics LibJS: Implement Atomics.isLockFree 2021-07-14 22:13:15 +01:00
BigInt LibJS: Fix typo in LHS Object and RHS BigInt loosely equals check 2021-10-15 01:59:09 +01:00
Boolean LibJS: Change wording of ErrorType::NotA to be independent of context 2021-09-12 00:16:39 +02:00
DataView LibJS: Use Checked<T> for offsets in the SetViewValue AO 2021-08-11 22:56:58 +01:00
Date LibJS: Change wording of ErrorType::NotA to be independent of context 2021-09-12 00:16:39 +02:00
Error LibJS: Implement the Error Cause proposal 2021-06-11 21:34:05 +01:00
FinalizationRegistry test-js: Add a mark_as_garbage method to force GC to collect that object 2021-09-08 08:53:02 +01:00
Function LibJS: Change wording of ErrorType::NotA to be independent of context 2021-09-12 00:16:39 +02:00
functions LibJS: Add the global escape() & unescape() methods 2021-06-05 18:55:08 +01:00
Infinity Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Intl LibJS: Begin implementing Intl.NumberFormat.prototype.format 2021-11-12 09:17:08 +00:00
JSON LibJS: Dont try to serialize symbol-keyed properties 2021-04-16 19:22:29 +02:00
Map LibJS/Tests: Test iteration order of Map.prototype.entries() 2021-08-13 23:54:08 +01:00
Math LibJS: Correctly handle mixing +0 and -0 in Math.{min,max}() 2021-04-23 20:51:48 +02:00
NaN Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Number LibJS: Change wording of ErrorType::NotA to be independent of context 2021-09-12 00:16:39 +02:00
Object LibJS/Tests: Remove two leftover console.log() calls 2021-07-28 21:57:30 +01:00
Promise LibJS: Clear exception after running each queued Promise job 2021-11-12 15:35:03 +02:00
Proxy LibJS: Add ErrorTypes for Promise ownKeys trap invariant violations 2021-10-20 18:46:24 +01:00
Reflect LibJS: Implement [[Call]] and [[Construct]] internal slots properly 2021-10-09 14:29:20 +01:00
RegExp LibJS: Create the RegExpExec result's "input" field last 2021-11-08 01:36:29 +01:00
Set LibJS: Add the SetIterator built-in and Set.prototype.{values, entries} 2021-06-09 11:48:04 +01:00
ShadowRealm LibJS: Implement ShadowRealm.prototype.importValue() 2021-10-15 09:36:21 +01:00
String LibJS: Implement ECMA-402 String.prototype.toLocale{Lower,Upper}Case 2021-09-06 15:24:27 +01:00
Symbol LibJS: Rename OrdinaryFunctionObject to ECMAScriptFunctionObject 2021-09-25 17:51:30 +02:00
Temporal LibJS: Implement Temporal.ZonedDateTime.prototype.subtract 2021-11-12 09:24:36 +00:00
TypedArray LibJS: Change wording of ErrorType::NotA to be independent of context 2021-09-12 00:16:39 +02:00
WeakMap test-js: Add a mark_as_garbage method to force GC to collect that object 2021-09-08 08:53:02 +01:00
WeakRef LibJS: Add the WeakRef.prototype.deref method 2021-06-12 18:39:23 +01:00
WeakSet test-js: Add a mark_as_garbage method to force GC to collect that object 2021-09-08 08:53:02 +01:00