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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 - 2022 ,  Linus  Groh  < linusg @ serenityos . org > 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 01:49:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/AbstractOperations.h> 
  
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Error.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/NativeFunction.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/PromiseReaction.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  JS  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 00:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 27.2.1.5 NewPromiseCapability ( C ), https://tc39.es/ecma262/#sec-newpromisecapability
  
						 
					
						
							
								
									
										
										
										
											2021-10-23 03:34:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ThrowCompletionOr < PromiseCapability >  new_promise_capability ( GlobalObject &  global_object ,  Value  constructor )  
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  global_object . vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 00:20:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  realm  =  * global_object . associated_realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If IsConstructor(C) is false, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 03:34:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! constructor . is_constructor ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  vm . throw_completion < TypeError > ( global_object ,  ErrorType : : NotAConstructor ,  constructor . to_string_without_side_effects ( ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 27.2.3.1).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let promiseCapability be the PromiseCapability Record { [[Promise]]: undefined, [[Resolve]]: undefined, [[Reject]]: undefined }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: This should not be stack-allocated, the executor function below can be captured and outlive it!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        See https://discord.com/channels/830522505605283862/886211697843531866/900081190621569154 for some discussion.
 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Value  resolve  {  js_undefined ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Value  reject  {  js_undefined ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  promise_capability_functions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. Let executorClosure be a new Abstract Closure with parameters (resolve, reject) that captures promiseCapability and performs the following steps when called:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-20 17:51:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  executor_closure  =  [ & promise_capability_functions ] ( auto &  vm ,  auto &  global_object )  - >  ThrowCompletionOr < Value >  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        auto  resolve  =  vm . argument ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  reject  =  vm . argument ( 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // No idea what other engines say here.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // a. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! promise_capability_functions . resolve . is_undefined ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 22:53:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  vm . template  throw_completion < TypeError > ( global_object ,  ErrorType : : GetCapabilitiesExecutorCalledMultipleTimes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // b. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! promise_capability_functions . reject . is_undefined ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 22:53:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  vm . template  throw_completion < TypeError > ( global_object ,  ErrorType : : GetCapabilitiesExecutorCalledMultipleTimes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // c. Set promiseCapability.[[Resolve]] to resolve.
 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        promise_capability_functions . resolve  =  resolve ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // d. Set promiseCapability.[[Reject]] to reject.
 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        promise_capability_functions . reject  =  reject ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // e. Return undefined.
 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  js_undefined ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-20 17:51:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-02 20:54:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 00:20:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  executor  =  NativeFunction : : create ( realm ,  move ( executor_closure ) ,  2 ,  " " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 6. Let promise be ? Construct(C, « executor »).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 15:06:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  promise  =  TRY ( construct ( global_object ,  constructor . as_function ( ) ,  executor ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 7. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 03:34:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! promise_capability_functions . resolve . is_function ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  vm . throw_completion < TypeError > ( global_object ,  ErrorType : : NotAFunction ,  promise_capability_functions . resolve . to_string_without_side_effects ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 8. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 03:34:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! promise_capability_functions . reject . is_function ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  vm . throw_completion < TypeError > ( global_object ,  ErrorType : : NotAFunction ,  promise_capability_functions . reject . to_string_without_side_effects ( ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-14 00:33:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 9. Set promiseCapability.[[Promise]] to promise.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 10. Return promiseCapability.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 03:34:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  PromiseCapability  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 01:49:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        promise , 
							 
						 
					
						
							
								
									
										
											 
										
											
												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-01 22:13:29 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        & promise_capability_functions . resolve . as_function ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        & promise_capability_functions . reject . as_function ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								PromiseReaction : : PromiseReaction ( Type  type ,  Optional < PromiseCapability >  capability ,  Optional < JobCallback >  handler )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  m_type ( type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_capability ( move ( capability ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_handler ( move ( handler ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  PromiseReaction : : visit_edges ( Cell : : Visitor &  visitor )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Cell : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_capability . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  capability  =  m_capability . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        visitor . visit ( capability . promise ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        visitor . visit ( capability . resolve ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        visitor . visit ( capability . reject ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}