porffor 0.41.4 → 0.41.6
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/builtins/__internal_object.ts +14 -8
- package/compiler/builtins/_internal_object.ts +93 -87
- package/compiler/builtins/object.ts +39 -21
- package/compiler/builtins.js +1 -61
- package/compiler/builtins_objects.js +10 -1
- package/compiler/builtins_precompiled.js +866 -865
- package/compiler/codegen.js +36 -4
- package/compiler/precompile.js +21 -5
- package/package.json +1 -1
- package/runner/index.js +1 -1
@@ -31,14 +31,20 @@ export const __Porffor_object_underlying = (obj: any): any => {
|
|
31
31
|
const key2: bytestring = 'constructor';
|
32
32
|
__Porffor_object_expr_initWithFlags(proto, key2, obj, 0b1010);
|
33
33
|
}
|
34
|
+
|
35
|
+
const key3: bytestring = 'name';
|
36
|
+
__Porffor_object_expr_initWithFlags(underlying, key3, __Porffor_funcLut_name(obj), 0b0010);
|
37
|
+
|
38
|
+
const key4: bytestring = 'length';
|
39
|
+
__Porffor_object_expr_initWithFlags(underlying, key4, __Porffor_funcLut_length(obj), 0b0010);
|
34
40
|
}
|
35
41
|
|
36
42
|
if (t == Porffor.TYPES.array) {
|
37
43
|
const arr: any[] = obj;
|
38
44
|
const len: i32 = arr.length;
|
39
45
|
|
40
|
-
const
|
41
|
-
__Porffor_object_expr_initWithFlags(underlying,
|
46
|
+
const key5: bytestring = 'length';
|
47
|
+
__Porffor_object_expr_initWithFlags(underlying, key5, len, 0b1000);
|
42
48
|
|
43
49
|
// todo: this should somehow be kept in sync?
|
44
50
|
for (let i: i32 = 0; i < len; i++) {
|
@@ -46,26 +52,26 @@ export const __Porffor_object_underlying = (obj: any): any => {
|
|
46
52
|
}
|
47
53
|
}
|
48
54
|
|
49
|
-
if (t == Porffor.TYPES.string) {
|
55
|
+
if (Porffor.fastOr(t == Porffor.TYPES.string, t == Porffor.TYPES.stringobject)) {
|
50
56
|
const str: string = obj;
|
51
57
|
const len: i32 = str.length;
|
52
58
|
|
53
|
-
const
|
54
|
-
__Porffor_object_expr_initWithFlags(underlying,
|
59
|
+
const key6: bytestring = 'length';
|
60
|
+
__Porffor_object_expr_initWithFlags(underlying, key6, len, 0b0000);
|
55
61
|
|
56
62
|
for (let i: i32 = 0; i < len; i++) {
|
57
63
|
__Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), str[i], 0b0100);
|
58
64
|
}
|
59
65
|
|
60
|
-
Porffor.object.preventExtensions(underlying);
|
66
|
+
if (t == Porffor.TYPES.string) Porffor.object.preventExtensions(underlying);
|
61
67
|
}
|
62
68
|
|
63
69
|
if (t == Porffor.TYPES.bytestring) {
|
64
70
|
const str: bytestring = obj;
|
65
71
|
const len: i32 = str.length;
|
66
72
|
|
67
|
-
const
|
68
|
-
__Porffor_object_expr_initWithFlags(underlying,
|
73
|
+
const key7: bytestring = 'length';
|
74
|
+
__Porffor_object_expr_initWithFlags(underlying, key7, len, 0b0000);
|
69
75
|
|
70
76
|
for (let i: i32 = 0; i < len; i++) {
|
71
77
|
__Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), str[i], 0b0100);
|
@@ -135,34 +135,30 @@ export const __Porffor_object_lookup = (obj: any, target: any): i32 => {
|
|
135
135
|
const size: i32 = Porffor.wasm.i32.load(obj, 0, 0);
|
136
136
|
const endPtr: i32 = ptr + size * 14;
|
137
137
|
|
138
|
-
if (targetType == Porffor.TYPES.
|
139
|
-
const
|
140
|
-
for (; ptr < endPtr; ptr += 14) {
|
141
|
-
const keyRaw: i32 = Porffor.wasm.i32.load(ptr, 0, 0);
|
142
|
-
if (keyRaw == 0) break; // ran out of keys
|
143
|
-
if (keyRaw >>> 31) continue; // MSB 1 set, not a bytestring
|
144
|
-
|
145
|
-
const keyStr: bytestring = keyRaw;
|
146
|
-
if (keyStr == targetStr) return ptr;
|
147
|
-
}
|
148
|
-
} else if (targetType == Porffor.TYPES.string) {
|
149
|
-
const targetStr: string = target;
|
138
|
+
if (targetType == Porffor.TYPES.symbol) {
|
139
|
+
const targetSym: symbol = target;
|
150
140
|
for (; ptr < endPtr; ptr += 14) {
|
151
141
|
const keyRaw: i32 = Porffor.wasm.i32.load(ptr, 0, 0);
|
152
142
|
if (keyRaw == 0) break; // ran out of keys
|
153
|
-
if (keyRaw >>> 30 ==
|
154
|
-
const
|
155
|
-
if (
|
143
|
+
if (keyRaw >>> 30 == 3) { // MSB 1 and 2 set, symbol
|
144
|
+
const keySym: symbol = keyRaw & 0x3FFFFFFF; // unset MSB
|
145
|
+
if (keySym == targetSym) return ptr;
|
156
146
|
}
|
157
147
|
}
|
158
|
-
} else {
|
159
|
-
const targetSym: symbol = target;
|
148
|
+
} else {
|
160
149
|
for (; ptr < endPtr; ptr += 14) {
|
161
150
|
const keyRaw: i32 = Porffor.wasm.i32.load(ptr, 0, 0);
|
162
151
|
if (keyRaw == 0) break; // ran out of keys
|
163
|
-
|
164
|
-
|
165
|
-
|
152
|
+
|
153
|
+
const msb: i32 = keyRaw >>> 30;
|
154
|
+
if (msb == 0) {
|
155
|
+
// bytestring
|
156
|
+
const keyStr: bytestring = keyRaw;
|
157
|
+
if (Porffor.strcmp(keyStr, target)) return ptr;
|
158
|
+
} else if (msb == 2) {
|
159
|
+
// string
|
160
|
+
const keyStr: string = keyRaw & 0x7FFFFFFF; // unset MSB
|
161
|
+
if (Porffor.strcmp(keyStr, target)) return ptr;
|
166
162
|
}
|
167
163
|
}
|
168
164
|
}
|
@@ -170,58 +166,96 @@ export const __Porffor_object_lookup = (obj: any, target: any): i32 => {
|
|
170
166
|
return -1;
|
171
167
|
};
|
172
168
|
|
173
|
-
export const
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
const t: i32 = Porffor.TYPES.bytestring;
|
180
|
-
Porffor.wasm`
|
181
|
-
local.get ${o}
|
182
|
-
f64.convert_i32_u
|
183
|
-
local.get ${t}
|
184
|
-
return`;
|
185
|
-
}
|
186
|
-
|
187
|
-
const tmp2: bytestring = 'length';
|
188
|
-
if (key == tmp2) {
|
189
|
-
const o: i32 = __Porffor_funcLut_length(obj);
|
190
|
-
Porffor.wasm`
|
191
|
-
local.get ${o}
|
192
|
-
f64.convert_i32_u
|
193
|
-
i32.const 1
|
169
|
+
export const __Porffor_object_readValue = (entryPtr: i32): any => {
|
170
|
+
Porffor.wasm`
|
171
|
+
local.get ${entryPtr}
|
172
|
+
f64.load 0 4
|
173
|
+
local.get ${entryPtr}
|
174
|
+
i32.load8_u 0 13
|
194
175
|
return`;
|
195
|
-
|
196
|
-
}
|
176
|
+
};
|
197
177
|
|
178
|
+
export const __Porffor_object_get = (obj: any, key: any): any => {
|
179
|
+
const trueType: i32 = Porffor.wasm`local.get ${obj+1}`;
|
198
180
|
if (trueType != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
199
181
|
|
200
182
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot get property of null');
|
201
183
|
|
202
184
|
let entryPtr: i32 = __Porffor_object_lookup(obj, key);
|
203
185
|
if (entryPtr == -1) {
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
186
|
+
// check prototype chain
|
187
|
+
const protoKey: bytestring = '__proto__';
|
188
|
+
let lastProto: any = obj;
|
189
|
+
if (key != protoKey) {
|
190
|
+
while (true) {
|
191
|
+
obj = __Porffor_object_get(obj, protoKey);
|
192
|
+
|
193
|
+
if (Porffor.comptime.flag`hasFunc.#get___String_prototype`) {
|
194
|
+
if (Porffor.fastOr(
|
195
|
+
trueType == Porffor.TYPES.string,
|
196
|
+
trueType == Porffor.TYPES.bytestring,
|
197
|
+
trueType == Porffor.TYPES.stringobject
|
198
|
+
)) {
|
199
|
+
obj = __String_prototype;
|
200
|
+
}
|
215
201
|
}
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
202
|
+
|
203
|
+
if (Porffor.comptime.flag`hasFunc.#get___Number_prototype`) {
|
204
|
+
if (Porffor.fastOr(
|
205
|
+
trueType == Porffor.TYPES.number,
|
206
|
+
trueType == Porffor.TYPES.numberobject
|
207
|
+
)) {
|
208
|
+
obj = __Number_prototype;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
if (Porffor.comptime.flag`hasFunc.#get___Boolean_prototype`) {
|
213
|
+
if (Porffor.fastOr(
|
214
|
+
trueType == Porffor.TYPES.boolean,
|
215
|
+
trueType == Porffor.TYPES.booleanobject
|
216
|
+
)) {
|
217
|
+
obj = __Boolean_prototype;
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
if (Porffor.comptime.flag`hasFunc.#get___Function_prototype`) {
|
222
|
+
if (trueType == Porffor.TYPES.function) {
|
223
|
+
obj = __Function_prototype;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
if (Porffor.comptime.flag`hasFunc.#get___Array_prototype`) {
|
228
|
+
if (trueType == Porffor.TYPES.array) {
|
229
|
+
obj = __Array_prototype;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
if (Porffor.comptime.flag`hasFunc.#get___Date_prototype`) {
|
234
|
+
if (trueType == Porffor.TYPES.date) {
|
235
|
+
obj = __Date_prototype;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
if (Porffor.comptime.flag`hasFunc.#get___Error_prototype`) {
|
240
|
+
if (trueType == Porffor.TYPES.error) {
|
241
|
+
obj = __Error_prototype;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
if (Porffor.fastOr(obj == null, Porffor.wasm`local.get ${obj}` == Porffor.wasm`local.get ${lastProto}`)) break;
|
246
|
+
lastProto = obj;
|
247
|
+
|
248
|
+
if ((entryPtr = __Porffor_object_lookup(obj, key)) != -1) break;
|
249
|
+
}
|
250
|
+
} else {
|
251
|
+
let proto: i32 = __Object_prototype;
|
252
|
+
if (trueType == Porffor.TYPES.function) proto = __Function_prototype;
|
253
|
+
|
254
|
+
Porffor.wasm`
|
220
255
|
local.get ${proto}
|
221
256
|
f64.convert_i32_u
|
222
257
|
i32.const 7 ;; object type
|
223
258
|
return`;
|
224
|
-
}
|
225
259
|
}
|
226
260
|
|
227
261
|
if (entryPtr == -1) {
|
@@ -535,20 +569,6 @@ local.set ${err}`;
|
|
535
569
|
export const __Porffor_object_delete = (obj: any, key: any): boolean => {
|
536
570
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
537
571
|
|
538
|
-
if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.function) {
|
539
|
-
const tmp1: bytestring = 'name';
|
540
|
-
if (key == tmp1) {
|
541
|
-
__Porffor_funcLut_deleteName(obj);
|
542
|
-
return true;
|
543
|
-
}
|
544
|
-
|
545
|
-
const tmp2: bytestring = 'length';
|
546
|
-
if (key == tmp2) {
|
547
|
-
__Porffor_funcLut_deleteLength(obj);
|
548
|
-
return true;
|
549
|
-
}
|
550
|
-
}
|
551
|
-
|
552
572
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
553
573
|
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
554
574
|
// todo: support non-pure objects
|
@@ -600,20 +620,6 @@ memory.copy 0 0`;
|
|
600
620
|
export const __Porffor_object_deleteStrict = (obj: any, key: any): boolean => {
|
601
621
|
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');
|
602
622
|
|
603
|
-
if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.function) {
|
604
|
-
const tmp1: bytestring = 'name';
|
605
|
-
if (key == tmp1) {
|
606
|
-
__Porffor_funcLut_deleteName(obj);
|
607
|
-
return true;
|
608
|
-
}
|
609
|
-
|
610
|
-
const tmp2: bytestring = 'length';
|
611
|
-
if (key == tmp2) {
|
612
|
-
__Porffor_funcLut_deleteLength(obj);
|
613
|
-
return true;
|
614
|
-
}
|
615
|
-
}
|
616
|
-
|
617
623
|
if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
|
618
624
|
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
|
619
625
|
// todo: support non-pure objects
|
@@ -150,16 +150,6 @@ export const __Object_prototype_hasOwnProperty = (_this: any, prop: any) => {
|
|
150
150
|
return Porffor.object.lookup(_this, p) != -1;
|
151
151
|
}
|
152
152
|
|
153
|
-
if (t == Porffor.TYPES.function) {
|
154
|
-
const tmp1: bytestring = 'name';
|
155
|
-
if (p == tmp1) return !__Porffor_funcLut_isNameDeleted(_this);
|
156
|
-
|
157
|
-
const tmp2: bytestring = 'length';
|
158
|
-
if (p == tmp2) return !__Porffor_funcLut_isLengthDeleted(_this);
|
159
|
-
|
160
|
-
return Porffor.object.lookup(_this, p) != -1;
|
161
|
-
}
|
162
|
-
|
163
153
|
const obj: any = __Porffor_object_underlying(_this);
|
164
154
|
if (Porffor.rawType(obj) == Porffor.TYPES.object) {
|
165
155
|
if (Porffor.object.lookup(obj, p) != -1) return true;
|
@@ -576,15 +566,27 @@ export const __Object_defineProperty = (target: any, prop: any, desc: any) => {
|
|
576
566
|
|
577
567
|
const existingDesc: any = __Object_getOwnPropertyDescriptor(target, prop);
|
578
568
|
if (existingDesc) {
|
579
|
-
|
580
|
-
|
569
|
+
let inKey: bytestring = '';
|
570
|
+
|
571
|
+
// probably slow due to excessive in's but needs to have them to be spec compliant handling explicit undefined vs non-existent
|
572
|
+
inKey = 'configurable';
|
573
|
+
if (configurable == null && !(inKey in desc)) configurable = existingDesc.configurable;
|
574
|
+
|
575
|
+
inKey = 'enumerable';
|
576
|
+
if (enumerable == null && !(inKey in desc)) enumerable = existingDesc.enumerable;
|
581
577
|
|
582
578
|
if (accessor) {
|
583
|
-
|
584
|
-
|
579
|
+
inKey = 'get';
|
580
|
+
if (get == null && !(inKey in desc)) get = existingDesc.get;
|
581
|
+
|
582
|
+
inKey = 'set';
|
583
|
+
if (set == null && !(inKey in desc)) set = existingDesc.set;
|
585
584
|
} else {
|
586
|
-
|
587
|
-
|
585
|
+
inKey = 'value';
|
586
|
+
if (value == null && !(inKey in desc)) value = existingDesc.value;
|
587
|
+
|
588
|
+
inKey = 'writable';
|
589
|
+
if (writable == null && !(inKey in desc)) writable = existingDesc.writable;
|
588
590
|
}
|
589
591
|
}
|
590
592
|
|
@@ -674,11 +676,19 @@ export const __Object_prototype_isPrototypeOf = (_this: any, obj: any) => {
|
|
674
676
|
|
675
677
|
export const __Object_prototype_toString = (_this: any) => {
|
676
678
|
if (Porffor.rawType(_this) == Porffor.TYPES.object) {
|
677
|
-
|
679
|
+
// todo: breaks with Foo.prototype
|
678
680
|
const obj: object = _this;
|
679
681
|
if (obj != null) {
|
680
|
-
|
681
|
-
if (ovr
|
682
|
+
let ovr: any = obj.toString;
|
683
|
+
if (Porffor.rawType(ovr) == Porffor.TYPES.function && ovr != __Object_prototype_toString) return ovr.call(_this);
|
684
|
+
|
685
|
+
const key: bytestring = 'toString';
|
686
|
+
const entryPtr: i32 = Porffor.object.lookup(obj, key);
|
687
|
+
if (entryPtr != -1) {
|
688
|
+
ovr = Porffor.object.readValue(entryPtr);
|
689
|
+
if (Porffor.rawType(ovr) == Porffor.TYPES.function) return ovr.call(_this);
|
690
|
+
else return undefined;
|
691
|
+
}
|
682
692
|
}
|
683
693
|
}
|
684
694
|
|
@@ -719,8 +729,16 @@ export const __Object_prototype_valueOf = (_this: any) => {
|
|
719
729
|
// todo: breaks with Foo.prototype
|
720
730
|
const obj: object = _this;
|
721
731
|
if (obj != null) {
|
722
|
-
|
723
|
-
if (ovr
|
732
|
+
let ovr: any = obj.valueOf;
|
733
|
+
if (Porffor.rawType(ovr) == Porffor.TYPES.function && ovr != __Object_prototype_valueOf) return ovr.call(_this);
|
734
|
+
|
735
|
+
const key: bytestring = 'valueOf';
|
736
|
+
const entryPtr: i32 = Porffor.object.lookup(obj, key);
|
737
|
+
if (entryPtr != -1) {
|
738
|
+
ovr = Porffor.object.readValue(entryPtr);
|
739
|
+
if (Porffor.rawType(ovr) == Porffor.TYPES.function) return ovr.call(_this);
|
740
|
+
else return undefined;
|
741
|
+
}
|
724
742
|
}
|
725
743
|
}
|
726
744
|
|
package/compiler/builtins.js
CHANGED
@@ -100,7 +100,7 @@ export const BuiltinVars = function(ctx) {
|
|
100
100
|
this.Infinity.floatOnly = true;
|
101
101
|
|
102
102
|
for (const x in TYPES) {
|
103
|
-
this['__Porffor_TYPES_' + x] = number(TYPES[x]);
|
103
|
+
this['__Porffor_TYPES_' + x] = () => number(TYPES[x]);
|
104
104
|
}
|
105
105
|
|
106
106
|
this.__performance_timeOrigin = [
|
@@ -1048,65 +1048,5 @@ export const BuiltinFuncs = function() {
|
|
1048
1048
|
table: true
|
1049
1049
|
};
|
1050
1050
|
|
1051
|
-
this.__Porffor_funcLut_deleteLength = {
|
1052
|
-
params: [ Valtype.i32 ],
|
1053
|
-
returns: [],
|
1054
|
-
wasm: (scope, { allocPage }) => [
|
1055
|
-
[ Opcodes.local_get, 0 ],
|
1056
|
-
...number(64, Valtype.i32),
|
1057
|
-
[ Opcodes.i32_mul ],
|
1058
|
-
...number(2, Valtype.i32),
|
1059
|
-
[ Opcodes.i32_add ],
|
1060
|
-
...number(0, Valtype.i32),
|
1061
|
-
[ Opcodes.i32_store16, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ],
|
1062
|
-
|
1063
|
-
[ Opcodes.local_get, 0 ],
|
1064
|
-
...number(1, Valtype.i32),
|
1065
|
-
[ Opcodes.i32_store8, 0, ...unsignedLEB128(allocPage(scope, 'func length deletion table')) ]
|
1066
|
-
],
|
1067
|
-
table: true
|
1068
|
-
};
|
1069
|
-
|
1070
|
-
this.__Porffor_funcLut_deleteName = {
|
1071
|
-
params: [ Valtype.i32 ],
|
1072
|
-
returns: [],
|
1073
|
-
wasm: (scope, { allocPage }) => [
|
1074
|
-
[ Opcodes.local_get, 0 ],
|
1075
|
-
...number(64, Valtype.i32),
|
1076
|
-
[ Opcodes.i32_mul ],
|
1077
|
-
...number(5, Valtype.i32),
|
1078
|
-
[ Opcodes.i32_add ],
|
1079
|
-
...number(0, Valtype.i32),
|
1080
|
-
[ Opcodes.i32_store, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ],
|
1081
|
-
|
1082
|
-
[ Opcodes.local_get, 0 ],
|
1083
|
-
...number(1, Valtype.i32),
|
1084
|
-
[ Opcodes.i32_store8, 0, ...unsignedLEB128(allocPage(scope, 'func name deletion table')) ],
|
1085
|
-
],
|
1086
|
-
table: true
|
1087
|
-
};
|
1088
|
-
|
1089
|
-
this.__Porffor_funcLut_isLengthDeleted = {
|
1090
|
-
params: [ Valtype.i32 ],
|
1091
|
-
returns: [ Valtype.i32 ],
|
1092
|
-
returnType: TYPES.boolean,
|
1093
|
-
wasm: (scope, { allocPage }) => [
|
1094
|
-
[ Opcodes.local_get, 0 ],
|
1095
|
-
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func length deletion table')) ]
|
1096
|
-
],
|
1097
|
-
table: true
|
1098
|
-
};
|
1099
|
-
|
1100
|
-
this.__Porffor_funcLut_isNameDeleted = {
|
1101
|
-
params: [ Valtype.i32 ],
|
1102
|
-
returns: [ Valtype.i32 ],
|
1103
|
-
returnType: TYPES.boolean,
|
1104
|
-
wasm: (scope, { allocPage }) => [
|
1105
|
-
[ Opcodes.local_get, 0 ],
|
1106
|
-
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func name deletion table')) ]
|
1107
|
-
],
|
1108
|
-
table: true
|
1109
|
-
};
|
1110
|
-
|
1111
1051
|
PrecompiledBuiltins.BuiltinFuncs.call(this);
|
1112
1052
|
};
|
@@ -199,7 +199,16 @@ export default function({ builtinFuncs }, Prefs) {
|
|
199
199
|
const props = autoFuncs(x);
|
200
200
|
|
201
201
|
// special case: Object.prototype.__proto__ = null
|
202
|
-
if (x === '__Object_prototype')
|
202
|
+
if (x === '__Object_prototype') {
|
203
|
+
Object.defineProperty(props, '__proto__', { value: { value: null, configurable: true }, enumerable: true });
|
204
|
+
}
|
205
|
+
|
206
|
+
// special case: Function.prototype.length = 0
|
207
|
+
// special case: Function.prototype.name = ''
|
208
|
+
if (x === '__Function_prototype') {
|
209
|
+
props.length = { value: 0, configurable: true };
|
210
|
+
props.name = { value: '', configurable: true };
|
211
|
+
}
|
203
212
|
|
204
213
|
// add constructor for constructors
|
205
214
|
const name = x.slice(2, x.indexOf('_', 2));
|