porffor 0.2.0-fdf0fc5 → 0.14.0-4057a18e9
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 +9 -2
- package/byg/index.js +3 -24
- package/compiler/2c.js +2 -53
- package/compiler/assemble.js +26 -11
- package/compiler/builtins/annexb_string.js +10 -10
- package/compiler/builtins/annexb_string.ts +3 -3
- package/compiler/builtins/array.ts +2 -6
- package/compiler/builtins/base64.ts +1 -1
- package/compiler/builtins/boolean.ts +0 -2
- package/compiler/builtins/crypto.ts +1 -1
- package/compiler/builtins/date.ts +1 -4
- package/compiler/builtins/escape.ts +1 -1
- package/compiler/builtins/function.ts +0 -2
- package/compiler/builtins/int.ts +0 -2
- package/compiler/builtins/number.ts +3 -8
- package/compiler/builtins/object.ts +0 -2
- package/compiler/builtins/porffor.d.ts +9 -8
- package/compiler/builtins/set.ts +184 -2
- package/compiler/builtins/string.ts +1 -1
- package/compiler/builtins.js +4 -7
- package/compiler/codegen.js +21 -106
- package/compiler/decompile.js +2 -2
- package/compiler/embedding.js +2 -2
- package/compiler/encoding.js +0 -14
- package/compiler/expression.js +1 -1
- package/compiler/generated_builtins.js +303 -204
- package/compiler/index.js +0 -2
- package/compiler/opt.js +7 -7
- package/compiler/parse.js +1 -3
- package/compiler/precompile.js +17 -25
- package/compiler/prototype.js +5 -5
- package/compiler/wasmSpec.js +5 -0
- package/compiler/wrap.js +69 -56
- package/package.json +1 -1
- package/runner/compare.js +0 -1
- package/runner/debug.js +1 -6
- package/runner/profiler.js +15 -42
- package/runner/repl.js +3 -9
- package/runner/sizes.js +2 -2
- package/runner/version.js +10 -8
package/compiler/builtins/set.ts
CHANGED
@@ -1,5 +1,187 @@
|
|
1
|
-
//
|
1
|
+
// dark wasm magic for dealing with memory, sorry.
|
2
|
+
export const __Porffor_allocate = (): number => {
|
3
|
+
Porffor.wasm`i32.const 1
|
4
|
+
memory.grow 0
|
5
|
+
drop
|
6
|
+
memory.size 0
|
7
|
+
i32.const 1
|
8
|
+
i32.sub
|
9
|
+
i32.const 65536
|
10
|
+
i32.mul
|
11
|
+
i32.from_u
|
12
|
+
return`;
|
13
|
+
};
|
2
14
|
|
3
|
-
export const
|
15
|
+
export const __Porffor_set_read = (_this: Set, index: number): any => {
|
16
|
+
Porffor.wasm`
|
17
|
+
local offset i32
|
18
|
+
local.get ${index}
|
19
|
+
i32.to_u
|
20
|
+
i32.const 9
|
21
|
+
i32.mul
|
22
|
+
local.get ${_this}
|
23
|
+
i32.to_u
|
24
|
+
i32.add
|
25
|
+
local.set offset
|
4
26
|
|
27
|
+
local.get offset
|
28
|
+
f64.load 0 4
|
29
|
+
|
30
|
+
local.get offset
|
31
|
+
i32.load8_u 0 12
|
32
|
+
return`;
|
33
|
+
};
|
34
|
+
|
35
|
+
export const __Porffor_set_write = (_this: Set, index: number, value: any): boolean => {
|
36
|
+
Porffor.wasm`
|
37
|
+
local offset i32
|
38
|
+
local.get ${index}
|
39
|
+
i32.to_u
|
40
|
+
i32.const 9
|
41
|
+
i32.mul
|
42
|
+
local.get ${_this}
|
43
|
+
i32.to_u
|
44
|
+
i32.add
|
45
|
+
local.set offset
|
46
|
+
|
47
|
+
local.get offset
|
48
|
+
local.get ${value}
|
49
|
+
f64.store 0 4
|
50
|
+
|
51
|
+
local.get offset
|
52
|
+
local.get ${value+1}
|
53
|
+
i32.store8 0 12`;
|
54
|
+
|
55
|
+
return true;
|
56
|
+
};
|
57
|
+
|
58
|
+
|
59
|
+
// todo: this should be a getter somehow not a method
|
60
|
+
export const __Set_prototype_size = (_this: Set) => {
|
61
|
+
return Porffor.wasm.i32.load(_this, 0, 0);
|
62
|
+
};
|
63
|
+
|
64
|
+
export const __Set_prototype_values = (_this: Set) => {
|
65
|
+
// todo: this should return an iterator not array
|
66
|
+
const size: number = __Set_prototype_size(_this);
|
67
|
+
|
68
|
+
const out: any[] = __Porffor_allocate();
|
69
|
+
for (let i: number = 0; i < size; i++) {
|
70
|
+
const val: any = __Porffor_set_read(_this, i);
|
71
|
+
out.push(val);
|
72
|
+
}
|
73
|
+
|
74
|
+
return out;
|
75
|
+
};
|
76
|
+
|
77
|
+
export const __Set_prototype_keys = (_this: Set) => {
|
78
|
+
return __Set_prototype_values(_this);
|
79
|
+
};
|
80
|
+
|
81
|
+
export const __Set_prototype_has = (_this: Set, value: any) => {
|
82
|
+
const size: number = __Set_prototype_size(_this);
|
83
|
+
|
84
|
+
for (let i: number = 0; i < size; i++) {
|
85
|
+
if (__Porffor_set_read(_this, i) === value) return true;
|
86
|
+
}
|
87
|
+
|
88
|
+
return false;
|
89
|
+
};
|
90
|
+
|
91
|
+
export const __Set_prototype_add = (_this: Set, value: any) => {
|
92
|
+
const size: number = __Set_prototype_size(_this);
|
93
|
+
|
94
|
+
// check if already in set
|
95
|
+
for (let i: number = 0; i < size; i++) {
|
96
|
+
if (__Porffor_set_read(_this, i) === value) return _this;
|
97
|
+
}
|
98
|
+
|
99
|
+
// not, add it
|
100
|
+
// increment size by 1
|
101
|
+
Porffor.wasm.i32.store(_this, size + 1, 0, 0);
|
102
|
+
|
103
|
+
// write new value at end
|
104
|
+
__Porffor_set_write(_this, size, value);
|
105
|
+
|
106
|
+
return _this;
|
107
|
+
};
|
108
|
+
|
109
|
+
export const __Set_prototype_delete = (_this: Set, value: any) => {
|
110
|
+
const size: number = __Set_prototype_size(_this);
|
111
|
+
|
112
|
+
// check if already in set
|
113
|
+
for (let i: number = 0; i < size; i++) {
|
114
|
+
if (__Porffor_set_read(_this, i) === value) {
|
115
|
+
// found, delete
|
116
|
+
// decrement size by 1
|
117
|
+
Porffor.wasm.i32.store(_this, size - 1, 0, 0);
|
118
|
+
|
119
|
+
// offset all elements after by -1 ind
|
120
|
+
Porffor.wasm`
|
121
|
+
local offset i32
|
122
|
+
local.get ${i}
|
123
|
+
i32.to_u
|
124
|
+
i32.const 9
|
125
|
+
i32.mul
|
126
|
+
local.get ${_this}
|
127
|
+
i32.to_u
|
128
|
+
i32.add
|
129
|
+
i32.const 4
|
130
|
+
i32.add
|
131
|
+
local.set offset
|
132
|
+
|
133
|
+
;; dst = offset (this element)
|
134
|
+
local.get offset
|
135
|
+
|
136
|
+
;; src = offset + 9 (this element + 1 element)
|
137
|
+
local.get offset
|
138
|
+
i32.const 9
|
139
|
+
i32.add
|
140
|
+
|
141
|
+
;; size = (size - i - 1) * 9
|
142
|
+
local.get ${size}
|
143
|
+
local.get ${i}
|
144
|
+
f64.sub
|
145
|
+
i32.to_u
|
146
|
+
i32.const 1
|
147
|
+
i32.sub
|
148
|
+
i32.const 9
|
149
|
+
i32.mul
|
150
|
+
|
151
|
+
memory.copy 0 0`;
|
152
|
+
|
153
|
+
return true;
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
// not, return false
|
158
|
+
return false;
|
159
|
+
};
|
160
|
+
|
161
|
+
export const __Set_prototype_clear = (_this: Set) => {
|
162
|
+
// just set size to 0
|
163
|
+
// do not need to delete any as will not be accessed anymore,
|
164
|
+
// and will be overwritten with new add
|
165
|
+
Porffor.wasm.i32.store(_this, 0, 0, 0);
|
166
|
+
};
|
167
|
+
|
168
|
+
export const Set = () => {
|
169
|
+
throw new TypeError("Constructor Set requires 'new'");
|
170
|
+
};
|
171
|
+
|
172
|
+
export const Set$constructor = (iterable: any): Set => {
|
173
|
+
const out: Set = __Porffor_allocate();
|
174
|
+
|
175
|
+
const type: number = Porffor.rawType(iterable);
|
176
|
+
if (Porffor.fastOr(
|
177
|
+
type == Porffor.TYPES.array,
|
178
|
+
type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
|
179
|
+
type == Porffor.TYPES.set
|
180
|
+
)) {
|
181
|
+
for (const x of iterable) {
|
182
|
+
__Set_prototype_add(out, x);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
return out;
|
5
187
|
};
|
package/compiler/builtins.js
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
import { Blocktype, Opcodes, Valtype, ValtypeSize } from "./wasmSpec.js";
|
2
|
-
import { number, i32x4 } from "./embedding.js";
|
3
|
-
import Prefs from './prefs.js';
|
4
1
|
import * as GeneratedBuiltins from './generated_builtins.js';
|
2
|
+
import { Blocktype, Opcodes, Valtype, ValtypeSize } from './wasmSpec.js';
|
3
|
+
import { number } from './embedding.js';
|
5
4
|
import { TYPES } from './types.js';
|
5
|
+
import Prefs from './prefs.js';
|
6
6
|
|
7
7
|
export const importedFuncs = [
|
8
8
|
{
|
@@ -48,8 +48,6 @@ for (let i = 0; i < importedFuncs.length; i++) {
|
|
48
48
|
importedFuncs[f.name] = i;
|
49
49
|
}
|
50
50
|
|
51
|
-
const char = c => number(c.charCodeAt(0));
|
52
|
-
|
53
51
|
const printStaticStr = str => {
|
54
52
|
const out = [];
|
55
53
|
|
@@ -140,7 +138,7 @@ export const BuiltinVars = function() {
|
|
140
138
|
this.Math = number(1);
|
141
139
|
|
142
140
|
// wintercg(tm)
|
143
|
-
this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.
|
141
|
+
this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.14.0`, false, '__navigator_userAgent');
|
144
142
|
this.__navigator_userAgent.type = Prefs.bytestring ? TYPES.bytestring : TYPES.string;
|
145
143
|
|
146
144
|
for (const x in TYPES) {
|
@@ -569,7 +567,6 @@ export const BuiltinFuncs = function() {
|
|
569
567
|
|
570
568
|
// this is an implementation of xorshift128+ (in wasm bytecode)
|
571
569
|
// fun fact: v8, SM, JSC also use this (you will need this fun fact to maintain your sanity reading this code)
|
572
|
-
// const prngSeed0 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER), prngSeed1 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
|
573
570
|
const prngSeed0 = (Math.random() * (2 ** 30)) | 0, prngSeed1 = (Math.random() * (2 ** 30)) | 0;
|
574
571
|
|
575
572
|
const prng = ({
|
package/compiler/codegen.js
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
import { Blocktype, Opcodes, Valtype, PageSize, ValtypeSize } from
|
2
|
-
import { ieee754_binary64, signedLEB128, unsignedLEB128, encodeVector } from
|
3
|
-
import { operatorOpcode } from
|
4
|
-
import { BuiltinFuncs, BuiltinVars, importedFuncs, NULL, UNDEFINED } from
|
5
|
-
import { PrototypeFuncs } from
|
6
|
-
import { number
|
7
|
-
import { log } from "./log.js";
|
8
|
-
import parse from "./parse.js";
|
9
|
-
import * as Rhemyn from "../rhemyn/compile.js";
|
10
|
-
import Prefs from './prefs.js';
|
1
|
+
import { Blocktype, Opcodes, Valtype, PageSize, ValtypeSize } from './wasmSpec.js';
|
2
|
+
import { ieee754_binary64, signedLEB128, unsignedLEB128, encodeVector } from './encoding.js';
|
3
|
+
import { operatorOpcode } from './expression.js';
|
4
|
+
import { BuiltinFuncs, BuiltinVars, importedFuncs, NULL, UNDEFINED } from './builtins.js';
|
5
|
+
import { PrototypeFuncs } from './prototype.js';
|
6
|
+
import { number } from './embedding.js';
|
11
7
|
import { TYPES, TYPE_NAMES } from './types.js';
|
8
|
+
import * as Rhemyn from '../rhemyn/compile.js';
|
9
|
+
import parse from './parse.js';
|
10
|
+
import { log } from './log.js';
|
11
|
+
import Prefs from './prefs.js';
|
12
12
|
|
13
13
|
let globals = {};
|
14
14
|
let globalInd = 0;
|
@@ -19,24 +19,6 @@ let funcIndex = {};
|
|
19
19
|
let currentFuncIndex = importedFuncs.length;
|
20
20
|
let builtinFuncs = {}, builtinVars = {}, prototypeFuncs = {};
|
21
21
|
|
22
|
-
const debug = str => {
|
23
|
-
const code = [];
|
24
|
-
|
25
|
-
const logChar = n => {
|
26
|
-
code.push(...number(n));
|
27
|
-
|
28
|
-
code.push([ Opcodes.call, 0 ]);
|
29
|
-
};
|
30
|
-
|
31
|
-
for (let i = 0; i < str.length; i++) {
|
32
|
-
logChar(str.charCodeAt(i));
|
33
|
-
}
|
34
|
-
|
35
|
-
logChar(10); // new line
|
36
|
-
|
37
|
-
return code;
|
38
|
-
};
|
39
|
-
|
40
22
|
class TodoError extends Error {
|
41
23
|
constructor(message) {
|
42
24
|
super(message);
|
@@ -171,11 +153,6 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
171
153
|
newFunc.export = true;
|
172
154
|
}
|
173
155
|
|
174
|
-
// if (funcsBefore === funcs.length) throw new Error('no new func added in export');
|
175
|
-
|
176
|
-
// const newFunc = funcs[funcs.length - 1];
|
177
|
-
// newFunc.export = true;
|
178
|
-
|
179
156
|
return [];
|
180
157
|
|
181
158
|
case 'TaggedTemplateExpression': {
|
@@ -858,31 +835,6 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
858
835
|
|
859
836
|
// if strict (in)equal check types match
|
860
837
|
if (strictOp) {
|
861
|
-
// startOut.push(
|
862
|
-
// ...leftType,
|
863
|
-
// ...rightType,
|
864
|
-
// [ Opcodes.i32_eq ]
|
865
|
-
// );
|
866
|
-
|
867
|
-
// endOut.push(
|
868
|
-
// [ Opcodes.i32_and ]
|
869
|
-
// );
|
870
|
-
|
871
|
-
// startOut.push(
|
872
|
-
// [ Opcodes.block, Valtype.i32 ],
|
873
|
-
// ...leftType,
|
874
|
-
// ...rightType,
|
875
|
-
// [ Opcodes.i32_ne ],
|
876
|
-
// [ Opcodes.if, Blocktype.void ],
|
877
|
-
// ...number(op === '===' ? 0 : 1, Valtype.i32),
|
878
|
-
// [ Opcodes.br, 1 ],
|
879
|
-
// [ Opcodes.end ]
|
880
|
-
// );
|
881
|
-
|
882
|
-
// endOut.push(
|
883
|
-
// [ Opcodes.end ]
|
884
|
-
// );
|
885
|
-
|
886
838
|
endOut.push(
|
887
839
|
...leftType,
|
888
840
|
...rightType,
|
@@ -1089,7 +1041,7 @@ const generateBinaryExp = (scope, decl, _global, _name) => {
|
|
1089
1041
|
|
1090
1042
|
const asmFuncToAsm = (func, { name = '#unknown_asm_func', params = [], locals = [], returns = [], localInd = 0 }) => {
|
1091
1043
|
return func({ name, params, locals, returns, localInd }, {
|
1092
|
-
TYPES, TYPE_NAMES, typeSwitch, makeArray, makeString, allocPage,
|
1044
|
+
TYPES, TYPE_NAMES, typeSwitch, makeArray, makeString, allocPage, internalThrow,
|
1093
1045
|
builtin: name => {
|
1094
1046
|
let idx = funcIndex[name] ?? importedFuncs[name];
|
1095
1047
|
if (idx === undefined && builtinFuncs[name]) {
|
@@ -1248,7 +1200,7 @@ const setLastType = scope => {
|
|
1248
1200
|
};
|
1249
1201
|
|
1250
1202
|
const getNodeType = (scope, node) => {
|
1251
|
-
const
|
1203
|
+
const ret = (() => {
|
1252
1204
|
if (node.type === 'Literal') {
|
1253
1205
|
if (node.regex) return TYPES.regexp;
|
1254
1206
|
|
@@ -1291,7 +1243,6 @@ const getNodeType = (scope, node) => {
|
|
1291
1243
|
const func = funcs.find(x => x.name === name);
|
1292
1244
|
|
1293
1245
|
if (func) {
|
1294
|
-
// console.log(scope, func, func.returnType);
|
1295
1246
|
if (func.returnType) return func.returnType;
|
1296
1247
|
}
|
1297
1248
|
|
@@ -1435,10 +1386,8 @@ const getNodeType = (scope, node) => {
|
|
1435
1386
|
// presume
|
1436
1387
|
// todo: warn here?
|
1437
1388
|
return TYPES.number;
|
1438
|
-
};
|
1389
|
+
})();
|
1439
1390
|
|
1440
|
-
const ret = inner();
|
1441
|
-
// console.trace(node, ret);
|
1442
1391
|
if (typeof ret === 'number') return number(ret, Valtype.i32);
|
1443
1392
|
return ret;
|
1444
1393
|
};
|
@@ -1577,15 +1526,6 @@ const RTArrayUtil = {
|
|
1577
1526
|
};
|
1578
1527
|
|
1579
1528
|
const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
1580
|
-
/* const callee = decl.callee;
|
1581
|
-
const args = decl.arguments;
|
1582
|
-
|
1583
|
-
return [
|
1584
|
-
...generate(args),
|
1585
|
-
...generate(callee),
|
1586
|
-
Opcodes.call_indirect,
|
1587
|
-
]; */
|
1588
|
-
|
1589
1529
|
let name = mapName(decl.callee.name);
|
1590
1530
|
if (isFuncType(decl.callee.type)) { // iife
|
1591
1531
|
const func = generateFunc(scope, decl.callee);
|
@@ -1759,8 +1699,6 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1759
1699
|
continue;
|
1760
1700
|
}
|
1761
1701
|
|
1762
|
-
// const protoLocal = protoFunc.local ? localTmp(scope, `__${TYPE_NAMES[x]}_${protoName}_tmp`, protoFunc.local) : -1;
|
1763
|
-
// const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${TYPE_NAMES[x]}_${protoName}_tmp2`, protoFunc.local2) : -1;
|
1764
1702
|
const protoLocal = protoFunc.local ? localTmp(scope, `__${protoName}_tmp`, protoFunc.local) : -1;
|
1765
1703
|
const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${protoName}_tmp2`, protoFunc.local2) : -1;
|
1766
1704
|
|
@@ -1837,22 +1775,6 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1837
1775
|
|
1838
1776
|
includeBuiltin(scope, name);
|
1839
1777
|
idx = funcIndex[name];
|
1840
|
-
|
1841
|
-
// infer arguments types from builtins params
|
1842
|
-
// const func = funcs.find(x => x.name === name);
|
1843
|
-
// for (let i = 0; i < decl.arguments.length; i++) {
|
1844
|
-
// const arg = decl.arguments[i];
|
1845
|
-
// if (!arg.name) continue;
|
1846
|
-
|
1847
|
-
// const local = scope.locals[arg.name];
|
1848
|
-
// if (!local) continue;
|
1849
|
-
|
1850
|
-
// local.type = func.params[i];
|
1851
|
-
// if (local.type === Valtype.v128) {
|
1852
|
-
// // specify vec subtype inferred from last vec type in function name
|
1853
|
-
// local.vecType = name.split('_').reverse().find(x => x.includes('x'));
|
1854
|
-
// }
|
1855
|
-
// }
|
1856
1778
|
}
|
1857
1779
|
|
1858
1780
|
if (idx === undefined && internalConstrs[name]) return internalConstrs[name].generate(scope, decl, _global, _name);
|
@@ -2178,7 +2100,6 @@ const addVarMetadata = (scope, name, global = false, metadata = {}) => {
|
|
2178
2100
|
const typeAnnoToPorfType = x => {
|
2179
2101
|
if (!x) return null;
|
2180
2102
|
if (TYPES[x.toLowerCase()] != null) return TYPES[x.toLowerCase()];
|
2181
|
-
if (TYPES['_' + x.toLowerCase()] != null) return TYPES['_' + x.toLowerCase()];
|
2182
2103
|
|
2183
2104
|
switch (x) {
|
2184
2105
|
case 'i32':
|
@@ -2219,9 +2140,8 @@ const generateVar = (scope, decl) => {
|
|
2219
2140
|
|
2220
2141
|
const topLevel = scope.name === 'main';
|
2221
2142
|
|
2222
|
-
// global variable if in top scope (main)
|
2223
|
-
const global = topLevel || decl._bare;
|
2224
|
-
const target = global ? globals : scope.locals;
|
2143
|
+
// global variable if in top scope (main) or if internally wanted
|
2144
|
+
const global = topLevel || decl._bare;
|
2225
2145
|
|
2226
2146
|
for (const x of decl.declarations) {
|
2227
2147
|
const name = mapName(x.id.name);
|
@@ -2235,7 +2155,6 @@ const generateVar = (scope, decl) => {
|
|
2235
2155
|
continue;
|
2236
2156
|
}
|
2237
2157
|
|
2238
|
-
// console.log(name);
|
2239
2158
|
if (topLevel && builtinVars[name]) {
|
2240
2159
|
// cannot redeclare
|
2241
2160
|
if (decl.kind !== 'var') return internalThrow(scope, 'SyntaxError', `Identifier '${unhackName(name)}' has already been declared`);
|
@@ -3036,13 +2955,6 @@ const generateEmpty = (scope, decl) => {
|
|
3036
2955
|
return [];
|
3037
2956
|
};
|
3038
2957
|
|
3039
|
-
const generateAssignPat = (scope, decl) => {
|
3040
|
-
// TODO
|
3041
|
-
// if identifier declared, use that
|
3042
|
-
// else, use default (right)
|
3043
|
-
return todo(scope, 'assignment pattern (optional arg)');
|
3044
|
-
};
|
3045
|
-
|
3046
2958
|
let pages = new Map();
|
3047
2959
|
const allocPage = (scope, reason, type) => {
|
3048
2960
|
if (pages.has(reason)) return pages.get(reason).ind;
|
@@ -3455,8 +3367,11 @@ const generateFunc = (scope, decl) => {
|
|
3455
3367
|
};
|
3456
3368
|
|
3457
3369
|
if (typedInput && decl.returnType) {
|
3458
|
-
|
3459
|
-
|
3370
|
+
const { type } = extractTypeAnnotation(decl.returnType);
|
3371
|
+
if (type != null) {
|
3372
|
+
innerScope.returnType = type;
|
3373
|
+
innerScope.returns = [ valtypeBinary ];
|
3374
|
+
}
|
3460
3375
|
}
|
3461
3376
|
|
3462
3377
|
for (let i = 0; i < params.length; i++) {
|
@@ -3498,7 +3413,7 @@ const generateFunc = (scope, decl) => {
|
|
3498
3413
|
if (name !== 'main' && wasm[wasm.length - 1]?.[0] !== Opcodes.return && countLeftover(wasm) === 0) {
|
3499
3414
|
wasm.push(
|
3500
3415
|
...number(0),
|
3501
|
-
...number(TYPES.undefined, Valtype.i32),
|
3416
|
+
...(innerScope.returnType != null ? [] : number(TYPES.undefined, Valtype.i32)),
|
3502
3417
|
[ Opcodes.return ]
|
3503
3418
|
);
|
3504
3419
|
}
|
package/compiler/decompile.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import { Blocktype, Opcodes, Valtype } from
|
2
|
-
import { read_ieee754_binary64, read_signedLEB128, read_unsignedLEB128 } from
|
1
|
+
import { Blocktype, Opcodes, Valtype } from './wasmSpec.js';
|
2
|
+
import { read_ieee754_binary64, read_signedLEB128, read_unsignedLEB128 } from './encoding.js';
|
3
3
|
|
4
4
|
const inv = (obj, keyMap = x => x) => Object.keys(obj).reduce((acc, x) => { acc[keyMap(obj[x])] = x; return acc; }, {});
|
5
5
|
const invOpcodes = inv(Opcodes);
|
package/compiler/embedding.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import { Opcodes, Valtype } from
|
2
|
-
import { signedLEB128, ieee754_binary64 } from
|
1
|
+
import { Opcodes, Valtype } from './wasmSpec.js';
|
2
|
+
import { signedLEB128, ieee754_binary64 } from './encoding.js';
|
3
3
|
|
4
4
|
export const number = (n, valtype = valtypeBinary) => {
|
5
5
|
switch (valtype) {
|
package/compiler/encoding.js
CHANGED
@@ -7,21 +7,7 @@ export const codifyString = str => {
|
|
7
7
|
return out;
|
8
8
|
};
|
9
9
|
|
10
|
-
// export const encodeString = str => [
|
11
|
-
// str.length,
|
12
|
-
// ...codifyString(str)
|
13
|
-
// ];
|
14
10
|
export const encodeString = str => unsignedLEB128(str.length).concat(codifyString(str));
|
15
|
-
|
16
|
-
// export const encodeVector = data => [
|
17
|
-
// ...unsignedLEB128(data.length),
|
18
|
-
// ...data.flat()
|
19
|
-
// ];
|
20
|
-
// export const encodeVector = data => {
|
21
|
-
// const out = data.flat();
|
22
|
-
// out.unshift.apply(out, unsignedLEB128(data.length));
|
23
|
-
// return out;
|
24
|
-
// };
|
25
11
|
export const encodeVector = data => unsignedLEB128(data.length).concat(data.flat());
|
26
12
|
|
27
13
|
export const encodeLocal = (count, type) => [
|
package/compiler/expression.js
CHANGED