porffor 0.30.13 → 0.31.0
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 -0
- package/compiler/assemble.js +12 -5
- package/compiler/builtins/_internal_object.ts +35 -12
- package/compiler/builtins/arraybuffer.ts +5 -1
- package/compiler/builtins/object.ts +24 -11
- package/compiler/builtins_objects.js +20 -5
- package/compiler/builtins_precompiled.js +522 -514
- package/compiler/codegen.js +127 -64
- package/compiler/cyclone.js +3 -3
- package/compiler/precompile.js +2 -5
- 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
@@ -39,6 +39,7 @@ export class StaticAllocator {
|
|
39
39
|
if (globalThis.precompile && scopeName === 'main') scopeName = globalThis.precompile;
|
40
40
|
const reason = `${this.allocType(itemType)}: ${Prefs.scopedPageNames ? (scopeName + '/') : ''}${name}`;
|
41
41
|
|
42
|
+
this.lastName = reason;
|
42
43
|
if (pages.has(reason)) {
|
43
44
|
const ptr = this.lastPtr = this.ptr(pages.get(reason).ind);
|
44
45
|
return number(ptr, Valtype.i32);
|
package/compiler/assemble.js
CHANGED
@@ -203,7 +203,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
203
203
|
}
|
204
204
|
|
205
205
|
data.push({
|
206
|
-
|
206
|
+
page: 'func lut',
|
207
207
|
bytes
|
208
208
|
});
|
209
209
|
data.addedFuncArgcLut = true;
|
@@ -358,11 +358,18 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
358
358
|
const dataSection = data.length === 0 ? [] : createSection(
|
359
359
|
Section.data,
|
360
360
|
encodeVector(data.map(x => {
|
361
|
-
|
362
|
-
|
361
|
+
const bytes = encodeVector(x.bytes);
|
362
|
+
|
363
|
+
if (x.page != null) {
|
364
|
+
// type: active
|
365
|
+
const offset = pages.get(x.page).ind * pageSize;
|
366
|
+
bytes.unshift(0x00, Opcodes.i32_const, ...signedLEB128(offset), Opcodes.end);
|
367
|
+
} else {
|
368
|
+
// type: passive
|
369
|
+
bytes.unshift(0x01);
|
370
|
+
}
|
363
371
|
|
364
|
-
|
365
|
-
return [ 0x01, ...encodeVector(x.bytes) ];
|
372
|
+
return bytes;
|
366
373
|
}))
|
367
374
|
);
|
368
375
|
|
@@ -174,9 +174,8 @@ export const __Porffor_object_get = (obj: any, key: any): any => {
|
|
174
174
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot get property of null');
|
175
175
|
|
176
176
|
if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.function) {
|
177
|
-
|
178
|
-
|
179
|
-
if (key == tmp) {
|
177
|
+
const tmp1: bytestring = 'name';
|
178
|
+
if (key == tmp1) {
|
180
179
|
const o: bytestring = __Porffor_funcLut_name(obj);
|
181
180
|
const t: i32 = Porffor.TYPES.bytestring;
|
182
181
|
Porffor.wasm`
|
@@ -186,8 +185,8 @@ local.get ${t}
|
|
186
185
|
return`;
|
187
186
|
}
|
188
187
|
|
189
|
-
|
190
|
-
if (key ==
|
188
|
+
const tmp2: bytestring = 'length';
|
189
|
+
if (key == tmp2) {
|
191
190
|
const o: i32 = __Porffor_funcLut_length(obj);
|
192
191
|
Porffor.wasm`
|
193
192
|
local.get ${o}
|
@@ -198,12 +197,37 @@ return`;
|
|
198
197
|
}
|
199
198
|
|
200
199
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_getObject(obj);
|
201
|
-
|
200
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
202
201
|
if (entryPtr == -1) {
|
203
|
-
|
202
|
+
const protoKey: bytestring = '__proto__';
|
203
|
+
|
204
|
+
if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.object) {
|
205
|
+
// check prototype chain
|
206
|
+
let lastProto = obj;
|
207
|
+
if (key != protoKey) {
|
208
|
+
while (true) {
|
209
|
+
obj = __Porffor_object_get(obj, protoKey);
|
210
|
+
if (Porffor.fastOr(obj == null, Porffor.wasm`local.get ${obj}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
211
|
+
lastProto = obj;
|
212
|
+
|
213
|
+
if ((entryPtr = __Porffor_object_lookup(obj, key)) != -1) break;
|
214
|
+
}
|
215
|
+
} else {
|
216
|
+
const i: i32 = __Object_prototype;
|
217
|
+
Porffor.wasm`
|
218
|
+
local.get ${i}
|
219
|
+
f64.convert_i32_u
|
220
|
+
i32.const 7 ;; object type
|
221
|
+
return`;
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
if (entryPtr == -1) {
|
226
|
+
Porffor.wasm`
|
204
227
|
f64.const 0
|
205
228
|
i32.const 128
|
206
229
|
return`;
|
230
|
+
}
|
207
231
|
}
|
208
232
|
|
209
233
|
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 12);
|
@@ -424,15 +448,14 @@ export const __Porffor_object_delete = (obj: any, key: any): boolean => {
|
|
424
448
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
425
449
|
|
426
450
|
if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.function) {
|
427
|
-
|
428
|
-
|
429
|
-
if (key == tmp) {
|
451
|
+
const tmp1: bytestring = 'name';
|
452
|
+
if (key == tmp1) {
|
430
453
|
__Porffor_funcLut_deleteName(obj);
|
431
454
|
return true;
|
432
455
|
}
|
433
456
|
|
434
|
-
|
435
|
-
if (key ==
|
457
|
+
const tmp2: bytestring = 'length';
|
458
|
+
if (key == tmp2) {
|
436
459
|
__Porffor_funcLut_deleteLength(obj);
|
437
460
|
return true;
|
438
461
|
}
|
@@ -1,7 +1,11 @@
|
|
1
1
|
import type {} from './porffor.d.ts';
|
2
2
|
|
3
3
|
export const __ArrayBuffer_isView = (value: any): boolean => {
|
4
|
-
|
4
|
+
const t: i32 = Porffor.rawType(value);
|
5
|
+
if (Porffor.fastOr(
|
6
|
+
t == Porffor.TYPES.dataview,
|
7
|
+
Porffor.fastAnd(t >= Porffor.TYPES.uint8array, t <= Porffor.TYPES.float64array)
|
8
|
+
)) return true;
|
5
9
|
return false;
|
6
10
|
};
|
7
11
|
|
@@ -171,13 +171,11 @@ export const __Object_prototype_hasOwnProperty = (_this: any, prop: any) => {
|
|
171
171
|
}
|
172
172
|
|
173
173
|
if (t == Porffor.TYPES.function) {
|
174
|
-
|
174
|
+
const tmp1: bytestring = 'name';
|
175
|
+
if (p == tmp1) return !__Porffor_funcLut_isNameDeleted(_this);
|
175
176
|
|
176
|
-
|
177
|
-
if (p ==
|
178
|
-
|
179
|
-
tmp = 'length';
|
180
|
-
if (p == tmp) return !__Porffor_funcLut_isLengthDeleted(_this);
|
177
|
+
const tmp2: bytestring = 'length';
|
178
|
+
if (p == tmp2) return !__Porffor_funcLut_isLengthDeleted(_this);
|
181
179
|
|
182
180
|
return false;
|
183
181
|
}
|
@@ -190,6 +188,26 @@ export const __Object_hasOwn = (obj: any, prop: any) => {
|
|
190
188
|
return __Object_prototype_hasOwnProperty(obj, prop);
|
191
189
|
};
|
192
190
|
|
191
|
+
export const __Porffor_object_in = (obj: any, prop: any) => {
|
192
|
+
if (__Object_prototype_hasOwnProperty(obj, prop)) {
|
193
|
+
return true;
|
194
|
+
}
|
195
|
+
|
196
|
+
const t: i32 = Porffor.rawType(obj);
|
197
|
+
if (t != Porffor.TYPES.object) {
|
198
|
+
return false;
|
199
|
+
}
|
200
|
+
|
201
|
+
let lastProto = obj;
|
202
|
+
while (true) {
|
203
|
+
obj = obj.__proto__;
|
204
|
+
if (Porffor.fastOr(obj == null, Porffor.wasm`local.get ${obj}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
205
|
+
lastProto = obj;
|
206
|
+
|
207
|
+
if (__Object_prototype_hasOwnProperty(obj, prop)) return true;
|
208
|
+
}
|
209
|
+
};
|
210
|
+
|
193
211
|
|
194
212
|
export const __Object_assign = (target: any, ...sources: any[]) => {
|
195
213
|
if (target == null) throw new TypeError('Argument is nullish, expected object');
|
@@ -601,11 +619,6 @@ export const __Object_groupBy = (items: any, callbackFn: any) => {
|
|
601
619
|
export const __Object_getPrototypeOf = (obj: any) => {
|
602
620
|
if (obj == null) throw new TypeError('Object is nullish, expected object');
|
603
621
|
|
604
|
-
// todo: support non-pure-objects
|
605
|
-
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
606
|
-
return {};
|
607
|
-
}
|
608
|
-
|
609
622
|
return obj.__proto__;
|
610
623
|
};
|
611
624
|
|
@@ -3,10 +3,12 @@ import { TYPES } from './types.js';
|
|
3
3
|
import { number } from './embedding.js';
|
4
4
|
|
5
5
|
export default function({ builtinFuncs }, Prefs) {
|
6
|
+
const makePrefix = name => (name.startsWith('__') ? '' : '__') + name + '_';
|
7
|
+
|
6
8
|
const done = new Set();
|
7
9
|
const object = (name, props) => {
|
8
10
|
done.add(name);
|
9
|
-
const prefix = name === 'globalThis' ? '' :
|
11
|
+
const prefix = name === 'globalThis' ? '' : makePrefix(name);
|
10
12
|
|
11
13
|
// already a func
|
12
14
|
const existingFunc = builtinFuncs[name];
|
@@ -58,7 +60,7 @@ export default function({ builtinFuncs }, Prefs) {
|
|
58
60
|
if (d.writable) flags |= 0b1000;
|
59
61
|
|
60
62
|
// hack: do not generate objects inside of objects as it causes issues atm
|
61
|
-
if (this[prefix + x]?.type === TYPES.object) value = { type: 'ObjectExpression', properties: [] };
|
63
|
+
if (this[prefix + x]?.type === TYPES.object && this[prefix + x] !== this.null) value = { type: 'ObjectExpression', properties: [] };
|
62
64
|
|
63
65
|
out.push(
|
64
66
|
[ Opcodes.global_get, 0 ],
|
@@ -124,6 +126,11 @@ export default function({ builtinFuncs }, Prefs) {
|
|
124
126
|
continue;
|
125
127
|
}
|
126
128
|
|
129
|
+
if (d.value === null) {
|
130
|
+
this[k] = this.null;
|
131
|
+
continue;
|
132
|
+
}
|
133
|
+
|
127
134
|
throw new Error(`unsupported value type (${typeof d.value})`);
|
128
135
|
}
|
129
136
|
}
|
@@ -151,7 +158,10 @@ export default function({ builtinFuncs }, Prefs) {
|
|
151
158
|
};
|
152
159
|
|
153
160
|
const builtinFuncKeys = Object.keys(builtinFuncs);
|
154
|
-
const autoFuncKeys = name =>
|
161
|
+
const autoFuncKeys = name => {
|
162
|
+
const prefix = makePrefix(name);
|
163
|
+
return builtinFuncKeys.filter(x => x.startsWith(prefix)).map(x => x.slice(prefix.length));
|
164
|
+
};
|
155
165
|
const autoFuncs = name => props({
|
156
166
|
writable: true,
|
157
167
|
enumerable: false,
|
@@ -191,7 +201,12 @@ export default function({ builtinFuncs }, Prefs) {
|
|
191
201
|
acc.add(x.slice(0, ind + 10));
|
192
202
|
return acc;
|
193
203
|
}, new Set())) {
|
194
|
-
|
204
|
+
const props = autoFuncs(x);
|
205
|
+
|
206
|
+
// special case: Object.prototype.__proto__ = null
|
207
|
+
if (x === '__Object_prototype') Object.defineProperty(props, '__proto__', { value: { value: null }, enumerable: true });
|
208
|
+
|
209
|
+
object(x, props);
|
195
210
|
}
|
196
211
|
|
197
212
|
|
@@ -291,7 +306,7 @@ export default function({ builtinFuncs }, Prefs) {
|
|
291
306
|
}
|
292
307
|
if (!t) continue;
|
293
308
|
|
294
|
-
if (!done.has(name)
|
309
|
+
if (!done.has(name)) {
|
295
310
|
console.log(name.replaceAll('_', '.'), !!builtinFuncs[name]);
|
296
311
|
done.add(name);
|
297
312
|
}
|