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 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
 
@@ -1,4 +1,4 @@
1
- import { Valtype, FuncType, ExportDesc, Section, Magic, ModuleVersion, Opcodes, PageSize, Reftype } from './wasmSpec.js';
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
- ...encodeVector([...encodeString(name), ...data])
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 (optLevel < 1 || !Prefs.treeshakeWasmImports || noTreeshake) {
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 ((inst[0] === Opcodes.call /* || inst[0] === Opcodes.return_call */) && inst[1] < importedFuncs.length) {
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
- const codeSection = createSection(
265
- Section.code,
266
- encodeVector(funcs.map(x => {
267
- // time(x.name);
268
- const locals = Object.values(x.locals).sort((a, b) => a.idx - b.idx).slice(x.params.length);
269
- // time(' locals gen');
270
-
271
- let localDecl = [], typeCount = 0, lastType;
272
- for (let i = 0; i < locals.length; i++) {
273
- const local = locals[i];
274
- if (i !== 0 && local.type !== lastType) {
275
- localDecl.push(encodeLocal(typeCount, lastType));
276
- typeCount = 0;
277
- }
278
-
279
- typeCount++;
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
- if (typeCount !== 0) localDecl.push(encodeLocal(typeCount, lastType));
284
- // time(' localDecl gen');
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
- // encode f64.const ops as ieee754 from raw number
303
- if (o[0] === Opcodes.f64_const) {
304
- const n = o[1];
305
- // o = [ o[0] ];
306
- // ieee754_binary64_into(n, o);
307
- o = ieee754_binary64(n);
308
- if (o.length === 8) o.unshift(Opcodes.f64_const);
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
- // encode call ops as unsigned leb128 from raw number
312
- if ((o[0] === Opcodes.call /* || o[0] === Opcodes.return_call */) && o[1] >= importedFuncs.length) {
313
- const n = o[1] - importDelta;
314
- // o = [ o[0] ];
315
- o = [ Opcodes.call ];
316
- unsignedLEB128_into(n, o);
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
- // encode call indirect ops as types from info
320
- if (o[0] === Opcodes.call_indirect) {
321
- o = [...o];
322
- const params = [];
323
- for (let i = 0; i < o[1]; i++) {
324
- params.push(valtypeBinary, Valtype.i32);
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
- for (let j = 0; j < o.length; j++) {
337
- const x = o[j];
338
- if (x == null || !(x <= 0xff)) continue;
339
- wasm.push(x);
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
- if (makeAssembled) wasmNonFlat.push(o);
319
+ o[1] = getType(params, returns);
343
320
  }
344
- // time(' wasm transform');
345
321
 
346
- if (makeAssembled) {
347
- x.assembled = { localDecl, wasm, wasmNonFlat };
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
- let out = unsignedLEB128(localDecl.length)
351
- .concat(localDecl.flat(), wasm, Opcodes.end);
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
- out.unshift(...unsignedLEB128(out.length));
336
+ let out = unsignedLEB128(declCount)
337
+ .concat(localDecl, wasm, Opcodes.end);
354
338
 
355
- // time(' finish');
356
- return out;
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
- const dataSection = data.length === 0 ? [] : createSection(
368
- Section.data,
369
- encodeVector(data.map(x => {
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
- bytes.unshift(0x00, Opcodes.i32_const, ...signedLEB128(offset), Opcodes.end);
367
+ dataSection.push(0x00, Opcodes.i32_const, ...signedLEB128(offset), Opcodes.end);
378
368
  } else {
379
369
  // type: passive
380
- bytes.unshift(0x01);
370
+ dataSection.push(0x01);
381
371
  }
382
372
 
383
- return bytes;
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
- // 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;
@@ -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 = {