porffor 0.25.2 → 0.25.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRIBUTING.md CHANGED
@@ -23,7 +23,6 @@ The repo comes with easy alias scripts for Unix and Windows, which you can use l
23
23
 
24
24
  You can also swap out `node` in the alias to use another runtime like Deno (`deno run -A ...`) or Bun (`bun ...`), or just use it yourself (eg `node runner/index.js ...`, `bun runner/index.js ...`). Node, Deno, Bun should work.
25
25
 
26
-
27
26
  ### Precompile
28
27
 
29
28
  **If you update any file inside `compiler/builtins` you will need to do this for it to update inside Porffor otherwise your changes will have no effect.** Run `./porf precompile` to precompile. It may error during this, if so, you might have an error in your code or there could be a compiler error with Porffor (feel free to ask for help as soon as you encounter any errors with it).
@@ -98,7 +97,7 @@ Loads the character code at the pointer `pointer` **for a String**.[^1]
98
97
  Porffor.wasm.i32.store(pointer, length, 0, 0)
99
98
  ```
100
99
 
101
- Stores the length `length` at pointer `pointer`, setting the length of an object. This is mostly unneeded today as you can just do `obj.length = length`. (The `0, 4` args are necessary for the Wasm instruction, but you don't need to worry about them (`0` alignment, `0` byte offset).
100
+ Stores the length `length` at pointer `pointer`, setting the length of an object. This is mostly unneeded today as you can just do `obj.length = length`. [^1]
102
101
 
103
102
  <br>
104
103
 
@@ -209,6 +208,141 @@ Store the character code into the `out` pointer variable, and increment it.
209
208
 
210
209
  <br>
211
210
 
211
+ ### Porffor.wasm
212
+ This is a macro that is essentially equivalent to C's `asm` macro. It allows you to write inline Wasm bytecode in a similar format to [WAT](https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format).
213
+
214
+ Let's look at an example to better illustrate how the format works.
215
+
216
+ ```ts
217
+ export const add_i32 = (a: any, b: any) => {
218
+ Porffor.wasm`
219
+ local aCasted i32
220
+ local bCasted i32
221
+ returns i32 i32
222
+
223
+ ;; if both types are number
224
+ local.get ${a+1}
225
+ i32.const 1
226
+ i32.eq
227
+ local.get ${b+1}
228
+ i32.const 1
229
+ i32.eq
230
+ i32.and
231
+ if
232
+ local.get ${a}
233
+ i32.from
234
+ local.set aCasted
235
+
236
+ local.get ${b}
237
+ i32.from
238
+ local.set bCasted
239
+
240
+ local.get aCasted
241
+ local.get bCasted
242
+ i32.add
243
+ i32.const 1
244
+ return
245
+ end
246
+
247
+ ;; return (0, 0) otherwise
248
+ i32.const 0
249
+ i32.const 0
250
+ return`;
251
+ }
252
+ ```
253
+
254
+ ---
255
+
256
+ ```
257
+ local aCasted i32
258
+ local bCasted i32
259
+ ```
260
+
261
+ Here we define two locals, which you can think of as typed variables. Here both of them have the type of `i32`, which was explained above. This type can also be `f64` or `i64`, which are doubles and 64-bit integers respectively.
262
+
263
+ ---
264
+
265
+ ```
266
+ returns i32 i32
267
+ ```
268
+
269
+ This sets the return type of the function, what the stack must look like before a `return` instruction. Normally Porffor functions have the return type `(f64, i32)`, which represents the valtype (usually f64) and an i32 type.
270
+
271
+ > [!WARNING]
272
+ > This is something you have to be incredibly careful with, as Porffor expects most functions to return `(valtype, i32)`. Be incredibly careful when using this.
273
+
274
+ ---
275
+
276
+ ```
277
+ ;; if both types are number
278
+ ```
279
+
280
+ This is a comment. `;;` is Wasm's `//`.
281
+
282
+ ---
283
+
284
+ ```
285
+ local.get ${a+1}
286
+ i32.const 1
287
+ i32.eq
288
+ local.get ${b+1}
289
+ i32.const 1
290
+ i32.eq
291
+ i32.and
292
+ ```
293
+
294
+ This part is a little more complicated, first you have to understand how Wasm represents function parameters and local variables in general. When looking at the decompiled output of something like `let a = 1;`, you'll likely see something like this:
295
+ ```
296
+ f64.const 1
297
+ i32.const 1
298
+ local.set 1 ;; a#type (i32)
299
+ local.set 0 ;; a
300
+ ```
301
+ Here the `i32.const 1` is equivalent to `TYPES.number`, which aligns with what we told Porffor to do, but what's up with the `local.set`s to a number? Well, internally locals are represented with indexes, and in this example `a` was assigned 0, and `a#type` was assigned 1.
302
+
303
+ That's where `local.get ${a+1}` comes from, it's Porffor's way of saying "get the local variable at index of `a` plus one". In most cases, this is the variable's type. The rest of the snippet is just checking if both of the parameters' types are equal to `TYPES.number`.
304
+
305
+ ---
306
+
307
+ ```
308
+ if
309
+ local.get ${a}
310
+ i32.from
311
+ local.set aCasted
312
+
313
+ local.get ${b}
314
+ i32.from
315
+ local.set bCasted
316
+ ```
317
+
318
+ Here we start an if block, equivalent to JS's `if (...) {}`, and as the locals' names imply, cast them to `i32`s. There is one strange thing about this section though, if you look at Wasm's list of instructions you won't find a `i32.from`. This is because Porffor has custom instructions for converting to and from the valtype. In this case, converting the valtype into an `i32`. There are a few more of these instructions, but in general these instructions come in the format of `type.from` (create `type` from valtype) and `type.to` (create valtype from `type`). You can find a full list at the bottom of `codegen.js`.
319
+
320
+ ---
321
+
322
+ ```
323
+ local.get aCasted
324
+ local.get bCasted
325
+ i32.add
326
+ i32.const 1
327
+ return
328
+ end
329
+ ```
330
+
331
+ Here, we get our two casted locals and add them together, returning the result and a `i32` with the value of 1. We then end the if block with the `end` instruction.
332
+
333
+ ---
334
+
335
+ ```
336
+ ;; return (0, 0) otherwise
337
+ i32.const 0
338
+ i32.const 0
339
+ return
340
+ ```
341
+
342
+ Finally, we return `(0, 0)` if either type is not a number. This example was very contrived, but should give you a good sense of how to use `Porffor.wasm`.
343
+
344
+ <br>
345
+
212
346
  ## Formatting/linting
213
347
 
214
348
  There is 0 setup for this (right now). You can try looking through the other built-ins files but do not worry about it a lot, I honestly do not mind going through and cleaning up after a PR as long as the code itself is good :^)
@@ -258,4 +392,9 @@ It will also log new passes/fails. Be careful as sometimes the overall passes ca
258
392
 
259
393
  <br>
260
394
 
261
- [^1]: The `0, 4` args are necessary for the Wasm instruction, but you don't need to worry about them (`0` alignment, `4` byte offset for length).
395
+ ### Resources
396
+
397
+ - [MDN](https://developer.mozilla.org/en-US/), not only a great resource for learning JS, but also for implementing it, as it has high level descriptions of functionality, as well as links to the relevant portions of the spec that govern the feature.
398
+ - [WebAssembly Opcodes](https://pengowray.github.io/wasm-ops/), this website not only describes what each wasm instruction does but the necessary stack needed, and contains some other useful resources as well.
399
+
400
+ [^1]: The last two args are necessary for the Wasm instruction, but you don't need to worry about them (the first is alignment, the second is byte offset).
package/README.md CHANGED
@@ -68,8 +68,8 @@ Expect nothing to work! Only very limited JS is currently supported. See files i
68
68
  - `-O3` to enable advanceder opt (precompute const math). unstable!
69
69
 
70
70
  ## Limitations
71
- - No full object support yet
72
71
  - Little built-ins/prototype
72
+ - No object prototypes yet
73
73
  - No async/promise/await
74
74
  - No variables between scopes (except args and globals)
75
75
  - No `eval()` etc (since it is AOT)
@@ -103,7 +103,7 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
103
103
  - Declaring functions
104
104
  - Calling functions
105
105
  - `return`
106
- - `let`/`const`/`var` basic declarations
106
+ - Basic declarations (`let`/`const`/`var`)
107
107
  - Some basic integer operators (`+-/*%`)
108
108
  - Some basic integer bitwise operators (`&|`)
109
109
  - Equality operators (`==`, `!=`, etc)
@@ -111,18 +111,18 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
111
111
  - Some unary operators (`!`, `+`, `-`)
112
112
  - Logical operators (`&&`, `||`)
113
113
  - Declaring multiple variables in one (`let a, b = 0`)
114
+ - Array destructuring (`let [a, ...b] = foo`)
114
115
  - Global variables (`var`/none in top scope)
115
- - Functions returning 1 number
116
- - Bool literals as ints (not real type)
116
+ - Booleans
117
117
  - `if` and `if ... else`
118
118
  - Anonymous functions
119
119
  - Setting functions using vars (`const foo = function() { ... }`)
120
120
  - Arrow functions
121
- - `undefined`/`null` as ints (hack)
121
+ - `undefined`/`null`
122
122
  - Update expressions (`a++`, `++b`, `c--`, etc)
123
123
  - `for` loops (`for (let i = 0; i < N; i++)`, etc)
124
- - *Basic* objects (hack)
125
- - `console.log` (hack)
124
+ - Basic objects (no prototypes)
125
+ - `console.log`
126
126
  - `while` loops
127
127
  - `break` and `continue`
128
128
  - Named export funcs
@@ -131,7 +131,7 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
131
131
  - Conditional/ternary operator (`cond ? a : b`)
132
132
  - Recursive functions
133
133
  - Bare returns (`return`)
134
- - `throw` (literals only)
134
+ - `throw` (literals only, hack for `new Error`)
135
135
  - Basic `try { ... } catch { ... }` (no error given)
136
136
  - Calling functions with non-matching arguments (eg `f(a, b); f(0); f(1, 2, 3);`)
137
137
  - `typeof`
@@ -145,11 +145,15 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
145
145
  - String comparison (eg `'a' == 'a'`, `'a' != 'b'`)
146
146
  - Nullish coalescing operator (`??`)
147
147
  - `for...of` (arrays and strings)
148
+ - `for...in`
148
149
  - Array member setting (`arr[0] = 2`, `arr[0] += 2`, etc)
149
150
  - Array constructor (`Array(5)`, `new Array(1, 2, 3)`)
150
151
  - Labelled statements (`foo: while (...)`)
151
152
  - `do...while` loops
152
153
  - Optional parameters (`(foo = 'bar') => { ... }`)
154
+ - Rest parameters (`(...foo) => { ... }`)
155
+ - `this`
156
+ - Constructors (`new Foo`)
153
157
 
154
158
  ### Built-ins
155
159
 
@@ -223,16 +227,27 @@ Porffor can run Test262 via some hacks/transforms which remove unsupported featu
223
227
 
224
228
  ## Codebase
225
229
  - `compiler`: contains the compiler itself
226
- - `builtins.js`: all built-ins of the engine (spec, custom. vars, funcs)
230
+ - `2c.js`: porffor's custom wasm-to-c engine
231
+ - `allocators.js`: static and dynamic allocators to power various language features
232
+ - `assemble.js`: assembles wasm ops and metadata into a wasm module/file
233
+ - `builtins.js`: all manually written built-ins of the engine (spec, custom. vars, funcs)
234
+ - `builtins_object.js`: all the various built-in objects (think `String`, `globalThis`, etc.)
235
+ - `builtins_precompiled.js`: dynamically generated builtins from the `builtins/` folder
227
236
  - `codegen.js`: code (wasm) generation, ast -> wasm. The bulk of the effort
237
+ - `cyclone.js`: wasm partial constant evaluator (it is fast and dangerous hence "cyclone")
228
238
  - `decompile.js`: basic wasm decompiler for debug info
229
239
  - `embedding.js`: utils for embedding consts
230
240
  - `encoding.js`: utils for encoding things as bytes as wasm expects
231
241
  - `expression.js`: mapping most operators to an opcode (advanced are as built-ins eg `f64_%`)
242
+ - `havoc.js`: wasm rewrite library (it wreaks havoc upon wasm bytecode hence "havoc")
232
243
  - `index.js`: doing all the compiler steps, takes code in, wasm out
233
244
  - `opt.js`: self-made wasm bytecode optimizer
234
245
  - `parse.js`: parser simply wrapping acorn
235
- - `assemble.js`: assembles wasm ops and metadata into a wasm module/file
246
+ - `pgo.js`: a profile guided optimizer
247
+ - `precompile.js`: the tool to generate `builtins_precompied.js`
248
+ - `prefs.js`: a utility to read command line arguments
249
+ - `prototype.js`: some builtin prototype functions
250
+ - `types.js`: definitions for each of the builtin types
236
251
  - `wasmSpec.js`: "enums"/info from wasm spec
237
252
  - `wrap.js`: wrapper for compiler which instantiates and produces nice exports
238
253
 
@@ -249,16 +264,16 @@ Porffor can run Test262 via some hacks/transforms which remove unsupported featu
249
264
  - `test262`: test262 runner and utils
250
265
 
251
266
  ## Usecases
252
- Basically none right now (other than giving people headaches). Potential ideas:
267
+ Currently, Porffor is seriously limited in features and functionality, however it has some key benefits:
253
268
  - Safety. As Porffor is written in JS, a memory-safe language\*, and compiles JS to Wasm, a fully sandboxed environment\*, it is quite safe. (\* These rely on the underlying implementations being secure. You could also run Wasm, or even Porffor itself, with an interpreter instead of a JIT for bonus security points too.)
254
269
  - Compiling JS to native binaries. This is still very early!
270
+ - Inline Wasm for when you want to beat the compiler in performance, or just want fine grained functionality.
271
+ - Potential for SIMD operations and other lower level concepts.
255
272
  - More in future probably?
256
273
 
257
274
  ## Todo
258
275
  No particular order and no guarentees, just what could happen soon™
259
276
 
260
- - Objects
261
- - Basic object expressions (eg `{}`, `{ a: 0 }`)
262
277
  - Asur
263
278
  - Support memory
264
279
  - Support exceptions
@@ -272,8 +287,6 @@ No particular order and no guarentees, just what could happen soon™
272
287
  - Runtime
273
288
  - WASI target
274
289
  - Run precompiled Wasm file if given
275
- - Docs
276
- - Update codebase readme section
277
290
  - Cool proposals
278
291
  - [Optional Chaining Assignment](https://github.com/tc39/proposal-optional-chaining-assignment)
279
292
  - [Modulus and Additional Integer Math](https://github.com/tc39/proposal-integer-and-modulus-math)
@@ -303,7 +316,6 @@ Porffor intentionally does not use Wasm proposals which are not commonly impleme
303
316
  - Exception handling (optional, only for errors)
304
317
  - Tail calls (opt-in, off by default)
305
318
 
306
-
307
319
  ## FAQ
308
320
 
309
321
  ### 1. Why the name?
@@ -0,0 +1,247 @@
1
+ import type {} from './porffor.d.ts';
2
+
3
+ export const __ecma262_NewPromiseReactionJob = (reaction: any[], argument: any): any[] => {
4
+ const job: any[] = Porffor.allocateBytes(22); // 2 length
5
+ job[0] = reaction;
6
+ job[1] = argument;
7
+
8
+ return job;
9
+ };
10
+
11
+ const jobQueue: any[] = new Array(0);
12
+ export const __ecma262_HostEnqueuePromiseJob = (job: any[]): void => {
13
+ Porffor.fastPush(jobQueue, job);
14
+ };
15
+
16
+ // 27.2.1.8 TriggerPromiseReactions (reactions, argument)
17
+ // https://tc39.es/ecma262/#sec-triggerpromisereactions
18
+ export const __ecma262_TriggerPromiseReactions = (reactions: any[], argument: any): void => {
19
+ // 1. For each element reaction of reactions, do
20
+ for (const reaction of reactions) {
21
+ // a. Let job be NewPromiseReactionJob(reaction, argument).
22
+ // b. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
23
+ __ecma262_HostEnqueuePromiseJob(__ecma262_NewPromiseReactionJob(reaction, argument));
24
+ }
25
+
26
+ // 2. Return unused.
27
+ };
28
+
29
+
30
+ // 27.2.1.6 IsPromise (x)
31
+ // https://tc39.es/ecma262/#sec-ispromise
32
+ export const __ecma262_IsPromise = (x: any): boolean => {
33
+ // custom impl
34
+ return Porffor.rawType(x) == Porffor.TYPES.promise;
35
+ };
36
+
37
+ // 27.2.1.4 FulfillPromise (promise, value)
38
+ // https://tc39.es/ecma262/#sec-fulfillpromise
39
+ export const __ecma262_FulfillPromise = (promise: any[], value: any): void => {
40
+ // 1. Assert: The value of promise.[[PromiseState]] is pending.
41
+ // todo
42
+
43
+ // 2. Let reactions be promise.[[PromiseFulfillReactions]].
44
+ const reactions: any[] = promise[2]; // fulfillReactions
45
+
46
+ // 3. Set promise.[[PromiseResult]] to value.
47
+ promise[0] = value;
48
+
49
+ // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
50
+ promise[2] = undefined;
51
+
52
+ // 5. Set promise.[[PromiseRejectReactions]] to undefined.
53
+ promise[3] = undefined;
54
+
55
+ // 6. Set promise.[[PromiseState]] to fulfilled.
56
+ promise[1] = 1;
57
+
58
+ // 7. Perform TriggerPromiseReactions(reactions, value).
59
+ __ecma262_TriggerPromiseReactions(reactions, value);
60
+
61
+ // 8. Return unused.
62
+ };
63
+
64
+ // 27.2.1.7 RejectPromise (promise, reason)
65
+ // https://tc39.es/ecma262/#sec-rejectpromise
66
+ export const __ecma262_RejectPromise = (promise: any[], reason: any): void => {
67
+ // 1. Assert: The value of promise.[[PromiseState]] is pending.
68
+ // todo
69
+
70
+ // 2. Let reactions be promise.[[PromiseRejectReactions]].
71
+ const reactions: any[] = promise[3]; // rejectReactions
72
+
73
+ // 3. Set promise.[[PromiseResult]] to reason.
74
+ promise[0] = reason;
75
+
76
+ // 4. Set promise.[[PromiseFulfillReactions]] to undefined.
77
+ promise[2] = undefined;
78
+
79
+ // 5. Set promise.[[PromiseRejectReactions]] to undefined.
80
+ promise[3] = undefined;
81
+
82
+ // 6. Set promise.[[PromiseState]] to rejected.
83
+ promise[1] = 2;
84
+
85
+ // 7. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "reject").
86
+ // unimplemented
87
+
88
+ // 8. Perform TriggerPromiseReactions(reactions, reason).
89
+ __ecma262_TriggerPromiseReactions(reactions, reason);
90
+
91
+ // 9. Return unused.
92
+ };
93
+
94
+
95
+ export const __Porffor_promise_noop = () => {};
96
+
97
+ let activePromise: any;
98
+ export const __Porffor_promise_resolve = (value: any): any => {
99
+ // todo: if value is own promise, reject with typeerror
100
+
101
+ if (__ecma262_IsPromise(value)) {
102
+ printStatic('todo res');
103
+ // todo
104
+ } else {
105
+ __ecma262_FulfillPromise(activePromise, value);
106
+ }
107
+
108
+ return undefined;
109
+ };
110
+
111
+ export const __Porffor_promise_reject = (reason: any): any => {
112
+ if (__ecma262_IsPromise(reason)) {
113
+ printStatic('todo rej');
114
+ // todo
115
+ } else {
116
+ __ecma262_RejectPromise(activePromise, reason);
117
+ }
118
+
119
+ return undefined;
120
+ };
121
+
122
+ export const __Porffor_promise_create = (): any[] => {
123
+ // Promise [ result, state, fulfillReactions, rejectReactions ]
124
+ const obj: any[] = Porffor.allocateBytes(40); // 4 length
125
+
126
+ // result = undefined
127
+ obj[0] = undefined;
128
+
129
+ // enum PromiseState { pending = 0, fulfilled = 1, rejected = 2 }
130
+ // state = .pending
131
+ obj[1] = 0;
132
+
133
+ // fulfillReactions = []
134
+ const fulfillReactions: any[] = Porffor.allocateBytes(256); // max length: 28
135
+ obj[2] = fulfillReactions;
136
+
137
+ // rejectReactions = []
138
+ const rejectReactions: any[] = Porffor.allocateBytes(256); // max length: 28
139
+ obj[3] = rejectReactions;
140
+
141
+ return obj;
142
+ };
143
+
144
+ export const __Porffor_promise_runJobs = () => {
145
+ while (true) {
146
+ let x: any = jobQueue.shift();
147
+ if (x == null) break;
148
+
149
+ const reaction: any[] = x[0];
150
+ const handler: Function = reaction[0];
151
+ const outPromise: any[] = reaction[1];
152
+
153
+ const value: any = x[1];
154
+
155
+ // todo: handle thrown errors in handler?
156
+ const outValue: any = handler(value);
157
+
158
+ // todo: should this be resolve or fulfill?
159
+ __ecma262_FulfillPromise(outPromise, outValue);
160
+ }
161
+ };
162
+
163
+
164
+ export const Promise = function (executor: any): Promise {
165
+ if (!new.target) throw new TypeError("Constructor Promise requires 'new'");
166
+ if (Porffor.rawType(executor) != Porffor.TYPES.function) throw new TypeError('Promise executor is not a function');
167
+
168
+ const obj: any[] = __Porffor_promise_create();
169
+
170
+ activePromise = obj;
171
+ executor(__Porffor_promise_resolve, __Porffor_promise_reject);
172
+
173
+ const pro: Promise = obj;
174
+ return pro;
175
+ };
176
+
177
+
178
+ export const __Promise_prototype_then = (_this: any, onFulfilled: any, onRejected: any) => {
179
+ // 27.2.5.4 Promise.prototype.then (onFulfilled, onRejected)
180
+ // https://tc39.es/ecma262/#sec-promise.prototype.then
181
+
182
+ // 1. Let promise be the this value.
183
+ // 2. If IsPromise(promise) is false, throw a TypeError exception.
184
+ if (!__ecma262_IsPromise(_this)) throw new TypeError('Promise.prototype.then called on non-Promise');
185
+
186
+ // 27.2.5.4.1 PerformPromiseThen (promise, onFulfilled, onRejected [, resultCapability])
187
+ // https://tc39.es/ecma262/#sec-performpromisethen
188
+
189
+ if (Porffor.rawType(onFulfilled) != Porffor.TYPES.function) onFulfilled = __Porffor_promise_noop;
190
+ if (Porffor.rawType(onRejected) != Porffor.TYPES.function) onRejected = __Porffor_promise_noop;
191
+
192
+ const promise: any[] = _this;
193
+ const state: i32 = promise[1];
194
+
195
+ const outPromise: any[] = __Porffor_promise_create();
196
+
197
+ const fulfillReaction: any[] = Porffor.allocateBytes(22); // 2 length
198
+ fulfillReaction[0] = onFulfilled;
199
+ fulfillReaction[1] = outPromise;
200
+
201
+ const rejectReaction: any[] = Porffor.allocateBytes(22); // 2 length
202
+ rejectReaction[0] = onRejected;
203
+ rejectReaction[1] = outPromise;
204
+
205
+ // 9. If promise.[[PromiseState]] is pending, then
206
+ if (state == 0) { // pending
207
+ // a. Append fulfillReaction to promise.[[PromiseFulfillReactions]].
208
+ const fulfillReactions: any[] = promise[2];
209
+ Porffor.fastPush(fulfillReactions, fulfillReaction);
210
+
211
+ // b. Append rejectReaction to promise.[[PromiseRejectReactions]].
212
+ const rejectReactions: any[] = promise[3];
213
+ Porffor.fastPush(rejectReactions, rejectReaction);
214
+ } else if (state == 1) { // fulfilled
215
+ // 10. Else if promise.[[PromiseState]] is fulfilled, then
216
+ // a. Let value be promise.[[PromiseResult]].
217
+ const value: any = promise[0];
218
+
219
+ // b. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
220
+ // c. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
221
+ __ecma262_HostEnqueuePromiseJob(__ecma262_NewPromiseReactionJob(fulfillReaction, value));
222
+ } else { // rejected
223
+ // 11. Else,
224
+ // a. Assert: The value of promise.[[PromiseState]] is rejected.
225
+ // todo
226
+
227
+ // b. Let reason be promise.[[PromiseResult]].
228
+ const reason: any = promise[0];
229
+
230
+ // c. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "handle").
231
+ // unimplemented
232
+
233
+ // d. Let rejectJob be NewPromiseReactionJob(rejectReaction, reason).
234
+ // e. Perform HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]]).
235
+ __ecma262_HostEnqueuePromiseJob(__ecma262_NewPromiseReactionJob(rejectReaction, reason));
236
+ }
237
+
238
+ const pro: Promise = outPromise;
239
+ return pro;
240
+ };
241
+
242
+ export const __Promise_prototype_toString = (_this: any) => {
243
+ const str: bytestring = '[object Promise]';
244
+ return str;
245
+ };
246
+
247
+ export const __Promise_prototype_toLocaleString = (_this: any) => __Promise_prototype_toString(_this);