porffor 0.41.5 → 0.41.7

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