2020-03-07 18:42:11 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
|
|
|
*
|
2021-04-22 08:24:48 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-03-07 18:42:11 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-06-20 11:55:34 +00:00
|
|
|
#define JS_DECLARE_NATIVE_FUNCTION(name) \
|
2020-09-27 16:36:49 +00:00
|
|
|
static JS::Value name(JS::VM&, JS::GlobalObject&)
|
2020-06-20 11:55:34 +00:00
|
|
|
|
|
|
|
#define JS_DECLARE_NATIVE_GETTER(name) \
|
2020-09-27 16:36:49 +00:00
|
|
|
static JS::Value name(JS::VM&, JS::GlobalObject&)
|
2020-06-20 11:55:34 +00:00
|
|
|
|
|
|
|
#define JS_DECLARE_NATIVE_SETTER(name) \
|
2020-09-27 16:36:49 +00:00
|
|
|
static void name(JS::VM&, JS::GlobalObject&, JS::Value)
|
2020-06-20 11:55:34 +00:00
|
|
|
|
|
|
|
#define JS_DEFINE_NATIVE_FUNCTION(name) \
|
2020-09-27 16:36:49 +00:00
|
|
|
JS::Value name([[maybe_unused]] JS::VM& vm, [[maybe_unused]] JS::GlobalObject& global_object)
|
2020-06-20 11:55:34 +00:00
|
|
|
|
|
|
|
#define JS_DEFINE_NATIVE_GETTER(name) \
|
2020-09-27 16:36:49 +00:00
|
|
|
JS::Value name([[maybe_unused]] JS::VM& vm, [[maybe_unused]] JS::GlobalObject& global_object)
|
2020-06-20 11:55:34 +00:00
|
|
|
|
|
|
|
#define JS_DEFINE_NATIVE_SETTER(name) \
|
2020-12-20 23:09:48 +00:00
|
|
|
void name([[maybe_unused]] JS::VM& vm, [[maybe_unused]] JS::GlobalObject& global_object, [[maybe_unused]] JS::Value value)
|
2020-06-20 11:55:34 +00:00
|
|
|
|
2020-11-30 22:50:43 +00:00
|
|
|
// NOTE: Proxy is not included here as it doesn't have a prototype - m_proxy_constructor is initialized separately.
|
2020-12-02 20:49:31 +00:00
|
|
|
#define JS_ENUMERATE_NATIVE_OBJECTS_EXCLUDING_TEMPLATES \
|
|
|
|
__JS_ENUMERATE(Array, array, ArrayPrototype, ArrayConstructor, void) \
|
|
|
|
__JS_ENUMERATE(ArrayBuffer, array_buffer, ArrayBufferPrototype, ArrayBufferConstructor, void) \
|
|
|
|
__JS_ENUMERATE(BigIntObject, bigint, BigIntPrototype, BigIntConstructor, void) \
|
|
|
|
__JS_ENUMERATE(BooleanObject, boolean, BooleanPrototype, BooleanConstructor, void) \
|
|
|
|
__JS_ENUMERATE(Date, date, DatePrototype, DateConstructor, void) \
|
|
|
|
__JS_ENUMERATE(Error, error, ErrorPrototype, ErrorConstructor, void) \
|
|
|
|
__JS_ENUMERATE(Function, function, FunctionPrototype, FunctionConstructor, void) \
|
|
|
|
__JS_ENUMERATE(NumberObject, number, NumberPrototype, NumberConstructor, void) \
|
|
|
|
__JS_ENUMERATE(Object, object, ObjectPrototype, ObjectConstructor, void) \
|
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 20:13:29 +00:00
|
|
|
__JS_ENUMERATE(Promise, promise, PromisePrototype, PromiseConstructor, void) \
|
2020-12-02 20:49:31 +00:00
|
|
|
__JS_ENUMERATE(RegExpObject, regexp, RegExpPrototype, RegExpConstructor, void) \
|
2021-06-08 21:08:47 +00:00
|
|
|
__JS_ENUMERATE(Set, set, SetPrototype, SetConstructor, void) \
|
2020-12-02 20:49:31 +00:00
|
|
|
__JS_ENUMERATE(StringObject, string, StringPrototype, StringConstructor, void) \
|
2020-12-01 20:05:25 +00:00
|
|
|
__JS_ENUMERATE(SymbolObject, symbol, SymbolPrototype, SymbolConstructor, void)
|
|
|
|
|
2020-12-02 00:23:40 +00:00
|
|
|
#define JS_ENUMERATE_NATIVE_OBJECTS \
|
|
|
|
JS_ENUMERATE_NATIVE_OBJECTS_EXCLUDING_TEMPLATES \
|
|
|
|
__JS_ENUMERATE(TypedArray, typed_array, TypedArrayPrototype, TypedArrayConstructor, void)
|
|
|
|
|
2020-12-01 20:05:25 +00:00
|
|
|
#define JS_ENUMERATE_ERROR_SUBCLASSES \
|
|
|
|
__JS_ENUMERATE(EvalError, eval_error, EvalErrorPrototype, EvalErrorConstructor, void) \
|
|
|
|
__JS_ENUMERATE(InternalError, internal_error, InternalErrorPrototype, InternalErrorConstructor, void) \
|
|
|
|
__JS_ENUMERATE(InvalidCharacterError, invalid_character_error, InvalidCharacterErrorPrototype, InvalidCharacterErrorConstructor, void) \
|
|
|
|
__JS_ENUMERATE(RangeError, range_error, RangeErrorPrototype, RangeErrorConstructor, void) \
|
|
|
|
__JS_ENUMERATE(ReferenceError, reference_error, ReferenceErrorPrototype, ReferenceErrorConstructor, void) \
|
|
|
|
__JS_ENUMERATE(SyntaxError, syntax_error, SyntaxErrorPrototype, SyntaxErrorConstructor, void) \
|
|
|
|
__JS_ENUMERATE(TypeError, type_error, TypeErrorPrototype, TypeErrorConstructor, void) \
|
|
|
|
__JS_ENUMERATE(URIError, uri_error, URIErrorPrototype, URIErrorConstructor, void)
|
|
|
|
|
2021-05-22 19:03:26 +00:00
|
|
|
#define JS_ENUMERATE_TYPED_ARRAYS \
|
|
|
|
__JS_ENUMERATE(Uint8Array, uint8_array, Uint8ArrayPrototype, Uint8ArrayConstructor, u8) \
|
|
|
|
__JS_ENUMERATE(Uint8ClampedArray, uint8_clamped_array, Uint8ClampedArrayPrototype, Uint8ClampedArrayConstructor, ClampedU8) \
|
|
|
|
__JS_ENUMERATE(Uint16Array, uint16_array, Uint16ArrayPrototype, Uint16ArrayConstructor, u16) \
|
|
|
|
__JS_ENUMERATE(Uint32Array, uint32_array, Uint32ArrayPrototype, Uint32ArrayConstructor, u32) \
|
|
|
|
__JS_ENUMERATE(Int8Array, int8_array, Int8ArrayPrototype, Int8ArrayConstructor, i8) \
|
|
|
|
__JS_ENUMERATE(Int16Array, int16_array, Int16ArrayPrototype, Int16ArrayConstructor, i16) \
|
|
|
|
__JS_ENUMERATE(Int32Array, int32_array, Int32ArrayPrototype, Int32ArrayConstructor, i32) \
|
|
|
|
__JS_ENUMERATE(Float32Array, float32_array, Float32ArrayPrototype, Float32ArrayConstructor, float) \
|
2020-12-05 22:28:10 +00:00
|
|
|
__JS_ENUMERATE(Float64Array, float64_array, Float64ArrayPrototype, Float64ArrayConstructor, double)
|
2020-04-10 12:06:52 +00:00
|
|
|
|
2020-09-18 07:49:51 +00:00
|
|
|
#define JS_ENUMERATE_ITERATOR_PROTOTYPES \
|
|
|
|
__JS_ENUMERATE(Iterator, iterator) \
|
|
|
|
__JS_ENUMERATE(ArrayIterator, array_iterator) \
|
2021-06-08 21:17:17 +00:00
|
|
|
__JS_ENUMERATE(SetIterator, set_iterator) \
|
2020-07-12 03:23:01 +00:00
|
|
|
__JS_ENUMERATE(StringIterator, string_iterator)
|
2020-07-09 21:58:20 +00:00
|
|
|
|
2020-04-10 12:06:52 +00:00
|
|
|
#define JS_ENUMERATE_BUILTIN_TYPES \
|
|
|
|
JS_ENUMERATE_NATIVE_OBJECTS \
|
2020-12-01 20:05:25 +00:00
|
|
|
JS_ENUMERATE_ERROR_SUBCLASSES \
|
|
|
|
JS_ENUMERATE_TYPED_ARRAYS
|
2020-04-10 10:42:33 +00:00
|
|
|
|
2020-09-18 07:49:51 +00:00
|
|
|
#define JS_ENUMERATE_WELL_KNOWN_SYMBOLS \
|
|
|
|
__JS_ENUMERATE(iterator, iterator) \
|
|
|
|
__JS_ENUMERATE(asyncIterator, async_iterator) \
|
|
|
|
__JS_ENUMERATE(match, match) \
|
|
|
|
__JS_ENUMERATE(matchAll, match_all) \
|
|
|
|
__JS_ENUMERATE(replace, replace) \
|
|
|
|
__JS_ENUMERATE(search, search) \
|
|
|
|
__JS_ENUMERATE(split, split) \
|
|
|
|
__JS_ENUMERATE(hasInstance, has_instance) \
|
|
|
|
__JS_ENUMERATE(isConcatSpreadable, is_concat_spreadable) \
|
|
|
|
__JS_ENUMERATE(unscopables, unscopables) \
|
|
|
|
__JS_ENUMERATE(species, species) \
|
|
|
|
__JS_ENUMERATE(toPrimitive, to_primitive) \
|
2020-07-09 22:34:20 +00:00
|
|
|
__JS_ENUMERATE(toStringTag, to_string_tag)
|
|
|
|
|
2020-11-27 23:04:01 +00:00
|
|
|
#define JS_ENUMERATE_REGEXP_FLAGS \
|
|
|
|
__JS_ENUMERATE(global, global, g, Global) \
|
|
|
|
__JS_ENUMERATE(ignoreCase, ignore_case, i, Insensitive) \
|
|
|
|
__JS_ENUMERATE(multiline, multiline, m, Multiline) \
|
|
|
|
__JS_ENUMERATE(dotAll, dot_all, s, SingleLine) \
|
|
|
|
__JS_ENUMERATE(unicode, unicode, u, Unicode) \
|
|
|
|
__JS_ENUMERATE(sticky, sticky, y, Sticky)
|
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
namespace JS {
|
|
|
|
|
|
|
|
class ASTNode;
|
2021-05-27 17:03:41 +00:00
|
|
|
class CellAllocator;
|
2020-06-06 00:14:10 +00:00
|
|
|
class BigInt;
|
2020-04-19 20:03:02 +00:00
|
|
|
class BoundFunction;
|
2020-03-08 18:23:58 +00:00
|
|
|
class Cell;
|
2020-09-29 19:15:06 +00:00
|
|
|
class Console;
|
2020-04-19 09:30:47 +00:00
|
|
|
class DeferGC;
|
2020-03-24 13:37:39 +00:00
|
|
|
class Error;
|
2020-03-24 21:03:50 +00:00
|
|
|
class Exception;
|
2020-03-11 18:27:43 +00:00
|
|
|
class Expression;
|
2020-05-21 18:14:23 +00:00
|
|
|
class Accessor;
|
2020-04-01 19:04:42 +00:00
|
|
|
class GlobalObject;
|
2020-03-18 19:03:17 +00:00
|
|
|
class HandleImpl;
|
2020-03-08 18:23:58 +00:00
|
|
|
class Heap;
|
|
|
|
class HeapBlock;
|
2020-03-07 18:42:11 +00:00
|
|
|
class Interpreter;
|
2020-04-15 19:58:22 +00:00
|
|
|
class LexicalEnvironment;
|
2020-04-19 15:24:56 +00:00
|
|
|
class MarkedValueList;
|
2021-01-18 07:33:41 +00:00
|
|
|
class NativeFunction;
|
2020-06-23 15:56:57 +00:00
|
|
|
class NativeProperty;
|
2020-03-11 17:55:01 +00:00
|
|
|
class PrimitiveString;
|
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 20:13:29 +00:00
|
|
|
class PromiseReaction;
|
|
|
|
class PromiseReactionJob;
|
|
|
|
class PromiseResolveThenableJob;
|
2021-03-02 17:04:13 +00:00
|
|
|
class PropertyName;
|
2020-04-27 10:10:16 +00:00
|
|
|
class Reference;
|
2020-03-07 18:42:11 +00:00
|
|
|
class ScopeNode;
|
2020-11-28 15:02:27 +00:00
|
|
|
class ScopeObject;
|
2020-04-02 17:32:21 +00:00
|
|
|
class Shape;
|
2020-03-23 15:46:41 +00:00
|
|
|
class Statement;
|
2021-06-05 12:22:11 +00:00
|
|
|
class StringOrSymbol;
|
2020-04-30 06:25:21 +00:00
|
|
|
class Symbol;
|
2020-05-25 19:24:46 +00:00
|
|
|
class Token;
|
2020-09-20 17:24:44 +00:00
|
|
|
class VM;
|
2020-03-07 18:42:11 +00:00
|
|
|
class Value;
|
2020-04-08 09:59:18 +00:00
|
|
|
enum class DeclarationKind;
|
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 20:13:29 +00:00
|
|
|
struct AlreadyResolved;
|
|
|
|
struct JobCallback;
|
|
|
|
struct PromiseCapability;
|
2020-03-07 18:42:11 +00:00
|
|
|
|
2020-11-30 22:50:43 +00:00
|
|
|
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype
|
|
|
|
class ProxyObject;
|
|
|
|
class ProxyConstructor;
|
|
|
|
|
2020-12-02 00:23:40 +00:00
|
|
|
class TypedArrayConstructor;
|
|
|
|
class TypedArrayPrototype;
|
|
|
|
|
2021-05-22 19:03:26 +00:00
|
|
|
// Tag type used to differentiate between u8 as used by Uint8Array and u8 as used by Uint8ClampedArray.
|
|
|
|
struct ClampedU8;
|
|
|
|
|
2020-12-01 20:05:25 +00:00
|
|
|
#define __JS_ENUMERATE(ClassName, snake_name, ConstructorName, PrototypeName, ArrayType) \
|
|
|
|
class ClassName; \
|
|
|
|
class ConstructorName; \
|
2020-04-10 12:06:52 +00:00
|
|
|
class PrototypeName;
|
2020-12-02 00:23:40 +00:00
|
|
|
JS_ENUMERATE_NATIVE_OBJECTS_EXCLUDING_TEMPLATES
|
|
|
|
JS_ENUMERATE_ERROR_SUBCLASSES
|
|
|
|
JS_ENUMERATE_TYPED_ARRAYS
|
2020-04-10 12:06:52 +00:00
|
|
|
#undef __JS_ENUMERATE
|
2020-04-10 10:42:33 +00:00
|
|
|
|
2020-03-18 19:03:17 +00:00
|
|
|
template<class T>
|
|
|
|
class Handle;
|
|
|
|
|
2021-06-03 08:46:30 +00:00
|
|
|
namespace Bytecode {
|
2021-06-09 02:19:58 +00:00
|
|
|
class BasicBlock;
|
2021-06-09 08:02:01 +00:00
|
|
|
struct Executable;
|
2021-06-03 08:46:30 +00:00
|
|
|
class Generator;
|
|
|
|
class Instruction;
|
|
|
|
class Interpreter;
|
|
|
|
class Register;
|
|
|
|
}
|
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
}
|