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 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 (floored to nearest int)
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
- // todo: if value is own promise, reject with typeerror
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
- // todo
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
- if (__ecma262_IsPromise(reason)) {
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 type: i32 = reaction[2];
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 (type == 0) { // 0: then reaction
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
- // todo: should this be resolve or fulfill?
178
- if (outPromise) __ecma262_FulfillPromise(outPromise, outValue);
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, 0);
295
+ const rejectReaction: any[] = __Porffor_promise_newReaction(onRejected, outPromise, 2);
258
296
 
259
- // 9. If promise.[[PromiseState]] is pending, then
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;