porffor 0.48.1 → 0.48.3
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/README.md +1 -1
- package/compiler/builtins/promise.ts +72 -65
- package/compiler/builtins_precompiled.js +89 -80
- package/compiler/codegen.js +5 -1
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/README.md
CHANGED
@@ -85,7 +85,7 @@ Rhemyn is Porffor's own regex engine; it compiles literal regex to Wasm bytecode
|
|
85
85
|
## Versioning
|
86
86
|
Porffor uses a unique versioning system, here's an example: `0.18.2+2aa3f0589`. Let's break it down:
|
87
87
|
1. `0` - major, always `0` as Porffor is not ready yet
|
88
|
-
2. `18` - minor, total Test262 pass percentage (
|
88
|
+
2. `18` - minor, total Test262 pass percentage (rounded half down, eg `49.4%` -> `48`, `49.5%` -> `49`)
|
89
89
|
3. `2` - micro, build number for that minor (incremented each publish/git push)
|
90
90
|
4. `2aa3f0589` - commit hash
|
91
91
|
|
@@ -92,13 +92,67 @@ export const __ecma262_RejectPromise = (promise: any[], reason: any): void => {
|
|
92
92
|
};
|
93
93
|
|
94
94
|
|
95
|
-
export const __Porffor_promise_noop = () =>
|
95
|
+
export const __Porffor_promise_noop = (x: any): any => x;
|
96
|
+
|
97
|
+
export const __Porffor_promise_newReaction = (handler: Function, promise: any, flags: i32): any[] => {
|
98
|
+
// enum ReactionType { then = 0, finally = 1 }
|
99
|
+
const out: any[] = Porffor.allocateBytes(32);
|
100
|
+
out[0] = handler;
|
101
|
+
out[1] = promise;
|
102
|
+
out[2] = flags;
|
103
|
+
|
104
|
+
return out;
|
105
|
+
};
|
106
|
+
|
107
|
+
export const __Porffor_then = (promise: any[], fulfillReaction: any[], rejectReaction: any[]): void => {
|
108
|
+
const state: i32 = promise[1];
|
109
|
+
|
110
|
+
// 27.2.5.4.1 PerformPromiseThen (promise, onFulfilled, onRejected [, resultCapability])
|
111
|
+
// https://tc39.es/ecma262/#sec-performpromisethen
|
112
|
+
|
113
|
+
// 9. If promise.[[PromiseState]] is pending, then
|
114
|
+
if (state == 0) { // pending
|
115
|
+
// a. Append fulfillReaction to promise.[[PromiseFulfillReactions]].
|
116
|
+
const fulfillReactions: any[] = promise[2];
|
117
|
+
Porffor.array.fastPush(fulfillReactions, fulfillReaction);
|
118
|
+
|
119
|
+
// b. Append rejectReaction to promise.[[PromiseRejectReactions]].
|
120
|
+
const rejectReactions: any[] = promise[3];
|
121
|
+
Porffor.array.fastPush(rejectReactions, rejectReaction);
|
122
|
+
} else if (state == 1) { // fulfilled
|
123
|
+
// 10. Else if promise.[[PromiseState]] is fulfilled, then
|
124
|
+
// a. Let value be promise.[[PromiseResult]].
|
125
|
+
const value: any = promise[0];
|
126
|
+
|
127
|
+
// b. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
|
128
|
+
// c. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
|
129
|
+
__ecma262_HostEnqueuePromiseJob(__ecma262_NewPromiseReactionJob(fulfillReaction, value));
|
130
|
+
} else { // rejected
|
131
|
+
// 11. Else,
|
132
|
+
// a. Assert: The value of promise.[[PromiseState]] is rejected.
|
133
|
+
// todo
|
134
|
+
|
135
|
+
// b. Let reason be promise.[[PromiseResult]].
|
136
|
+
const reason: any = promise[0];
|
137
|
+
|
138
|
+
// c. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "handle").
|
139
|
+
// unimplemented
|
140
|
+
|
141
|
+
// d. Let rejectJob be NewPromiseReactionJob(rejectReaction, reason).
|
142
|
+
// e. Perform HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]]).
|
143
|
+
__ecma262_HostEnqueuePromiseJob(__ecma262_NewPromiseReactionJob(rejectReaction, reason));
|
144
|
+
}
|
145
|
+
};
|
96
146
|
|
97
147
|
export const __Porffor_promise_resolve = (value: any, promise: any): any => {
|
98
|
-
//
|
148
|
+
// if value is own promise, reject with typeerror
|
149
|
+
if (value === promise) throw new TypeError('cannot resolve promise with itself');
|
99
150
|
|
100
151
|
if (__ecma262_IsPromise(value)) {
|
101
|
-
|
152
|
+
const fulfillReaction: any[] = __Porffor_promise_newReaction(__Porffor_promise_noop, promise, 0);
|
153
|
+
const rejectReaction: any[] = __Porffor_promise_newReaction(__Porffor_promise_noop, promise, 2);
|
154
|
+
|
155
|
+
__Porffor_then(value, fulfillReaction, rejectReaction);
|
102
156
|
} else {
|
103
157
|
__ecma262_FulfillPromise(promise, value);
|
104
158
|
}
|
@@ -107,12 +161,7 @@ export const __Porffor_promise_resolve = (value: any, promise: any): any => {
|
|
107
161
|
};
|
108
162
|
|
109
163
|
export const __Porffor_promise_reject = (reason: any, promise: any): any => {
|
110
|
-
|
111
|
-
// todo
|
112
|
-
} else {
|
113
|
-
__ecma262_RejectPromise(promise, reason);
|
114
|
-
}
|
115
|
-
|
164
|
+
__ecma262_RejectPromise(promise, reason);
|
116
165
|
return undefined;
|
117
166
|
};
|
118
167
|
|
@@ -138,18 +187,8 @@ export const __Porffor_promise_create = (): any[] => {
|
|
138
187
|
return obj;
|
139
188
|
};
|
140
189
|
|
141
|
-
export const __Porffor_promise_newReaction = (handler: Function, promise: any, type: i32): any[] => {
|
142
|
-
// enum ReactionType { then = 0, finally = 1 }
|
143
|
-
const out: any[] = Porffor.allocateBytes(32);
|
144
|
-
out[0] = handler;
|
145
|
-
out[1] = promise;
|
146
|
-
out[2] = type;
|
147
|
-
|
148
|
-
return out;
|
149
|
-
};
|
150
|
-
|
151
190
|
export const __Porffor_promise_runNext = (func: Function) => {
|
152
|
-
const reaction = __Porffor_promise_newReaction(func, undefined, 1);
|
191
|
+
const reaction: any[] = __Porffor_promise_newReaction(func, undefined, 1);
|
153
192
|
__ecma262_HostEnqueuePromiseJob(__ecma262_NewPromiseReactionJob(reaction, undefined));
|
154
193
|
};
|
155
194
|
|
@@ -161,21 +200,26 @@ export const __Porffor_promise_runJobs = () => {
|
|
161
200
|
const reaction: any[] = x[0];
|
162
201
|
const handler: Function = reaction[0];
|
163
202
|
const outPromise: any = reaction[1];
|
164
|
-
const
|
203
|
+
const flags: i32 = reaction[2];
|
165
204
|
|
166
205
|
const value: any = x[1];
|
167
206
|
|
168
207
|
// todo: handle thrown errors in handler?
|
169
208
|
let outValue: any;
|
170
|
-
if (
|
171
|
-
outValue = handler(value);
|
172
|
-
} else { // 1: finally reaction
|
209
|
+
if (flags & 0b01) { // finally reaction
|
173
210
|
handler();
|
174
211
|
outValue = value;
|
212
|
+
} else { // then reaction
|
213
|
+
outValue = handler(value);
|
175
214
|
}
|
176
215
|
|
177
|
-
|
178
|
-
|
216
|
+
if (outPromise) if (flags & 0b10) {
|
217
|
+
// reject reaction
|
218
|
+
__Porffor_promise_reject(outValue, outPromise);
|
219
|
+
} else {
|
220
|
+
// resolve reaction
|
221
|
+
__Porffor_promise_resolve(outValue, outPromise);
|
222
|
+
}
|
179
223
|
}
|
180
224
|
};
|
181
225
|
|
@@ -242,52 +286,15 @@ export const __Promise_prototype_then = (_this: any, onFulfilled: any, onRejecte
|
|
242
286
|
// 2. If IsPromise(promise) is false, throw a TypeError exception.
|
243
287
|
if (!__ecma262_IsPromise(_this)) throw new TypeError('Promise.prototype.then called on non-Promise');
|
244
288
|
|
245
|
-
// 27.2.5.4.1 PerformPromiseThen (promise, onFulfilled, onRejected [, resultCapability])
|
246
|
-
// https://tc39.es/ecma262/#sec-performpromisethen
|
247
|
-
|
248
289
|
if (Porffor.rawType(onFulfilled) != Porffor.TYPES.function) onFulfilled = __Porffor_promise_noop;
|
249
290
|
if (Porffor.rawType(onRejected) != Porffor.TYPES.function) onRejected = __Porffor_promise_noop;
|
250
291
|
|
251
|
-
const promise: any[] = _this;
|
252
|
-
const state: i32 = promise[1];
|
253
|
-
|
254
292
|
const outPromise: any[] = __Porffor_promise_create();
|
255
293
|
|
256
294
|
const fulfillReaction: any[] = __Porffor_promise_newReaction(onFulfilled, outPromise, 0);
|
257
|
-
const rejectReaction: any[] = __Porffor_promise_newReaction(onRejected, outPromise,
|
295
|
+
const rejectReaction: any[] = __Porffor_promise_newReaction(onRejected, outPromise, 2);
|
258
296
|
|
259
|
-
|
260
|
-
if (state == 0) { // pending
|
261
|
-
// a. Append fulfillReaction to promise.[[PromiseFulfillReactions]].
|
262
|
-
const fulfillReactions: any[] = promise[2];
|
263
|
-
Porffor.array.fastPush(fulfillReactions, fulfillReaction);
|
264
|
-
|
265
|
-
// b. Append rejectReaction to promise.[[PromiseRejectReactions]].
|
266
|
-
const rejectReactions: any[] = promise[3];
|
267
|
-
Porffor.array.fastPush(rejectReactions, rejectReaction);
|
268
|
-
} else if (state == 1) { // fulfilled
|
269
|
-
// 10. Else if promise.[[PromiseState]] is fulfilled, then
|
270
|
-
// a. Let value be promise.[[PromiseResult]].
|
271
|
-
const value: any = promise[0];
|
272
|
-
|
273
|
-
// b. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
|
274
|
-
// c. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
|
275
|
-
__ecma262_HostEnqueuePromiseJob(__ecma262_NewPromiseReactionJob(fulfillReaction, value));
|
276
|
-
} else { // rejected
|
277
|
-
// 11. Else,
|
278
|
-
// a. Assert: The value of promise.[[PromiseState]] is rejected.
|
279
|
-
// todo
|
280
|
-
|
281
|
-
// b. Let reason be promise.[[PromiseResult]].
|
282
|
-
const reason: any = promise[0];
|
283
|
-
|
284
|
-
// c. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "handle").
|
285
|
-
// unimplemented
|
286
|
-
|
287
|
-
// d. Let rejectJob be NewPromiseReactionJob(rejectReaction, reason).
|
288
|
-
// e. Perform HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]]).
|
289
|
-
__ecma262_HostEnqueuePromiseJob(__ecma262_NewPromiseReactionJob(rejectReaction, reason));
|
290
|
-
}
|
297
|
+
__Porffor_then(_this, fulfillReaction, rejectReaction);
|
291
298
|
|
292
299
|
const pro: Promise = outPromise;
|
293
300
|
return pro;
|