porffor 0.55.21 → 0.55.23
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/allocator.js +1 -1
- package/compiler/builtins/_internal_object.ts +560 -279
- package/compiler/builtins/bigint.ts +2 -2
- package/compiler/builtins/function.ts +1 -1
- package/compiler/builtins/object.ts +35 -44
- package/compiler/builtins/object_prototypeWithHidden.js +47 -0
- package/compiler/builtins/reflect.ts +4 -4
- package/compiler/builtins/z_ecma262.ts +3 -0
- package/compiler/builtins_precompiled.js +569 -550
- package/compiler/codegen.js +124 -198
- package/compiler/precompile.js +6 -5
- package/compiler/prototype.js +80 -66
- package/compiler/wrap.js +3 -4
- package/package.json +1 -1
- package/r.cjs +29 -0
- package/runner/index.js +1 -1
@@ -1,30 +1,60 @@
|
|
1
1
|
// @porf --valtype=i32
|
2
2
|
import type {} from './porffor.d.ts';
|
3
3
|
|
4
|
-
//
|
5
|
-
//
|
6
|
-
// size (
|
7
|
-
// root flags (
|
4
|
+
// __memory layout__
|
5
|
+
// per object (8):
|
6
|
+
// size (u16, 2)
|
7
|
+
// root flags (u8, 1):
|
8
8
|
// inextensible - 0b0001
|
9
|
-
//
|
9
|
+
// prototype type (u8, 1)
|
10
|
+
// prototype (u32, 4)
|
11
|
+
// per entry (18):
|
12
|
+
// key - hash (u32, 4)
|
10
13
|
// key - value, type MSB encoded (u32, 4)
|
11
14
|
// value - value (f64, 8)
|
12
|
-
// value - type +
|
13
|
-
// flags:
|
15
|
+
// value - type + flags (u16, 2):
|
14
16
|
// accessor - 0b0001
|
15
17
|
// configurable - 0b0010
|
16
18
|
// enumerable - 0b0100
|
17
19
|
// writable - 0b1000
|
18
20
|
|
21
|
+
export const __Porffor_object_isObject = (arg: any): boolean => {
|
22
|
+
const t: i32 = Porffor.wasm`local.get ${arg+1}`;
|
23
|
+
return Porffor.fastAnd(
|
24
|
+
arg != 0, // null
|
25
|
+
t > 0x05,
|
26
|
+
t != Porffor.TYPES.string,
|
27
|
+
t != Porffor.TYPES.bytestring
|
28
|
+
);
|
29
|
+
};
|
30
|
+
|
31
|
+
export const __Porffor_object_isObjectOrNull = (arg: any): boolean => {
|
32
|
+
const t: i32 = Porffor.wasm`local.get ${arg+1}`;
|
33
|
+
return Porffor.fastAnd(
|
34
|
+
t > 0x05,
|
35
|
+
t != Porffor.TYPES.string,
|
36
|
+
t != Porffor.TYPES.bytestring
|
37
|
+
);
|
38
|
+
};
|
39
|
+
|
40
|
+
export const __Porffor_object_isObjectOrSymbol = (arg: any): boolean => {
|
41
|
+
const t: i32 = Porffor.wasm`local.get ${arg+1}`;
|
42
|
+
return Porffor.fastAnd(
|
43
|
+
arg != 0, // null
|
44
|
+
t > 0x04,
|
45
|
+
t != Porffor.TYPES.string,
|
46
|
+
t != Porffor.TYPES.bytestring
|
47
|
+
);
|
48
|
+
};
|
49
|
+
|
50
|
+
|
19
51
|
export const __Porffor_object_preventExtensions = (obj: any): void => {
|
20
52
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
21
53
|
obj = __Porffor_object_underlying(obj);
|
22
54
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return;
|
23
55
|
}
|
24
56
|
|
25
|
-
|
26
|
-
rootFlags |= 0b0001;
|
27
|
-
Porffor.wasm.i32.store8(obj, rootFlags, 0, 4);
|
57
|
+
Porffor.wasm.i32.store8(obj, Porffor.wasm.i32.load8_u(obj, 0, 2) | 0b0001, 0, 2);
|
28
58
|
};
|
29
59
|
|
30
60
|
export const __Porffor_object_isInextensible = (obj: any): boolean => {
|
@@ -33,8 +63,39 @@ export const __Porffor_object_isInextensible = (obj: any): boolean => {
|
|
33
63
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return false;
|
34
64
|
}
|
35
65
|
|
36
|
-
|
37
|
-
|
66
|
+
return (Porffor.wasm.i32.load8_u(obj, 0, 2) & 0b0001) as boolean;
|
67
|
+
};
|
68
|
+
|
69
|
+
export const __Porffor_object_setPrototype = (obj: any, proto: any): void => {
|
70
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
71
|
+
obj = __Porffor_object_underlying(obj);
|
72
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return;
|
73
|
+
}
|
74
|
+
|
75
|
+
if (__Porffor_object_isObjectOrNull(proto)) {
|
76
|
+
Porffor.wasm.i32.store(obj, proto, 0, 4);
|
77
|
+
Porffor.wasm.i32.store8(obj, Porffor.rawType(proto), 0, 3);
|
78
|
+
}
|
79
|
+
};
|
80
|
+
|
81
|
+
export const __Porffor_object_getPrototype = (obj: any): any => {
|
82
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
83
|
+
obj = __Porffor_object_underlying(obj);
|
84
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
85
|
+
// return empty
|
86
|
+
Porffor.wasm`
|
87
|
+
i32.const 0
|
88
|
+
i32.const 0
|
89
|
+
return`;
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
Porffor.wasm`
|
94
|
+
local.get ${obj}
|
95
|
+
i32.load 0 4
|
96
|
+
local.get ${obj}
|
97
|
+
i32.load8_u 0 3
|
98
|
+
return`;
|
38
99
|
};
|
39
100
|
|
40
101
|
|
@@ -44,15 +105,15 @@ export const __Porffor_object_overrideAllFlags = (obj: any, overrideOr: i32, ove
|
|
44
105
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return;
|
45
106
|
}
|
46
107
|
|
47
|
-
let ptr: i32 = Porffor.wasm`local.get ${obj}
|
108
|
+
let ptr: i32 = Porffor.wasm`local.get ${obj}`;
|
48
109
|
|
49
|
-
const size: i32 = Porffor.wasm.i32.
|
50
|
-
const endPtr: i32 = ptr + size *
|
110
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
111
|
+
const endPtr: i32 = ptr + size * 18;
|
51
112
|
|
52
|
-
for (; ptr < endPtr; ptr +=
|
53
|
-
let flags: i32 = Porffor.wasm.i32.load8_u(ptr, 0,
|
113
|
+
for (; ptr < endPtr; ptr += 18) {
|
114
|
+
let flags: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 24);
|
54
115
|
flags = (flags | overrideOr) & overrideAnd;
|
55
|
-
Porffor.wasm.i32.store8(ptr, flags, 0,
|
116
|
+
Porffor.wasm.i32.store8(ptr, flags, 0, 24);
|
56
117
|
}
|
57
118
|
};
|
58
119
|
|
@@ -62,13 +123,13 @@ export const __Porffor_object_checkAllFlags = (obj: any, dataAnd: i32, accessorA
|
|
62
123
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return false;
|
63
124
|
}
|
64
125
|
|
65
|
-
let ptr: i32 = Porffor.wasm`local.get ${obj}
|
126
|
+
let ptr: i32 = Porffor.wasm`local.get ${obj}`;
|
66
127
|
|
67
|
-
const size: i32 = Porffor.wasm.i32.
|
68
|
-
const endPtr: i32 = ptr + size *
|
128
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
129
|
+
const endPtr: i32 = ptr + size * 18;
|
69
130
|
|
70
|
-
for (; ptr < endPtr; ptr +=
|
71
|
-
const flags: i32 = Porffor.wasm.i32.load8_u(ptr, 0,
|
131
|
+
for (; ptr < endPtr; ptr += 18) {
|
132
|
+
const flags: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 24);
|
72
133
|
if (flags & 0b0001) {
|
73
134
|
// accessor
|
74
135
|
if ((flags & accessorAnd) != accessorExpected) return false;
|
@@ -83,7 +144,7 @@ export const __Porffor_object_checkAllFlags = (obj: any, dataAnd: i32, accessorA
|
|
83
144
|
};
|
84
145
|
|
85
146
|
export const __Porffor_object_packAccessor = (get: any, set: any): f64 => {
|
86
|
-
// pack i32s get & set into a single f64 (
|
147
|
+
// pack i32s get & set into a single f64 (reinterpreted u64)
|
87
148
|
Porffor.wasm`
|
88
149
|
local.get ${set}
|
89
150
|
i64.extend_i32_u
|
@@ -97,7 +158,7 @@ return`;
|
|
97
158
|
};
|
98
159
|
|
99
160
|
export const __Porffor_object_accessorGet = (entryPtr: i32): Function|undefined => {
|
100
|
-
const out: Function = Porffor.wasm.i32.load(entryPtr, 0,
|
161
|
+
const out: Function = Porffor.wasm.i32.load(entryPtr, 0, 8);
|
101
162
|
|
102
163
|
// no getter, return undefined
|
103
164
|
if (Porffor.wasm`local.get ${out}` == 0) {
|
@@ -108,7 +169,7 @@ export const __Porffor_object_accessorGet = (entryPtr: i32): Function|undefined
|
|
108
169
|
};
|
109
170
|
|
110
171
|
export const __Porffor_object_accessorSet = (entryPtr: i32): Function|undefined => {
|
111
|
-
const out: Function = Porffor.wasm.i32.load(entryPtr, 0,
|
172
|
+
const out: Function = Porffor.wasm.i32.load(entryPtr, 0, 12);
|
112
173
|
|
113
174
|
// no setter, return undefined
|
114
175
|
if (Porffor.wasm`local.get ${out}` == 0) {
|
@@ -119,49 +180,232 @@ export const __Porffor_object_accessorSet = (entryPtr: i32): Function|undefined
|
|
119
180
|
};
|
120
181
|
|
121
182
|
|
122
|
-
export const
|
183
|
+
export const __Porffor_object_hash = (key: any): i32 => {
|
184
|
+
if (Porffor.wasm`local.get ${key+1}` == Porffor.TYPES.symbol) {
|
185
|
+
// symbol, hash is just the symbol
|
186
|
+
return key as number;
|
187
|
+
}
|
188
|
+
|
189
|
+
// bytestring or string, fnv-1a hash (custom variant)
|
190
|
+
// todo/opt: custom wasm simd variant?
|
191
|
+
|
192
|
+
let ptr: i32 = Porffor.wasm`local.get ${key}`;
|
193
|
+
const len: i32 = Porffor.wasm.i32.load(key, 0, 0);
|
194
|
+
|
195
|
+
let hash: i32 = (2166136261 ^ len) * 16777619;
|
196
|
+
if (Porffor.wasm`local.get ${key+1}` == Porffor.TYPES.bytestring) {
|
197
|
+
// chunks of 8 bytes via i64.load
|
198
|
+
const endPtr: i32 = ptr + len - 8;
|
199
|
+
for (; ptr <= endPtr; ptr += 8) {
|
200
|
+
Porffor.wasm`
|
201
|
+
local x i64
|
202
|
+
local.get ${ptr}
|
203
|
+
i64.load 0 4
|
204
|
+
local.set x
|
205
|
+
|
206
|
+
local.get ${hash}
|
207
|
+
local.get x
|
208
|
+
i64.const 32
|
209
|
+
i64.shr_u
|
210
|
+
i32.wrap_i64
|
211
|
+
i32.xor
|
212
|
+
i32.const 16777619
|
213
|
+
i32.mul
|
214
|
+
|
215
|
+
local.get x
|
216
|
+
i32.wrap_i64
|
217
|
+
i32.xor
|
218
|
+
i32.const 16777619
|
219
|
+
i32.mul
|
220
|
+
|
221
|
+
local.set ${hash}`;
|
222
|
+
}
|
223
|
+
|
224
|
+
// remaining 0-7 bytes via i64.load and bitwise
|
225
|
+
Porffor.wasm`
|
226
|
+
local.get ${ptr}
|
227
|
+
i64.load 0 4
|
228
|
+
|
229
|
+
local shift i64
|
230
|
+
local.get ${ptr}
|
231
|
+
local.get ${endPtr}
|
232
|
+
i32.sub
|
233
|
+
i32.const 8
|
234
|
+
i32.mul
|
235
|
+
i64.extend_i32_u
|
236
|
+
local.tee shift
|
237
|
+
|
238
|
+
i64.shl
|
239
|
+
local.get shift
|
240
|
+
i64.shr_u
|
241
|
+
local.set x
|
242
|
+
|
243
|
+
local.get ${hash}
|
244
|
+
local.get x
|
245
|
+
i64.const 32
|
246
|
+
i64.shr_u
|
247
|
+
i32.wrap_i64
|
248
|
+
i32.xor
|
249
|
+
i32.const 16777619
|
250
|
+
i32.mul
|
251
|
+
|
252
|
+
local.get x
|
253
|
+
i32.wrap_i64
|
254
|
+
i32.xor
|
255
|
+
i32.const 16777619
|
256
|
+
i32.mul
|
257
|
+
|
258
|
+
local.set ${hash}`;
|
259
|
+
} else {
|
260
|
+
// slow path: string, process like bytestring
|
261
|
+
// skips 1 byte per char but we want collisions (false positives) instead of lack there of
|
262
|
+
// 4x 16 chars (u64): 0x0012003400560078
|
263
|
+
// 4x 8 chars (u32): 0x12345678
|
264
|
+
// todo: this doesn't work?
|
265
|
+
|
266
|
+
const endPtr: i32 = ptr + len * 2 - 8;
|
267
|
+
for (; ptr <= endPtr; ptr += 8) {
|
268
|
+
Porffor.wasm`
|
269
|
+
local.get ${ptr}
|
270
|
+
i64.load 0 4
|
271
|
+
local.set x
|
272
|
+
|
273
|
+
local.get ${hash}
|
274
|
+
local.get x
|
275
|
+
i64.const 48
|
276
|
+
i64.shr_u
|
277
|
+
i64.const 255
|
278
|
+
i64.and
|
279
|
+
i64.const 24
|
280
|
+
i64.shl
|
281
|
+
local.get x
|
282
|
+
i64.const 32
|
283
|
+
i64.shr_u
|
284
|
+
i64.const 255
|
285
|
+
i64.and
|
286
|
+
i64.const 16
|
287
|
+
i64.shl
|
288
|
+
i64.or
|
289
|
+
local.get x
|
290
|
+
i64.const 16
|
291
|
+
i64.shr_u
|
292
|
+
i64.const 255
|
293
|
+
i64.and
|
294
|
+
i64.const 8
|
295
|
+
i64.shl
|
296
|
+
i64.or
|
297
|
+
local.get x
|
298
|
+
i64.const 255
|
299
|
+
i64.and
|
300
|
+
i64.or
|
301
|
+
i32.wrap_i64
|
302
|
+
i32.xor
|
303
|
+
i32.const 16777619
|
304
|
+
i32.mul
|
305
|
+
local.set ${hash}`;
|
306
|
+
}
|
307
|
+
|
308
|
+
// remaining 0-7 bytes via i64.load and bitwise
|
309
|
+
Porffor.wasm`
|
310
|
+
local.get ${ptr}
|
311
|
+
i64.load 0 4
|
312
|
+
|
313
|
+
local.get ${ptr}
|
314
|
+
local.get ${endPtr}
|
315
|
+
i32.sub
|
316
|
+
i32.const 8
|
317
|
+
i32.mul
|
318
|
+
i64.extend_i32_u
|
319
|
+
local.tee shift
|
320
|
+
|
321
|
+
i64.shl
|
322
|
+
local.get shift
|
323
|
+
i64.shr_u
|
324
|
+
local.set x
|
325
|
+
|
326
|
+
local.get ${hash}
|
327
|
+
local.get x
|
328
|
+
i64.const 48
|
329
|
+
i64.shr_u
|
330
|
+
i64.const 255
|
331
|
+
i64.and
|
332
|
+
i64.const 24
|
333
|
+
i64.shl
|
334
|
+
local.get x
|
335
|
+
i64.const 32
|
336
|
+
i64.shr_u
|
337
|
+
i64.const 255
|
338
|
+
i64.and
|
339
|
+
i64.const 16
|
340
|
+
i64.shl
|
341
|
+
i64.or
|
342
|
+
local.get x
|
343
|
+
i64.const 16
|
344
|
+
i64.shr_u
|
345
|
+
i64.const 255
|
346
|
+
i64.and
|
347
|
+
i64.const 8
|
348
|
+
i64.shl
|
349
|
+
i64.or
|
350
|
+
local.get x
|
351
|
+
i64.const 255
|
352
|
+
i64.and
|
353
|
+
i64.or
|
354
|
+
i32.wrap_i64
|
355
|
+
i32.xor
|
356
|
+
i32.const 16777619
|
357
|
+
i32.mul
|
358
|
+
local.set ${hash}`;
|
359
|
+
}
|
360
|
+
|
361
|
+
return hash;
|
362
|
+
};
|
363
|
+
|
364
|
+
export const __Porffor_object_lookup = (obj: any, target: any, targetHash: i32): i32 => {
|
123
365
|
if (Porffor.wasm`local.get ${obj}` == 0) return -1;
|
124
366
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
125
367
|
obj = __Porffor_object_underlying(obj);
|
126
368
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return -1;
|
127
369
|
}
|
128
370
|
|
129
|
-
|
130
|
-
|
131
|
-
let ptr: i32 = Porffor.wasm`local.get ${obj}` + 5;
|
132
|
-
|
133
|
-
const size: i32 = Porffor.wasm.i32.load(obj, 0, 0);
|
134
|
-
const endPtr: i32 = ptr + size * 14;
|
371
|
+
let ptr: i32 = Porffor.wasm`local.get ${obj}` + 8;
|
372
|
+
const endPtr: i32 = ptr + Porffor.wasm.i32.load16_u(obj, 0, 0) * 18;
|
135
373
|
|
136
374
|
let out: boolean = false;
|
137
|
-
if (
|
138
|
-
for (; ptr < endPtr; ptr +=
|
139
|
-
const
|
140
|
-
if (
|
375
|
+
if (Porffor.wasm`local.get ${target+1}` == Porffor.TYPES.symbol) {
|
376
|
+
for (; ptr < endPtr; ptr += 18) {
|
377
|
+
const key: i32 = Porffor.wasm.i32.load(ptr, 0, 4);
|
378
|
+
if (key == 0) {
|
141
379
|
if (out) break; // ran out of keys
|
142
380
|
out = true;
|
143
381
|
}
|
144
382
|
|
145
|
-
if (
|
383
|
+
if ((key >>> 30) == 3) { // MSB 1 and 2 set, symbol (unset MSB x2)
|
146
384
|
// todo: remove casts once weird bug which breaks unrelated things is fixed (https://github.com/CanadaHonk/porffor/commit/5747f0c1f3a4af95283ebef175cdacb21e332a52)
|
147
|
-
if ((
|
385
|
+
if ((key & 0x3FFFFFFF) as symbol == target as symbol) return ptr;
|
148
386
|
}
|
149
387
|
}
|
150
388
|
} else {
|
151
|
-
|
152
|
-
|
153
|
-
|
389
|
+
if (targetHash == 0) targetHash = __Porffor_object_hash(target);
|
390
|
+
for (; ptr < endPtr; ptr += 18) {
|
391
|
+
const hash: i32 = Porffor.wasm.i32.load(ptr, 0, 0);
|
392
|
+
|
393
|
+
// todo: is below needed anymore?
|
394
|
+
if (hash == 0) {
|
154
395
|
if (out) break; // ran out of keys
|
155
396
|
out = true;
|
156
397
|
}
|
157
398
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
if (
|
162
|
-
|
163
|
-
|
164
|
-
if (
|
399
|
+
if (hash == targetHash) {
|
400
|
+
const key: i32 = Porffor.wasm.i32.load(ptr, 0, 4);
|
401
|
+
const msb: i32 = key >>> 30;
|
402
|
+
if (msb == 0) {
|
403
|
+
// bytestring
|
404
|
+
if (Porffor.strcmp(key as bytestring, target)) return ptr;
|
405
|
+
} else if (msb == 2) {
|
406
|
+
// string (unset MSB)
|
407
|
+
if (Porffor.strcmp((key & 0x7FFFFFFF) as string, target)) return ptr;
|
408
|
+
}
|
165
409
|
}
|
166
410
|
}
|
167
411
|
}
|
@@ -172,9 +416,9 @@ export const __Porffor_object_lookup = (obj: any, target: any): i32 => {
|
|
172
416
|
export const __Porffor_object_readValue = (entryPtr: i32): any => {
|
173
417
|
Porffor.wasm`
|
174
418
|
local.get ${entryPtr}
|
175
|
-
f64.load 0
|
419
|
+
f64.load 0 8
|
176
420
|
local.get ${entryPtr}
|
177
|
-
i32.load8_u 0
|
421
|
+
i32.load8_u 0 17
|
178
422
|
return`;
|
179
423
|
};
|
180
424
|
|
@@ -184,83 +428,31 @@ export const __Porffor_object_get = (obj: any, key: any): any => {
|
|
184
428
|
|
185
429
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot get property of null');
|
186
430
|
|
187
|
-
|
431
|
+
const hash: i32 = __Porffor_object_hash(key);
|
432
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
188
433
|
if (entryPtr == -1) {
|
189
434
|
// check prototype chain
|
190
|
-
|
191
|
-
let lastProto: any = obj;
|
192
|
-
if (key != protoKey) {
|
193
|
-
while (true) {
|
194
|
-
obj = __Porffor_object_get(obj, protoKey);
|
195
|
-
|
196
|
-
if (Porffor.comptime.flag`hasFunc.#get___String_prototype`) {
|
197
|
-
if (Porffor.fastOr(
|
198
|
-
trueType == Porffor.TYPES.string,
|
199
|
-
trueType == Porffor.TYPES.bytestring,
|
200
|
-
trueType == Porffor.TYPES.stringobject
|
201
|
-
)) {
|
202
|
-
obj = __String_prototype;
|
203
|
-
}
|
204
|
-
}
|
205
|
-
|
206
|
-
if (Porffor.comptime.flag`hasFunc.#get___Number_prototype`) {
|
207
|
-
if (Porffor.fastOr(
|
208
|
-
trueType == Porffor.TYPES.number,
|
209
|
-
trueType == Porffor.TYPES.numberobject
|
210
|
-
)) {
|
211
|
-
obj = __Number_prototype;
|
212
|
-
}
|
213
|
-
}
|
214
|
-
|
215
|
-
if (Porffor.comptime.flag`hasFunc.#get___Boolean_prototype`) {
|
216
|
-
if (Porffor.fastOr(
|
217
|
-
trueType == Porffor.TYPES.boolean,
|
218
|
-
trueType == Porffor.TYPES.booleanobject
|
219
|
-
)) {
|
220
|
-
obj = __Boolean_prototype;
|
221
|
-
}
|
222
|
-
}
|
223
|
-
|
224
|
-
if (Porffor.comptime.flag`hasFunc.#get___Function_prototype`) {
|
225
|
-
if (trueType == Porffor.TYPES.function) {
|
226
|
-
obj = __Function_prototype;
|
227
|
-
}
|
228
|
-
}
|
229
|
-
|
230
|
-
if (Porffor.comptime.flag`hasFunc.#get___Array_prototype`) {
|
231
|
-
if (trueType == Porffor.TYPES.array) {
|
232
|
-
obj = __Array_prototype;
|
233
|
-
}
|
234
|
-
}
|
235
|
-
|
236
|
-
if (Porffor.comptime.flag`hasFunc.#get___Date_prototype`) {
|
237
|
-
if (trueType == Porffor.TYPES.date) {
|
238
|
-
obj = __Date_prototype;
|
239
|
-
}
|
240
|
-
}
|
241
|
-
|
242
|
-
if (Porffor.comptime.flag`hasFunc.#get___Error_prototype`) {
|
243
|
-
if (trueType == Porffor.TYPES.error) {
|
244
|
-
obj = __Error_prototype;
|
245
|
-
}
|
246
|
-
}
|
247
|
-
|
248
|
-
if (Porffor.fastOr(obj == null, Porffor.wasm`local.get ${obj}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
249
|
-
lastProto = obj;
|
250
|
-
|
251
|
-
if ((entryPtr = __Porffor_object_lookup(obj, key)) != -1) break;
|
252
|
-
}
|
253
|
-
} else {
|
254
|
-
let proto: i32 = __Object_prototype;
|
255
|
-
if (trueType == Porffor.TYPES.function) proto = __Function_prototype;
|
435
|
+
obj = __Porffor_object_getPrototypeWithHidden(obj, trueType);
|
256
436
|
|
437
|
+
// todo/opt: put this behind comptime flag if only __proto__ is used
|
438
|
+
if (hash == -406948493) if (key == '__proto__') {
|
439
|
+
// get prototype
|
257
440
|
Porffor.wasm`
|
258
|
-
local.get ${
|
441
|
+
local.get ${obj}
|
259
442
|
f64.convert_i32_u
|
260
|
-
|
443
|
+
local.get ${obj+1}
|
261
444
|
return`;
|
262
445
|
}
|
263
446
|
|
447
|
+
let lastProto: any = obj;
|
448
|
+
while (true) {
|
449
|
+
if ((entryPtr = __Porffor_object_lookup(obj, key, hash)) != -1) break;
|
450
|
+
|
451
|
+
obj = __Porffor_object_getPrototype(obj);
|
452
|
+
if (Porffor.fastOr(obj == null, Porffor.wasm`local.get ${obj}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
453
|
+
lastProto = obj;
|
454
|
+
}
|
455
|
+
|
264
456
|
if (entryPtr == -1) {
|
265
457
|
Porffor.wasm`
|
266
458
|
f64.const 0
|
@@ -269,8 +461,7 @@ return`;
|
|
269
461
|
}
|
270
462
|
}
|
271
463
|
|
272
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
273
|
-
|
464
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
274
465
|
if (tail & 0b0001) {
|
275
466
|
// accessor descriptor
|
276
467
|
const get: Function = __Porffor_object_accessorGet(entryPtr);
|
@@ -289,14 +480,17 @@ return`;
|
|
289
480
|
// data descriptor
|
290
481
|
Porffor.wasm`
|
291
482
|
local.get ${entryPtr}
|
292
|
-
f64.load 0
|
483
|
+
f64.load 0 8
|
293
484
|
local.get ${tail}
|
294
485
|
i32.const 8
|
295
486
|
i32.shr_u
|
296
487
|
return`;
|
297
488
|
};
|
298
489
|
|
299
|
-
export const __Porffor_object_writeKey = (ptr: i32, key: any): void => {
|
490
|
+
export const __Porffor_object_writeKey = (ptr: i32, key: any, hash: i32 = __Porffor_object_hash(key)): void => {
|
491
|
+
// write hash to ptr
|
492
|
+
Porffor.wasm.i32.store(ptr, hash, 0, 0);
|
493
|
+
|
300
494
|
// encode key type
|
301
495
|
let keyEnc: i32 = Porffor.wasm`local.get ${key}`;
|
302
496
|
|
@@ -305,11 +499,10 @@ export const __Porffor_object_writeKey = (ptr: i32, key: any): void => {
|
|
305
499
|
// set MSB 1&2 if symbol
|
306
500
|
else if (Porffor.wasm`local.get ${key+1}` == Porffor.TYPES.symbol) keyEnc |= 0xc0000000;
|
307
501
|
|
308
|
-
// write encoded key to ptr
|
309
|
-
Porffor.wasm.i32.store(ptr, keyEnc, 0,
|
502
|
+
// write encoded key to ptr + 4
|
503
|
+
Porffor.wasm.i32.store(ptr, keyEnc, 0, 4);
|
310
504
|
};
|
311
505
|
|
312
|
-
// todo: check prototype for setters
|
313
506
|
export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
314
507
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
315
508
|
obj = __Porffor_object_underlying(obj);
|
@@ -318,9 +511,53 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
|
318
511
|
|
319
512
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot set property of null');
|
320
513
|
|
321
|
-
|
514
|
+
const hash: i32 = __Porffor_object_hash(key);
|
515
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
322
516
|
let flags: i32;
|
323
517
|
if (entryPtr == -1) {
|
518
|
+
if (hash == -406948493) if (key == '__proto__') {
|
519
|
+
// set prototype
|
520
|
+
Porffor.wasm`
|
521
|
+
local.get ${obj}
|
522
|
+
local.get ${obj+1}
|
523
|
+
local.get ${value}
|
524
|
+
i32.trunc_sat_f64_u
|
525
|
+
local.get ${value+1}
|
526
|
+
call __Porffor_object_setPrototype`;
|
527
|
+
return value;
|
528
|
+
}
|
529
|
+
|
530
|
+
// todo/opt: skip if no setters used
|
531
|
+
// check prototype chain for setter
|
532
|
+
let proto: any = __Porffor_object_getPrototype(obj);
|
533
|
+
if (proto != null) {
|
534
|
+
let lastProto: any = proto;
|
535
|
+
while (true) {
|
536
|
+
if ((entryPtr = __Porffor_object_lookup(proto, key, hash)) != -1) break;
|
537
|
+
|
538
|
+
proto = __Porffor_object_getPrototype(proto);
|
539
|
+
if (Porffor.fastOr(proto == null, Porffor.wasm`local.get ${proto}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
540
|
+
lastProto = proto;
|
541
|
+
}
|
542
|
+
|
543
|
+
if (entryPtr != -1) {
|
544
|
+
// found possible setter
|
545
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
546
|
+
if (tail & 0b0001) {
|
547
|
+
// accessor descriptor
|
548
|
+
const set: Function = __Porffor_object_accessorSet(entryPtr);
|
549
|
+
|
550
|
+
// no setter, return early
|
551
|
+
if (Porffor.wasm`local.get ${set}` == 0) {
|
552
|
+
return value;
|
553
|
+
}
|
554
|
+
|
555
|
+
set.call(obj, value);
|
556
|
+
return value;
|
557
|
+
}
|
558
|
+
}
|
559
|
+
}
|
560
|
+
|
324
561
|
// add new entry
|
325
562
|
// check if object is inextensible
|
326
563
|
if (__Porffor_object_isInextensible(obj)) {
|
@@ -328,19 +565,19 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
|
328
565
|
}
|
329
566
|
|
330
567
|
// bump size +1
|
331
|
-
const size: i32 = Porffor.wasm.i32.
|
332
|
-
Porffor.wasm.i32.
|
568
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
569
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
333
570
|
|
334
571
|
// entryPtr = current end of object
|
335
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
572
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
336
573
|
|
337
|
-
__Porffor_object_writeKey(entryPtr, key);
|
574
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
338
575
|
|
339
576
|
// flags = writable, enumerable, configurable, not accessor
|
340
577
|
flags = 0b1110;
|
341
578
|
} else {
|
342
579
|
// existing entry, modify it
|
343
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
580
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
344
581
|
|
345
582
|
if (tail & 0b0001) {
|
346
583
|
// accessor descriptor
|
@@ -365,13 +602,13 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
|
365
602
|
flags = tail & 0xff;
|
366
603
|
}
|
367
604
|
|
368
|
-
// write new value value
|
369
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
605
|
+
// write new value value
|
606
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
370
607
|
|
371
608
|
// write new tail (value type + flags)
|
372
609
|
Porffor.wasm.i32.store16(entryPtr,
|
373
610
|
flags + (Porffor.wasm`local.get ${value+1}` << 8),
|
374
|
-
0,
|
611
|
+
0, 16);
|
375
612
|
|
376
613
|
return value;
|
377
614
|
};
|
@@ -384,9 +621,53 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
|
|
384
621
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return value;
|
385
622
|
}
|
386
623
|
|
387
|
-
|
624
|
+
const hash: i32 = __Porffor_object_hash(key);
|
625
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
388
626
|
let flags: i32;
|
389
627
|
if (entryPtr == -1) {
|
628
|
+
if (hash == -406948493) if (key == '__proto__') {
|
629
|
+
// set prototype
|
630
|
+
Porffor.wasm`
|
631
|
+
local.get ${obj}
|
632
|
+
local.get ${obj+1}
|
633
|
+
local.get ${value}
|
634
|
+
i32.trunc_sat_f64_u
|
635
|
+
local.get ${value+1}
|
636
|
+
call __Porffor_object_setPrototype`;
|
637
|
+
return value;
|
638
|
+
}
|
639
|
+
|
640
|
+
// todo/opt: skip if no setters used
|
641
|
+
// check prototype chain for setter
|
642
|
+
let proto: any = __Porffor_object_getPrototype(obj);
|
643
|
+
if (proto != null) {
|
644
|
+
let lastProto: any = proto;
|
645
|
+
while (true) {
|
646
|
+
if ((entryPtr = __Porffor_object_lookup(proto, key, hash)) != -1) break;
|
647
|
+
|
648
|
+
proto = __Porffor_object_getPrototype(proto);
|
649
|
+
if (Porffor.fastOr(proto == null, Porffor.wasm`local.get ${proto}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
650
|
+
lastProto = proto;
|
651
|
+
}
|
652
|
+
|
653
|
+
if (entryPtr != -1) {
|
654
|
+
// found possible setter
|
655
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
656
|
+
if (tail & 0b0001) {
|
657
|
+
// accessor descriptor
|
658
|
+
const set: Function = __Porffor_object_accessorSet(entryPtr);
|
659
|
+
|
660
|
+
// no setter, return early
|
661
|
+
if (Porffor.wasm`local.get ${set}` == 0) {
|
662
|
+
return value;
|
663
|
+
}
|
664
|
+
|
665
|
+
set.call(obj, value);
|
666
|
+
return value;
|
667
|
+
}
|
668
|
+
}
|
669
|
+
}
|
670
|
+
|
390
671
|
// add new entry
|
391
672
|
// check if object is inextensible
|
392
673
|
if (__Porffor_object_isInextensible(obj)) {
|
@@ -394,19 +675,19 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
|
|
394
675
|
}
|
395
676
|
|
396
677
|
// bump size +1
|
397
|
-
const size: i32 = Porffor.wasm.i32.
|
398
|
-
Porffor.wasm.i32.
|
678
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
679
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
399
680
|
|
400
681
|
// entryPtr = current end of object
|
401
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
682
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
402
683
|
|
403
|
-
__Porffor_object_writeKey(entryPtr, key);
|
684
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
404
685
|
|
405
686
|
// flags = writable, enumerable, configurable, not accessor
|
406
687
|
flags = 0b1110;
|
407
688
|
} else {
|
408
689
|
// existing entry, modify it
|
409
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
690
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
410
691
|
|
411
692
|
if (tail & 0b0001) {
|
412
693
|
// accessor descriptor
|
@@ -432,12 +713,12 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
|
|
432
713
|
}
|
433
714
|
|
434
715
|
// write new value value (lol)
|
435
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
716
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
436
717
|
|
437
718
|
// write new tail (value type + flags)
|
438
719
|
Porffor.wasm.i32.store16(entryPtr,
|
439
720
|
flags + (Porffor.wasm`local.get ${value+1}` << 8),
|
440
|
-
0,
|
721
|
+
0, 16);
|
441
722
|
|
442
723
|
return value;
|
443
724
|
};
|
@@ -448,7 +729,8 @@ export const __Porffor_object_define = (obj: any, key: any, value: any, flags: i
|
|
448
729
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return;
|
449
730
|
}
|
450
731
|
|
451
|
-
|
732
|
+
const hash: i32 = __Porffor_object_hash(key);
|
733
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
452
734
|
if (entryPtr == -1) {
|
453
735
|
// add new entry
|
454
736
|
// check if object is inextensible
|
@@ -457,16 +739,16 @@ export const __Porffor_object_define = (obj: any, key: any, value: any, flags: i
|
|
457
739
|
}
|
458
740
|
|
459
741
|
// bump size +1
|
460
|
-
const size: i32 = Porffor.wasm.i32.
|
461
|
-
Porffor.wasm.i32.
|
742
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
743
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
462
744
|
|
463
745
|
// entryPtr = current end of object
|
464
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
746
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
465
747
|
|
466
|
-
__Porffor_object_writeKey(entryPtr, key);
|
748
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
467
749
|
} else {
|
468
750
|
// existing entry, check and maybe modify it
|
469
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
751
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
470
752
|
|
471
753
|
if ((tail & 0b0010) == 0) {
|
472
754
|
// not already configurable, check to see if we can redefine
|
@@ -484,9 +766,9 @@ export const __Porffor_object_define = (obj: any, key: any, value: any, flags: i
|
|
484
766
|
// if already non-writable, check value isn't being changed
|
485
767
|
Porffor.wasm`
|
486
768
|
local.get ${entryPtr}
|
487
|
-
f64.load 0
|
769
|
+
f64.load 0 8
|
488
770
|
local.get ${entryPtr}
|
489
|
-
i32.load8_u 0
|
771
|
+
i32.load8_u 0 17
|
490
772
|
|
491
773
|
local.get ${value}
|
492
774
|
local.get ${value+1}
|
@@ -503,21 +785,20 @@ local.set ${err}`;
|
|
503
785
|
}
|
504
786
|
|
505
787
|
// write new value value (lol)
|
506
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
788
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
507
789
|
|
508
790
|
// write new tail (value type + flags)
|
509
791
|
Porffor.wasm.i32.store16(entryPtr,
|
510
792
|
flags + (Porffor.wasm`local.get ${value+1}` << 8),
|
511
|
-
0,
|
793
|
+
0, 16);
|
512
794
|
};
|
513
795
|
|
514
796
|
export const __Porffor_object_delete = (obj: any, key: any): boolean => {
|
515
797
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
516
798
|
|
517
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
518
|
-
|
519
|
-
|
520
|
-
return true;
|
799
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
800
|
+
obj = __Porffor_object_underlying(obj);
|
801
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return true;
|
521
802
|
}
|
522
803
|
|
523
804
|
const entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
@@ -526,17 +807,17 @@ export const __Porffor_object_delete = (obj: any, key: any): boolean => {
|
|
526
807
|
return true;
|
527
808
|
}
|
528
809
|
|
529
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
810
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
530
811
|
if (!(tail & 0b0010)) {
|
531
812
|
// not configurable
|
532
813
|
return false;
|
533
814
|
}
|
534
815
|
|
535
|
-
const ind: i32 = (entryPtr - Porffor.wasm`local.get ${obj}`) /
|
816
|
+
const ind: i32 = (entryPtr - Porffor.wasm`local.get ${obj}`) / 18;
|
536
817
|
|
537
818
|
// decrement size
|
538
|
-
let size: i32 = Porffor.wasm.i32.
|
539
|
-
Porffor.wasm.i32.
|
819
|
+
let size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
820
|
+
Porffor.wasm.i32.store16(obj, --size, 0, 0);
|
540
821
|
|
541
822
|
if (size > ind) {
|
542
823
|
// offset all elements after by -1 ind
|
@@ -544,16 +825,16 @@ export const __Porffor_object_delete = (obj: any, key: any): boolean => {
|
|
544
825
|
;; dst = entryPtr
|
545
826
|
local.get ${entryPtr}
|
546
827
|
|
547
|
-
;; src = entryPtr +
|
828
|
+
;; src = entryPtr + 18 (+ 1 entry)
|
548
829
|
local.get ${entryPtr}
|
549
|
-
i32.const
|
830
|
+
i32.const 18
|
550
831
|
i32.add
|
551
832
|
|
552
|
-
;; size = (size - ind) *
|
833
|
+
;; size = (size - ind) * 18
|
553
834
|
local.get ${size}
|
554
835
|
local.get ${ind}
|
555
836
|
i32.sub
|
556
|
-
i32.const
|
837
|
+
i32.const 18
|
557
838
|
i32.mul
|
558
839
|
|
559
840
|
memory.copy 0 0`;
|
@@ -565,10 +846,9 @@ memory.copy 0 0`;
|
|
565
846
|
export const __Porffor_object_deleteStrict = (obj: any, key: any): boolean => {
|
566
847
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
567
848
|
|
568
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
569
|
-
|
570
|
-
|
571
|
-
return true;
|
849
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
850
|
+
obj = __Porffor_object_underlying(obj);
|
851
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return true;
|
572
852
|
}
|
573
853
|
|
574
854
|
const entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
@@ -577,17 +857,17 @@ export const __Porffor_object_deleteStrict = (obj: any, key: any): boolean => {
|
|
577
857
|
return true;
|
578
858
|
}
|
579
859
|
|
580
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
860
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
581
861
|
if (!(tail & 0b0010)) {
|
582
862
|
// not configurable
|
583
863
|
throw new TypeError('Cannot delete non-configurable property of object');
|
584
864
|
}
|
585
865
|
|
586
|
-
const ind: i32 = (entryPtr - Porffor.wasm`local.get ${obj}`) /
|
866
|
+
const ind: i32 = (entryPtr - Porffor.wasm`local.get ${obj}`) / 18;
|
587
867
|
|
588
868
|
// decrement size
|
589
|
-
let size: i32 = Porffor.wasm.i32.
|
590
|
-
Porffor.wasm.i32.
|
869
|
+
let size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
870
|
+
Porffor.wasm.i32.store16(obj, --size, 0, 0);
|
591
871
|
|
592
872
|
if (size > ind) {
|
593
873
|
// offset all elements after by -1 ind
|
@@ -595,16 +875,16 @@ export const __Porffor_object_deleteStrict = (obj: any, key: any): boolean => {
|
|
595
875
|
;; dst = entryPtr
|
596
876
|
local.get ${entryPtr}
|
597
877
|
|
598
|
-
;; src = entryPtr +
|
878
|
+
;; src = entryPtr + 18 (+ 1 entry)
|
599
879
|
local.get ${entryPtr}
|
600
|
-
i32.const
|
880
|
+
i32.const 18
|
601
881
|
i32.add
|
602
882
|
|
603
|
-
;; size = (size - ind) *
|
883
|
+
;; size = (size - ind) * 18
|
604
884
|
local.get ${size}
|
605
885
|
local.get ${ind}
|
606
886
|
i32.sub
|
607
|
-
i32.const
|
887
|
+
i32.const 18
|
608
888
|
i32.mul
|
609
889
|
|
610
890
|
memory.copy 0 0`;
|
@@ -615,156 +895,155 @@ memory.copy 0 0`;
|
|
615
895
|
|
616
896
|
|
617
897
|
export const __Porffor_object_isEnumerable = (entryPtr: i32): boolean => {
|
618
|
-
|
619
|
-
return out;
|
620
|
-
};
|
621
|
-
|
622
|
-
|
623
|
-
export const __Porffor_object_isObject = (arg: any): boolean => {
|
624
|
-
const t: i32 = Porffor.wasm`local.get ${arg+1}`;
|
625
|
-
return Porffor.fastAnd(
|
626
|
-
arg != 0, // null
|
627
|
-
t > 0x05,
|
628
|
-
t != Porffor.TYPES.string,
|
629
|
-
t != Porffor.TYPES.bytestring,
|
630
|
-
);
|
631
|
-
};
|
632
|
-
|
633
|
-
export const __Porffor_object_isObjectOrNull = (arg: any): boolean => {
|
634
|
-
const t: i32 = Porffor.wasm`local.get ${arg+1}`;
|
635
|
-
return Porffor.fastAnd(
|
636
|
-
t > 0x05,
|
637
|
-
t != Porffor.TYPES.string,
|
638
|
-
t != Porffor.TYPES.bytestring,
|
639
|
-
);
|
640
|
-
};
|
641
|
-
|
642
|
-
export const __Porffor_object_isObjectOrSymbol = (arg: any): boolean => {
|
643
|
-
const t: i32 = Porffor.wasm`local.get ${arg+1}`;
|
644
|
-
return Porffor.fastAnd(
|
645
|
-
arg != 0, // null
|
646
|
-
t > 0x04,
|
647
|
-
t != Porffor.TYPES.string,
|
648
|
-
t != Porffor.TYPES.bytestring,
|
649
|
-
);
|
898
|
+
return (Porffor.wasm.i32.load8_u(entryPtr, 0, 16) & 0b0100) as boolean;
|
650
899
|
};
|
651
900
|
|
652
901
|
|
653
902
|
// used for { foo: 5 }
|
654
903
|
export const __Porffor_object_expr_init = (obj: any, key: any, value: any): void => {
|
655
904
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
656
|
-
|
905
|
+
|
906
|
+
const hash: i32 = __Porffor_object_hash(key);
|
907
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
657
908
|
if (entryPtr == -1) {
|
909
|
+
if (key == '__proto__') {
|
910
|
+
// set prototype
|
911
|
+
Porffor.wasm`
|
912
|
+
local.get ${obj}
|
913
|
+
local.get ${obj+1}
|
914
|
+
local.get ${value}
|
915
|
+
i32.trunc_sat_f64_u
|
916
|
+
local.get ${value+1}
|
917
|
+
call __Porffor_object_setPrototype`;
|
918
|
+
return value;
|
919
|
+
}
|
920
|
+
|
658
921
|
// add new entry
|
659
922
|
// bump size +1
|
660
|
-
const size: i32 = Porffor.wasm.i32.
|
661
|
-
Porffor.wasm.i32.
|
923
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
924
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
662
925
|
|
663
926
|
// entryPtr = current end of object
|
664
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
665
|
-
|
666
|
-
__Porffor_object_writeKey(entryPtr, key);
|
927
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
928
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
667
929
|
}
|
668
930
|
|
669
|
-
// write new value value
|
670
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
931
|
+
// write new value value
|
932
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
671
933
|
|
672
934
|
// write new tail (value type + flags)
|
673
935
|
// flags = writable, enumerable, configurable, not accessor
|
674
936
|
Porffor.wasm.i32.store16(entryPtr,
|
675
937
|
0b1110 + (Porffor.wasm`local.get ${value+1}` << 8),
|
676
|
-
0,
|
938
|
+
0, 16);
|
677
939
|
};
|
678
940
|
|
679
941
|
export const __Porffor_object_expr_initWithFlags = (obj: any, key: any, value: any, flags: i32): void => {
|
680
942
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
681
|
-
|
943
|
+
|
944
|
+
const hash: i32 = __Porffor_object_hash(key);
|
945
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
682
946
|
if (entryPtr == -1) {
|
947
|
+
if (key == '__proto__') {
|
948
|
+
// set prototype
|
949
|
+
Porffor.wasm`
|
950
|
+
local.get ${obj}
|
951
|
+
local.get ${obj+1}
|
952
|
+
local.get ${value}
|
953
|
+
i32.trunc_sat_f64_u
|
954
|
+
local.get ${value+1}
|
955
|
+
call __Porffor_object_setPrototype`;
|
956
|
+
return value;
|
957
|
+
}
|
958
|
+
|
683
959
|
// add new entry
|
684
960
|
// bump size +1
|
685
|
-
const size: i32 = Porffor.wasm.i32.
|
686
|
-
Porffor.wasm.i32.
|
961
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
962
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
687
963
|
|
688
964
|
// entryPtr = current end of object
|
689
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
690
|
-
|
691
|
-
__Porffor_object_writeKey(entryPtr, key);
|
965
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
966
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
692
967
|
}
|
693
968
|
|
694
|
-
// write new value value
|
695
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
969
|
+
// write new value value
|
970
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
696
971
|
|
697
972
|
// write new tail (value type + flags)
|
698
973
|
Porffor.wasm.i32.store16(entryPtr,
|
699
974
|
flags + (Porffor.wasm`local.get ${value+1}` << 8),
|
700
|
-
0,
|
975
|
+
0, 16);
|
701
976
|
};
|
702
977
|
|
703
978
|
// used for { get foo() {} }
|
704
979
|
export const __Porffor_object_expr_get = (obj: any, key: any, get: any): void => {
|
705
980
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
706
|
-
|
981
|
+
|
982
|
+
const hash: i32 = __Porffor_object_hash(key);
|
983
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
707
984
|
let set: any = undefined;
|
708
985
|
if (entryPtr == -1) {
|
709
986
|
// add new entry
|
710
987
|
// bump size +1
|
711
|
-
const size: i32 = Porffor.wasm.i32.
|
712
|
-
Porffor.wasm.i32.
|
988
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
989
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
713
990
|
|
714
991
|
// entryPtr = current end of object
|
715
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
716
|
-
|
717
|
-
__Porffor_object_writeKey(entryPtr, key);
|
992
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
993
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
718
994
|
} else {
|
719
995
|
// existing entry, keep set (if exists)
|
720
996
|
set = __Porffor_object_accessorSet(entryPtr);
|
721
997
|
}
|
722
998
|
|
723
|
-
// write new value value
|
724
|
-
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0,
|
999
|
+
// write new value value
|
1000
|
+
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0, 8);
|
725
1001
|
|
726
1002
|
// write new tail (value type + flags)
|
727
1003
|
// flags = writable, enumerable, configurable, accessor
|
728
1004
|
Porffor.wasm.i32.store16(entryPtr,
|
729
1005
|
0b1111 + (Porffor.TYPES.number << 8),
|
730
|
-
0,
|
1006
|
+
0, 16);
|
731
1007
|
};
|
732
1008
|
|
733
1009
|
// used for { set foo(v) {} }
|
734
1010
|
export const __Porffor_object_expr_set = (obj: any, key: any, set: any): void => {
|
735
1011
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
736
|
-
|
1012
|
+
|
1013
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1014
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
737
1015
|
let get: any = undefined;
|
738
1016
|
if (entryPtr == -1) {
|
739
1017
|
// add new entry
|
740
1018
|
// bump size +1
|
741
|
-
const size: i32 = Porffor.wasm.i32.
|
742
|
-
Porffor.wasm.i32.
|
1019
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1020
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
743
1021
|
|
744
1022
|
// entryPtr = current end of object
|
745
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
746
|
-
|
747
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1023
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1024
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
748
1025
|
} else {
|
749
1026
|
// existing entry, keep set (if exists)
|
750
1027
|
get = __Porffor_object_accessorGet(entryPtr);
|
751
1028
|
}
|
752
1029
|
|
753
|
-
// write new value value
|
754
|
-
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0,
|
1030
|
+
// write new value value
|
1031
|
+
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0, 8);
|
755
1032
|
|
756
1033
|
// write new tail (value type + flags)
|
757
1034
|
// flags = writable, enumerable, configurable, accessor
|
758
1035
|
Porffor.wasm.i32.store16(entryPtr,
|
759
1036
|
0b1111 + (Porffor.TYPES.number << 8),
|
760
|
-
0,
|
1037
|
+
0, 16);
|
761
1038
|
};
|
762
1039
|
|
763
1040
|
|
764
1041
|
// used for { foo: 5 }
|
765
1042
|
export const __Porffor_object_class_value = (obj: any, key: any, value: any): void => {
|
766
1043
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
767
|
-
|
1044
|
+
|
1045
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1046
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
768
1047
|
if (entryPtr == -1) {
|
769
1048
|
// add new entry
|
770
1049
|
// check if object is inextensible
|
@@ -773,29 +1052,30 @@ export const __Porffor_object_class_value = (obj: any, key: any, value: any): vo
|
|
773
1052
|
}
|
774
1053
|
|
775
1054
|
// bump size +1
|
776
|
-
const size: i32 = Porffor.wasm.i32.
|
777
|
-
Porffor.wasm.i32.
|
1055
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1056
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
778
1057
|
|
779
1058
|
// entryPtr = current end of object
|
780
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
781
|
-
|
782
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1059
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1060
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
783
1061
|
}
|
784
1062
|
|
785
|
-
// write new value value
|
786
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
1063
|
+
// write new value value
|
1064
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
787
1065
|
|
788
1066
|
// write new tail (value type + flags)
|
789
1067
|
// flags = writable, enumerable, configurable, not accessor
|
790
1068
|
Porffor.wasm.i32.store16(entryPtr,
|
791
1069
|
0b1110 + (Porffor.wasm`local.get ${value+1}` << 8),
|
792
|
-
0,
|
1070
|
+
0, 16);
|
793
1071
|
};
|
794
1072
|
|
795
1073
|
// used for { foo() {} }
|
796
1074
|
export const __Porffor_object_class_method = (obj: any, key: any, value: any): void => {
|
797
1075
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
798
|
-
|
1076
|
+
|
1077
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1078
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
799
1079
|
if (entryPtr == -1) {
|
800
1080
|
// add new entry
|
801
1081
|
// check if object is inextensible
|
@@ -804,29 +1084,30 @@ export const __Porffor_object_class_method = (obj: any, key: any, value: any): v
|
|
804
1084
|
}
|
805
1085
|
|
806
1086
|
// bump size +1
|
807
|
-
const size: i32 = Porffor.wasm.i32.
|
808
|
-
Porffor.wasm.i32.
|
1087
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1088
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
809
1089
|
|
810
1090
|
// entryPtr = current end of object
|
811
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
812
|
-
|
813
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1091
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1092
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
814
1093
|
}
|
815
1094
|
|
816
1095
|
// write new value value (lol)
|
817
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
1096
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
818
1097
|
|
819
1098
|
// write new tail (value type + flags)
|
820
1099
|
// flags = writable, enumerable, configurable, not accessor
|
821
1100
|
Porffor.wasm.i32.store16(entryPtr,
|
822
1101
|
0b1010 + (Porffor.wasm`local.get ${value+1}` << 8),
|
823
|
-
0,
|
1102
|
+
0, 16);
|
824
1103
|
};
|
825
1104
|
|
826
1105
|
// used for { get foo() {} }
|
827
1106
|
export const __Porffor_object_class_get = (obj: any, key: any, get: any): void => {
|
828
1107
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
829
|
-
|
1108
|
+
|
1109
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1110
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
830
1111
|
let set: any = undefined;
|
831
1112
|
if (entryPtr == -1) {
|
832
1113
|
// add new entry
|
@@ -836,32 +1117,33 @@ export const __Porffor_object_class_get = (obj: any, key: any, get: any): void =
|
|
836
1117
|
}
|
837
1118
|
|
838
1119
|
// bump size +1
|
839
|
-
const size: i32 = Porffor.wasm.i32.
|
840
|
-
Porffor.wasm.i32.
|
1120
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1121
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
841
1122
|
|
842
1123
|
// entryPtr = current end of object
|
843
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
844
|
-
|
845
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1124
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1125
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
846
1126
|
} else {
|
847
1127
|
// existing entry, keep set (if exists)
|
848
1128
|
set = __Porffor_object_accessorSet(entryPtr);
|
849
1129
|
}
|
850
1130
|
|
851
1131
|
// write new value value (lol)
|
852
|
-
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0,
|
1132
|
+
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0, 8);
|
853
1133
|
|
854
1134
|
// write new tail (value type + flags)
|
855
1135
|
// flags = writable, enumerable, configurable, accessor
|
856
1136
|
Porffor.wasm.i32.store16(entryPtr,
|
857
1137
|
0b1011 + (Porffor.TYPES.number << 8),
|
858
|
-
0,
|
1138
|
+
0, 16);
|
859
1139
|
};
|
860
1140
|
|
861
1141
|
// used for { set foo(v) {} }
|
862
1142
|
export const __Porffor_object_class_set = (obj: any, key: any, set: any): void => {
|
863
1143
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
864
|
-
|
1144
|
+
|
1145
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1146
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
865
1147
|
let get: any = undefined;
|
866
1148
|
if (entryPtr == -1) {
|
867
1149
|
// add new entry
|
@@ -871,24 +1153,23 @@ export const __Porffor_object_class_set = (obj: any, key: any, set: any): void =
|
|
871
1153
|
}
|
872
1154
|
|
873
1155
|
// bump size +1
|
874
|
-
const size: i32 = Porffor.wasm.i32.
|
875
|
-
Porffor.wasm.i32.
|
1156
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1157
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
876
1158
|
|
877
1159
|
// entryPtr = current end of object
|
878
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
879
|
-
|
880
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1160
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1161
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
881
1162
|
} else {
|
882
1163
|
// existing entry, keep set (if exists)
|
883
1164
|
get = __Porffor_object_accessorGet(entryPtr);
|
884
1165
|
}
|
885
1166
|
|
886
1167
|
// write new value value (lol)
|
887
|
-
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0,
|
1168
|
+
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0, 8);
|
888
1169
|
|
889
1170
|
// write new tail (value type + flags)
|
890
1171
|
// flags = writable, enumerable, configurable, accessor
|
891
1172
|
Porffor.wasm.i32.store16(entryPtr,
|
892
1173
|
0b1011 + (Porffor.TYPES.number << 8),
|
893
|
-
0,
|
1174
|
+
0, 16);
|
894
1175
|
};
|