porffor 0.30.12 → 0.30.14
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/2c.js +16 -16
- package/compiler/allocators.js +1 -1
- package/compiler/builtins/_internal_object.ts +34 -7
- package/compiler/builtins/object.ts +7 -43
- package/compiler/builtins.js +0 -38
- package/compiler/builtins_objects.js +45 -20
- package/compiler/builtins_precompiled.js +177 -177
- package/compiler/codegen.js +20 -6
- package/compiler/cyclone.js +3 -3
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/2c.js
CHANGED
@@ -231,20 +231,6 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
231
231
|
prependMain.set('argv', `_argc = argc; _argv = argv;`);
|
232
232
|
}
|
233
233
|
|
234
|
-
prepend.set('func decls', funcs.filter(x => x.name !== 'main').map(f => {
|
235
|
-
const returns = f.returns.length > 0;
|
236
|
-
const typedReturns = f.returnType == null;
|
237
|
-
|
238
|
-
const invLocals = inv(f.locals, x => x.idx);
|
239
|
-
for (const x in invLocals) {
|
240
|
-
invLocals[x] = sanitize(invLocals[x]);
|
241
|
-
}
|
242
|
-
|
243
|
-
const shouldInline = false;
|
244
|
-
|
245
|
-
return `${!typedReturns ? (returns ? CValtype[f.returns[0]] : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')});`;
|
246
|
-
}).join('\n'));
|
247
|
-
|
248
234
|
if (out) out += '\n';
|
249
235
|
|
250
236
|
const line = (str, semi = true) => out += `${str}${semi ? ';' : ''}\n`;
|
@@ -438,7 +424,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
438
424
|
|
439
425
|
case Opcodes.f64_const: {
|
440
426
|
const val = i[1];
|
441
|
-
vals.push(val);
|
427
|
+
vals.push(val.toString());
|
442
428
|
break;
|
443
429
|
}
|
444
430
|
|
@@ -822,7 +808,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
822
808
|
break;
|
823
809
|
}
|
824
810
|
|
825
|
-
|
811
|
+
if (Prefs.d) log.warning('2c', `unimplemented op: ${invOpcodes[i[0]]} \x1b[90m(${f.name})`);
|
826
812
|
}
|
827
813
|
|
828
814
|
lastCond = false;
|
@@ -844,6 +830,20 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
844
830
|
|
845
831
|
cify(funcs.find(x => x.name === 'main'));
|
846
832
|
|
833
|
+
prepend.set('func decls', funcs.filter(x => x.name !== 'main' && cified.has(x.name)).map(f => {
|
834
|
+
const returns = f.returns.length > 0;
|
835
|
+
const typedReturns = f.returnType == null;
|
836
|
+
|
837
|
+
const invLocals = inv(f.locals, x => x.idx);
|
838
|
+
for (const x in invLocals) {
|
839
|
+
invLocals[x] = sanitize(invLocals[x]);
|
840
|
+
}
|
841
|
+
|
842
|
+
const shouldInline = false;
|
843
|
+
|
844
|
+
return `${!typedReturns ? (returns ? CValtype[f.returns[0]] : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')});`;
|
845
|
+
}).join('\n'));
|
846
|
+
|
847
847
|
const makeIncludes = includes => [...includes.keys()].map(x => `#include <${x}>\n`).join('');
|
848
848
|
out = platformSpecific(makeIncludes(winIncludes), makeIncludes(unixIncludes), false) + '\n' + makeIncludes(includes) + '\n' + alwaysPreface + [...prepend.values()].join('\n') + '\n\n' + out;
|
849
849
|
|
package/compiler/allocators.js
CHANGED
@@ -17,21 +17,33 @@ import type {} from './porffor.d.ts';
|
|
17
17
|
// writable - 0b1000
|
18
18
|
|
19
19
|
export const __Porffor_object_preventExtensions = (obj: any): void => {
|
20
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
20
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
21
|
+
obj = __Porffor_object_getObject(obj);
|
22
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return;
|
23
|
+
}
|
24
|
+
|
21
25
|
let rootFlags: i32 = Porffor.wasm.i32.load8_u(obj, 0, 4);
|
22
26
|
rootFlags |= 0b0001;
|
23
27
|
Porffor.wasm.i32.store8(obj, rootFlags, 0, 4);
|
24
28
|
};
|
25
29
|
|
26
30
|
export const __Porffor_object_isInextensible = (obj: any): boolean => {
|
27
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
31
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
32
|
+
obj = __Porffor_object_getObject(obj);
|
33
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return false;
|
34
|
+
}
|
35
|
+
|
28
36
|
const out: boolean = Porffor.wasm.i32.load8_u(obj, 0, 4) & 0b0001;
|
29
37
|
return out;
|
30
38
|
};
|
31
39
|
|
32
40
|
|
33
41
|
export const __Porffor_object_overrideAllFlags = (obj: any, overrideOr: i32, overrideAnd: i32): void => {
|
34
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
42
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
43
|
+
obj = __Porffor_object_getObject(obj);
|
44
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return;
|
45
|
+
}
|
46
|
+
|
35
47
|
let ptr: i32 = Porffor.wasm`local.get ${obj}` + 5;
|
36
48
|
|
37
49
|
const size: i32 = Porffor.wasm.i32.load(obj, 0, 0);
|
@@ -45,7 +57,11 @@ export const __Porffor_object_overrideAllFlags = (obj: any, overrideOr: i32, ove
|
|
45
57
|
};
|
46
58
|
|
47
59
|
export const __Porffor_object_checkAllFlags = (obj: any, dataAnd: i32, accessorAnd: i32, dataExpected: i32, accessorExpected: i32): boolean => {
|
48
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
60
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
61
|
+
obj = __Porffor_object_getObject(obj);
|
62
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return false;
|
63
|
+
}
|
64
|
+
|
49
65
|
let ptr: i32 = Porffor.wasm`local.get ${obj}` + 5;
|
50
66
|
|
51
67
|
const size: i32 = Porffor.wasm.i32.load(obj, 0, 0);
|
@@ -107,7 +123,10 @@ export const __Porffor_object_accessorSet = (entryPtr: i32): Function => {
|
|
107
123
|
|
108
124
|
export const __Porffor_object_lookup = (obj: any, target: any): i32 => {
|
109
125
|
if (Porffor.wasm`local.get ${obj}` == 0) return -1;
|
110
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
126
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
127
|
+
obj = __Porffor_object_getObject(obj);
|
128
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return -1;
|
129
|
+
}
|
111
130
|
|
112
131
|
const targetType: i32 = Porffor.wasm`local.get ${target+1}`;
|
113
132
|
|
@@ -247,7 +266,11 @@ export const __Porffor_object_writeKey = (ptr: i32, key: any): void => {
|
|
247
266
|
export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
248
267
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot set property of null');
|
249
268
|
|
250
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
269
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
270
|
+
obj = __Porffor_object_getObject(obj);
|
271
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return value;
|
272
|
+
}
|
273
|
+
|
251
274
|
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
252
275
|
let flags: i32;
|
253
276
|
if (entryPtr == -1) {
|
@@ -328,7 +351,11 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
|
328
351
|
};
|
329
352
|
|
330
353
|
export const __Porffor_object_define = (obj: any, key: any, value: any, flags: i32): void => {
|
331
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
354
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
355
|
+
obj = __Porffor_object_getObject(obj);
|
356
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return;
|
357
|
+
}
|
358
|
+
|
332
359
|
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
333
360
|
if (entryPtr == -1) {
|
334
361
|
// add new entry
|
@@ -245,11 +245,6 @@ export const __Object_is = (x: any, y: any): boolean => {
|
|
245
245
|
|
246
246
|
|
247
247
|
export const __Object_preventExtensions = (obj: any): any => {
|
248
|
-
// todo: support non-pure-objects
|
249
|
-
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
250
|
-
return obj;
|
251
|
-
}
|
252
|
-
|
253
248
|
Porffor.object.preventExtensions(obj);
|
254
249
|
|
255
250
|
return obj;
|
@@ -260,21 +255,11 @@ export const __Object_isExtensible = (obj: any): any => {
|
|
260
255
|
return false;
|
261
256
|
}
|
262
257
|
|
263
|
-
// todo: support non-pure-objects
|
264
|
-
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
265
|
-
return true;
|
266
|
-
}
|
267
|
-
|
268
258
|
return !Porffor.object.isInextensible(obj);
|
269
259
|
};
|
270
260
|
|
271
261
|
|
272
262
|
export const __Object_freeze = (obj: any): any => {
|
273
|
-
// todo: support non-pure-objects
|
274
|
-
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
275
|
-
return obj;
|
276
|
-
}
|
277
|
-
|
278
263
|
// make inextensible
|
279
264
|
Porffor.object.preventExtensions(obj);
|
280
265
|
|
@@ -289,11 +274,6 @@ export const __Object_isFrozen = (obj: any): any => {
|
|
289
274
|
return true;
|
290
275
|
}
|
291
276
|
|
292
|
-
// todo: support non-pure-objects
|
293
|
-
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
294
|
-
return false;
|
295
|
-
}
|
296
|
-
|
297
277
|
// check obj is inextensible
|
298
278
|
if (!Porffor.object.isInextensible(obj)) {
|
299
279
|
return false;
|
@@ -305,11 +285,6 @@ export const __Object_isFrozen = (obj: any): any => {
|
|
305
285
|
|
306
286
|
|
307
287
|
export const __Object_seal = (obj: any): any => {
|
308
|
-
// todo: support non-pure-objects
|
309
|
-
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
310
|
-
return obj;
|
311
|
-
}
|
312
|
-
|
313
288
|
// make inextensible
|
314
289
|
Porffor.object.preventExtensions(obj);
|
315
290
|
|
@@ -324,11 +299,6 @@ export const __Object_isSealed = (obj: any): any => {
|
|
324
299
|
return true;
|
325
300
|
}
|
326
301
|
|
327
|
-
// todo: support non-pure-objects
|
328
|
-
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
329
|
-
return false;
|
330
|
-
}
|
331
|
-
|
332
302
|
// check obj is inextensible
|
333
303
|
if (!Porffor.object.isInextensible(obj)) {
|
334
304
|
return false;
|
@@ -345,24 +315,18 @@ export const __Object_getOwnPropertyDescriptor = (obj: any, prop: any): any => {
|
|
345
315
|
const objType: i32 = Porffor.rawType(obj);
|
346
316
|
if (objType == Porffor.TYPES.function) {
|
347
317
|
// hack: function .name and .length
|
348
|
-
const out: object = {};
|
349
|
-
|
350
|
-
out.writable = false;
|
351
|
-
out.enumerable = false;
|
352
|
-
out.configurable = true;
|
353
|
-
|
354
318
|
const v = obj[p];
|
355
319
|
if (v != null) {
|
320
|
+
const out: object = {};
|
321
|
+
out.writable = false;
|
322
|
+
out.enumerable = false;
|
323
|
+
out.configurable = true;
|
324
|
+
|
356
325
|
out.value = v;
|
357
326
|
return out;
|
358
327
|
}
|
359
328
|
}
|
360
329
|
|
361
|
-
// todo: support non-pure-objects
|
362
|
-
if (objType != Porffor.TYPES.object) {
|
363
|
-
return undefined;
|
364
|
-
}
|
365
|
-
|
366
330
|
const entryPtr: i32 = Porffor.object.lookup(obj, p);
|
367
331
|
if (entryPtr == -1) return undefined;
|
368
332
|
|
@@ -397,9 +361,9 @@ local.set ${value+1}`;
|
|
397
361
|
export const __Object_getOwnPropertyDescriptors = (obj: any): any => {
|
398
362
|
const out: object = {};
|
399
363
|
|
400
|
-
// todo: support non-pure-objects
|
401
364
|
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
402
|
-
|
365
|
+
obj = __Porffor_object_getObject(obj);
|
366
|
+
if (Porffor.rawType(obj) != Porffor.TYPES.object) return out;
|
403
367
|
}
|
404
368
|
|
405
369
|
for (const x in obj) {
|
package/compiler/builtins.js
CHANGED
@@ -99,44 +99,6 @@ export const BuiltinVars = function(ctx) {
|
|
99
99
|
this.Infinity = number(Infinity);
|
100
100
|
this.Infinity.floatOnly = true;
|
101
101
|
|
102
|
-
this.__Number_NaN = number(NaN);
|
103
|
-
this.__Number_NaN.floatOnly = true;
|
104
|
-
|
105
|
-
this.__Number_POSITIVE_INFINITY = number(Infinity);
|
106
|
-
this.__Number_POSITIVE_INFINITY.floatOnly = true;
|
107
|
-
|
108
|
-
this.__Number_NEGATIVE_INFINITY = number(-Infinity);
|
109
|
-
this.__Number_NEGATIVE_INFINITY.floatOnly = true;
|
110
|
-
|
111
|
-
switch (valtype) {
|
112
|
-
case 'i32':
|
113
|
-
this.__Number_MAX_VALUE = number(2147483647);
|
114
|
-
this.__Number_MIN_VALUE = number(-2147483648);
|
115
|
-
|
116
|
-
this.__Number_MAX_SAFE_INTEGER = this.__Number_MAX_VALUE;
|
117
|
-
this.__Number_MIN_SAFE_INTEGER = this.__Number_MIN_VALUE;
|
118
|
-
break;
|
119
|
-
|
120
|
-
case 'i64':
|
121
|
-
// todo: we use 32 bit limits here as we cannot encode 64 bit integers yet
|
122
|
-
this.__Number_MAX_VALUE = number(2147483647);
|
123
|
-
this.__Number_MIN_VALUE = number(-2147483648);
|
124
|
-
|
125
|
-
this.__Number_MAX_SAFE_INTEGER = this.__Number_MAX_VALUE;
|
126
|
-
this.__Number_MIN_SAFE_INTEGER = this.__Number_MIN_VALUE;
|
127
|
-
break;
|
128
|
-
|
129
|
-
case 'f64':
|
130
|
-
this.__Number_MAX_VALUE = number(1.7976931348623157e+308);
|
131
|
-
this.__Number_MIN_VALUE = number(5e-324);
|
132
|
-
|
133
|
-
this.__Number_MAX_SAFE_INTEGER = number(9007199254740991);
|
134
|
-
this.__Number_MIN_SAFE_INTEGER = number(-9007199254740991);
|
135
|
-
|
136
|
-
this.__Number_EPSILON = number(2.220446049250313e-16);
|
137
|
-
break;
|
138
|
-
}
|
139
|
-
|
140
102
|
for (const x in TYPES) {
|
141
103
|
this['__Porffor_TYPES_' + x] = number(TYPES[x]);
|
142
104
|
}
|
@@ -8,6 +8,9 @@ export default function({ builtinFuncs }, Prefs) {
|
|
8
8
|
done.add(name);
|
9
9
|
const prefix = name === 'globalThis' ? '' : `__${name}_`;
|
10
10
|
|
11
|
+
// already a func
|
12
|
+
const existingFunc = builtinFuncs[name];
|
13
|
+
|
11
14
|
builtinFuncs['#get_' + name] = {
|
12
15
|
params: [],
|
13
16
|
locals: [],
|
@@ -20,8 +23,13 @@ export default function({ builtinFuncs }, Prefs) {
|
|
20
23
|
|
21
24
|
// todo/perf: precompute bytes here instead of calling real funcs if we really care about perf later
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
let ptr;
|
27
|
+
if (existingFunc) {
|
28
|
+
ptr = 1;
|
29
|
+
} else {
|
30
|
+
const page = allocPage(scope, `builtin object: ${name}`);
|
31
|
+
ptr = page === 0 ? 16 : page * PageSize;
|
32
|
+
}
|
25
33
|
|
26
34
|
const out = [
|
27
35
|
// check if already made/cached
|
@@ -54,7 +62,7 @@ export default function({ builtinFuncs }, Prefs) {
|
|
54
62
|
|
55
63
|
out.push(
|
56
64
|
[ Opcodes.global_get, 0 ],
|
57
|
-
...number(TYPES.object, Valtype.i32),
|
65
|
+
...number(existingFunc ? TYPES.function : TYPES.object, Valtype.i32),
|
58
66
|
|
59
67
|
...makeString(scope, x, false, `#builtin_object_${name}_${x}`),
|
60
68
|
Opcodes.i32_to_u,
|
@@ -80,17 +88,28 @@ export default function({ builtinFuncs }, Prefs) {
|
|
80
88
|
}
|
81
89
|
};
|
82
90
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
91
|
+
if (existingFunc) {
|
92
|
+
const originalWasm = existingFunc.wasm;
|
93
|
+
existingFunc.wasm = (...args) => {
|
94
|
+
const { builtin } = args[1];
|
95
|
+
return [
|
96
|
+
[ Opcodes.call, builtin('#get_' + name) ],
|
97
|
+
[ Opcodes.drop ],
|
98
|
+
...originalWasm(...args)
|
99
|
+
];
|
100
|
+
};
|
101
|
+
} else {
|
102
|
+
this[name] = (scope, { builtin }) => [
|
103
|
+
[ Opcodes.call, builtin('#get_' + name) ],
|
104
|
+
Opcodes.i32_from_u
|
105
|
+
];
|
106
|
+
this[name].type = TYPES.object;
|
107
|
+
}
|
89
108
|
|
90
109
|
for (const x in props) {
|
91
110
|
const d = props[x];
|
92
111
|
|
93
|
-
if (d
|
112
|
+
if (Object.hasOwn(d, 'value')) {
|
94
113
|
const k = prefix + x;
|
95
114
|
|
96
115
|
if (typeof d.value === 'number') {
|
@@ -177,19 +196,25 @@ export default function({ builtinFuncs }, Prefs) {
|
|
177
196
|
|
178
197
|
|
179
198
|
// todo: support when existing func
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
199
|
+
object('Number', {
|
200
|
+
...props({
|
201
|
+
writable: false,
|
202
|
+
enumerable: false,
|
203
|
+
configurable: false
|
204
|
+
}, {
|
205
|
+
NaN: NaN,
|
206
|
+
POSITIVE_INFINITY: Infinity,
|
207
|
+
NEGATIVE_INFINITY: -Infinity,
|
184
208
|
|
185
|
-
|
186
|
-
|
209
|
+
MAX_VALUE: valtype === 'i32' ? 2147483647 : 1.7976931348623157e+308,
|
210
|
+
MIN_VALUE: valtype === 'i32' ? -2147483648 : 5e-324,
|
187
211
|
|
188
|
-
|
189
|
-
|
212
|
+
MAX_SAFE_INTEGER: valtype === 'i32' ? 2147483647 : 9007199254740991,
|
213
|
+
MIN_SAFE_INTEGER: valtype === 'i32' ? -2147483648 : -9007199254740991,
|
190
214
|
|
191
|
-
|
192
|
-
|
215
|
+
EPSILON: 2.220446049250313e-16
|
216
|
+
})
|
217
|
+
});
|
193
218
|
|
194
219
|
|
195
220
|
// these technically not spec compliant as it should be classes or non-enumerable but eh
|