porffor 0.22.6 → 0.22.8
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/compiler/assemble.js +23 -2
- package/compiler/builtins/_internal_object.ts +36 -7
- package/compiler/builtins/object.ts +3 -1
- package/compiler/builtins/reflect.ts +113 -15
- package/compiler/codegen.js +3 -4
- package/compiler/generated_builtins.js +80 -21
- package/compiler/precompile.js +2 -1
- package/compiler/wrap.js +8 -1
- package/package.json +1 -1
- package/runner/index.js +1 -1
- package/tmp.txt +423 -0
package/compiler/assemble.js
CHANGED
@@ -107,6 +107,8 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
107
107
|
}
|
108
108
|
|
109
109
|
if (inst[0] === Opcodes.call_indirect) {
|
110
|
+
if (!funcs.table) funcs.table = true;
|
111
|
+
|
110
112
|
const params = [];
|
111
113
|
for (let i = 0; i < inst[1]; i++) {
|
112
114
|
params.push(valtypeBinary, Valtype.i32);
|
@@ -230,7 +232,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
230
232
|
// };
|
231
233
|
// }
|
232
234
|
|
233
|
-
const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, x.index ]);
|
235
|
+
const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.index) ]);
|
234
236
|
|
235
237
|
if (Prefs.alwaysMemory && pages.size === 0) pages.set('--always-memory', 0);
|
236
238
|
if (optLevel === 0) pages.set('O0 precaution', 0);
|
@@ -276,7 +278,26 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
276
278
|
|
277
279
|
if (typeCount !== 0) localDecl.push(encodeLocal(typeCount, lastType));
|
278
280
|
|
279
|
-
|
281
|
+
// todo: move const, call transforms here too?
|
282
|
+
|
283
|
+
const wasm = [];
|
284
|
+
for (let i = 0; i < x.wasm.length; i++) {
|
285
|
+
let o = x.wasm[i];
|
286
|
+
|
287
|
+
if (
|
288
|
+
(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) &&
|
289
|
+
o[1] > 127
|
290
|
+
) {
|
291
|
+
const n = o[1];
|
292
|
+
o = [...o];
|
293
|
+
o.pop();
|
294
|
+
unsignedLEB128_into(n, o);
|
295
|
+
}
|
296
|
+
|
297
|
+
wasm.push(...o);
|
298
|
+
}
|
299
|
+
|
300
|
+
return encodeVector([ ...encodeVector(localDecl), ...wasm.flat().filter(x => x != null && x <= 0xff), Opcodes.end ]);
|
280
301
|
}))
|
281
302
|
);
|
282
303
|
|
@@ -63,6 +63,33 @@ export const __Porffor_object_checkAllFlags = (_this: object, dataAnd: i32, acce
|
|
63
63
|
};
|
64
64
|
|
65
65
|
|
66
|
+
export const __Porffor_object_packAccessor = (get: i32, set: i32): f64 => {
|
67
|
+
// pack i32s get & set into a single f64 (i64)
|
68
|
+
Porffor.wasm`
|
69
|
+
local.get ${set}
|
70
|
+
i64.extend_i32_u
|
71
|
+
i64.const 32
|
72
|
+
i64.shl
|
73
|
+
local.get ${get}
|
74
|
+
i64.extend_i32_u
|
75
|
+
i64.or
|
76
|
+
|
77
|
+
f64.reinterpret_i64
|
78
|
+
i32.const 1
|
79
|
+
return`;
|
80
|
+
};
|
81
|
+
|
82
|
+
export const __Porffor_object_accessorGet = (entryPtr: i32): Function => {
|
83
|
+
const out: Function = Porffor.wasm.i32.load(entryPtr, 0, 4);
|
84
|
+
return out;
|
85
|
+
};
|
86
|
+
|
87
|
+
export const __Porffor_object_accessorSet = (entryPtr: i32): Function => {
|
88
|
+
const out: Function = Porffor.wasm.i32.load(entryPtr, 0, 8);
|
89
|
+
return out;
|
90
|
+
};
|
91
|
+
|
92
|
+
|
66
93
|
export const __Porffor_object_lookup = (_this: object, target: any): i32 => {
|
67
94
|
const targetType: i32 = Porffor.wasm`local.get ${target+1}`;
|
68
95
|
|
@@ -120,11 +147,10 @@ return`;
|
|
120
147
|
|
121
148
|
if (tail & 0b0001) {
|
122
149
|
// accessor descriptor
|
123
|
-
|
124
|
-
|
150
|
+
const get: Function = __Porffor_object_accessorGet(entryPtr);
|
125
151
|
Porffor.wasm`
|
126
|
-
|
127
|
-
|
152
|
+
local.get ${get}
|
153
|
+
call_indirect 0 0
|
128
154
|
return`;
|
129
155
|
}
|
130
156
|
|
@@ -178,7 +204,12 @@ export const __Porffor_object_set = (_this: object, key: any, value: any): any =
|
|
178
204
|
|
179
205
|
if (tail & 0b0001) {
|
180
206
|
// accessor descriptor
|
181
|
-
|
207
|
+
const set: Function = __Porffor_object_accessorSet(entryPtr);
|
208
|
+
Porffor.wasm`
|
209
|
+
local.get ${value}
|
210
|
+
local.get ${value+1}
|
211
|
+
local.get ${set}
|
212
|
+
call_indirect 1 0`;
|
182
213
|
|
183
214
|
return value;
|
184
215
|
}
|
@@ -325,7 +356,6 @@ export const __Porffor_object_isObject = (arg: any): boolean => {
|
|
325
356
|
return Porffor.fastAnd(
|
326
357
|
arg != 0, // null
|
327
358
|
t > 0x05,
|
328
|
-
t != Porffor.TYPES.undefined,
|
329
359
|
t != Porffor.TYPES.string,
|
330
360
|
t != Porffor.TYPES.bytestring,
|
331
361
|
);
|
@@ -336,7 +366,6 @@ export const __Porffor_object_isObjectOrSymbol = (arg: any): boolean => {
|
|
336
366
|
return Porffor.fastAnd(
|
337
367
|
arg != 0, // null
|
338
368
|
t > 0x04,
|
339
|
-
t != Porffor.TYPES.undefined,
|
340
369
|
t != Porffor.TYPES.string,
|
341
370
|
t != Porffor.TYPES.bytestring,
|
342
371
|
);
|
@@ -227,6 +227,7 @@ export const __Object_defineProperty = (target: any, prop: any, descriptor: any)
|
|
227
227
|
}
|
228
228
|
|
229
229
|
accessor = true;
|
230
|
+
value = Porffor.object.packAccessor(get, set);
|
230
231
|
}
|
231
232
|
|
232
233
|
let flags: i32 = 0b0000;
|
@@ -412,7 +413,8 @@ export const __Object_getOwnPropertyDescriptor = (obj: any, prop: any): any => {
|
|
412
413
|
out.enumerable = Boolean(tail & 0b0100);
|
413
414
|
|
414
415
|
if (tail & 0b0001) {
|
415
|
-
|
416
|
+
out.get = Porffor.object.accessorGet(entryPtr);
|
417
|
+
out.set = Porffor.object.accessorSet(entryPtr);
|
416
418
|
|
417
419
|
return out;
|
418
420
|
}
|
@@ -1,34 +1,132 @@
|
|
1
1
|
import type {} from './porffor.d.ts';
|
2
2
|
|
3
3
|
// todo: support receiver
|
4
|
-
export const __Reflect_get = (target: any,
|
4
|
+
export const __Reflect_get = (target: any, prop: any) => {
|
5
5
|
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
6
6
|
|
7
|
-
|
7
|
+
return target[prop];
|
8
|
+
};
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
// todo: support receiver
|
11
|
+
export const __Reflect_set = (target: any, prop: any, value: any) => {
|
12
|
+
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
13
|
+
|
14
|
+
try {
|
15
|
+
target[prop] = value;
|
16
|
+
return true;
|
17
|
+
} catch {
|
18
|
+
return false;
|
12
19
|
}
|
20
|
+
};
|
13
21
|
|
14
|
-
|
15
|
-
|
16
|
-
if (idx == -1) return undefined;
|
22
|
+
export const __Reflect_has = (target: any, prop: any) => {
|
23
|
+
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
17
24
|
|
18
|
-
|
19
|
-
return vals[idx];
|
25
|
+
return prop in target;
|
20
26
|
};
|
21
27
|
|
22
|
-
export const
|
28
|
+
export const __Reflect_defineProperty = (target: any, prop: any, descriptor: any) => {
|
23
29
|
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
30
|
+
if (!Porffor.object.isObject(descriptor)) throw new TypeError('Descriptor is a non-object');
|
24
31
|
|
25
|
-
|
32
|
+
try {
|
33
|
+
Object.defineProperty(target, prop, descriptor);
|
34
|
+
return true;
|
35
|
+
} catch {
|
36
|
+
return false;
|
37
|
+
}
|
38
|
+
};
|
39
|
+
|
40
|
+
export const __Reflect_deleteProperty = (target: any, prop: any) => {
|
41
|
+
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
42
|
+
|
43
|
+
return delete target[prop];
|
44
|
+
};
|
45
|
+
|
46
|
+
export const __Reflect_getOwnPropertyDescriptor = (target: any, prop: any) => {
|
47
|
+
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
48
|
+
|
49
|
+
return Object.getOwnPropertyDescriptor(target, prop);
|
50
|
+
};
|
51
|
+
|
52
|
+
export const __Reflect_isExtensible = (target: any) => {
|
53
|
+
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
54
|
+
|
55
|
+
return Object.isExtensible(target);
|
56
|
+
};
|
57
|
+
|
58
|
+
export const __Reflect_preventExtensions = (target: any) => {
|
59
|
+
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
60
|
+
|
61
|
+
try {
|
62
|
+
Object.preventExtensions(target);
|
63
|
+
return true;
|
64
|
+
} catch {
|
65
|
+
return false;
|
66
|
+
}
|
67
|
+
};
|
68
|
+
|
69
|
+
export const __Reflect_ownKeys = (target: any) => {
|
70
|
+
if (!Porffor.object.isObject(target)) throw new TypeError('Target is a non-object');
|
71
|
+
|
72
|
+
const out: any[] = Porffor.allocate();
|
26
73
|
|
27
74
|
const t: i32 = Porffor.rawType(target);
|
28
75
|
if (t == Porffor.TYPES.object) {
|
29
|
-
|
76
|
+
let ptr: i32 = Porffor.wasm`local.get ${target}` + 5;
|
77
|
+
const endPtr: i32 = ptr + Porffor.wasm.i32.load(target, 0, 0) * 14;
|
78
|
+
|
79
|
+
let i: i32 = 0;
|
80
|
+
for (; ptr < endPtr; ptr += 14) {
|
81
|
+
let key: any;
|
82
|
+
Porffor.wasm`local raw i32
|
83
|
+
local msb i32
|
84
|
+
local.get ${ptr}
|
85
|
+
i32.to_u
|
86
|
+
i32.load 0 0
|
87
|
+
local.set raw
|
88
|
+
|
89
|
+
local.get raw
|
90
|
+
i32.const 30
|
91
|
+
i32.shr_u
|
92
|
+
local.tee msb
|
93
|
+
if 127
|
94
|
+
i32.const 5 ;; symbol
|
95
|
+
i32.const 67 ;; string
|
96
|
+
local.get msb
|
97
|
+
i32.const 3
|
98
|
+
i32.eq
|
99
|
+
select
|
100
|
+
local.set ${key+1}
|
101
|
+
|
102
|
+
local.get raw
|
103
|
+
i32.const 1073741823
|
104
|
+
i32.and ;; unset 2 MSBs
|
105
|
+
else
|
106
|
+
i32.const 195
|
107
|
+
local.set ${key+1}
|
108
|
+
|
109
|
+
local.get raw
|
110
|
+
end
|
111
|
+
i32.from_u
|
112
|
+
local.set ${key}`;
|
113
|
+
|
114
|
+
out[i++] = key;
|
115
|
+
}
|
116
|
+
|
117
|
+
out.length = i;
|
118
|
+
} else if (Porffor.fastOr(
|
119
|
+
t == Porffor.TYPES.array,
|
120
|
+
t == Porffor.TYPES.bytestring,
|
121
|
+
t == Porffor.TYPES.string
|
122
|
+
)) {
|
123
|
+
const len: i32 = target.length;
|
124
|
+
out.length = len;
|
125
|
+
|
126
|
+
for (let i: i32 = 0; i < len; i++) {
|
127
|
+
out[i] = __Number_prototype_toString(i);
|
128
|
+
}
|
30
129
|
}
|
31
130
|
|
32
|
-
|
33
|
-
return __Array_prototype_includes(keys, p);
|
131
|
+
return out;
|
34
132
|
};
|
package/compiler/codegen.js
CHANGED
@@ -39,7 +39,7 @@ const todo = (scope, msg, expectsValue = undefined) => {
|
|
39
39
|
const isFuncType = type =>
|
40
40
|
type === 'FunctionDeclaration' || type === 'FunctionExpression' || type === 'ArrowFunctionExpression';
|
41
41
|
const hasFuncWithName = name =>
|
42
|
-
Object.hasOwn(funcIndex, name)
|
42
|
+
Object.hasOwn(funcIndex, name) || Object.hasOwn(builtinFuncs, name) || Object.hasOwn(importedFuncs, name) || Object.hasOwn(internalConstrs, name);
|
43
43
|
|
44
44
|
const astCache = new WeakMap();
|
45
45
|
const cacheAst = (decl, wasm) => {
|
@@ -164,6 +164,8 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
164
164
|
return cacheAst(decl, generateMember(scope, decl, global, name));
|
165
165
|
|
166
166
|
case 'ExportNamedDeclaration':
|
167
|
+
if (!decl.declaration) return todo(scope, 'unsupported export declaration');
|
168
|
+
|
167
169
|
const funcsBefore = funcs.map(x => x.name);
|
168
170
|
generate(scope, decl.declaration);
|
169
171
|
|
@@ -2835,9 +2837,6 @@ const generateVar = (scope, decl) => {
|
|
2835
2837
|
scope.globalInits[name] = newOut;
|
2836
2838
|
}
|
2837
2839
|
}
|
2838
|
-
|
2839
|
-
// hack: this follows spec properly but is mostly unneeded 😅
|
2840
|
-
// out.push(...setType(scope, name, x.init ? getNodeType(scope, x.init) : TYPES.undefined));
|
2841
2840
|
}
|
2842
2841
|
|
2843
2842
|
return out;
|