porffor 0.47.5 → 0.47.7
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 +0 -128
- package/compiler/2c.js +4 -4
- package/compiler/allocator.js +64 -0
- package/compiler/assemble.js +2 -2
- package/compiler/builtins/__internal_string.ts +117 -34
- package/compiler/builtins/function.ts +12 -3
- package/compiler/builtins.js +2 -2
- package/compiler/builtins_objects.js +2 -2
- package/compiler/builtins_precompiled.js +705 -770
- package/compiler/cache.js +44 -0
- package/compiler/codegen.js +182 -302
- package/compiler/index.js +7 -1
- package/compiler/opt.js +1 -1
- package/compiler/parse.js +1 -1
- package/compiler/pgo.js +1 -1
- package/compiler/precompile.js +15 -20
- package/compiler/prototype.js +135 -123
- package/compiler/types.js +1 -1
- package/compiler/wrap.js +5 -5
- package/package.json +1 -1
- package/rhemyn/compile.js +1 -1
- package/runner/index.js +1 -1
- package/runner/repl.js +3 -3
- package/compiler/allocators.js +0 -130
package/README.md
CHANGED
@@ -82,107 +82,6 @@ Rhemyn is Porffor's own regex engine; it compiles literal regex to Wasm bytecode
|
|
82
82
|
### 2c
|
83
83
|
2c is Porffor's own Wasm -> C compiler, using generated Wasm bytecode and internal info to generate specific and efficient/fast C code. Little boilerplate/preluded code or required external files, just for CLI binaries (not like wasm2c very much).
|
84
84
|
|
85
|
-
## Supported
|
86
|
-
See [optimizations](#optimizations) for opts implemented/supported.
|
87
|
-
|
88
|
-
### Proposals
|
89
|
-
These include some early (stage 1/0) and/or dead (last commit years ago) proposals but *I* think they are pretty neat, so.
|
90
|
-
|
91
|
-
#### `Math` proposals (stage 1/0)
|
92
|
-
|
93
|
-
- [`Math.clamp` Proposal](https://github.com/Richienb/proposal-math-clamp): `Math.clamp` (stage 0 - last commit april 2023)
|
94
|
-
- [`Math` Extensions Proposal](https://github.com/rwaldron/proposal-math-extensions): `Math.scale`, `Math.radians`, `Math.degrees`, `Math.RAD_PER_DEG`, `Math.DEG_PER_RAD` (stage 1 - last commit september 2020)
|
95
|
-
- [`Math.signbit` Proposal](https://github.com/tc39/proposal-Math.signbit): `Math.signbit` (stage 1 - last commit february 2020)
|
96
|
-
|
97
|
-
### Language
|
98
|
-
|
99
|
-
- Number literals
|
100
|
-
- Declaring functions
|
101
|
-
- Calling functions
|
102
|
-
- `return`
|
103
|
-
- Basic declarations (`let`/`const`/`var`)
|
104
|
-
- Some basic integer operators (`+-/*%`)
|
105
|
-
- Some basic integer bitwise operators (`&|`)
|
106
|
-
- Equality operators (`==`, `!=`, etc)
|
107
|
-
- GT/LT operators (`>`, `<`, `>=`, etc)
|
108
|
-
- Some unary operators (`!`, `+`, `-`)
|
109
|
-
- Logical operators (`&&`, `||`)
|
110
|
-
- Declaring multiple variables in one (`let a, b = 0`)
|
111
|
-
- Array destructuring (`let [a, ...b] = foo`)
|
112
|
-
- Global variables (`var`/none in top scope)
|
113
|
-
- Booleans
|
114
|
-
- `if` and `if ... else`
|
115
|
-
- Anonymous functions
|
116
|
-
- Setting functions using vars (`const foo = function() { ... }`)
|
117
|
-
- Arrow functions
|
118
|
-
- `undefined`/`null`
|
119
|
-
- Update expressions (`a++`, `++b`, `c--`, etc)
|
120
|
-
- `for` loops (`for (let i = 0; i < N; i++)`, etc)
|
121
|
-
- Basic objects (no prototypes)
|
122
|
-
- `console.log`
|
123
|
-
- `while` loops
|
124
|
-
- `break` and `continue`
|
125
|
-
- Named export funcs
|
126
|
-
- IIFE support
|
127
|
-
- Assignment operators (`+=`, `-=`, `>>=`, `&&=`, etc)
|
128
|
-
- Conditional/ternary operator (`cond ? a : b`)
|
129
|
-
- Recursive functions
|
130
|
-
- Bare returns (`return`)
|
131
|
-
- `throw` (literals only, hack for `new Error`)
|
132
|
-
- Basic `try { ... } catch { ... }` (no error given)
|
133
|
-
- Calling functions with non-matching arguments (eg `f(a, b); f(0); f(1, 2, 3);`)
|
134
|
-
- `typeof`
|
135
|
-
- Runtime errors for undeclared variables (`ReferenceError`), not functions (`TypeError`)
|
136
|
-
- Array creation via `[]` (eg `let arr = [ 1, 2, 3 ]`)
|
137
|
-
- Array member access via `arr[ind]` (eg `arr[0]`)
|
138
|
-
- String literals (`'hello world'`)
|
139
|
-
- String member (char) access via `str[ind]` (eg `str[0]`)
|
140
|
-
- String concat (`+`) (eg `'a' + 'b'`)
|
141
|
-
- Truthy/falsy (eg `!'' == true`)
|
142
|
-
- String comparison (eg `'a' == 'a'`, `'a' != 'b'`)
|
143
|
-
- Nullish coalescing operator (`??`)
|
144
|
-
- `for...of` (arrays and strings)
|
145
|
-
- `for...in`
|
146
|
-
- Array member setting (`arr[0] = 2`, `arr[0] += 2`, etc)
|
147
|
-
- Array constructor (`Array(5)`, `new Array(1, 2, 3)`)
|
148
|
-
- Labelled statements (`foo: while (...)`)
|
149
|
-
- `do...while` loops
|
150
|
-
- Optional parameters (`(foo = 'bar') => { ... }`)
|
151
|
-
- Rest parameters (`(...foo) => { ... }`)
|
152
|
-
- `this`
|
153
|
-
- Constructors (`new Foo`)
|
154
|
-
- Classes (`class A {}`)
|
155
|
-
- Await (`await promise`)
|
156
|
-
|
157
|
-
### Built-ins
|
158
|
-
|
159
|
-
- `NaN` and `Infinity`
|
160
|
-
- `isNaN()` and `isFinite()`
|
161
|
-
- Most of `Number` (`MAX_VALUE`, `MIN_VALUE`, `MAX_SAFE_INTEGER`, `MIN_SAFE_INTEGER`, `POSITIVE_INFINITY`, `NEGATIVE_INFINITY`, `EPSILON`, `NaN`, `isNaN`, `isFinite`, `isInteger`, `isSafeInteger`)
|
162
|
-
- Most `Math` funcs (`sqrt`, `abs`, `floor`, `sign`, `round`, `trunc`, `clz32`, `fround`, `random`, `exp`, `log`, `log2`, `log10`, `pow`, `expm1`, `log1p`, `sqrt`, `cbrt`, `hypot`, `sin`, `cos`, `tan`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `asin`, `acos`, `atan`, `atan2`)
|
163
|
-
- Basic `globalThis` support
|
164
|
-
- Basic `Boolean` and `Number`
|
165
|
-
- Basic `eval` for literals
|
166
|
-
- `Math.random()` using self-made xorshift128+ PRNG
|
167
|
-
- Some of `performance` (`now()`, `timeOrigin`)
|
168
|
-
- Most of `Array.prototype` (`at`, `push`, `pop`, `shift`, `fill`, `slice`, `indexOf`, `lastIndexOf`, `includes`, `with`, `reverse`, `toReversed`, `forEach`, `filter`, `map`, `find`, `findLast`, `findIndex`, `findLastIndex`, `every`, `some`, `reduce`, `reduceRight`, `join`, `toString`)
|
169
|
-
- Most of `Array` (`of`, `isArray`)
|
170
|
-
- Most of `String.prototype` (`at`, `charAt`, `charCodeAt`, `toUpperCase`, `toLowerCase`, `startsWith`, `endsWith`, `indexOf`, `lastIndexOf`, `includes`, `padStart`, `padEnd`, `substring`, `substr`, `slice`, `trimStart`, `trimEnd`, `trim`, `toString`, `big`, `blink`, `bold`, `fixed`, `italics`, `small`, `strike`, `sub`, `sup`, `trimLeft`, `trimRight`, `trim`)
|
171
|
-
- Some of `crypto` (`randomUUID`)
|
172
|
-
- `escape`
|
173
|
-
- `btoa`
|
174
|
-
- Most of `Number.prototype` (`toString`, `toFixed`, `toExponential`)
|
175
|
-
- `parseInt`
|
176
|
-
- Spec-compliant `Date`
|
177
|
-
- WIP typed arrays (`Uint8Array`, `Int32Array`, etc)
|
178
|
-
- Synchronous `Promise`
|
179
|
-
|
180
|
-
### Custom
|
181
|
-
|
182
|
-
- Supports i32, i64, and f64 for valtypes
|
183
|
-
- Intrinsic functions (see below)
|
184
|
-
- Inlining wasm via ``asm`...``\` "macro"
|
185
|
-
|
186
85
|
## Versioning
|
187
86
|
Porffor uses a unique versioning system, here's an example: `0.18.2+2aa3f0589`. Let's break it down:
|
188
87
|
1. `0` - major, always `0` as Porffor is not ready yet
|
@@ -193,33 +92,6 @@ Porffor uses a unique versioning system, here's an example: `0.18.2+2aa3f0589`.
|
|
193
92
|
## Performance
|
194
93
|
*For the features it supports most of the time*, Porffor is *blazingly fast* compared to most interpreters and common engines running without JIT. For those with JIT, it is usually slower by default, but can catch up with compiler arguments and typed input, even more so when compiling to native binaries.
|
195
94
|
|
196
|
-
## Optimizations
|
197
|
-
Mostly for reducing size. I do not really care about compiler perf/time as long as it is reasonable. We do not use/rely on external opt tools (`wasm-opt`, etc), instead doing optimization inside the compiler itself creating even smaller code sizes than `wasm-opt` itself can produce as we have more internal information.
|
198
|
-
|
199
|
-
### Traditional opts
|
200
|
-
- Inlining functions (WIP, limited)
|
201
|
-
- Inline const math ops
|
202
|
-
- Tail calls (behind flag `--tail-call`)
|
203
|
-
|
204
|
-
### Wasm transforms
|
205
|
-
- `local.set`, `local.get` -> `local.tee`
|
206
|
-
- `i32.const 0`, `i32.eq` -> `i32.eqz`
|
207
|
-
- `i64.extend_i32_s`, `i32.wrap_i64` -> ``
|
208
|
-
- `f64.convert_i32_u`, `i32.trunc_sat_f64_s` -> ``
|
209
|
-
- `return`, `end` -> `end`
|
210
|
-
- Change const, convert to const of converted valtype (eg `f64.const`, `i32.trunc_sat_f64_s` -> `i32.const`)
|
211
|
-
- Remove some redundant sets/gets
|
212
|
-
- Remove unneeded single just used vars
|
213
|
-
- Remove unneeded blocks (no `br`s inside)
|
214
|
-
- Remove unused imports
|
215
|
-
- Use data segments for initing arrays/strings
|
216
|
-
- (Likely more not documented yet, todo)
|
217
|
-
|
218
|
-
### Wasm module
|
219
|
-
- Type cache/index (no repeated types)
|
220
|
-
- No main func if empty (and other exports)
|
221
|
-
- No tags if unused/optimized out
|
222
|
-
|
223
95
|
## Test262
|
224
96
|
Porffor can run Test262 via some hacks/transforms which remove unsupported features whilst still doing the same asserts (eg simpler error messages using literals only). It currently passes >14% (see latest commit desc for latest and details). Use `node test262` to test, it will also show a difference of overall results between the last commit and current results.
|
225
97
|
|
package/compiler/2c.js
CHANGED
@@ -2,7 +2,7 @@ import { read_ieee754_binary64, read_signedLEB128, read_unsignedLEB128 } from '.
|
|
2
2
|
import { Blocktype, Opcodes, Valtype } from './wasmSpec.js';
|
3
3
|
import { operatorOpcode } from './expression.js';
|
4
4
|
import { log } from './log.js';
|
5
|
-
import
|
5
|
+
import './prefs.js';
|
6
6
|
|
7
7
|
const CValtype = {
|
8
8
|
i8: 'u8',
|
@@ -222,7 +222,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
222
222
|
|
223
223
|
const activeData = data.filter(x => x.page != null);
|
224
224
|
if (activeData.length > 0) {
|
225
|
-
const dataOffset = x => pages.get(x.page).
|
225
|
+
const dataOffset = x => pages.allocs.get(x.page) ?? (pages.get(x.page) * pageSize);
|
226
226
|
if (Prefs['2cMemcpy']) {
|
227
227
|
prependMain.set('_data', activeData.map(x => `memcpy(_memory + ${dataOffset(x)}, (unsigned char[]){${x.bytes.join(',')}}, ${x.bytes.length});`).join('\n '));
|
228
228
|
} else {
|
@@ -857,7 +857,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
857
857
|
const name = invOpcodes[i[0]];
|
858
858
|
const func = CMemFuncs[i[0]];
|
859
859
|
if (!prepend.has(name)) {
|
860
|
-
prepend.set(name,
|
860
|
+
prepend.set(name, `inline ${func.returns || 'void'} ${name}(i32 align, i32 offset, ${func.args.map((x, i) => `${func.argTypes[i]} ${x}`).join(', ')}) {\n ${func.c.replaceAll('\n', '\n ')}\n}\n`);
|
861
861
|
}
|
862
862
|
|
863
863
|
const immediates = [ i[1], read_unsignedLEB128(i.slice(2)) ];
|
@@ -915,5 +915,5 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
915
915
|
const makeIncludes = includes => [...includes.keys()].map(x => `#include <${x}>\n`).join('');
|
916
916
|
out = platformSpecific(makeIncludes(winIncludes), makeIncludes(unixIncludes), false) + '\n' + makeIncludes(includes) + '\n' + alwaysPreface + [...prepend.values()].join('\n') + '\n\n' + out;
|
917
917
|
|
918
|
-
return `// generated by porffor ${globalThis.version
|
918
|
+
return `// generated by porffor ${globalThis.version}\n` + out.trim();
|
919
919
|
};
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import { PageSize } from './wasmSpec.js';
|
2
|
+
import './prefs.js';
|
3
|
+
|
4
|
+
const pagePtr = ind => {
|
5
|
+
if (ind === 0) return 16;
|
6
|
+
return ind * PageSize;
|
7
|
+
};
|
8
|
+
|
9
|
+
export const nameToReason = (scope, name) => {
|
10
|
+
let scopeName = scope.name;
|
11
|
+
if (globalThis.precompile && scopeName === 'main') scopeName = globalThis.precompile;
|
12
|
+
|
13
|
+
return `${Prefs.scopedPageNames ? (scopeName + '/') : ''}${name}`;
|
14
|
+
};
|
15
|
+
|
16
|
+
export const allocPage = ({ scope, pages }, name) => {
|
17
|
+
const reason = nameToReason(scope, name);
|
18
|
+
|
19
|
+
if (pages.has(reason)) {
|
20
|
+
return pagePtr(pages.get(reason));
|
21
|
+
}
|
22
|
+
|
23
|
+
const ind = pages.size;
|
24
|
+
pages.set(reason, ind);
|
25
|
+
|
26
|
+
scope.pages ??= new Map();
|
27
|
+
scope.pages.set(reason, ind);
|
28
|
+
|
29
|
+
return pagePtr(ind);
|
30
|
+
};
|
31
|
+
|
32
|
+
export const allocBytes = ({ scope, pages }, reason, bytes) => {
|
33
|
+
const allocs = pages.allocs ??= new Map();
|
34
|
+
const bins = pages.bins ??= [];
|
35
|
+
|
36
|
+
if (allocs.has(reason)) {
|
37
|
+
return allocs.get(reason);
|
38
|
+
}
|
39
|
+
|
40
|
+
let bin = bins.find(x => (PageSize - x.used) >= bytes);
|
41
|
+
if (!bin) {
|
42
|
+
// new bin
|
43
|
+
const page = pages.size;
|
44
|
+
bin = {
|
45
|
+
used: 0,
|
46
|
+
page
|
47
|
+
};
|
48
|
+
|
49
|
+
const id = bins.push(bin);
|
50
|
+
pages.set(`#bin_${id}`, page);
|
51
|
+
}
|
52
|
+
|
53
|
+
const ptr = pagePtr(bin.page) + bin.used;
|
54
|
+
bin.used += bytes;
|
55
|
+
|
56
|
+
allocs.set(reason, ptr);
|
57
|
+
return ptr;
|
58
|
+
};
|
59
|
+
|
60
|
+
export const allocStr = ({ scope, pages }, str, bytestring) => {
|
61
|
+
// basic string interning for ~free
|
62
|
+
const bytes = 4 + str.length * (bytestring ? 1 : 2);
|
63
|
+
return allocBytes({ scope, pages }, str, bytes);
|
64
|
+
};
|
package/compiler/assemble.js
CHANGED
@@ -2,7 +2,7 @@ import { Valtype, FuncType, ExportDesc, Section, Magic, ModuleVersion, Opcodes,
|
|
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';
|
5
|
-
import
|
5
|
+
import './prefs.js';
|
6
6
|
|
7
7
|
const createSection = (type, data) => [
|
8
8
|
type,
|
@@ -372,7 +372,7 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
|
372
372
|
const bytes = unsignedLEB128(x.bytes.length).concat(x.bytes);
|
373
373
|
if (x.page != null) {
|
374
374
|
// type: active
|
375
|
-
let offset = pages.get(x.page).
|
375
|
+
let offset = pages.allocs.get(x.page) ?? (pages.get(x.page) * pageSize);
|
376
376
|
if (offset === 0) offset = 16;
|
377
377
|
bytes.unshift(0x00, Opcodes.i32_const, ...signedLEB128(offset), Opcodes.end);
|
378
378
|
} else {
|
@@ -158,44 +158,127 @@ end`;
|
|
158
158
|
return true;
|
159
159
|
} else {
|
160
160
|
// string, string
|
161
|
-
|
162
|
-
|
161
|
+
// change char lengths to byte lengths
|
162
|
+
al *= 2;
|
163
|
+
bl *= 2;
|
164
|
+
|
165
|
+
// copied from bytestring, bytestring
|
166
|
+
let ap32: i32 = a - 28;
|
167
|
+
let bp32: i32 = b - 28;
|
168
|
+
let ap8: i32 = a - 4;
|
169
|
+
let bp8: i32 = b - 4;
|
163
170
|
Porffor.wasm`
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
171
|
+
;; load in 2 i64x2 chunks while length >= 32
|
172
|
+
local.get ${al}
|
173
|
+
i32.const 32
|
174
|
+
i32.ge_s
|
175
|
+
if 64
|
176
|
+
loop 64
|
177
|
+
local.get ${ap32}
|
178
|
+
local.get ${al}
|
179
|
+
i32.add
|
180
|
+
v128.load 0 0
|
181
|
+
|
182
|
+
local.get ${bp32}
|
183
|
+
local.get ${al}
|
184
|
+
i32.add
|
185
|
+
v128.load 0 0
|
186
|
+
v128.xor
|
187
|
+
|
188
|
+
local.get ${ap32}
|
189
|
+
local.get ${al}
|
190
|
+
i32.add
|
191
|
+
v128.load 0 16
|
192
|
+
|
193
|
+
local.get ${bp32}
|
194
|
+
local.get ${al}
|
195
|
+
i32.add
|
196
|
+
v128.load 0 16
|
197
|
+
v128.xor
|
198
|
+
|
199
|
+
v128.or
|
200
|
+
v128.any_true
|
201
|
+
if 64
|
202
|
+
i32.const 0
|
203
|
+
i32.const 2
|
204
|
+
return
|
205
|
+
end
|
206
|
+
|
207
|
+
local.get ${al}
|
208
|
+
i32.const 32
|
209
|
+
i32.sub
|
210
|
+
local.tee ${al}
|
211
|
+
i32.const 32
|
212
|
+
i32.ge_s
|
213
|
+
br_if 0
|
184
214
|
end
|
215
|
+
end
|
185
216
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
217
|
+
;; load in i64 chunks while length >= 8
|
218
|
+
local.get ${al}
|
219
|
+
i32.const 8
|
220
|
+
i32.ge_s
|
221
|
+
if 64
|
222
|
+
loop 64
|
223
|
+
local.get ${ap8}
|
224
|
+
local.get ${al}
|
225
|
+
i32.add
|
226
|
+
i64.load 0 0
|
194
227
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
228
|
+
local.get ${bp8}
|
229
|
+
local.get ${al}
|
230
|
+
i32.add
|
231
|
+
i64.load 0 0
|
232
|
+
|
233
|
+
i64.ne
|
234
|
+
if 64
|
235
|
+
i32.const 0
|
236
|
+
i32.const 2
|
237
|
+
return
|
238
|
+
end
|
239
|
+
|
240
|
+
local.get ${al}
|
241
|
+
i32.const 8
|
242
|
+
i32.sub
|
243
|
+
local.tee ${al}
|
244
|
+
i32.const 8
|
245
|
+
i32.ge_s
|
246
|
+
br_if 0
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
;; load in u16 chunks while length >= 2
|
251
|
+
local.get ${al}
|
252
|
+
i32.const 2
|
253
|
+
i32.ge_s
|
254
|
+
if 64
|
255
|
+
loop 64
|
256
|
+
local.get ${a}
|
257
|
+
local.get ${al}
|
258
|
+
i32.add
|
259
|
+
i32.load16_u 0 2
|
260
|
+
|
261
|
+
local.get ${b}
|
262
|
+
local.get ${al}
|
263
|
+
i32.add
|
264
|
+
i32.load16_u 0 2
|
265
|
+
|
266
|
+
i32.ne
|
267
|
+
if 64
|
268
|
+
i32.const 0
|
269
|
+
i32.const 2
|
270
|
+
return
|
271
|
+
end
|
272
|
+
|
273
|
+
local.get ${al}
|
274
|
+
i32.const 2
|
275
|
+
i32.sub
|
276
|
+
local.tee ${al}
|
277
|
+
i32.const 2
|
278
|
+
i32.ge_s
|
279
|
+
br_if 0
|
280
|
+
end
|
281
|
+
end`;
|
199
282
|
return true;
|
200
283
|
}
|
201
284
|
}
|
@@ -1,7 +1,16 @@
|
|
1
1
|
import type {} from './porffor.d.ts';
|
2
2
|
|
3
3
|
export const __Function_prototype_toString = (_this: Function) => {
|
4
|
-
|
5
|
-
|
4
|
+
const out: bytestring = Porffor.allocate();
|
5
|
+
|
6
|
+
const prefix: bytestring = 'function ';
|
7
|
+
Porffor.bytestring.appendStr(out, prefix);
|
8
|
+
|
9
|
+
Porffor.bytestring.appendStr(out, _this.name);
|
10
|
+
|
11
|
+
const postfix: bytestring = '() { [native code] }';
|
12
|
+
Porffor.bytestring.appendStr(out, postfix);
|
6
13
|
return out;
|
7
|
-
};
|
14
|
+
};
|
15
|
+
|
16
|
+
export const __Function_prototype_toLocaleString = (_this: Function) => __Function_prototype_toString(_this);
|
package/compiler/builtins.js
CHANGED
@@ -3,7 +3,7 @@ import ObjectBuiltins from './builtins_objects.js';
|
|
3
3
|
import { Blocktype, Opcodes, Valtype, ValtypeSize } from './wasmSpec.js';
|
4
4
|
import { number } from './embedding.js';
|
5
5
|
import { TYPES, TYPE_NAMES } from './types.js';
|
6
|
-
import
|
6
|
+
import './prefs.js';
|
7
7
|
import { unsignedLEB128 } from './encoding.js';
|
8
8
|
|
9
9
|
export const importedFuncs = [
|
@@ -860,7 +860,7 @@ export const BuiltinFuncs = function() {
|
|
860
860
|
wasm: (scope, { typeSwitch, makeString }) => {
|
861
861
|
const bc = {};
|
862
862
|
for (const x in TYPE_NAMES) {
|
863
|
-
bc[x] = makeString(scope, TYPE_NAMES[x]
|
863
|
+
bc[x] = makeString(scope, TYPE_NAMES[x]);
|
864
864
|
}
|
865
865
|
|
866
866
|
return typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], bc);
|
@@ -64,7 +64,7 @@ export default function({ builtinFuncs }, Prefs) {
|
|
64
64
|
getPtr,
|
65
65
|
...number(existingFunc ? TYPES.function : TYPES.object, Valtype.i32),
|
66
66
|
|
67
|
-
...makeString(scope, x
|
67
|
+
...makeString(scope, x),
|
68
68
|
Opcodes.i32_to_u,
|
69
69
|
...number(TYPES.bytestring, Valtype.i32),
|
70
70
|
|
@@ -109,7 +109,7 @@ export default function({ builtinFuncs }, Prefs) {
|
|
109
109
|
}
|
110
110
|
|
111
111
|
if (typeof d.value === 'string') {
|
112
|
-
this[k] = (scope, { makeString }) => makeString(scope, d.value
|
112
|
+
this[k] = (scope, { makeString }) => makeString(scope, d.value);
|
113
113
|
this[k].type = TYPES.bytestring;
|
114
114
|
continue;
|
115
115
|
}
|