porffor 0.48.2 → 0.48.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/README.md +1 -1
- package/compiler/assemble.js +105 -128
- package/compiler/builtins/promise.ts +72 -65
- package/compiler/builtins.js +2 -15
- package/compiler/builtins_precompiled.js +55 -40
- package/compiler/codegen.js +137 -129
- package/compiler/precompile.js +1 -1
- package/compiler/wasmSpec.js +1 -2
- package/compiler/wrap.js +1 -3
- package/package.json +1 -1
- package/runner/index.js +1 -13
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
|
|
package/compiler/assemble.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Valtype, FuncType, ExportDesc, Section, Magic,
|
1
|
+
import { Valtype, FuncType, ExportDesc, Section, Magic, Opcodes, PageSize, Reftype } from './wasmSpec.js';
|
2
2
|
import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64, ieee754_binary64_into } from './encoding.js';
|
3
3
|
import { importedFuncs } from './builtins.js';
|
4
4
|
import { log } from './log.js';
|
@@ -9,17 +9,10 @@ const createSection = (type, data) => [
|
|
9
9
|
...encodeVector(data)
|
10
10
|
];
|
11
11
|
|
12
|
-
const customSection = (name, data) =>
|
12
|
+
const customSection = (name, data) => createSection(
|
13
13
|
Section.custom,
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
const chHint = (topTier, baselineTier, strategy) => {
|
18
|
-
// 1 byte of 4 2 bit components: spare, top tier, baseline tier, compilation strategy
|
19
|
-
// tiers: 0x00 = default, 0x01 = baseline (liftoff), 0x02 = optimized (turbofan)
|
20
|
-
// strategy: 0x00 = default, 0x01 = lazy, 0x02 = eager, 0x03 = lazy baseline, eager top tier
|
21
|
-
return (strategy | (baselineTier << 2) | (topTier << 4));
|
22
|
-
};
|
14
|
+
[ ...encodeString(name), ...data ]
|
15
|
+
);
|
23
16
|
|
24
17
|
const encodeNames = funcs => {
|
25
18
|
const encodeSection = (id, section) => [
|
@@ -50,11 +43,6 @@ const encodeNames = funcs => {
|
|
50
43
|
export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
51
44
|
const types = [], typeCache = {};
|
52
45
|
|
53
|
-
const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
|
54
|
-
|
55
|
-
const compileHints = Prefs.compileHints;
|
56
|
-
if (compileHints) log.warning('assemble', 'compile hints is V8 only w/ experimental arg! (you used -compile-hints)');
|
57
|
-
|
58
46
|
const getType = (params, returns) => {
|
59
47
|
const hash = `${params.join(',')}_${returns.join(',')}`;
|
60
48
|
if (Prefs.optLog) log('assemble', `getType(${JSON.stringify(params)}, ${JSON.stringify(returns)}) -> ${hash} | cache: ${typeCache[hash]}`);
|
@@ -77,15 +65,15 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
|
77
65
|
};
|
78
66
|
|
79
67
|
let importFuncs = [], importDelta = 0;
|
80
|
-
if (
|
68
|
+
if (!Prefs.treeshakeWasmImports || noTreeshake) {
|
81
69
|
importFuncs = importedFuncs;
|
82
70
|
} else {
|
83
71
|
let imports = new Map();
|
84
72
|
|
85
73
|
// tree shake imports
|
86
74
|
for (const f of funcs) {
|
87
|
-
for (const inst of f.wasm) {
|
88
|
-
if (
|
75
|
+
if (f.usesImports) for (const inst of f.wasm) {
|
76
|
+
if (inst[0] === Opcodes.call && inst[1] < importedFuncs.length) {
|
89
77
|
const idx = inst[1];
|
90
78
|
const func = importedFuncs[idx];
|
91
79
|
|
@@ -261,101 +249,103 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
|
261
249
|
);
|
262
250
|
time('export section');
|
263
251
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
lastType = local.type;
|
252
|
+
let codeSection = [];
|
253
|
+
for (let i = 0; i < funcs.length; i++) {
|
254
|
+
const x = funcs[i];
|
255
|
+
// time(x.name);
|
256
|
+
const locals = Object.values(x.locals).sort((a, b) => a.idx - b.idx);
|
257
|
+
// time(' locals gen');
|
258
|
+
|
259
|
+
const paramCount = x.params.length;
|
260
|
+
let localDecl = [], typeCount = 0, lastType, declCount = 0;
|
261
|
+
for (let i = paramCount; i <= locals.length; i++) {
|
262
|
+
const local = locals[i];
|
263
|
+
if (i !== paramCount && local?.type !== lastType) {
|
264
|
+
unsignedLEB128_into(typeCount, localDecl);
|
265
|
+
localDecl.push(lastType);
|
266
|
+
typeCount = 0;
|
267
|
+
declCount++;
|
281
268
|
}
|
282
269
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
const makeAssembled = Prefs.d;
|
287
|
-
let wasm = [], wasmNonFlat = [];
|
288
|
-
for (let i = 0; i < x.wasm.length; i++) {
|
289
|
-
let o = x.wasm[i];
|
290
|
-
|
291
|
-
// encode local/global ops as unsigned leb128 from raw number
|
292
|
-
if (
|
293
|
-
// (o[0] === Opcodes.local_get || o[0] === Opcodes.local_set || o[0] === Opcodes.local_tee || o[0] === Opcodes.global_get || o[0] === Opcodes.global_set) &&
|
294
|
-
(o[0] >= Opcodes.local_get && o[0] <= Opcodes.global_set) &&
|
295
|
-
o[1] > 127
|
296
|
-
) {
|
297
|
-
const n = o[1];
|
298
|
-
o = [ o[0] ];
|
299
|
-
unsignedLEB128_into(n, o);
|
300
|
-
}
|
270
|
+
typeCount++;
|
271
|
+
lastType = local?.type;
|
272
|
+
}
|
301
273
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
274
|
+
// time(' localDecl gen');
|
275
|
+
|
276
|
+
const makeAssembled = Prefs.d;
|
277
|
+
let wasm = [], wasmNonFlat = [];
|
278
|
+
for (let i = 0; i < x.wasm.length; i++) {
|
279
|
+
let o = x.wasm[i];
|
280
|
+
|
281
|
+
// encode local/global ops as unsigned leb128 from raw number
|
282
|
+
if (
|
283
|
+
(o[0] >= Opcodes.local_get && o[0] <= Opcodes.global_set) &&
|
284
|
+
o[1] > 127
|
285
|
+
) {
|
286
|
+
const n = o[1];
|
287
|
+
o = [ o[0] ];
|
288
|
+
unsignedLEB128_into(n, o);
|
289
|
+
}
|
310
290
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
291
|
+
// encode f64.const ops as ieee754 from raw number
|
292
|
+
if (o[0] === Opcodes.f64_const) {
|
293
|
+
const n = o[1];
|
294
|
+
o = ieee754_binary64(n);
|
295
|
+
if (o.length === 8) o.unshift(Opcodes.f64_const);
|
296
|
+
}
|
297
|
+
|
298
|
+
// encode call ops as unsigned leb128 from raw number
|
299
|
+
if ((o[0] === Opcodes.call /* || o[0] === Opcodes.return_call */) && o[1] >= importedFuncs.length) {
|
300
|
+
const n = o[1] - importDelta;
|
301
|
+
o = [ Opcodes.call ];
|
302
|
+
unsignedLEB128_into(n, o);
|
303
|
+
}
|
318
304
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
}
|
326
|
-
|
327
|
-
let returns = [ valtypeBinary, Valtype.i32 ];
|
328
|
-
if (o.at(-1) === 'no_type_return') {
|
329
|
-
o.pop();
|
330
|
-
returns = [ valtypeBinary ];
|
331
|
-
}
|
332
|
-
|
333
|
-
o[1] = getType(params, returns);
|
305
|
+
// encode call indirect ops as types from info
|
306
|
+
if (o[0] === Opcodes.call_indirect) {
|
307
|
+
o = [...o];
|
308
|
+
const params = [];
|
309
|
+
for (let i = 0; i < o[1]; i++) {
|
310
|
+
params.push(valtypeBinary, Valtype.i32);
|
334
311
|
}
|
335
312
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
313
|
+
let returns = [ valtypeBinary, Valtype.i32 ];
|
314
|
+
if (o.at(-1) === 'no_type_return') {
|
315
|
+
o.pop();
|
316
|
+
returns = [ valtypeBinary ];
|
340
317
|
}
|
341
318
|
|
342
|
-
|
319
|
+
o[1] = getType(params, returns);
|
343
320
|
}
|
344
|
-
// time(' wasm transform');
|
345
321
|
|
346
|
-
|
347
|
-
x
|
322
|
+
for (let j = 0; j < o.length; j++) {
|
323
|
+
const x = o[j];
|
324
|
+
if (x == null || !(x <= 0xff)) continue;
|
325
|
+
wasm.push(x);
|
348
326
|
}
|
349
327
|
|
350
|
-
|
351
|
-
|
328
|
+
if (makeAssembled) wasmNonFlat.push(o);
|
329
|
+
}
|
330
|
+
// time(' wasm transform');
|
331
|
+
|
332
|
+
if (makeAssembled) {
|
333
|
+
x.assembled = { localDecl, wasm, wasmNonFlat };
|
334
|
+
}
|
352
335
|
|
353
|
-
|
336
|
+
let out = unsignedLEB128(declCount)
|
337
|
+
.concat(localDecl, wasm, Opcodes.end);
|
354
338
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
339
|
+
codeSection.push(
|
340
|
+
...unsignedLEB128(out.length),
|
341
|
+
...out
|
342
|
+
);
|
343
|
+
|
344
|
+
// time(' finish');
|
345
|
+
}
|
346
|
+
|
347
|
+
codeSection.unshift(...unsignedLEB128(funcs.length, codeSection));
|
348
|
+
codeSection.unshift(Section.code, ...unsignedLEB128(codeSection.length));
|
359
349
|
time('code section');
|
360
350
|
|
361
351
|
const typeSection = createSection(
|
@@ -364,25 +354,32 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
|
364
354
|
);
|
365
355
|
time('type section');
|
366
356
|
|
367
|
-
|
368
|
-
|
369
|
-
|
357
|
+
let dataSection = [];
|
358
|
+
if (data.length > 0) {
|
359
|
+
for (let i = 0; i < data.length; i++) {
|
360
|
+
const x = data[i];
|
370
361
|
if (Prefs.d && x.bytes.length > PageSize) log.warning('assemble', `data (${x.page}) has more bytes than Wasm page size! (${x.bytes.length})`);
|
371
362
|
|
372
|
-
const bytes = unsignedLEB128(x.bytes.length).concat(x.bytes);
|
373
363
|
if (x.page != null) {
|
374
364
|
// type: active
|
375
365
|
let offset = pages.allocs.get(x.page) ?? (pages.get(x.page) * pageSize);
|
376
366
|
if (offset === 0) offset = 16;
|
377
|
-
|
367
|
+
dataSection.push(0x00, Opcodes.i32_const, ...signedLEB128(offset), Opcodes.end);
|
378
368
|
} else {
|
379
369
|
// type: passive
|
380
|
-
|
370
|
+
dataSection.push(0x01);
|
381
371
|
}
|
382
372
|
|
383
|
-
|
384
|
-
|
385
|
-
|
373
|
+
dataSection.push(
|
374
|
+
...unsignedLEB128(x.bytes.length),
|
375
|
+
...x.bytes
|
376
|
+
);
|
377
|
+
}
|
378
|
+
|
379
|
+
dataSection.unshift(...unsignedLEB128(data.length, dataSection));
|
380
|
+
dataSection.unshift(Section.data, ...unsignedLEB128(dataSection.length));
|
381
|
+
}
|
382
|
+
|
386
383
|
time('data section');
|
387
384
|
|
388
385
|
const dataCountSection = data.length === 0 ? [] : createSection(
|
@@ -391,31 +388,11 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
|
391
388
|
);
|
392
389
|
time('datacount section');
|
393
390
|
|
394
|
-
if (Prefs.sections) console.log({
|
395
|
-
typeSection: typeSection.map(x => x.toString(16)),
|
396
|
-
importSection: importSection.map(x => x.toString(16)),
|
397
|
-
funcSection: funcSection.map(x => x.toString(16)),
|
398
|
-
globalSection: globalSection.map(x => x.toString(16)),
|
399
|
-
exportSection: exportSection.map(x => x.toString(16)),
|
400
|
-
codeSection: codeSection.map(x => x.toString(16)),
|
401
|
-
dataSection: dataSection.map(x => x.toString(16)),
|
402
|
-
});
|
403
|
-
|
404
|
-
// compilation hints section - unspecd, v8 only
|
405
|
-
// https://github.com/WebAssembly/design/issues/1473#issuecomment-1431274746
|
406
|
-
const chSection = !compileHints ? [] : customSection(
|
407
|
-
'compilationHints',
|
408
|
-
// for now just do everything as optimize eager
|
409
|
-
encodeVector(funcs.map(_ => chHint(0x02, 0x02, 0x02)))
|
410
|
-
);
|
411
|
-
|
412
391
|
return Uint8Array.from([
|
413
392
|
...Magic,
|
414
|
-
...ModuleVersion,
|
415
393
|
...typeSection,
|
416
394
|
...importSection,
|
417
395
|
...funcSection,
|
418
|
-
...chSection,
|
419
396
|
...tableSection,
|
420
397
|
...memorySection,
|
421
398
|
...tagSection,
|
@@ -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;
|
package/compiler/builtins.js
CHANGED
@@ -68,21 +68,6 @@ for (let i = 0; i < importedFuncs.length; i++) {
|
|
68
68
|
importedFuncs[f.name] = i;
|
69
69
|
}
|
70
70
|
|
71
|
-
const printStaticStr = str => {
|
72
|
-
const out = [];
|
73
|
-
|
74
|
-
for (let i = 0; i < str.length; i++) {
|
75
|
-
out.push(
|
76
|
-
// ...number(str.charCodeAt(i)),
|
77
|
-
...number(str.charCodeAt(i), Valtype.i32),
|
78
|
-
Opcodes.i32_from_u,
|
79
|
-
[ Opcodes.call, importedFuncs.printChar ]
|
80
|
-
);
|
81
|
-
}
|
82
|
-
|
83
|
-
return out;
|
84
|
-
};
|
85
|
-
|
86
71
|
export const UNDEFINED = 0;
|
87
72
|
export const NULL = 0;
|
88
73
|
|
@@ -106,6 +91,7 @@ export const BuiltinVars = function(ctx) {
|
|
106
91
|
this.__performance_timeOrigin = [
|
107
92
|
[ Opcodes.call, importedFuncs.timeOrigin ]
|
108
93
|
];
|
94
|
+
this.__performance_timeOrigin.usesImports = true;
|
109
95
|
|
110
96
|
this.__Uint8Array_BYTES_PER_ELEMENT = number(1);
|
111
97
|
this.__Int8Array_BYTES_PER_ELEMENT = number(1);
|
@@ -849,6 +835,7 @@ export const BuiltinFuncs = function() {
|
|
849
835
|
[ Opcodes.call, importedFuncs.time ]
|
850
836
|
]
|
851
837
|
};
|
838
|
+
this.__performance_now.usesImports = true;
|
852
839
|
|
853
840
|
|
854
841
|
this.__Porffor_type = {
|