porffor 0.60.7 → 0.60.9

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.
@@ -1,13 +1,78 @@
1
1
  import { Blocktype, Opcodes, Valtype, ValtypeSize } from './wasmSpec.js';
2
- import { number, ieee754_binary64, signedLEB128, unsignedLEB128, encodeVector, read_signedLEB128 } from './encoding.js';
2
+ import { number, ieee754_binary64, signedLEB128, unsignedLEB128, encodeVector } from './encoding.js';
3
3
  import { operatorOpcode } from './expression.js';
4
4
  import { BuiltinFuncs, BuiltinVars, importedFuncs, NULL, UNDEFINED } from './builtins.js';
5
5
  import { TYPES, TYPE_FLAGS, TYPE_NAMES } from './types.js';
6
6
  import parse from './parse.js';
7
7
  import { log } from './log.js';
8
- import { allocPage, allocStr } from './allocator.js';
9
8
  import './prefs.js';
10
9
 
10
+ const pagePtr = ind => {
11
+ if (ind === 0) return 16;
12
+ return ind * pageSize;
13
+ };
14
+
15
+ const allocPage = (scope, name) => {
16
+ if (!name.startsWith('#')) {
17
+ name = `${scope.name}/${name}`;
18
+ if (globalThis.precompile) name = `${globalThis.precompile}/${name}`;
19
+ }
20
+
21
+ if (pages.has(name)) {
22
+ return pagePtr(pages.get(name));
23
+ }
24
+
25
+ const ind = pages.size;
26
+ pages.set(name, ind);
27
+
28
+ scope.pages ??= new Map();
29
+ scope.pages.set(name, ind);
30
+
31
+ return pagePtr(ind);
32
+ };
33
+
34
+ const allocBytes = (scope, reason, bytes) => {
35
+ bytes += 2; // overallocate by 2 bytes to ensure null termination
36
+
37
+ const allocs = pages.allocs ??= new Map();
38
+ const bins = pages.bins ??= [];
39
+
40
+ if (allocs.has(reason)) {
41
+ return allocs.get(reason);
42
+ }
43
+
44
+ let startingPtr = 0;
45
+ while (bytes > 0) {
46
+ const alloc = Math.min(bytes, pageSize);
47
+ bytes -= alloc;
48
+
49
+ let bin = bins.find(x => (pageSize - x.used) >= alloc);
50
+ if (!bin) {
51
+ // new bin
52
+ const page = pages.size;
53
+ bin = {
54
+ used: 0,
55
+ page
56
+ };
57
+
58
+ const id = bins.push(bin);
59
+ pages.set(`#bin: ${id}`, page);
60
+ }
61
+
62
+ if (!startingPtr) startingPtr = pagePtr(bin.page) + bin.used;
63
+ bin.used += alloc;
64
+ }
65
+
66
+ allocs.set(reason, startingPtr);
67
+ return startingPtr;
68
+ };
69
+
70
+ export const allocStr = (scope, str, bytestring) => {
71
+ // basic string interning for ~free
72
+ const bytes = 4 + str.length * (bytestring ? 1 : 2);
73
+ return allocBytes(scope, str, bytes);
74
+ };
75
+
11
76
  const todo = (scope, msg, expectsValue = undefined) => {
12
77
  msg = `todo: ${msg}`;
13
78
 
@@ -1465,10 +1530,10 @@ const asmFuncToAsm = (scope, func, extra) => func(scope, {
1465
1530
  wasm.push(Opcodes.i32_to_u);
1466
1531
  return wasm;
1467
1532
  },
1468
- allocPage: (scope, name) => allocPage({ scope, pages }, name),
1533
+ allocPage,
1469
1534
  allocLargePage: (scope, name) => {
1470
- const _ = allocPage({ scope, pages }, name);
1471
- allocPage({ scope, pages }, name + '#2');
1535
+ const _ = allocPage(scope, name);
1536
+ allocPage(scope, name + '#2');
1472
1537
 
1473
1538
  return _;
1474
1539
  }
@@ -2781,7 +2846,7 @@ const knownType = (scope, type) => {
2781
2846
  if (typeof type === 'number') return type;
2782
2847
 
2783
2848
  if (type.length === 1 && type[0][0] === Opcodes.i32_const) {
2784
- return read_signedLEB128(type[0].slice(1));
2849
+ return type[0][1];
2785
2850
  }
2786
2851
 
2787
2852
  if (typedInput && type.length === 1 && type[0][0] === Opcodes.local_get) {
@@ -4260,7 +4325,7 @@ const generateUnary = (scope, decl) => {
4260
4325
  return [
4261
4326
  ...toNumeric(),
4262
4327
  Opcodes.i32_to,
4263
- [ Opcodes.i32_const, ...signedLEB128(-1) ],
4328
+ [ Opcodes.i32_const, -1 ],
4264
4329
  [ Opcodes.i32_xor ],
4265
4330
  Opcodes.i32_from
4266
4331
  ];
@@ -5059,14 +5124,14 @@ const generateForIn = (scope, decl) => {
5059
5124
  [ Opcodes.local_set, tmp ],
5060
5125
 
5061
5126
  // symbol is MSB 2 is set
5062
- [ Opcodes.i32_const, ...unsignedLEB128(TYPES.string) ],
5063
- [ Opcodes.i32_const, ...unsignedLEB128(TYPES.symbol) ],
5127
+ [ Opcodes.i32_const, TYPES.string ],
5128
+ [ Opcodes.i32_const, TYPES.symbol ],
5064
5129
  [ Opcodes.local_get, tmp ],
5065
5130
  number(0x40000000, Valtype.i32),
5066
5131
  [ Opcodes.i32_and ],
5067
5132
  [ Opcodes.select ],
5068
5133
  [ Opcodes.else ], // bytestring
5069
- [ Opcodes.i32_const, ...unsignedLEB128(TYPES.bytestring) ],
5134
+ [ Opcodes.i32_const, TYPES.bytestring ],
5070
5135
  [ Opcodes.end ]
5071
5136
  ]),
5072
5137
 
@@ -5582,7 +5647,7 @@ const makeString = (scope, str, bytestring = true) => {
5582
5647
  if (c > 0xFF) bytestring = false;
5583
5648
  }
5584
5649
 
5585
- const ptr = allocStr({ scope, pages }, str, bytestring);
5650
+ const ptr = allocStr(scope, str, bytestring);
5586
5651
  makeData(scope, elements, str, bytestring ? 'i8' : 'i16');
5587
5652
 
5588
5653
  return [ number(ptr) ];
@@ -5598,7 +5663,7 @@ const generateArray = (scope, decl, global = false, name = '$undeclared', static
5598
5663
  if (staticAlloc || decl._staticAlloc) {
5599
5664
  const uniqueName = name === '$undeclared' ? name + uniqId() : name;
5600
5665
 
5601
- const ptr = allocPage({ scope, pages }, uniqueName);
5666
+ const ptr = allocPage(scope, uniqueName);
5602
5667
  pointer = number(ptr, Valtype.i32);
5603
5668
 
5604
5669
  scope.arrays ??= new Map();
@@ -6556,6 +6621,7 @@ const generateTaggedTemplate = (scope, decl, global = false, name = undefined, v
6556
6621
 
6557
6622
  const encodeFunc = ({
6558
6623
  [Opcodes.f64_const]: x => x,
6624
+ [Opcodes.i32_const]: x => x,
6559
6625
  [Opcodes.if]: unsignedLEB128,
6560
6626
  [Opcodes.loop]: unsignedLEB128
6561
6627
  })[inst[0]] ?? signedLEB128;
@@ -1,5 +1,5 @@
1
1
  // cyclone: wasm partial constant evaluator (it is fast and dangerous hence "cyclone")
2
- import { number, read_signedLEB128 } from './encoding.js';
2
+ import { number } from './encoding.js';
3
3
  import { Opcodes, Valtype } from './wasmSpec.js';
4
4
  import './prefs.js';
5
5
 
@@ -123,7 +123,7 @@ export default ({ name, wasm, locals: _locals, params }) => {
123
123
  }
124
124
 
125
125
  case Opcodes.i32_const: {
126
- const n = read_signedLEB128(op.slice(1));
126
+ const n = op[1];
127
127
  push(n);
128
128
  break;
129
129
  }
@@ -1,5 +1,5 @@
1
1
  import { Blocktype, Opcodes, Valtype } from './wasmSpec.js';
2
- import { read_ieee754_binary64, read_signedLEB128, read_unsignedLEB128 } from './encoding.js';
2
+ import { read_unsignedLEB128 } from './encoding.js';
3
3
  import { importedFuncs } from './builtins.js';
4
4
 
5
5
  const inv = (obj, keyMap = x => x) => Object.keys(obj).reduce((acc, x) => { acc[keyMap(obj[x])] = x; return acc; }, {});
@@ -74,7 +74,7 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
74
74
  if (inst[0] === Opcodes.f64_const) {
75
75
  out += ` ${inst[1]}`;
76
76
  } else if (inst[0] === Opcodes.i32_const || inst[0] === Opcodes.i64_const) {
77
- out += ` ${read_signedLEB128(inst.slice(1))}`;
77
+ out += ` ${inst[1]}`;
78
78
  } else if (inst[0] === Opcodes.i32_load || inst[0] === Opcodes.i64_load || inst[0] === Opcodes.f64_load || inst[0] === Opcodes.i32_store || inst[0] === Opcodes.i64_store || inst[0] === Opcodes.f64_store || inst[0] === Opcodes.i32_store16 || inst[0] === Opcodes.i32_load16_u) {
79
79
  out += ` ${inst[1]} ${read_unsignedLEB128(inst.slice(2))}`;
80
80
  } else for (const operand of inst.slice(1)) {
@@ -3,10 +3,10 @@ import { Opcodes, Valtype } from './wasmSpec.js';
3
3
  export const number = (n, valtype = valtypeBinary) => {
4
4
  if (valtype === Valtype.f64) return [ Opcodes.f64_const, n ];
5
5
 
6
- const out = [ valtype === Valtype.i32 ? Opcodes.i32_const : Opcodes.i64_const ];
7
- signedLEB128_into(n, out);
8
-
9
- return out;
6
+ return [
7
+ valtype === Valtype.i32 ? Opcodes.i32_const : Opcodes.i64_const,
8
+ n
9
+ ];
10
10
  };
11
11
 
12
12
  export const codifyString = str => {
@@ -23,6 +23,9 @@ export const encodeVector = data => unsignedLEB128(data.length).concat(data.flat
23
23
 
24
24
  // todo: this only works with integers within 32 bit range
25
25
  export const signedLEB128 = n => {
26
+ if (n === Infinity) return signedLEB128(2147483647);
27
+ if (n === -Infinity) return signedLEB128(-2147483648);
28
+
26
29
  n |= 0;
27
30
 
28
31
  // just input for small numbers (for perf as common)
@@ -49,6 +52,9 @@ export const signedLEB128 = n => {
49
52
  };
50
53
 
51
54
  export const unsignedLEB128 = n => {
55
+ if (n === Infinity) return unsignedLEB128(4294967295);
56
+ if (n === -Infinity) return unsignedLEB128(0);
57
+
52
58
  n |= 0;
53
59
 
54
60
  // just input for small numbers (for perf as common)
@@ -69,6 +75,9 @@ export const unsignedLEB128 = n => {
69
75
  };
70
76
 
71
77
  export const unsignedLEB128_length = n => {
78
+ if (n === Infinity) return unsignedLEB128_length(4294967295);
79
+ if (n === -Infinity) return unsignedLEB128_length(0);
80
+
72
81
  if (n < 0) n = n >>> 0;
73
82
  if (n <= 127) return 1;
74
83
  if (n <= 16383) return 2;
@@ -85,6 +94,9 @@ export const unsignedLEB128_length = n => {
85
94
  };
86
95
 
87
96
  export const signedLEB128_length = n => {
97
+ if (n === Infinity) return signedLEB128_length(2147483647);
98
+ if (n === -Infinity) return signedLEB128_length(-2147483648);
99
+
88
100
  if (n >= -64 && n <= 63) return 1;
89
101
  if (n >= -8192 && n <= 8191) return 2;
90
102
  if (n >= -1048576 && n <= 1048575) return 3;
@@ -201,6 +213,9 @@ export const read_ieee754_binary64 = buffer => new Float64Array(new Uint8Array(b
201
213
 
202
214
  // into funcs append to a given existing buffer instead of creating our own for perf
203
215
  export const signedLEB128_into = (n, buffer) => {
216
+ if (n === Infinity) return signedLEB128_into(2147483647, buffer);
217
+ if (n === -Infinity) return signedLEB128_into(-2147483648, buffer);
218
+
204
219
  n |= 0;
205
220
 
206
221
  // just input for small numbers (for perf as common)
@@ -224,6 +239,9 @@ export const signedLEB128_into = (n, buffer) => {
224
239
  };
225
240
 
226
241
  export const unsignedLEB128_into = (n, buffer) => {
242
+ if (n === Infinity) return unsignedLEB128_into(4294967295, buffer);
243
+ if (n === -Infinity) return unsignedLEB128_into(0, buffer);
244
+
227
245
  n |= 0;
228
246
 
229
247
  // just input for small numbers (for perf as common)
@@ -46,31 +46,6 @@ export const operatorOpcode = {
46
46
  ]
47
47
  },
48
48
 
49
- i64: {
50
- '+': Opcodes.i64_add,
51
- '-': Opcodes.i64_sub,
52
- '*': Opcodes.i64_mul,
53
- '/': Opcodes.i64_div_s,
54
- '%': Opcodes.i64_rem_s,
55
-
56
- '&': Opcodes.i64_and,
57
- '|': Opcodes.i64_or,
58
- '^': Opcodes.i64_xor,
59
- '<<': Opcodes.i64_shl,
60
- '>>': Opcodes.i64_shr_s,
61
- '>>>': Opcodes.i64_shr_u,
62
-
63
- '==': Opcodes.i64_eq,
64
- '===': Opcodes.i64_eq,
65
- '!=': Opcodes.i64_ne,
66
- '!==': Opcodes.i64_ne,
67
-
68
- '>': Opcodes.i64_gt_s,
69
- '>=': Opcodes.i64_ge_s,
70
- '<': Opcodes.i64_lt_s,
71
- '<=': Opcodes.i64_le_s
72
- },
73
-
74
49
  f64: {
75
50
  '+': Opcodes.f64_add,
76
51
  '-': Opcodes.f64_sub,
package/compiler/opt.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Opcodes, Valtype } from './wasmSpec.js';
2
- import { number, read_signedLEB128 } from './encoding.js';
2
+ import { number } from './encoding.js';
3
3
  import { log } from './log.js';
4
4
  import './prefs.js';
5
5
 
@@ -177,7 +177,7 @@ export default (funcs, globals, pages, tags, exceptions) => {
177
177
  // -->
178
178
  // i32.const 0
179
179
 
180
- wasm[i - 1] = number(valtype === 'f64' ? lastInst[1] : read_signedLEB128(lastInst.slice(1)), Valtype.i32); // f64.const -> i32.const
180
+ wasm[i - 1] = number(lastInst[1], Valtype.i32); // f64.const -> i32.const
181
181
 
182
182
  wasm.splice(i, 1); // remove this inst
183
183
  i--;
@@ -192,7 +192,7 @@ export default (funcs, globals, pages, tags, exceptions) => {
192
192
  // -->
193
193
  // f64.const 0
194
194
 
195
- wasm[i - 1] = number(read_signedLEB128(lastInst.slice(1))); // i32.const -> f64.const
195
+ wasm[i - 1] = number(lastInst[1], Valtype.f64); // i32.const -> f64.const
196
196
 
197
197
  wasm.splice(i, 1); // remove this inst
198
198
  i--;
@@ -215,18 +215,18 @@ export default (funcs, globals, pages, tags, exceptions) => {
215
215
  continue;
216
216
  }
217
217
 
218
- if (false && i === wasm.length - 1 && inst[0] === Opcodes.return) {
219
- // replace final return, end -> end (wasm has implicit return)
220
- // return
221
- // end
222
- // -->
223
- // end
224
-
225
- wasm.splice(i, 1); // remove this inst (return)
226
- i--;
227
- // if (Prefs.optLog) log('opt', `removed redundant return at end`);
228
- continue;
229
- }
218
+ // if (i === wasm.length - 1 && inst[0] === Opcodes.return) {
219
+ // // replace final return, end -> end (wasm has implicit return)
220
+ // // return
221
+ // // end
222
+ // // -->
223
+ // // end
224
+
225
+ // wasm.splice(i, 1); // remove this inst (return)
226
+ // i--;
227
+ // // if (Prefs.optLog) log('opt', `removed redundant return at end`);
228
+ // continue;
229
+ // }
230
230
 
231
231
  // remove unneeded before get with update exprs (n++, etc) when value is unused
232
232
  if (i < wasm.length - 4 && lastInst[1] === inst[1] && lastInst[0] === Opcodes.local_get && inst[0] === Opcodes.local_get && wasm[i + 1][0] === Opcodes.const && [Opcodes.add, Opcodes.sub].includes(wasm[i + 2][0]) && wasm[i + 3][0] === Opcodes.local_set && wasm[i + 3][1] === inst[1] && (wasm[i + 4][0] === Opcodes.drop || wasm[i + 4][0] === Opcodes.br)) {
@@ -57,7 +57,7 @@ const compile = async (file, _funcs) => {
57
57
  first = source.slice(0, source.indexOf('\n'));
58
58
  }
59
59
 
60
- let args = ['--module', '--todo-time=compile', '--truthy=no_nan_negative', '--no-rm-unused-types', '--scoped-page-names', '--fast-length', '--parse-types', '--opt-types', '--no-passive-data', '--active-data', '--no-treeshake-wasm-imports', '--no-coctc'];
60
+ let args = ['--module', '--todo-time=compile', '--truthy=no_nan_negative', '--no-rm-unused-types', '--fast-length', '--parse-types', '--opt-types', '--no-passive-data', '--active-data', '--no-treeshake-wasm-imports', '--no-coctc'];
61
61
  if (first.startsWith('// @porf')) {
62
62
  args = first.slice('// @porf '.length).split(' ').concat(args);
63
63
  }
@@ -176,7 +176,7 @@ const compile = async (file, _funcs) => {
176
176
  x.usesTag = true;
177
177
  let id;
178
178
  if (y[0] === Opcodes.i32_const && n[1] === 0) {
179
- id = read_signedLEB128(y.slice(1));
179
+ id = y[1];
180
180
  wasm[i] = [ 'throw', exceptions[id].constructor, exceptions[id].message ];
181
181
 
182
182
  // remove throw inst
@@ -244,7 +244,7 @@ ${funcs.map(x => {
244
244
  if (Number.isNaN(v) || v === Infinity || v === -Infinity) return v.toString();
245
245
  return v;
246
246
  })
247
- .replace(/\["alloc","(.*?)",(.*?)\]/g, (_, reason, valtype) => `number(allocPage(_,'${reason}'),${valtype})`)
247
+ .replace(/\["alloc","(.*?)",(.*?)\]/g, (_, reason, valtype) => `[${valtype === Valtype.i32 ? Opcodes.i32_const : Opcodes.f64_const},allocPage(_,'${reason}')]`)
248
248
  .replace(/\["global",(.*?),"(.*?)",(.*?)\]/g, (_, opcode, name, valtype) => `...glbl(${opcode},'${name}',${valtype})`)
249
249
  .replace(/\"local","(.*?)",(.*?)\]/g, (_, name, valtype) => `loc('${name}',${valtype})]`)
250
250
  .replace(/\[16,"(.*?)"]/g, (_, name) => `[16,builtin('${name}')]`)
package/compiler/wrap.js CHANGED
@@ -586,7 +586,10 @@ export default (source, module = undefined, print = str => process.stdout.write(
586
586
  }
587
587
 
588
588
  times.push(performance.now() - t2);
589
- if (Prefs.profileCompiler && !globalThis.onProgress) console.log(`instantiated in ${times[1].toFixed(2)}ms`);
589
+ if (Prefs.profileCompiler) {
590
+ if (globalThis.onProgress) globalThis.onProgress('instantiated', times[1]);
591
+ else console.log(`instantiated in ${times[1].toFixed(2)}ms`);
592
+ }
590
593
 
591
594
  const exports = {};
592
595
  const rawValues = Prefs.d;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "An ahead-of-time JavaScript compiler",
4
- "version": "0.60.7",
4
+ "version": "0.60.9",
5
5
  "author": "Oliver Medhurst <honk@goose.icu>",
6
6
  "license": "MIT",
7
7
  "scripts": {},
8
8
  "dependencies": {
9
9
  "acorn": "^8.15.0",
10
- "node-repl-polyfill": "github:CanadaHonk/node-repl-polyfill"
10
+ "node-repl-polyfill": "^0.1.2"
11
11
  },
12
12
  "optionalDependencies": {
13
13
  "@babel/parser": "^7.24.4",
package/runtime/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.60.7';
3
+ globalThis.version = '0.60.9';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
package/AGENTS.md DELETED
@@ -1,20 +0,0 @@
1
- you are an assistant coder for Porffor - an early javascript and typescript to webassembly and native ahead-of-time compiler. the codebase is written in js and ts.
2
-
3
- - built-ins apis (Date, String.prototype, etc) are written in ts inside `compiler/builtins`
4
- - once you update a file inside that directory, you MUST run `./porf precompile` to compile to make your changes effective
5
- - test your work using the test262 tools available, iterate independently but do not get stuck on one chain of thought or approach. paths for test262 tools should be relative to the 'test262/test' directory (e.g., 'built-ins/RegExp' NOT 'test262/test/built-ins/RegExp').
6
- - to get an overview of the most failing directories, use the command: `node test262/fails.cjs`
7
- - to just evaluate code in the engine, use the command: `./porf -p "..."`
8
- - after finishing, check if your work/diff could be simplified
9
- - always use single quotes (unless double is required)
10
- - 2-space indentation, LF line endings, no trailing whitespace
11
- - built-in APIs in `compiler/builtins/` written in TypeScript
12
- - inline code in built-ins, avoid helper functions
13
- - use semicolons
14
- - do not use trailing commas
15
- - use const/let, avoid var
16
- - follow existing naming: camelCase for variables, PascalCase for types
17
- - when possible, do not concat strings and instead write to them directly using wasm memory
18
- - there are no closures, you cannot use locals between functions. use arguments or globals if really necessary
19
- - The user prefers that prototype functions not have explicit return types in this codebase.
20
- - The user prefers not to use global variables in built-in functions.
@@ -1,65 +0,0 @@
1
- import './prefs.js';
2
-
3
- const pagePtr = ind => {
4
- if (ind === 0) return 16;
5
- return ind * pageSize;
6
- };
7
-
8
- export const nameToReason = (scope, name) => {
9
- let scopeName = scope.name;
10
- if (globalThis.precompile && scopeName === '#main') scopeName = globalThis.precompile;
11
-
12
- return `${Prefs.scopedPageNames ? (scopeName + '/') : ''}${name}`;
13
- };
14
-
15
- export const allocPage = ({ scope, pages }, name) => {
16
- const reason = nameToReason(scope, name);
17
-
18
- if (pages.has(reason)) {
19
- return pagePtr(pages.get(reason));
20
- }
21
-
22
- const ind = pages.size;
23
- pages.set(reason, ind);
24
-
25
- scope.pages ??= new Map();
26
- scope.pages.set(reason, ind);
27
-
28
- return pagePtr(ind);
29
- };
30
-
31
- export const allocBytes = ({ scope, pages }, reason, bytes) => {
32
- bytes += 2; // overallocate by 2 bytes to ensure null termination
33
-
34
- const allocs = pages.allocs ??= new Map();
35
- const bins = pages.bins ??= [];
36
-
37
- if (allocs.has(reason)) {
38
- return allocs.get(reason);
39
- }
40
-
41
- let bin = bins.find(x => (pageSize - x.used) >= bytes);
42
- if (!bin) {
43
- // new bin
44
- const page = pages.size;
45
- bin = {
46
- used: 0,
47
- page
48
- };
49
-
50
- const id = bins.push(bin);
51
- pages.set(`#bin: ${id}`, page);
52
- }
53
-
54
- const ptr = pagePtr(bin.page) + bin.used;
55
- bin.used += bytes;
56
-
57
- allocs.set(reason, ptr);
58
- return ptr;
59
- };
60
-
61
- export const allocStr = ({ scope, pages }, str, bytestring) => {
62
- // basic string interning for ~free
63
- const bytes = 4 + str.length * (bytestring ? 1 : 2);
64
- return allocBytes({ scope, pages }, str, bytes);
65
- };