porffor 0.41.5 → 0.41.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/compiler/assemble.js +13 -14
- package/compiler/builtins/__internal_object.ts +12 -6
- package/compiler/builtins/_internal_object.ts +96 -147
- package/compiler/builtins/object.ts +39 -21
- package/compiler/builtins.js +9 -71
- package/compiler/builtins_objects.js +10 -1
- package/compiler/builtins_precompiled.js +340 -336
- package/compiler/codegen.js +179 -228
- package/compiler/precompile.js +37 -23
- package/package.json +1 -1
- package/runner/index.js +2 -2
package/compiler/assemble.js
CHANGED
@@ -132,13 +132,12 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
|
132
132
|
encodeVector([ [
|
133
133
|
0x00,
|
134
134
|
Opcodes.i32_const, 0, Opcodes.end,
|
135
|
-
...encodeVector(funcs.map(x => unsignedLEB128(x.asmIndex)))
|
135
|
+
...encodeVector(funcs.map(x => unsignedLEB128((x.wrapperFunc ?? x).asmIndex)))
|
136
136
|
] ])
|
137
137
|
);
|
138
138
|
time('element section');
|
139
139
|
|
140
140
|
if (pages.has('func lut')) {
|
141
|
-
const offset = pages.get('func lut').ind * pageSize;
|
142
141
|
if (data.addedFuncArgcLut) {
|
143
142
|
// remove existing data
|
144
143
|
data = data.filter(x => x.page !== 'func lut');
|
@@ -150,17 +149,16 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
|
150
149
|
const func = funcs[i];
|
151
150
|
let name = func.name;
|
152
151
|
|
153
|
-
// real argc
|
154
|
-
let argc = func.params.length;
|
155
|
-
if (func.constr) argc -= 4;
|
156
|
-
if (!func.internal || func.typedParams) argc = Math.floor(argc / 2);
|
157
|
-
|
158
|
-
bytes.push(argc % 256, (argc / 256 | 0) % 256);
|
159
|
-
|
160
152
|
// userland exposed .length
|
161
|
-
let length = func.jsLength
|
162
|
-
|
163
|
-
|
153
|
+
let length = func.jsLength;
|
154
|
+
if (length == null) {
|
155
|
+
length = func.params.length;
|
156
|
+
if (func.constr) length -= 4;
|
157
|
+
if (!func.internal || func.typedParams) length = Math.floor(length / 2);
|
158
|
+
|
159
|
+
// remove _this from internal prototype funcs
|
160
|
+
if (func.internal && name.includes('_prototype_')) length--;
|
161
|
+
}
|
164
162
|
|
165
163
|
bytes.push(length % 256, (length / 256 | 0) % 256);
|
166
164
|
|
@@ -169,14 +167,15 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
|
|
169
167
|
if (func.constr) flags |= 0b10;
|
170
168
|
bytes.push(flags);
|
171
169
|
|
170
|
+
if (name.startsWith('#indirect_')) name = name.slice(10);
|
172
171
|
if (name.startsWith('#')) name = '';
|
173
172
|
|
174
173
|
// eg: __String_prototype_toLowerCase -> toLowerCase
|
175
174
|
if (name.startsWith('__')) name = name.split('_').pop();
|
176
175
|
|
177
|
-
bytes.push(...new Uint8Array(new Int32Array([ name.length ]).buffer));
|
176
|
+
bytes.push(...new Uint8Array(new Int32Array([ Math.min(name.length, 48 - 5 - 4) ]).buffer));
|
178
177
|
|
179
|
-
for (let i = 0; i < (
|
178
|
+
for (let i = 0; i < (48 - 3 - 4); i++) {
|
180
179
|
const c = name.charCodeAt(i);
|
181
180
|
bytes.push((c || 0) % 256);
|
182
181
|
}
|
@@ -31,14 +31,20 @@ export const __Porffor_object_underlying = (obj: any): any => {
|
|
31
31
|
const key2: bytestring = 'constructor';
|
32
32
|
__Porffor_object_expr_initWithFlags(proto, key2, obj, 0b1010);
|
33
33
|
}
|
34
|
+
|
35
|
+
const key3: bytestring = 'name';
|
36
|
+
__Porffor_object_expr_initWithFlags(underlying, key3, __Porffor_funcLut_name(obj), 0b0010);
|
37
|
+
|
38
|
+
const key4: bytestring = 'length';
|
39
|
+
__Porffor_object_expr_initWithFlags(underlying, key4, __Porffor_funcLut_length(obj), 0b0010);
|
34
40
|
}
|
35
41
|
|
36
42
|
if (t == Porffor.TYPES.array) {
|
37
43
|
const arr: any[] = obj;
|
38
44
|
const len: i32 = arr.length;
|
39
45
|
|
40
|
-
const
|
41
|
-
__Porffor_object_expr_initWithFlags(underlying,
|
46
|
+
const key5: bytestring = 'length';
|
47
|
+
__Porffor_object_expr_initWithFlags(underlying, key5, len, 0b1000);
|
42
48
|
|
43
49
|
// todo: this should somehow be kept in sync?
|
44
50
|
for (let i: i32 = 0; i < len; i++) {
|
@@ -50,8 +56,8 @@ export const __Porffor_object_underlying = (obj: any): any => {
|
|
50
56
|
const str: string = obj;
|
51
57
|
const len: i32 = str.length;
|
52
58
|
|
53
|
-
const
|
54
|
-
__Porffor_object_expr_initWithFlags(underlying,
|
59
|
+
const key6: bytestring = 'length';
|
60
|
+
__Porffor_object_expr_initWithFlags(underlying, key6, len, 0b0000);
|
55
61
|
|
56
62
|
for (let i: i32 = 0; i < len; i++) {
|
57
63
|
__Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), str[i], 0b0100);
|
@@ -64,8 +70,8 @@ export const __Porffor_object_underlying = (obj: any): any => {
|
|
64
70
|
const str: bytestring = obj;
|
65
71
|
const len: i32 = str.length;
|
66
72
|
|
67
|
-
const
|
68
|
-
__Porffor_object_expr_initWithFlags(underlying,
|
73
|
+
const key7: bytestring = 'length';
|
74
|
+
__Porffor_object_expr_initWithFlags(underlying, key7, len, 0b0000);
|
69
75
|
|
70
76
|
for (let i: i32 = 0; i < len; i++) {
|
71
77
|
__Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), str[i], 0b0100);
|
@@ -135,34 +135,30 @@ export const __Porffor_object_lookup = (obj: any, target: any): i32 => {
|
|
135
135
|
const size: i32 = Porffor.wasm.i32.load(obj, 0, 0);
|
136
136
|
const endPtr: i32 = ptr + size * 14;
|
137
137
|
|
138
|
-
if (targetType == Porffor.TYPES.
|
139
|
-
const
|
140
|
-
for (; ptr < endPtr; ptr += 14) {
|
141
|
-
const keyRaw: i32 = Porffor.wasm.i32.load(ptr, 0, 0);
|
142
|
-
if (keyRaw == 0) break; // ran out of keys
|
143
|
-
if (keyRaw >>> 31) continue; // MSB 1 set, not a bytestring
|
144
|
-
|
145
|
-
const keyStr: bytestring = keyRaw;
|
146
|
-
if (keyStr == targetStr) return ptr;
|
147
|
-
}
|
148
|
-
} else if (targetType == Porffor.TYPES.string) {
|
149
|
-
const targetStr: string = target;
|
138
|
+
if (targetType == Porffor.TYPES.symbol) {
|
139
|
+
const targetSym: symbol = target;
|
150
140
|
for (; ptr < endPtr; ptr += 14) {
|
151
141
|
const keyRaw: i32 = Porffor.wasm.i32.load(ptr, 0, 0);
|
152
142
|
if (keyRaw == 0) break; // ran out of keys
|
153
|
-
if (keyRaw >>> 30 ==
|
154
|
-
const
|
155
|
-
if (
|
143
|
+
if (keyRaw >>> 30 == 3) { // MSB 1 and 2 set, symbol
|
144
|
+
const keySym: symbol = keyRaw & 0x3FFFFFFF; // unset MSB
|
145
|
+
if (keySym == targetSym) return ptr;
|
156
146
|
}
|
157
147
|
}
|
158
|
-
} else {
|
159
|
-
const targetSym: symbol = target;
|
148
|
+
} else {
|
160
149
|
for (; ptr < endPtr; ptr += 14) {
|
161
150
|
const keyRaw: i32 = Porffor.wasm.i32.load(ptr, 0, 0);
|
162
151
|
if (keyRaw == 0) break; // ran out of keys
|
163
|
-
|
164
|
-
|
165
|
-
|
152
|
+
|
153
|
+
const msb: i32 = keyRaw >>> 30;
|
154
|
+
if (msb == 0) {
|
155
|
+
// bytestring
|
156
|
+
const keyStr: bytestring = keyRaw;
|
157
|
+
if (Porffor.strcmp(keyStr, target)) return ptr;
|
158
|
+
} else if (msb == 2) {
|
159
|
+
// string
|
160
|
+
const keyStr: string = keyRaw & 0x7FFFFFFF; // unset MSB
|
161
|
+
if (Porffor.strcmp(keyStr, target)) return ptr;
|
166
162
|
}
|
167
163
|
}
|
168
164
|
}
|
@@ -170,58 +166,96 @@ export const __Porffor_object_lookup = (obj: any, target: any): i32 => {
|
|
170
166
|
return -1;
|
171
167
|
};
|
172
168
|
|
173
|
-
export const
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
const t: i32 = Porffor.TYPES.bytestring;
|
180
|
-
Porffor.wasm`
|
181
|
-
local.get ${o}
|
182
|
-
f64.convert_i32_u
|
183
|
-
local.get ${t}
|
184
|
-
return`;
|
185
|
-
}
|
186
|
-
|
187
|
-
const tmp2: bytestring = 'length';
|
188
|
-
if (key == tmp2) {
|
189
|
-
const o: i32 = __Porffor_funcLut_length(obj);
|
190
|
-
Porffor.wasm`
|
191
|
-
local.get ${o}
|
192
|
-
f64.convert_i32_u
|
193
|
-
i32.const 1
|
169
|
+
export const __Porffor_object_readValue = (entryPtr: i32): any => {
|
170
|
+
Porffor.wasm`
|
171
|
+
local.get ${entryPtr}
|
172
|
+
f64.load 0 4
|
173
|
+
local.get ${entryPtr}
|
174
|
+
i32.load8_u 0 13
|
194
175
|
return`;
|
195
|
-
|
196
|
-
}
|
176
|
+
};
|
197
177
|
|
178
|
+
export const __Porffor_object_get = (obj: any, key: any): any => {
|
179
|
+
const trueType: i32 = Porffor.wasm`local.get ${obj+1}`;
|
198
180
|
if (trueType != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
199
181
|
|
200
182
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot get property of null');
|
201
183
|
|
202
184
|
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
203
185
|
if (entryPtr == -1) {
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
186
|
+
// check prototype chain
|
187
|
+
const protoKey: bytestring = '__proto__';
|
188
|
+
let lastProto: any = obj;
|
189
|
+
if (key != protoKey) {
|
190
|
+
while (true) {
|
191
|
+
obj = __Porffor_object_get(obj, protoKey);
|
192
|
+
|
193
|
+
if (Porffor.comptime.flag`hasFunc.#get___String_prototype`) {
|
194
|
+
if (Porffor.fastOr(
|
195
|
+
trueType == Porffor.TYPES.string,
|
196
|
+
trueType == Porffor.TYPES.bytestring,
|
197
|
+
trueType == Porffor.TYPES.stringobject
|
198
|
+
)) {
|
199
|
+
obj = __String_prototype;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
if (Porffor.comptime.flag`hasFunc.#get___Number_prototype`) {
|
204
|
+
if (Porffor.fastOr(
|
205
|
+
trueType == Porffor.TYPES.number,
|
206
|
+
trueType == Porffor.TYPES.numberobject
|
207
|
+
)) {
|
208
|
+
obj = __Number_prototype;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
if (Porffor.comptime.flag`hasFunc.#get___Boolean_prototype`) {
|
213
|
+
if (Porffor.fastOr(
|
214
|
+
trueType == Porffor.TYPES.boolean,
|
215
|
+
trueType == Porffor.TYPES.booleanobject
|
216
|
+
)) {
|
217
|
+
obj = __Boolean_prototype;
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
if (Porffor.comptime.flag`hasFunc.#get___Function_prototype`) {
|
222
|
+
if (trueType == Porffor.TYPES.function) {
|
223
|
+
obj = __Function_prototype;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
if (Porffor.comptime.flag`hasFunc.#get___Array_prototype`) {
|
228
|
+
if (trueType == Porffor.TYPES.array) {
|
229
|
+
obj = __Array_prototype;
|
230
|
+
}
|
215
231
|
}
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
232
|
+
|
233
|
+
if (Porffor.comptime.flag`hasFunc.#get___Date_prototype`) {
|
234
|
+
if (trueType == Porffor.TYPES.date) {
|
235
|
+
obj = __Date_prototype;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
if (Porffor.comptime.flag`hasFunc.#get___Error_prototype`) {
|
240
|
+
if (trueType == Porffor.TYPES.error) {
|
241
|
+
obj = __Error_prototype;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
if (Porffor.fastOr(obj == null, Porffor.wasm`local.get ${obj}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
246
|
+
lastProto = obj;
|
247
|
+
|
248
|
+
if ((entryPtr = __Porffor_object_lookup(obj, key)) != -1) break;
|
249
|
+
}
|
250
|
+
} else {
|
251
|
+
let proto: i32 = __Object_prototype;
|
252
|
+
if (trueType == Porffor.TYPES.function) proto = __Function_prototype;
|
253
|
+
|
254
|
+
Porffor.wasm`
|
220
255
|
local.get ${proto}
|
221
256
|
f64.convert_i32_u
|
222
257
|
i32.const 7 ;; object type
|
223
258
|
return`;
|
224
|
-
}
|
225
259
|
}
|
226
260
|
|
227
261
|
if (entryPtr == -1) {
|
@@ -246,24 +280,7 @@ i32.const 128
|
|
246
280
|
return`;
|
247
281
|
}
|
248
282
|
|
249
|
-
|
250
|
-
if (funcFlags & 0b10) {
|
251
|
-
// constructor func, add new.target, this args
|
252
|
-
Porffor.wasm`
|
253
|
-
f64.const 0
|
254
|
-
i32.const 0
|
255
|
-
local.get ${obj}
|
256
|
-
f64.convert_i32_u
|
257
|
-
local.get ${obj+1}
|
258
|
-
local.get ${get}
|
259
|
-
call_indirect 2 0
|
260
|
-
return`;
|
261
|
-
} else {
|
262
|
-
Porffor.wasm`
|
263
|
-
local.get ${get}
|
264
|
-
call_indirect 0 0
|
265
|
-
return`;
|
266
|
-
}
|
283
|
+
return get.call(obj);
|
267
284
|
}
|
268
285
|
|
269
286
|
// data descriptor
|
@@ -330,27 +347,7 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
|
330
347
|
return value;
|
331
348
|
}
|
332
349
|
|
333
|
-
|
334
|
-
if (funcFlags & 0b10) {
|
335
|
-
// constructor func, add new.target, this args
|
336
|
-
Porffor.wasm`
|
337
|
-
f64.const 0
|
338
|
-
i32.const 0
|
339
|
-
local.get ${obj}
|
340
|
-
f64.convert_i32_u
|
341
|
-
i32.const 7
|
342
|
-
local.get ${value}
|
343
|
-
local.get ${value+1}
|
344
|
-
local.get ${set}
|
345
|
-
call_indirect 3 0`;
|
346
|
-
} else {
|
347
|
-
Porffor.wasm`
|
348
|
-
local.get ${value}
|
349
|
-
local.get ${value+1}
|
350
|
-
local.get ${set}
|
351
|
-
call_indirect 1 0`;
|
352
|
-
}
|
353
|
-
|
350
|
+
set.call(obj, value);
|
354
351
|
return value;
|
355
352
|
}
|
356
353
|
|
@@ -416,27 +413,7 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
|
|
416
413
|
throw new TypeError('Cannot set property with no setter of object');
|
417
414
|
}
|
418
415
|
|
419
|
-
|
420
|
-
if (funcFlags & 0b10) {
|
421
|
-
// constructor func, add new.target, this args
|
422
|
-
Porffor.wasm`
|
423
|
-
f64.const 0
|
424
|
-
i32.const 0
|
425
|
-
local.get ${obj}
|
426
|
-
f64.convert_i32_u
|
427
|
-
i32.const 7
|
428
|
-
local.get ${value}
|
429
|
-
local.get ${value+1}
|
430
|
-
local.get ${set}
|
431
|
-
call_indirect 3 0`;
|
432
|
-
} else {
|
433
|
-
Porffor.wasm`
|
434
|
-
local.get ${value}
|
435
|
-
local.get ${value+1}
|
436
|
-
local.get ${set}
|
437
|
-
call_indirect 1 0`;
|
438
|
-
}
|
439
|
-
|
416
|
+
set.call(obj, value);
|
440
417
|
return value;
|
441
418
|
}
|
442
419
|
|
@@ -535,20 +512,6 @@ local.set ${err}`;
|
|
535
512
|
export const __Porffor_object_delete = (obj: any, key: any): boolean => {
|
536
513
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
537
514
|
|
538
|
-
if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.function) {
|
539
|
-
const tmp1: bytestring = 'name';
|
540
|
-
if (key == tmp1) {
|
541
|
-
__Porffor_funcLut_deleteName(obj);
|
542
|
-
return true;
|
543
|
-
}
|
544
|
-
|
545
|
-
const tmp2: bytestring = 'length';
|
546
|
-
if (key == tmp2) {
|
547
|
-
__Porffor_funcLut_deleteLength(obj);
|
548
|
-
return true;
|
549
|
-
}
|
550
|
-
}
|
551
|
-
|
552
515
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
553
516
|
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
554
517
|
// todo: support non-pure objects
|
@@ -600,20 +563,6 @@ memory.copy 0 0`;
|
|
600
563
|
export const __Porffor_object_deleteStrict = (obj: any, key: any): boolean => {
|
601
564
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
602
565
|
|
603
|
-
if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.function) {
|
604
|
-
const tmp1: bytestring = 'name';
|
605
|
-
if (key == tmp1) {
|
606
|
-
__Porffor_funcLut_deleteName(obj);
|
607
|
-
return true;
|
608
|
-
}
|
609
|
-
|
610
|
-
const tmp2: bytestring = 'length';
|
611
|
-
if (key == tmp2) {
|
612
|
-
__Porffor_funcLut_deleteLength(obj);
|
613
|
-
return true;
|
614
|
-
}
|
615
|
-
}
|
616
|
-
|
617
566
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
618
567
|
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
619
568
|
// todo: support non-pure objects
|
@@ -150,16 +150,6 @@ export const __Object_prototype_hasOwnProperty = (_this: any, prop: any) => {
|
|
150
150
|
return Porffor.object.lookup(_this, p) != -1;
|
151
151
|
}
|
152
152
|
|
153
|
-
if (t == Porffor.TYPES.function) {
|
154
|
-
const tmp1: bytestring = 'name';
|
155
|
-
if (p == tmp1) return !__Porffor_funcLut_isNameDeleted(_this);
|
156
|
-
|
157
|
-
const tmp2: bytestring = 'length';
|
158
|
-
if (p == tmp2) return !__Porffor_funcLut_isLengthDeleted(_this);
|
159
|
-
|
160
|
-
return Porffor.object.lookup(_this, p) != -1;
|
161
|
-
}
|
162
|
-
|
163
153
|
const obj: any = __Porffor_object_underlying(_this);
|
164
154
|
if (Porffor.rawType(obj) == Porffor.TYPES.object) {
|
165
155
|
if (Porffor.object.lookup(obj, p) != -1) return true;
|
@@ -576,15 +566,27 @@ export const __Object_defineProperty = (target: any, prop: any, desc: any) => {
|
|
576
566
|
|
577
567
|
const existingDesc: any = __Object_getOwnPropertyDescriptor(target, prop);
|
578
568
|
if (existingDesc) {
|
579
|
-
|
580
|
-
|
569
|
+
let inKey: bytestring = '';
|
570
|
+
|
571
|
+
// probably slow due to excessive in's but needs to have them to be spec compliant handling explicit undefined vs non-existent
|
572
|
+
inKey = 'configurable';
|
573
|
+
if (configurable == null && !(inKey in desc)) configurable = existingDesc.configurable;
|
574
|
+
|
575
|
+
inKey = 'enumerable';
|
576
|
+
if (enumerable == null && !(inKey in desc)) enumerable = existingDesc.enumerable;
|
581
577
|
|
582
578
|
if (accessor) {
|
583
|
-
|
584
|
-
|
579
|
+
inKey = 'get';
|
580
|
+
if (get == null && !(inKey in desc)) get = existingDesc.get;
|
581
|
+
|
582
|
+
inKey = 'set';
|
583
|
+
if (set == null && !(inKey in desc)) set = existingDesc.set;
|
585
584
|
} else {
|
586
|
-
|
587
|
-
|
585
|
+
inKey = 'value';
|
586
|
+
if (value == null && !(inKey in desc)) value = existingDesc.value;
|
587
|
+
|
588
|
+
inKey = 'writable';
|
589
|
+
if (writable == null && !(inKey in desc)) writable = existingDesc.writable;
|
588
590
|
}
|
589
591
|
}
|
590
592
|
|
@@ -674,11 +676,19 @@ export const __Object_prototype_isPrototypeOf = (_this: any, obj: any) => {
|
|
674
676
|
|
675
677
|
export const __Object_prototype_toString = (_this: any) => {
|
676
678
|
if (Porffor.rawType(_this) == Porffor.TYPES.object) {
|
677
|
-
|
679
|
+
// todo: breaks with Foo.prototype
|
678
680
|
const obj: object = _this;
|
679
681
|
if (obj != null) {
|
680
|
-
|
681
|
-
if (ovr
|
682
|
+
let ovr: any = obj.toString;
|
683
|
+
if (Porffor.rawType(ovr) == Porffor.TYPES.function && ovr != __Object_prototype_toString) return ovr.call(_this);
|
684
|
+
|
685
|
+
const key: bytestring = 'toString';
|
686
|
+
const entryPtr: i32 = Porffor.object.lookup(obj, key);
|
687
|
+
if (entryPtr != -1) {
|
688
|
+
ovr = Porffor.object.readValue(entryPtr);
|
689
|
+
if (Porffor.rawType(ovr) == Porffor.TYPES.function) return ovr.call(_this);
|
690
|
+
else return undefined;
|
691
|
+
}
|
682
692
|
}
|
683
693
|
}
|
684
694
|
|
@@ -719,8 +729,16 @@ export const __Object_prototype_valueOf = (_this: any) => {
|
|
719
729
|
// todo: breaks with Foo.prototype
|
720
730
|
const obj: object = _this;
|
721
731
|
if (obj != null) {
|
722
|
-
|
723
|
-
if (ovr
|
732
|
+
let ovr: any = obj.valueOf;
|
733
|
+
if (Porffor.rawType(ovr) == Porffor.TYPES.function && ovr != __Object_prototype_valueOf) return ovr.call(_this);
|
734
|
+
|
735
|
+
const key: bytestring = 'valueOf';
|
736
|
+
const entryPtr: i32 = Porffor.object.lookup(obj, key);
|
737
|
+
if (entryPtr != -1) {
|
738
|
+
ovr = Porffor.object.readValue(entryPtr);
|
739
|
+
if (Porffor.rawType(ovr) == Porffor.TYPES.function) return ovr.call(_this);
|
740
|
+
else return undefined;
|
741
|
+
}
|
724
742
|
}
|
725
743
|
}
|
726
744
|
|
package/compiler/builtins.js
CHANGED
@@ -100,7 +100,7 @@ export const BuiltinVars = function(ctx) {
|
|
100
100
|
this.Infinity.floatOnly = true;
|
101
101
|
|
102
102
|
for (const x in TYPES) {
|
103
|
-
this['__Porffor_TYPES_' + x] = number(TYPES[x]);
|
103
|
+
this['__Porffor_TYPES_' + x] = () => number(TYPES[x]);
|
104
104
|
}
|
105
105
|
|
106
106
|
this.__performance_timeOrigin = [
|
@@ -1002,32 +1002,30 @@ export const BuiltinFuncs = function() {
|
|
1002
1002
|
]
|
1003
1003
|
};
|
1004
1004
|
|
1005
|
-
this.
|
1005
|
+
this.__Porffor_funcLut_length = {
|
1006
1006
|
params: [ Valtype.i32 ],
|
1007
1007
|
returns: [ Valtype.i32 ],
|
1008
1008
|
returnType: TYPES.number,
|
1009
1009
|
wasm: (scope, { allocPage }) => [
|
1010
1010
|
[ Opcodes.local_get, 0 ],
|
1011
|
-
...number(
|
1011
|
+
...number(48, Valtype.i32),
|
1012
1012
|
[ Opcodes.i32_mul ],
|
1013
|
-
...
|
1014
|
-
[ Opcodes.i32_add ],
|
1015
|
-
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ]
|
1013
|
+
[ Opcodes.i32_load16_u, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ]
|
1016
1014
|
],
|
1017
1015
|
table: true
|
1018
1016
|
};
|
1019
1017
|
|
1020
|
-
this.
|
1018
|
+
this.__Porffor_funcLut_flags = {
|
1021
1019
|
params: [ Valtype.i32 ],
|
1022
1020
|
returns: [ Valtype.i32 ],
|
1023
1021
|
returnType: TYPES.number,
|
1024
1022
|
wasm: (scope, { allocPage }) => [
|
1025
1023
|
[ Opcodes.local_get, 0 ],
|
1026
|
-
...number(
|
1024
|
+
...number(48, Valtype.i32),
|
1027
1025
|
[ Opcodes.i32_mul ],
|
1028
1026
|
...number(2, Valtype.i32),
|
1029
1027
|
[ Opcodes.i32_add ],
|
1030
|
-
[ Opcodes.
|
1028
|
+
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ]
|
1031
1029
|
],
|
1032
1030
|
table: true
|
1033
1031
|
};
|
@@ -1038,9 +1036,9 @@ export const BuiltinFuncs = function() {
|
|
1038
1036
|
returnType: TYPES.bytestring,
|
1039
1037
|
wasm: (scope, { allocPage }) => [
|
1040
1038
|
[ Opcodes.local_get, 0 ],
|
1041
|
-
...number(
|
1039
|
+
...number(48, Valtype.i32),
|
1042
1040
|
[ Opcodes.i32_mul ],
|
1043
|
-
...number(
|
1041
|
+
...number(3, Valtype.i32),
|
1044
1042
|
[ Opcodes.i32_add ],
|
1045
1043
|
...number(allocPage(scope, 'func lut'), Valtype.i32),
|
1046
1044
|
[ Opcodes.i32_add ]
|
@@ -1048,65 +1046,5 @@ export const BuiltinFuncs = function() {
|
|
1048
1046
|
table: true
|
1049
1047
|
};
|
1050
1048
|
|
1051
|
-
this.__Porffor_funcLut_deleteLength = {
|
1052
|
-
params: [ Valtype.i32 ],
|
1053
|
-
returns: [],
|
1054
|
-
wasm: (scope, { allocPage }) => [
|
1055
|
-
[ Opcodes.local_get, 0 ],
|
1056
|
-
...number(64, Valtype.i32),
|
1057
|
-
[ Opcodes.i32_mul ],
|
1058
|
-
...number(2, Valtype.i32),
|
1059
|
-
[ Opcodes.i32_add ],
|
1060
|
-
...number(0, Valtype.i32),
|
1061
|
-
[ Opcodes.i32_store16, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ],
|
1062
|
-
|
1063
|
-
[ Opcodes.local_get, 0 ],
|
1064
|
-
...number(1, Valtype.i32),
|
1065
|
-
[ Opcodes.i32_store8, 0, ...unsignedLEB128(allocPage(scope, 'func length deletion table')) ]
|
1066
|
-
],
|
1067
|
-
table: true
|
1068
|
-
};
|
1069
|
-
|
1070
|
-
this.__Porffor_funcLut_deleteName = {
|
1071
|
-
params: [ Valtype.i32 ],
|
1072
|
-
returns: [],
|
1073
|
-
wasm: (scope, { allocPage }) => [
|
1074
|
-
[ Opcodes.local_get, 0 ],
|
1075
|
-
...number(64, Valtype.i32),
|
1076
|
-
[ Opcodes.i32_mul ],
|
1077
|
-
...number(5, Valtype.i32),
|
1078
|
-
[ Opcodes.i32_add ],
|
1079
|
-
...number(0, Valtype.i32),
|
1080
|
-
[ Opcodes.i32_store, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ],
|
1081
|
-
|
1082
|
-
[ Opcodes.local_get, 0 ],
|
1083
|
-
...number(1, Valtype.i32),
|
1084
|
-
[ Opcodes.i32_store8, 0, ...unsignedLEB128(allocPage(scope, 'func name deletion table')) ],
|
1085
|
-
],
|
1086
|
-
table: true
|
1087
|
-
};
|
1088
|
-
|
1089
|
-
this.__Porffor_funcLut_isLengthDeleted = {
|
1090
|
-
params: [ Valtype.i32 ],
|
1091
|
-
returns: [ Valtype.i32 ],
|
1092
|
-
returnType: TYPES.boolean,
|
1093
|
-
wasm: (scope, { allocPage }) => [
|
1094
|
-
[ Opcodes.local_get, 0 ],
|
1095
|
-
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func length deletion table')) ]
|
1096
|
-
],
|
1097
|
-
table: true
|
1098
|
-
};
|
1099
|
-
|
1100
|
-
this.__Porffor_funcLut_isNameDeleted = {
|
1101
|
-
params: [ Valtype.i32 ],
|
1102
|
-
returns: [ Valtype.i32 ],
|
1103
|
-
returnType: TYPES.boolean,
|
1104
|
-
wasm: (scope, { allocPage }) => [
|
1105
|
-
[ Opcodes.local_get, 0 ],
|
1106
|
-
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func name deletion table')) ]
|
1107
|
-
],
|
1108
|
-
table: true
|
1109
|
-
};
|
1110
|
-
|
1111
1049
|
PrecompiledBuiltins.BuiltinFuncs.call(this);
|
1112
1050
|
};
|
@@ -199,7 +199,16 @@ export default function({ builtinFuncs }, Prefs) {
|
|
199
199
|
const props = autoFuncs(x);
|
200
200
|
|
201
201
|
// special case: Object.prototype.__proto__ = null
|
202
|
-
if (x === '__Object_prototype')
|
202
|
+
if (x === '__Object_prototype') {
|
203
|
+
Object.defineProperty(props, '__proto__', { value: { value: null, configurable: true }, enumerable: true });
|
204
|
+
}
|
205
|
+
|
206
|
+
// special case: Function.prototype.length = 0
|
207
|
+
// special case: Function.prototype.name = ''
|
208
|
+
if (x === '__Function_prototype') {
|
209
|
+
props.length = { value: 0, configurable: true };
|
210
|
+
props.name = { value: '', configurable: true };
|
211
|
+
}
|
203
212
|
|
204
213
|
// add constructor for constructors
|
205
214
|
const name = x.slice(2, x.indexOf('_', 2));
|