porffor 0.55.22 → 0.55.24
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 +568 -285
- package/compiler/builtins/bigint.ts +2 -2
- package/compiler/builtins/console.ts +1 -1
- package/compiler/builtins/function.ts +1 -1
- package/compiler/builtins/object.ts +46 -51
- 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 +575 -554
- package/compiler/codegen.js +86 -216
- 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 +30 -6
- package/runner/flamegraph.js +13 -13
- 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,234 @@ 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 unused so just return 0
|
186
|
+
return 0;
|
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
|
-
for (; ptr < endPtr; ptr +=
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
389
|
+
for (; ptr < endPtr; ptr += 18) {
|
390
|
+
if (Porffor.wasm.i32.load(ptr, 0, 0) == targetHash) {
|
391
|
+
const key: i32 = Porffor.wasm.i32.load(ptr, 0, 4);
|
392
|
+
Porffor.wasm`
|
393
|
+
local.get ${key}
|
394
|
+
i32.const 2147483647
|
395
|
+
i32.and
|
396
|
+
|
397
|
+
i32.const 67 ;; bytestring
|
398
|
+
i32.const 195 ;; string
|
399
|
+
local.get ${key}
|
400
|
+
i32.const 30
|
401
|
+
i32.shr_u
|
402
|
+
select
|
403
|
+
|
404
|
+
local.get ${target}
|
405
|
+
local.get ${target+1}
|
406
|
+
call __Porffor_strcmp
|
407
|
+
if 64
|
408
|
+
local.get ${ptr}
|
409
|
+
return
|
410
|
+
end`;
|
165
411
|
}
|
166
412
|
}
|
167
413
|
}
|
@@ -172,9 +418,9 @@ export const __Porffor_object_lookup = (obj: any, target: any): i32 => {
|
|
172
418
|
export const __Porffor_object_readValue = (entryPtr: i32): any => {
|
173
419
|
Porffor.wasm`
|
174
420
|
local.get ${entryPtr}
|
175
|
-
f64.load 0
|
421
|
+
f64.load 0 8
|
176
422
|
local.get ${entryPtr}
|
177
|
-
i32.load8_u 0
|
423
|
+
i32.load8_u 0 17
|
178
424
|
return`;
|
179
425
|
};
|
180
426
|
|
@@ -184,83 +430,31 @@ export const __Porffor_object_get = (obj: any, key: any): any => {
|
|
184
430
|
|
185
431
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot get property of null');
|
186
432
|
|
187
|
-
|
433
|
+
const hash: i32 = __Porffor_object_hash(key);
|
434
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
188
435
|
if (entryPtr == -1) {
|
189
436
|
// 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;
|
437
|
+
obj = __Porffor_object_getPrototypeWithHidden(obj, trueType);
|
256
438
|
|
439
|
+
// todo/opt: put this behind comptime flag if only __proto__ is used
|
440
|
+
if (hash == -406948493) if (key == '__proto__') {
|
441
|
+
// get prototype
|
257
442
|
Porffor.wasm`
|
258
|
-
local.get ${
|
443
|
+
local.get ${obj}
|
259
444
|
f64.convert_i32_u
|
260
|
-
|
445
|
+
local.get ${obj+1}
|
261
446
|
return`;
|
262
447
|
}
|
263
448
|
|
449
|
+
let lastProto: any = obj;
|
450
|
+
while (true) {
|
451
|
+
if ((entryPtr = __Porffor_object_lookup(obj, key, hash)) != -1) break;
|
452
|
+
|
453
|
+
obj = __Porffor_object_getPrototype(obj);
|
454
|
+
if (Porffor.fastOr(obj == null, Porffor.wasm`local.get ${obj}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
455
|
+
lastProto = obj;
|
456
|
+
}
|
457
|
+
|
264
458
|
if (entryPtr == -1) {
|
265
459
|
Porffor.wasm`
|
266
460
|
f64.const 0
|
@@ -269,8 +463,7 @@ return`;
|
|
269
463
|
}
|
270
464
|
}
|
271
465
|
|
272
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
273
|
-
|
466
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
274
467
|
if (tail & 0b0001) {
|
275
468
|
// accessor descriptor
|
276
469
|
const get: Function = __Porffor_object_accessorGet(entryPtr);
|
@@ -289,14 +482,17 @@ return`;
|
|
289
482
|
// data descriptor
|
290
483
|
Porffor.wasm`
|
291
484
|
local.get ${entryPtr}
|
292
|
-
f64.load 0
|
485
|
+
f64.load 0 8
|
293
486
|
local.get ${tail}
|
294
487
|
i32.const 8
|
295
488
|
i32.shr_u
|
296
489
|
return`;
|
297
490
|
};
|
298
491
|
|
299
|
-
export const __Porffor_object_writeKey = (ptr: i32, key: any): void => {
|
492
|
+
export const __Porffor_object_writeKey = (ptr: i32, key: any, hash: i32 = __Porffor_object_hash(key)): void => {
|
493
|
+
// write hash to ptr
|
494
|
+
Porffor.wasm.i32.store(ptr, hash, 0, 0);
|
495
|
+
|
300
496
|
// encode key type
|
301
497
|
let keyEnc: i32 = Porffor.wasm`local.get ${key}`;
|
302
498
|
|
@@ -305,11 +501,10 @@ export const __Porffor_object_writeKey = (ptr: i32, key: any): void => {
|
|
305
501
|
// set MSB 1&2 if symbol
|
306
502
|
else if (Porffor.wasm`local.get ${key+1}` == Porffor.TYPES.symbol) keyEnc |= 0xc0000000;
|
307
503
|
|
308
|
-
// write encoded key to ptr
|
309
|
-
Porffor.wasm.i32.store(ptr, keyEnc, 0,
|
504
|
+
// write encoded key to ptr + 4
|
505
|
+
Porffor.wasm.i32.store(ptr, keyEnc, 0, 4);
|
310
506
|
};
|
311
507
|
|
312
|
-
// todo: check prototype for setters
|
313
508
|
export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
314
509
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
315
510
|
obj = __Porffor_object_underlying(obj);
|
@@ -318,9 +513,53 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
|
318
513
|
|
319
514
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot set property of null');
|
320
515
|
|
321
|
-
|
516
|
+
const hash: i32 = __Porffor_object_hash(key);
|
517
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
322
518
|
let flags: i32;
|
323
519
|
if (entryPtr == -1) {
|
520
|
+
if (hash == -406948493) if (key == '__proto__') {
|
521
|
+
// set prototype
|
522
|
+
Porffor.wasm`
|
523
|
+
local.get ${obj}
|
524
|
+
local.get ${obj+1}
|
525
|
+
local.get ${value}
|
526
|
+
i32.trunc_sat_f64_u
|
527
|
+
local.get ${value+1}
|
528
|
+
call __Porffor_object_setPrototype`;
|
529
|
+
return value;
|
530
|
+
}
|
531
|
+
|
532
|
+
// todo/opt: skip if no setters used
|
533
|
+
// check prototype chain for setter
|
534
|
+
let proto: any = __Porffor_object_getPrototype(obj);
|
535
|
+
if (proto != null) {
|
536
|
+
let lastProto: any = proto;
|
537
|
+
while (true) {
|
538
|
+
if ((entryPtr = __Porffor_object_lookup(proto, key, hash)) != -1) break;
|
539
|
+
|
540
|
+
proto = __Porffor_object_getPrototype(proto);
|
541
|
+
if (Porffor.fastOr(proto == null, Porffor.wasm`local.get ${proto}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
542
|
+
lastProto = proto;
|
543
|
+
}
|
544
|
+
|
545
|
+
if (entryPtr != -1) {
|
546
|
+
// found possible setter
|
547
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
548
|
+
if (tail & 0b0001) {
|
549
|
+
// accessor descriptor
|
550
|
+
const set: Function = __Porffor_object_accessorSet(entryPtr);
|
551
|
+
|
552
|
+
// no setter, return early
|
553
|
+
if (Porffor.wasm`local.get ${set}` == 0) {
|
554
|
+
return value;
|
555
|
+
}
|
556
|
+
|
557
|
+
set.call(obj, value);
|
558
|
+
return value;
|
559
|
+
}
|
560
|
+
}
|
561
|
+
}
|
562
|
+
|
324
563
|
// add new entry
|
325
564
|
// check if object is inextensible
|
326
565
|
if (__Porffor_object_isInextensible(obj)) {
|
@@ -328,19 +567,19 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
|
328
567
|
}
|
329
568
|
|
330
569
|
// bump size +1
|
331
|
-
const size: i32 = Porffor.wasm.i32.
|
332
|
-
Porffor.wasm.i32.
|
570
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
571
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
333
572
|
|
334
573
|
// entryPtr = current end of object
|
335
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
574
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
336
575
|
|
337
|
-
__Porffor_object_writeKey(entryPtr, key);
|
576
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
338
577
|
|
339
578
|
// flags = writable, enumerable, configurable, not accessor
|
340
579
|
flags = 0b1110;
|
341
580
|
} else {
|
342
581
|
// existing entry, modify it
|
343
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
582
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
344
583
|
|
345
584
|
if (tail & 0b0001) {
|
346
585
|
// accessor descriptor
|
@@ -365,13 +604,13 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
|
|
365
604
|
flags = tail & 0xff;
|
366
605
|
}
|
367
606
|
|
368
|
-
// write new value value
|
369
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
607
|
+
// write new value value
|
608
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
370
609
|
|
371
610
|
// write new tail (value type + flags)
|
372
611
|
Porffor.wasm.i32.store16(entryPtr,
|
373
612
|
flags + (Porffor.wasm`local.get ${value+1}` << 8),
|
374
|
-
0,
|
613
|
+
0, 16);
|
375
614
|
|
376
615
|
return value;
|
377
616
|
};
|
@@ -384,9 +623,53 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
|
|
384
623
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return value;
|
385
624
|
}
|
386
625
|
|
387
|
-
|
626
|
+
const hash: i32 = __Porffor_object_hash(key);
|
627
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
388
628
|
let flags: i32;
|
389
629
|
if (entryPtr == -1) {
|
630
|
+
if (hash == -406948493) if (key == '__proto__') {
|
631
|
+
// set prototype
|
632
|
+
Porffor.wasm`
|
633
|
+
local.get ${obj}
|
634
|
+
local.get ${obj+1}
|
635
|
+
local.get ${value}
|
636
|
+
i32.trunc_sat_f64_u
|
637
|
+
local.get ${value+1}
|
638
|
+
call __Porffor_object_setPrototype`;
|
639
|
+
return value;
|
640
|
+
}
|
641
|
+
|
642
|
+
// todo/opt: skip if no setters used
|
643
|
+
// check prototype chain for setter
|
644
|
+
let proto: any = __Porffor_object_getPrototype(obj);
|
645
|
+
if (proto != null) {
|
646
|
+
let lastProto: any = proto;
|
647
|
+
while (true) {
|
648
|
+
if ((entryPtr = __Porffor_object_lookup(proto, key, hash)) != -1) break;
|
649
|
+
|
650
|
+
proto = __Porffor_object_getPrototype(proto);
|
651
|
+
if (Porffor.fastOr(proto == null, Porffor.wasm`local.get ${proto}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
652
|
+
lastProto = proto;
|
653
|
+
}
|
654
|
+
|
655
|
+
if (entryPtr != -1) {
|
656
|
+
// found possible setter
|
657
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
658
|
+
if (tail & 0b0001) {
|
659
|
+
// accessor descriptor
|
660
|
+
const set: Function = __Porffor_object_accessorSet(entryPtr);
|
661
|
+
|
662
|
+
// no setter, return early
|
663
|
+
if (Porffor.wasm`local.get ${set}` == 0) {
|
664
|
+
return value;
|
665
|
+
}
|
666
|
+
|
667
|
+
set.call(obj, value);
|
668
|
+
return value;
|
669
|
+
}
|
670
|
+
}
|
671
|
+
}
|
672
|
+
|
390
673
|
// add new entry
|
391
674
|
// check if object is inextensible
|
392
675
|
if (__Porffor_object_isInextensible(obj)) {
|
@@ -394,19 +677,19 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
|
|
394
677
|
}
|
395
678
|
|
396
679
|
// bump size +1
|
397
|
-
const size: i32 = Porffor.wasm.i32.
|
398
|
-
Porffor.wasm.i32.
|
680
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
681
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
399
682
|
|
400
683
|
// entryPtr = current end of object
|
401
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
684
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
402
685
|
|
403
|
-
__Porffor_object_writeKey(entryPtr, key);
|
686
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
404
687
|
|
405
688
|
// flags = writable, enumerable, configurable, not accessor
|
406
689
|
flags = 0b1110;
|
407
690
|
} else {
|
408
691
|
// existing entry, modify it
|
409
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
692
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
410
693
|
|
411
694
|
if (tail & 0b0001) {
|
412
695
|
// accessor descriptor
|
@@ -432,12 +715,12 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
|
|
432
715
|
}
|
433
716
|
|
434
717
|
// write new value value (lol)
|
435
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
718
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
436
719
|
|
437
720
|
// write new tail (value type + flags)
|
438
721
|
Porffor.wasm.i32.store16(entryPtr,
|
439
722
|
flags + (Porffor.wasm`local.get ${value+1}` << 8),
|
440
|
-
0,
|
723
|
+
0, 16);
|
441
724
|
|
442
725
|
return value;
|
443
726
|
};
|
@@ -448,7 +731,8 @@ export const __Porffor_object_define = (obj: any, key: any, value: any, flags: i
|
|
448
731
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return;
|
449
732
|
}
|
450
733
|
|
451
|
-
|
734
|
+
const hash: i32 = __Porffor_object_hash(key);
|
735
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
452
736
|
if (entryPtr == -1) {
|
453
737
|
// add new entry
|
454
738
|
// check if object is inextensible
|
@@ -457,16 +741,16 @@ export const __Porffor_object_define = (obj: any, key: any, value: any, flags: i
|
|
457
741
|
}
|
458
742
|
|
459
743
|
// bump size +1
|
460
|
-
const size: i32 = Porffor.wasm.i32.
|
461
|
-
Porffor.wasm.i32.
|
744
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
745
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
462
746
|
|
463
747
|
// entryPtr = current end of object
|
464
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
748
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
465
749
|
|
466
|
-
__Porffor_object_writeKey(entryPtr, key);
|
750
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
467
751
|
} else {
|
468
752
|
// existing entry, check and maybe modify it
|
469
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
753
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
470
754
|
|
471
755
|
if ((tail & 0b0010) == 0) {
|
472
756
|
// not already configurable, check to see if we can redefine
|
@@ -484,9 +768,9 @@ export const __Porffor_object_define = (obj: any, key: any, value: any, flags: i
|
|
484
768
|
// if already non-writable, check value isn't being changed
|
485
769
|
Porffor.wasm`
|
486
770
|
local.get ${entryPtr}
|
487
|
-
f64.load 0
|
771
|
+
f64.load 0 8
|
488
772
|
local.get ${entryPtr}
|
489
|
-
i32.load8_u 0
|
773
|
+
i32.load8_u 0 17
|
490
774
|
|
491
775
|
local.get ${value}
|
492
776
|
local.get ${value+1}
|
@@ -503,40 +787,39 @@ local.set ${err}`;
|
|
503
787
|
}
|
504
788
|
|
505
789
|
// write new value value (lol)
|
506
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
790
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
507
791
|
|
508
792
|
// write new tail (value type + flags)
|
509
793
|
Porffor.wasm.i32.store16(entryPtr,
|
510
794
|
flags + (Porffor.wasm`local.get ${value+1}` << 8),
|
511
|
-
0,
|
795
|
+
0, 16);
|
512
796
|
};
|
513
797
|
|
514
798
|
export const __Porffor_object_delete = (obj: any, key: any): boolean => {
|
515
799
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
516
800
|
|
517
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
518
|
-
|
519
|
-
|
520
|
-
return true;
|
801
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
802
|
+
obj = __Porffor_object_underlying(obj);
|
803
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return true;
|
521
804
|
}
|
522
805
|
|
523
|
-
const entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
806
|
+
const entryPtr: i32 = __Porffor_object_lookup(obj, key, __Porffor_object_hash(key));
|
524
807
|
if (entryPtr == -1) {
|
525
808
|
// not found, stop
|
526
809
|
return true;
|
527
810
|
}
|
528
811
|
|
529
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
812
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
530
813
|
if (!(tail & 0b0010)) {
|
531
814
|
// not configurable
|
532
815
|
return false;
|
533
816
|
}
|
534
817
|
|
535
|
-
const ind: i32 = (entryPtr - Porffor.wasm`local.get ${obj}`) /
|
818
|
+
const ind: i32 = (entryPtr - Porffor.wasm`local.get ${obj}`) / 18;
|
536
819
|
|
537
820
|
// decrement size
|
538
|
-
let size: i32 = Porffor.wasm.i32.
|
539
|
-
Porffor.wasm.i32.
|
821
|
+
let size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
822
|
+
Porffor.wasm.i32.store16(obj, --size, 0, 0);
|
540
823
|
|
541
824
|
if (size > ind) {
|
542
825
|
// offset all elements after by -1 ind
|
@@ -544,16 +827,16 @@ export const __Porffor_object_delete = (obj: any, key: any): boolean => {
|
|
544
827
|
;; dst = entryPtr
|
545
828
|
local.get ${entryPtr}
|
546
829
|
|
547
|
-
;; src = entryPtr +
|
830
|
+
;; src = entryPtr + 18 (+ 1 entry)
|
548
831
|
local.get ${entryPtr}
|
549
|
-
i32.const
|
832
|
+
i32.const 18
|
550
833
|
i32.add
|
551
834
|
|
552
|
-
;; size = (size - ind) *
|
835
|
+
;; size = (size - ind) * 18
|
553
836
|
local.get ${size}
|
554
837
|
local.get ${ind}
|
555
838
|
i32.sub
|
556
|
-
i32.const
|
839
|
+
i32.const 18
|
557
840
|
i32.mul
|
558
841
|
|
559
842
|
memory.copy 0 0`;
|
@@ -565,29 +848,28 @@ memory.copy 0 0`;
|
|
565
848
|
export const __Porffor_object_deleteStrict = (obj: any, key: any): boolean => {
|
566
849
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
567
850
|
|
568
|
-
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object)
|
569
|
-
|
570
|
-
|
571
|
-
return true;
|
851
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) {
|
852
|
+
obj = __Porffor_object_underlying(obj);
|
853
|
+
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) return true;
|
572
854
|
}
|
573
855
|
|
574
|
-
const entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
856
|
+
const entryPtr: i32 = __Porffor_object_lookup(obj, key, __Porffor_object_hash(key));
|
575
857
|
if (entryPtr == -1) {
|
576
858
|
// not found, stop
|
577
859
|
return true;
|
578
860
|
}
|
579
861
|
|
580
|
-
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0,
|
862
|
+
const tail: i32 = Porffor.wasm.i32.load16_u(entryPtr, 0, 16);
|
581
863
|
if (!(tail & 0b0010)) {
|
582
864
|
// not configurable
|
583
865
|
throw new TypeError('Cannot delete non-configurable property of object');
|
584
866
|
}
|
585
867
|
|
586
|
-
const ind: i32 = (entryPtr - Porffor.wasm`local.get ${obj}`) /
|
868
|
+
const ind: i32 = (entryPtr - Porffor.wasm`local.get ${obj}`) / 18;
|
587
869
|
|
588
870
|
// decrement size
|
589
|
-
let size: i32 = Porffor.wasm.i32.
|
590
|
-
Porffor.wasm.i32.
|
871
|
+
let size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
872
|
+
Porffor.wasm.i32.store16(obj, --size, 0, 0);
|
591
873
|
|
592
874
|
if (size > ind) {
|
593
875
|
// offset all elements after by -1 ind
|
@@ -595,16 +877,16 @@ export const __Porffor_object_deleteStrict = (obj: any, key: any): boolean => {
|
|
595
877
|
;; dst = entryPtr
|
596
878
|
local.get ${entryPtr}
|
597
879
|
|
598
|
-
;; src = entryPtr +
|
880
|
+
;; src = entryPtr + 18 (+ 1 entry)
|
599
881
|
local.get ${entryPtr}
|
600
|
-
i32.const
|
882
|
+
i32.const 18
|
601
883
|
i32.add
|
602
884
|
|
603
|
-
;; size = (size - ind) *
|
885
|
+
;; size = (size - ind) * 18
|
604
886
|
local.get ${size}
|
605
887
|
local.get ${ind}
|
606
888
|
i32.sub
|
607
|
-
i32.const
|
889
|
+
i32.const 18
|
608
890
|
i32.mul
|
609
891
|
|
610
892
|
memory.copy 0 0`;
|
@@ -615,156 +897,155 @@ memory.copy 0 0`;
|
|
615
897
|
|
616
898
|
|
617
899
|
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
|
-
);
|
900
|
+
return (Porffor.wasm.i32.load8_u(entryPtr, 0, 16) & 0b0100) as boolean;
|
650
901
|
};
|
651
902
|
|
652
903
|
|
653
904
|
// used for { foo: 5 }
|
654
905
|
export const __Porffor_object_expr_init = (obj: any, key: any, value: any): void => {
|
655
906
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
656
|
-
|
907
|
+
|
908
|
+
const hash: i32 = __Porffor_object_hash(key);
|
909
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
657
910
|
if (entryPtr == -1) {
|
911
|
+
if (key == '__proto__') {
|
912
|
+
// set prototype
|
913
|
+
Porffor.wasm`
|
914
|
+
local.get ${obj}
|
915
|
+
local.get ${obj+1}
|
916
|
+
local.get ${value}
|
917
|
+
i32.trunc_sat_f64_u
|
918
|
+
local.get ${value+1}
|
919
|
+
call __Porffor_object_setPrototype`;
|
920
|
+
return value;
|
921
|
+
}
|
922
|
+
|
658
923
|
// add new entry
|
659
924
|
// bump size +1
|
660
|
-
const size: i32 = Porffor.wasm.i32.
|
661
|
-
Porffor.wasm.i32.
|
925
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
926
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
662
927
|
|
663
928
|
// entryPtr = current end of object
|
664
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
665
|
-
|
666
|
-
__Porffor_object_writeKey(entryPtr, key);
|
929
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
930
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
667
931
|
}
|
668
932
|
|
669
|
-
// write new value value
|
670
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
933
|
+
// write new value value
|
934
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
671
935
|
|
672
936
|
// write new tail (value type + flags)
|
673
937
|
// flags = writable, enumerable, configurable, not accessor
|
674
938
|
Porffor.wasm.i32.store16(entryPtr,
|
675
939
|
0b1110 + (Porffor.wasm`local.get ${value+1}` << 8),
|
676
|
-
0,
|
940
|
+
0, 16);
|
677
941
|
};
|
678
942
|
|
679
943
|
export const __Porffor_object_expr_initWithFlags = (obj: any, key: any, value: any, flags: i32): void => {
|
680
944
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
681
|
-
|
945
|
+
|
946
|
+
const hash: i32 = __Porffor_object_hash(key);
|
947
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
682
948
|
if (entryPtr == -1) {
|
949
|
+
if (key == '__proto__') {
|
950
|
+
// set prototype
|
951
|
+
Porffor.wasm`
|
952
|
+
local.get ${obj}
|
953
|
+
local.get ${obj+1}
|
954
|
+
local.get ${value}
|
955
|
+
i32.trunc_sat_f64_u
|
956
|
+
local.get ${value+1}
|
957
|
+
call __Porffor_object_setPrototype`;
|
958
|
+
return value;
|
959
|
+
}
|
960
|
+
|
683
961
|
// add new entry
|
684
962
|
// bump size +1
|
685
|
-
const size: i32 = Porffor.wasm.i32.
|
686
|
-
Porffor.wasm.i32.
|
963
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
964
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
687
965
|
|
688
966
|
// entryPtr = current end of object
|
689
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
690
|
-
|
691
|
-
__Porffor_object_writeKey(entryPtr, key);
|
967
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
968
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
692
969
|
}
|
693
970
|
|
694
|
-
// write new value value
|
695
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
971
|
+
// write new value value
|
972
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
696
973
|
|
697
974
|
// write new tail (value type + flags)
|
698
975
|
Porffor.wasm.i32.store16(entryPtr,
|
699
976
|
flags + (Porffor.wasm`local.get ${value+1}` << 8),
|
700
|
-
0,
|
977
|
+
0, 16);
|
701
978
|
};
|
702
979
|
|
703
980
|
// used for { get foo() {} }
|
704
981
|
export const __Porffor_object_expr_get = (obj: any, key: any, get: any): void => {
|
705
982
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
706
|
-
|
983
|
+
|
984
|
+
const hash: i32 = __Porffor_object_hash(key);
|
985
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
707
986
|
let set: any = undefined;
|
708
987
|
if (entryPtr == -1) {
|
709
988
|
// add new entry
|
710
989
|
// bump size +1
|
711
|
-
const size: i32 = Porffor.wasm.i32.
|
712
|
-
Porffor.wasm.i32.
|
990
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
991
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
713
992
|
|
714
993
|
// entryPtr = current end of object
|
715
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
716
|
-
|
717
|
-
__Porffor_object_writeKey(entryPtr, key);
|
994
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
995
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
718
996
|
} else {
|
719
997
|
// existing entry, keep set (if exists)
|
720
998
|
set = __Porffor_object_accessorSet(entryPtr);
|
721
999
|
}
|
722
1000
|
|
723
|
-
// write new value value
|
724
|
-
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0,
|
1001
|
+
// write new value value
|
1002
|
+
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0, 8);
|
725
1003
|
|
726
1004
|
// write new tail (value type + flags)
|
727
1005
|
// flags = writable, enumerable, configurable, accessor
|
728
1006
|
Porffor.wasm.i32.store16(entryPtr,
|
729
1007
|
0b1111 + (Porffor.TYPES.number << 8),
|
730
|
-
0,
|
1008
|
+
0, 16);
|
731
1009
|
};
|
732
1010
|
|
733
1011
|
// used for { set foo(v) {} }
|
734
1012
|
export const __Porffor_object_expr_set = (obj: any, key: any, set: any): void => {
|
735
1013
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
736
|
-
|
1014
|
+
|
1015
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1016
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
737
1017
|
let get: any = undefined;
|
738
1018
|
if (entryPtr == -1) {
|
739
1019
|
// add new entry
|
740
1020
|
// bump size +1
|
741
|
-
const size: i32 = Porffor.wasm.i32.
|
742
|
-
Porffor.wasm.i32.
|
1021
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1022
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
743
1023
|
|
744
1024
|
// entryPtr = current end of object
|
745
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
746
|
-
|
747
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1025
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1026
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
748
1027
|
} else {
|
749
1028
|
// existing entry, keep set (if exists)
|
750
1029
|
get = __Porffor_object_accessorGet(entryPtr);
|
751
1030
|
}
|
752
1031
|
|
753
|
-
// write new value value
|
754
|
-
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0,
|
1032
|
+
// write new value value
|
1033
|
+
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0, 8);
|
755
1034
|
|
756
1035
|
// write new tail (value type + flags)
|
757
1036
|
// flags = writable, enumerable, configurable, accessor
|
758
1037
|
Porffor.wasm.i32.store16(entryPtr,
|
759
1038
|
0b1111 + (Porffor.TYPES.number << 8),
|
760
|
-
0,
|
1039
|
+
0, 16);
|
761
1040
|
};
|
762
1041
|
|
763
1042
|
|
764
1043
|
// used for { foo: 5 }
|
765
1044
|
export const __Porffor_object_class_value = (obj: any, key: any, value: any): void => {
|
766
1045
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
767
|
-
|
1046
|
+
|
1047
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1048
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
768
1049
|
if (entryPtr == -1) {
|
769
1050
|
// add new entry
|
770
1051
|
// check if object is inextensible
|
@@ -773,29 +1054,30 @@ export const __Porffor_object_class_value = (obj: any, key: any, value: any): vo
|
|
773
1054
|
}
|
774
1055
|
|
775
1056
|
// bump size +1
|
776
|
-
const size: i32 = Porffor.wasm.i32.
|
777
|
-
Porffor.wasm.i32.
|
1057
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1058
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
778
1059
|
|
779
1060
|
// entryPtr = current end of object
|
780
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
781
|
-
|
782
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1061
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1062
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
783
1063
|
}
|
784
1064
|
|
785
|
-
// write new value value
|
786
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
1065
|
+
// write new value value
|
1066
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
787
1067
|
|
788
1068
|
// write new tail (value type + flags)
|
789
1069
|
// flags = writable, enumerable, configurable, not accessor
|
790
1070
|
Porffor.wasm.i32.store16(entryPtr,
|
791
1071
|
0b1110 + (Porffor.wasm`local.get ${value+1}` << 8),
|
792
|
-
0,
|
1072
|
+
0, 16);
|
793
1073
|
};
|
794
1074
|
|
795
1075
|
// used for { foo() {} }
|
796
1076
|
export const __Porffor_object_class_method = (obj: any, key: any, value: any): void => {
|
797
1077
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
798
|
-
|
1078
|
+
|
1079
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1080
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
799
1081
|
if (entryPtr == -1) {
|
800
1082
|
// add new entry
|
801
1083
|
// check if object is inextensible
|
@@ -804,29 +1086,30 @@ export const __Porffor_object_class_method = (obj: any, key: any, value: any): v
|
|
804
1086
|
}
|
805
1087
|
|
806
1088
|
// bump size +1
|
807
|
-
const size: i32 = Porffor.wasm.i32.
|
808
|
-
Porffor.wasm.i32.
|
1089
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1090
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
809
1091
|
|
810
1092
|
// entryPtr = current end of object
|
811
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
812
|
-
|
813
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1093
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1094
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
814
1095
|
}
|
815
1096
|
|
816
1097
|
// write new value value (lol)
|
817
|
-
Porffor.wasm.f64.store(entryPtr, value, 0,
|
1098
|
+
Porffor.wasm.f64.store(entryPtr, value, 0, 8);
|
818
1099
|
|
819
1100
|
// write new tail (value type + flags)
|
820
1101
|
// flags = writable, enumerable, configurable, not accessor
|
821
1102
|
Porffor.wasm.i32.store16(entryPtr,
|
822
1103
|
0b1010 + (Porffor.wasm`local.get ${value+1}` << 8),
|
823
|
-
0,
|
1104
|
+
0, 16);
|
824
1105
|
};
|
825
1106
|
|
826
1107
|
// used for { get foo() {} }
|
827
1108
|
export const __Porffor_object_class_get = (obj: any, key: any, get: any): void => {
|
828
1109
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
829
|
-
|
1110
|
+
|
1111
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1112
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
830
1113
|
let set: any = undefined;
|
831
1114
|
if (entryPtr == -1) {
|
832
1115
|
// add new entry
|
@@ -836,32 +1119,33 @@ export const __Porffor_object_class_get = (obj: any, key: any, get: any): void =
|
|
836
1119
|
}
|
837
1120
|
|
838
1121
|
// bump size +1
|
839
|
-
const size: i32 = Porffor.wasm.i32.
|
840
|
-
Porffor.wasm.i32.
|
1122
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1123
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
841
1124
|
|
842
1125
|
// entryPtr = current end of object
|
843
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
844
|
-
|
845
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1126
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1127
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
846
1128
|
} else {
|
847
1129
|
// existing entry, keep set (if exists)
|
848
1130
|
set = __Porffor_object_accessorSet(entryPtr);
|
849
1131
|
}
|
850
1132
|
|
851
1133
|
// write new value value (lol)
|
852
|
-
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0,
|
1134
|
+
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0, 8);
|
853
1135
|
|
854
1136
|
// write new tail (value type + flags)
|
855
1137
|
// flags = writable, enumerable, configurable, accessor
|
856
1138
|
Porffor.wasm.i32.store16(entryPtr,
|
857
1139
|
0b1011 + (Porffor.TYPES.number << 8),
|
858
|
-
0,
|
1140
|
+
0, 16);
|
859
1141
|
};
|
860
1142
|
|
861
1143
|
// used for { set foo(v) {} }
|
862
1144
|
export const __Porffor_object_class_set = (obj: any, key: any, set: any): void => {
|
863
1145
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
864
|
-
|
1146
|
+
|
1147
|
+
const hash: i32 = __Porffor_object_hash(key);
|
1148
|
+
let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
|
865
1149
|
let get: any = undefined;
|
866
1150
|
if (entryPtr == -1) {
|
867
1151
|
// add new entry
|
@@ -871,24 +1155,23 @@ export const __Porffor_object_class_set = (obj: any, key: any, set: any): void =
|
|
871
1155
|
}
|
872
1156
|
|
873
1157
|
// bump size +1
|
874
|
-
const size: i32 = Porffor.wasm.i32.
|
875
|
-
Porffor.wasm.i32.
|
1158
|
+
const size: i32 = Porffor.wasm.i32.load16_u(obj, 0, 0);
|
1159
|
+
Porffor.wasm.i32.store16(obj, size + 1, 0, 0);
|
876
1160
|
|
877
1161
|
// entryPtr = current end of object
|
878
|
-
entryPtr = Porffor.wasm`local.get ${obj}` +
|
879
|
-
|
880
|
-
__Porffor_object_writeKey(entryPtr, key);
|
1162
|
+
entryPtr = Porffor.wasm`local.get ${obj}` + 8 + size * 18;
|
1163
|
+
__Porffor_object_writeKey(entryPtr, key, hash);
|
881
1164
|
} else {
|
882
1165
|
// existing entry, keep set (if exists)
|
883
1166
|
get = __Porffor_object_accessorGet(entryPtr);
|
884
1167
|
}
|
885
1168
|
|
886
1169
|
// write new value value (lol)
|
887
|
-
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0,
|
1170
|
+
Porffor.wasm.f64.store(entryPtr, __Porffor_object_packAccessor(get, set), 0, 8);
|
888
1171
|
|
889
1172
|
// write new tail (value type + flags)
|
890
1173
|
// flags = writable, enumerable, configurable, accessor
|
891
1174
|
Porffor.wasm.i32.store16(entryPtr,
|
892
1175
|
0b1011 + (Porffor.TYPES.number << 8),
|
893
|
-
0,
|
1176
|
+
0, 16);
|
894
1177
|
};
|