porffor 0.57.21 → 0.57.22

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.
@@ -25,76 +25,79 @@ export const __Porffor_object_hash = (key: any): i32 => {
25
25
  return 0;
26
26
  }
27
27
 
28
- // bytestring or string, fnv-1a hash (custom variant)
28
+ // bytestring or string, xxh32-based hash
29
29
  // todo/opt: custom wasm simd variant?
30
- // todo/opt: pgo for if no hash collisions?
31
30
  // todo: bytestring/string symmetric hashing
32
-
33
- let ptr: i32 = Porffor.wasm`local.get ${key}`;
34
- const len: i32 = Porffor.wasm.i32.load(key, 0, 0);
35
-
36
- let hash: i32 = (2166136261 ^ len) * 16777619;
37
-
38
- // chunks of 8 bytes via i64.load
39
- const endPtr: i32 = ptr + len - 8;
40
- for (; ptr <= endPtr; ptr += 8) {
31
+ let p: i32 = Porffor.wasm`local.get ${key}`;
32
+ let len: i32 = Porffor.wasm.i32.load(key, 0, 0);
33
+ if (Porffor.wasm`local.get ${key+1}` == Porffor.TYPES.string) len *= 2;
34
+
35
+ let hash: i32 = 374761393 + len;
36
+ const end: i32 = p + len;
37
+ while (p + 4 <= end) {
38
+ // hash in chunks of i32 (4 bytes)
41
39
  Porffor.wasm`
42
- local x i64
43
- local.get ${ptr}
44
- i64.load 0 4
45
- local.set x
46
-
47
- local.get ${hash}
48
- local.get x
49
- i64.const 32
50
- i64.shr_u
51
- i32.wrap_i64
52
- i32.xor
53
- i32.const 16777619
40
+ local.get hash
41
+ local.get p
42
+ i32.load 0 4
43
+ i32.const 3266489917
54
44
  i32.mul
55
-
56
- local.get x
57
- i32.wrap_i64
58
- i32.xor
59
- i32.const 16777619
45
+ i32.add
46
+ i32.const 17
47
+ i32.rotl
48
+ i32.const 668265263
60
49
  i32.mul
61
-
62
- local.set ${hash}`;
50
+ local.set hash`;
51
+ p += 4;
63
52
  }
64
53
 
65
- // remaining 0-7 bytes via i64.load and bitwise
66
54
  Porffor.wasm`
67
- local.get ${ptr}
68
- i64.load 0 4
55
+ ;; hash final bytes up to 4 via shift depending on bytes remaining
56
+ local.get hash
57
+ local.get p
58
+ i32.load 0 4
69
59
 
70
- local shift i64
71
- local.get ${ptr}
72
- local.get ${endPtr}
60
+ i32.const 1
61
+ local.get end
62
+ local.get p
73
63
  i32.sub
74
64
  i32.const 8
75
65
  i32.mul
76
- i64.extend_i32_u
77
- local.tee shift
66
+ i32.shl
67
+ i32.const 1
68
+ i32.sub
69
+ i32.and
78
70
 
79
- i64.shl
80
- local.get shift
81
- i64.shr_u
82
- local.set x
71
+ i32.const 3266489917
72
+ i32.mul
73
+ i32.add
74
+ i32.const 17
75
+ i32.rotl
76
+ i32.const 668265263
77
+ i32.mul
78
+ local.tee hash
83
79
 
84
- local.get ${hash}
85
- local.get x
86
- i64.const 32
87
- i64.shr_u
88
- i32.wrap_i64
80
+ ;; final avalanche
81
+ local.get hash
82
+ i32.const 15
83
+ i32.shr_u
89
84
  i32.xor
90
- i32.const 16777619
85
+ i32.const 2246822519
91
86
  i32.mul
87
+ local.tee hash
92
88
 
93
- local.get x
94
- i32.wrap_i64
89
+ local.get hash
90
+ i32.const 13
91
+ i32.shr_u
95
92
  i32.xor
96
- i32.const 16777619
93
+ i32.const 3266489917
97
94
  i32.mul
95
+ local.tee hash
96
+
97
+ local.get hash
98
+ i32.const 16
99
+ i32.shr_u
100
+ i32.xor
98
101
  return`;
99
102
  };
100
103
 
@@ -489,7 +492,7 @@ local.set ${obj+1}`;
489
492
  } else obj = __Porffor_object_getHiddenPrototype(trueType);
490
493
 
491
494
  // todo/opt: put this behind comptime flag if only __proto__ is used
492
- if (hash == -406948493) if (Porffor.strcmp(key, '__proto__')) {
495
+ if (hash == 593337848) if (Porffor.strcmp(key, '__proto__')) {
493
496
  // get prototype
494
497
  Porffor.wasm`
495
498
  local.get ${obj}
@@ -565,7 +568,7 @@ export const __Porffor_object_set = (obj: any, key: any, value: any): any => {
565
568
  let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
566
569
  let flags: i32;
567
570
  if (entryPtr == -1) {
568
- if (hash == -406948493) if (Porffor.strcmp(key, '__proto__')) {
571
+ if (hash == 593337848) if (Porffor.strcmp(key, '__proto__')) {
569
572
  // set prototype
570
573
  __Porffor_object_setPrototype(obj, value);
571
574
  return value;
@@ -671,7 +674,7 @@ export const __Porffor_object_setStrict = (obj: any, key: any, value: any): any
671
674
  let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
672
675
  let flags: i32;
673
676
  if (entryPtr == -1) {
674
- if (hash == -406948493) if (Porffor.strcmp(key, '__proto__')) {
677
+ if (hash == 593337848) if (Porffor.strcmp(key, '__proto__')) {
675
678
  // set prototype
676
679
  __Porffor_object_setPrototype(obj, value);
677
680
  return value;
@@ -949,7 +952,7 @@ export const __Porffor_object_expr_init = (obj: any, key: any, value: any): void
949
952
  const hash: i32 = __Porffor_object_hash(key);
950
953
  let entryPtr: i32 = __Porffor_object_lookup(obj, key, hash);
951
954
  if (entryPtr == -1) {
952
- if (hash == -406948493) if (Porffor.strcmp(key, '__proto__')) {
955
+ if (hash == 593337848) if (Porffor.strcmp(key, '__proto__')) {
953
956
  // set prototype
954
957
  __Porffor_object_setPrototype(obj, value);
955
958
  return value;
@@ -13,9 +13,9 @@ params:[127,127,127,127],typedParams:1,returns:[127,127],
13
13
  locals:[127,127,127,127,127],localNames:["a","a#type","b","b#type","al","bl","out","i","ptr"],
14
14
  }
15
15
  this.__Porffor_object_hash = {
16
- wasm:()=>[[32,1],[65,5],[70],[4,64],[65,0],[15],[26],[11],[32,0],[33,2],[32,0],[40,0,0],[33,3],[65,197,187,242,136,120],[32,3],[115],[65,147,131,128,8],[108],[33,4],[32,2],[32,3],[106],[65,8],[107],[33,5],[3,64],[32,2],[32,5],[76],[4,64],[32,2],[41,0,4],[33,6],[32,4],[32,6],[66,32],[136],[167],[115],[65,147,131,128,8],[108],[32,6],[167],[115],[65,147,131,128,8],[108],[33,4],[32,2],[65,8],[106],[33,2],[12,1],[11],[11],[32,2],[41,0,4],[32,2],[32,5],[107],[65,8],[108],[173],[34,7],[134],[32,7],[136],[33,6],[32,4],[32,6],[66,32],[136],[167],[115],[65,147,131,128,8],[108],[32,6],[167],[115],[65,147,131,128,8],[108],[15]],
16
+ wasm:()=>[[32,1],[65,5],[70],[4,64],[65,0],[15],[26],[11],[32,0],[33,2],[32,0],[40,0,0],[33,3],[32,1],[65,195,0],[70],[4,64],[32,3],[65,2],[108],[33,3],[11],[65,177,207,217,178,1],[32,3],[106],[33,4],[32,2],[32,3],[106],[33,5],[3,64],[32,2],[65,4],[106],[32,5],[76],[4,64],[32,4],[32,2],[40,0,4],[65,189,220,202,149,124],[108],[106],[65,17],[119],[65,175,214,211,190,2],[108],[33,4],[32,2],[65,4],[106],[33,2],[12,1],[11],[11],[32,4],[32,2],[40,0,4],[65,1],[32,5],[32,2],[107],[65,8],[108],[116],[65,1],[107],[113],[65,189,220,202,149,124],[108],[106],[65,17],[119],[65,175,214,211,190,2],[108],[34,4],[32,4],[65,15],[118],[115],[65,247,148,175,175,120],[108],[34,4],[32,4],[65,13],[118],[115],[65,189,220,202,149,124],[108],[34,4],[32,4],[65,16],[118],[115],[15]],
17
17
  params:[127,127],typedParams:1,returns:[127],returnType:1,
18
- locals:[127,127,127,127,126,126],localNames:["key","key#type","ptr","len","hash","endPtr","x","shift"],
18
+ locals:[127,127,127,127],localNames:["key","key#type","p","len","hash","end"],
19
19
  }
20
20
  this.__Porffor_object_writeKey = {
21
21
  wasm:()=>[[32,0],[32,4],[54,0,0],[32,2],[33,6],[32,3],[65,195,0],[70],[4,64],[32,6],[65,128,128,128,128,120],[114],[33,6],[5],[32,3],[65,5],[70],[4,64],[32,6],[65,128,128,128,128,124],[114],[33,6],[11],[11],[32,0],[32,6],[54,0,4],[15]],
@@ -109,19 +109,19 @@ params:[127,127],typedParams:1,returns:[124,127],
109
109
  locals:[],localNames:["entryPtr","entryPtr#type"],
110
110
  }
111
111
  this.__Porffor_object_get = {
112
- wasm:(_,{i32ify,t,makeString,builtin,internalThrow})=>[[32,1],[34,4],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,5],[33,1],[33,0],[11],[32,0],[69],[4,64],...internalThrow(_,'TypeError',`Cannot get property of null`),[26],[11],[32,2],[32,3],[16,builtin('__Porffor_object_hash')],[33,6],[32,0],[32,1],[32,2],[32,3],[32,6],[65,1],[16,builtin('__Porffor_object_lookup')],[34,7],[65,127],[70],[4,64],[32,4],[65,7],[70],[4,64],[32,0],[32,0],[40,0,4],[33,0],[45,0,3],[34,1],[69],[4,64],[16,builtin('#get___Object_prototype')],[33,0],[65,7],[33,1],[11],[5],[32,4],[65,1],[16,builtin('__Porffor_object_getHiddenPrototype')],[34,5],[33,1],[33,0],[11],[32,6],[65,243,234,249,189,126],[70],[4,64],[32,2],[32,3],...i32ify(makeString(_,"__proto__",1)),[65,195,1],[16,builtin('__Porffor_strcmp')],[4,64],[32,0],[184],[32,1],[15],[26],[11],[11],[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,5],[33,1],[33,0],[11],[32,0],[33,8],[32,1],[33,9],[3,64],[65,1],[4,64],[32,0],[32,1],[32,2],[32,3],[32,6],[65,1],[16,builtin('__Porffor_object_lookup')],[34,7],[65,127],[71],[4,64],[12,1],[26],[11],[32,1],[65,7],[70],[4,64],[32,0],[32,0],[40,0,4],[33,0],[45,0,3],[33,1],[5],[32,0],[32,1],[16,builtin('__Porffor_object_getPrototype')],[34,5],[33,1],[33,0],[11],[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,5],[33,1],[33,0],[11],[32,0],[33,10],[32,1],[33,11],[2,127],...t([0,128],()=>[[32,11],[69],[32,11],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),[32,11],[65,7],[70],[4,64],[32,10],[69],[12,1],[11],[65,0],[11],[32,0],[32,8],[70],[114],[4,64],[12,1],[26],[11],[32,0],[33,8],[32,1],[33,9],[12,1],[11],[11],[32,7],[65,127],[70],[4,64],[68,0],[65,128,1],[15],[26],[11],[11],[32,7],[47,0,16],[34,12],[65,1],[113],[4,64],[32,7],[65,1],[16,builtin('__Porffor_object_accessorGet')],[33,5],[34,13],[69],[4,64],[68,0],[65,128,1],[15],[26],[11],[32,13],[33,16],[65,0],[65,128,1],[33,17],[183],[32,17],[32,0],[34,14],[32,1],[34,15],[33,17],[183],[32,17],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,16],[17,12,0],[34,5],[15],[26],[11],[32,7],[43,0,8],[32,12],[65,8],[118],[15]],
112
+ wasm:(_,{i32ify,t,makeString,builtin,internalThrow})=>[[32,1],[34,4],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,5],[33,1],[33,0],[11],[32,0],[69],[4,64],...internalThrow(_,'TypeError',`Cannot get property of null`),[26],[11],[32,2],[32,3],[16,builtin('__Porffor_object_hash')],[33,6],[32,0],[32,1],[32,2],[32,3],[32,6],[65,1],[16,builtin('__Porffor_object_lookup')],[34,7],[65,127],[70],[4,64],[32,4],[65,7],[70],[4,64],[32,0],[32,0],[40,0,4],[33,0],[45,0,3],[34,1],[69],[4,64],[16,builtin('#get___Object_prototype')],[33,0],[65,7],[33,1],[11],[5],[32,4],[65,1],[16,builtin('__Porffor_object_getHiddenPrototype')],[34,5],[33,1],[33,0],[11],[32,6],[65,248,187,246,154,2],[70],[4,64],[32,2],[32,3],...i32ify(makeString(_,"__proto__",1)),[65,195,1],[16,builtin('__Porffor_strcmp')],[4,64],[32,0],[184],[32,1],[15],[26],[11],[11],[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,5],[33,1],[33,0],[11],[32,0],[33,8],[32,1],[33,9],[3,64],[65,1],[4,64],[32,0],[32,1],[32,2],[32,3],[32,6],[65,1],[16,builtin('__Porffor_object_lookup')],[34,7],[65,127],[71],[4,64],[12,1],[26],[11],[32,1],[65,7],[70],[4,64],[32,0],[32,0],[40,0,4],[33,0],[45,0,3],[33,1],[5],[32,0],[32,1],[16,builtin('__Porffor_object_getPrototype')],[34,5],[33,1],[33,0],[11],[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,5],[33,1],[33,0],[11],[32,0],[33,10],[32,1],[33,11],[2,127],...t([0,128],()=>[[32,11],[69],[32,11],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),[32,11],[65,7],[70],[4,64],[32,10],[69],[12,1],[11],[65,0],[11],[32,0],[32,8],[70],[114],[4,64],[12,1],[26],[11],[32,0],[33,8],[32,1],[33,9],[12,1],[11],[11],[32,7],[65,127],[70],[4,64],[68,0],[65,128,1],[15],[26],[11],[11],[32,7],[47,0,16],[34,12],[65,1],[113],[4,64],[32,7],[65,1],[16,builtin('__Porffor_object_accessorGet')],[33,5],[34,13],[69],[4,64],[68,0],[65,128,1],[15],[26],[11],[32,13],[33,16],[65,0],[65,128,1],[33,17],[183],[32,17],[32,0],[34,14],[32,1],[34,15],[33,17],[183],[32,17],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,16],[17,12,0],[34,5],[15],[26],[11],[32,7],[43,0,8],[32,12],[65,8],[118],[15]],
113
113
  params:[127,127,127,127],typedParams:1,returns:[124,127],
114
114
  locals:[127,127,127,127,127,127,127,127,127,127,127,127,127,127],localNames:["obj","obj#type","key","key#type","trueType","#last_type","hash","entryPtr","lastProto","lastProto#type","#logicinner_tmp","#typeswitch_tmp1","tail","get","#call_val","#call_type","#indirect_2_callee","#swap"],
115
115
  table:1,usesTag:1,
116
116
  }
117
117
  this.__Porffor_object_set = {
118
- wasm:(_,{i32ify,t,makeString,builtin,internalThrow})=>[[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,6],[33,1],[33,0],[32,1],[65,7],[71],[4,64],[32,4],[32,5],[15],[26],[11],[11],[32,0],[69],[4,64],...internalThrow(_,'TypeError',`Cannot set property of null`),[26],[11],[32,2],[32,3],[16,builtin('__Porffor_object_hash')],[33,7],[32,0],[32,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[70],[4,64],[32,7],[65,243,234,249,189,126],[70],[4,64],[32,2],[32,3],...i32ify(makeString(_,"__proto__",1)),[65,195,1],[16,builtin('__Porffor_strcmp')],[4,64],[32,0],[32,1],[32,4],[252,2],[32,5],[16,builtin('__Porffor_object_setPrototype')],[32,4],[32,5],[15],[26],[11],[11],[32,0],[32,1],[16,builtin('__Porffor_object_getPrototype')],[34,6],[33,11],[34,10],[33,12],[32,11],[33,13],[2,127],...t([0,128],()=>[[32,13],[69],[32,13],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),...t([7],()=>[[32,13],[65,7],[70],[4,64],[32,12],[69],[12,1],[11]]),[65,0],[11],[69],[4,64],[32,11],[65,7],[71],[4,64],[32,10],[183],[32,11],[16,builtin('__Porffor_object_underlying')],[34,6],[33,11],[33,10],[11],[32,10],[33,14],[32,11],[33,15],[3,64],[65,1],[4,64],[32,10],[32,11],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[71],[4,64],[12,1],[26],[11],[32,10],[32,11],[16,builtin('__Porffor_object_getPrototype')],[34,6],[33,11],[33,10],[32,11],[65,7],[71],[4,64],[32,10],[183],[32,11],[16,builtin('__Porffor_object_underlying')],[34,6],[33,11],[33,10],[11],[32,10],[33,12],[32,11],[33,13],[2,127],...t([0,128],()=>[[32,13],[69],[32,13],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),...t([7],()=>[[32,13],[65,7],[70],[4,64],[32,12],[69],[12,1],[11]]),[65,0],[11],[32,10],[32,14],[70],[114],[4,64],[12,1],[26],[11],[32,10],[33,14],[32,11],[33,15],[12,1],[11],[11],[32,8],[65,127],[71],[4,64],[32,8],[47,0,16],[34,16],[65,1],[113],[4,64],[32,8],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,6],[34,17],[69],[4,64],[32,4],[32,5],[15],[26],[11],[32,17],[33,20],[65,0],[65,128,1],[33,21],[183],[32,21],[32,0],[34,18],[32,1],[34,19],[33,21],[183],[32,21],[32,4],[32,5],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,20],[17,12,0],[33,6],[26],[32,4],[32,5],[15],[26],[11],[11],[11],[32,0],[32,1],[16,builtin('__Porffor_object_isInextensible')],[4,64],[32,4],[32,5],[15],[26],[11],[32,0],[47,0,0],[33,22],[32,0],[32,22],[65,1],[106],[59,0,0],[32,0],[65,8],[106],[32,22],[65,18],[108],[106],[34,8],[65,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_writeKey')],[65,14],[33,9],[5],[32,8],[47,0,16],[34,16],[65,1],[113],[4,64],[32,8],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,6],[34,17],[69],[4,64],[32,4],[32,5],[15],[26],[11],[32,17],[33,23],[65,0],[65,128,1],[33,21],[183],[32,21],[32,0],[34,18],[32,1],[34,19],[33,21],[183],[32,21],[32,4],[32,5],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,23],[17,12,0],[33,6],[26],[32,4],[32,5],[15],[26],[11],[32,16],[65,8],[113],[69],[4,64],[32,4],[32,5],[15],[26],[11],[32,16],[65,255,1],[113],[33,9],[11],[32,8],[32,4],[57,0,8],[32,8],[32,9],[32,5],[65,8],[116],[106],[59,0,16],[32,4],[32,5],[15]],
118
+ wasm:(_,{i32ify,t,makeString,builtin,internalThrow})=>[[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,6],[33,1],[33,0],[32,1],[65,7],[71],[4,64],[32,4],[32,5],[15],[26],[11],[11],[32,0],[69],[4,64],...internalThrow(_,'TypeError',`Cannot set property of null`),[26],[11],[32,2],[32,3],[16,builtin('__Porffor_object_hash')],[33,7],[32,0],[32,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[70],[4,64],[32,7],[65,248,187,246,154,2],[70],[4,64],[32,2],[32,3],...i32ify(makeString(_,"__proto__",1)),[65,195,1],[16,builtin('__Porffor_strcmp')],[4,64],[32,0],[32,1],[32,4],[252,2],[32,5],[16,builtin('__Porffor_object_setPrototype')],[32,4],[32,5],[15],[26],[11],[11],[32,0],[32,1],[16,builtin('__Porffor_object_getPrototype')],[34,6],[33,11],[34,10],[33,12],[32,11],[33,13],[2,127],...t([0,128],()=>[[32,13],[69],[32,13],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),...t([7],()=>[[32,13],[65,7],[70],[4,64],[32,12],[69],[12,1],[11]]),[65,0],[11],[69],[4,64],[32,11],[65,7],[71],[4,64],[32,10],[183],[32,11],[16,builtin('__Porffor_object_underlying')],[34,6],[33,11],[33,10],[11],[32,10],[33,14],[32,11],[33,15],[3,64],[65,1],[4,64],[32,10],[32,11],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[71],[4,64],[12,1],[26],[11],[32,10],[32,11],[16,builtin('__Porffor_object_getPrototype')],[34,6],[33,11],[33,10],[32,11],[65,7],[71],[4,64],[32,10],[183],[32,11],[16,builtin('__Porffor_object_underlying')],[34,6],[33,11],[33,10],[11],[32,10],[33,12],[32,11],[33,13],[2,127],...t([0,128],()=>[[32,13],[69],[32,13],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),...t([7],()=>[[32,13],[65,7],[70],[4,64],[32,12],[69],[12,1],[11]]),[65,0],[11],[32,10],[32,14],[70],[114],[4,64],[12,1],[26],[11],[32,10],[33,14],[32,11],[33,15],[12,1],[11],[11],[32,8],[65,127],[71],[4,64],[32,8],[47,0,16],[34,16],[65,1],[113],[4,64],[32,8],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,6],[34,17],[69],[4,64],[32,4],[32,5],[15],[26],[11],[32,17],[33,20],[65,0],[65,128,1],[33,21],[183],[32,21],[32,0],[34,18],[32,1],[34,19],[33,21],[183],[32,21],[32,4],[32,5],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,20],[17,12,0],[33,6],[26],[32,4],[32,5],[15],[26],[11],[11],[11],[32,0],[32,1],[16,builtin('__Porffor_object_isInextensible')],[4,64],[32,4],[32,5],[15],[26],[11],[32,0],[47,0,0],[33,22],[32,0],[32,22],[65,1],[106],[59,0,0],[32,0],[65,8],[106],[32,22],[65,18],[108],[106],[34,8],[65,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_writeKey')],[65,14],[33,9],[5],[32,8],[47,0,16],[34,16],[65,1],[113],[4,64],[32,8],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,6],[34,17],[69],[4,64],[32,4],[32,5],[15],[26],[11],[32,17],[33,23],[65,0],[65,128,1],[33,21],[183],[32,21],[32,0],[34,18],[32,1],[34,19],[33,21],[183],[32,21],[32,4],[32,5],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,23],[17,12,0],[33,6],[26],[32,4],[32,5],[15],[26],[11],[32,16],[65,8],[113],[69],[4,64],[32,4],[32,5],[15],[26],[11],[32,16],[65,255,1],[113],[33,9],[11],[32,8],[32,4],[57,0,8],[32,8],[32,9],[32,5],[65,8],[116],[106],[59,0,16],[32,4],[32,5],[15]],
119
119
  params:[127,127,127,127,124,127],typedParams:1,returns:[124,127],
120
120
  locals:[127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127],localNames:["obj","obj#type","key","key#type","value","value#type","#last_type","hash","entryPtr","flags","proto","proto#type","#logicinner_tmp","#typeswitch_tmp1","lastProto","lastProto#type","tail","set","#call_val","#call_type","#indirect_3_callee","#swap","size","#indirect_4_callee"],
121
121
  table:1,usesTag:1,
122
122
  }
123
123
  this.__Porffor_object_setStrict = {
124
- wasm:(_,{i32ify,t,makeString,builtin,internalThrow})=>[[32,0],[69],[4,64],...internalThrow(_,'TypeError',`Cannot set property of null`),[26],[11],[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,6],[33,1],[33,0],[32,1],[65,7],[71],[4,64],[32,4],[32,5],[15],[26],[11],[11],[32,2],[32,3],[16,builtin('__Porffor_object_hash')],[33,7],[32,0],[32,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[70],[4,64],[32,7],[65,243,234,249,189,126],[70],[4,64],[32,2],[32,3],...i32ify(makeString(_,"__proto__",1)),[65,195,1],[16,builtin('__Porffor_strcmp')],[4,64],[32,0],[32,1],[32,4],[252,2],[32,5],[16,builtin('__Porffor_object_setPrototype')],[32,4],[32,5],[15],[26],[11],[11],[32,0],[32,1],[16,builtin('__Porffor_object_getPrototype')],[34,6],[33,11],[34,10],[33,12],[32,11],[33,13],[2,127],...t([0,128],()=>[[32,13],[69],[32,13],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),...t([7],()=>[[32,13],[65,7],[70],[4,64],[32,12],[69],[12,1],[11]]),[65,0],[11],[69],[4,64],[32,11],[65,7],[71],[4,64],[32,10],[183],[32,11],[16,builtin('__Porffor_object_underlying')],[34,6],[33,11],[33,10],[11],[32,10],[33,14],[32,11],[33,15],[3,64],[65,1],[4,64],[32,10],[32,11],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[71],[4,64],[12,1],[26],[11],[32,10],[32,11],[16,builtin('__Porffor_object_getPrototype')],[34,6],[33,11],[33,10],[32,11],[65,7],[71],[4,64],[32,10],[183],[32,11],[16,builtin('__Porffor_object_underlying')],[34,6],[33,11],[33,10],[11],[32,10],[33,12],[32,11],[33,13],[2,127],...t([0,128],()=>[[32,13],[69],[32,13],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),...t([7],()=>[[32,13],[65,7],[70],[4,64],[32,12],[69],[12,1],[11]]),[65,0],[11],[32,10],[32,14],[70],[114],[4,64],[12,1],[26],[11],[32,10],[33,14],[32,11],[33,15],[12,1],[11],[11],[32,8],[65,127],[71],[4,64],[32,8],[47,0,16],[34,16],[65,1],[113],[4,64],[32,8],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,6],[34,17],[69],[4,64],[32,4],[32,5],[15],[26],[11],[32,17],[33,20],[65,0],[65,128,1],[33,21],[183],[32,21],[32,0],[34,18],[32,1],[34,19],[33,21],[183],[32,21],[32,4],[32,5],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,20],[17,12,0],[33,6],[26],[32,4],[32,5],[15],[26],[11],[11],[11],[32,0],[32,1],[16,builtin('__Porffor_object_isInextensible')],[4,64],...internalThrow(_,'TypeError',`Cannot add property to inextensible object`),[26],[11],[32,0],[47,0,0],[33,22],[32,0],[32,22],[65,1],[106],[59,0,0],[32,0],[65,8],[106],[32,22],[65,18],[108],[106],[34,8],[65,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_writeKey')],[65,14],[33,9],[5],[32,8],[47,0,16],[34,16],[65,1],[113],[4,64],[32,8],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,6],[34,17],[69],[4,64],...internalThrow(_,'TypeError',`Cannot set property with no setter of object`),[26],[11],[32,17],[33,23],[65,0],[65,128,1],[33,21],[183],[32,21],[32,0],[34,18],[32,1],[34,19],[33,21],[183],[32,21],[32,4],[32,5],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,23],[17,12,0],[33,6],[26],[32,4],[32,5],[15],[26],[11],[32,16],[65,8],[113],[69],[4,64],...internalThrow(_,'TypeError',`Cannot modify read-only property of object`),[26],[11],[32,16],[65,255,1],[113],[33,9],[11],[32,8],[32,4],[57,0,8],[32,8],[32,9],[32,5],[65,8],[116],[106],[59,0,16],[32,4],[32,5],[15]],
124
+ wasm:(_,{i32ify,t,makeString,builtin,internalThrow})=>[[32,0],[69],[4,64],...internalThrow(_,'TypeError',`Cannot set property of null`),[26],[11],[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,6],[33,1],[33,0],[32,1],[65,7],[71],[4,64],[32,4],[32,5],[15],[26],[11],[11],[32,2],[32,3],[16,builtin('__Porffor_object_hash')],[33,7],[32,0],[32,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[70],[4,64],[32,7],[65,248,187,246,154,2],[70],[4,64],[32,2],[32,3],...i32ify(makeString(_,"__proto__",1)),[65,195,1],[16,builtin('__Porffor_strcmp')],[4,64],[32,0],[32,1],[32,4],[252,2],[32,5],[16,builtin('__Porffor_object_setPrototype')],[32,4],[32,5],[15],[26],[11],[11],[32,0],[32,1],[16,builtin('__Porffor_object_getPrototype')],[34,6],[33,11],[34,10],[33,12],[32,11],[33,13],[2,127],...t([0,128],()=>[[32,13],[69],[32,13],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),...t([7],()=>[[32,13],[65,7],[70],[4,64],[32,12],[69],[12,1],[11]]),[65,0],[11],[69],[4,64],[32,11],[65,7],[71],[4,64],[32,10],[183],[32,11],[16,builtin('__Porffor_object_underlying')],[34,6],[33,11],[33,10],[11],[32,10],[33,14],[32,11],[33,15],[3,64],[65,1],[4,64],[32,10],[32,11],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[71],[4,64],[12,1],[26],[11],[32,10],[32,11],[16,builtin('__Porffor_object_getPrototype')],[34,6],[33,11],[33,10],[32,11],[65,7],[71],[4,64],[32,10],[183],[32,11],[16,builtin('__Porffor_object_underlying')],[34,6],[33,11],[33,10],[11],[32,10],[33,12],[32,11],[33,13],[2,127],...t([0,128],()=>[[32,13],[69],[32,13],[65,128,1],[70],[114],[4,64],[65,1],[12,1],[11]]),...t([7],()=>[[32,13],[65,7],[70],[4,64],[32,12],[69],[12,1],[11]]),[65,0],[11],[32,10],[32,14],[70],[114],[4,64],[12,1],[26],[11],[32,10],[33,14],[32,11],[33,15],[12,1],[11],[11],[32,8],[65,127],[71],[4,64],[32,8],[47,0,16],[34,16],[65,1],[113],[4,64],[32,8],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,6],[34,17],[69],[4,64],[32,4],[32,5],[15],[26],[11],[32,17],[33,20],[65,0],[65,128,1],[33,21],[183],[32,21],[32,0],[34,18],[32,1],[34,19],[33,21],[183],[32,21],[32,4],[32,5],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,20],[17,12,0],[33,6],[26],[32,4],[32,5],[15],[26],[11],[11],[11],[32,0],[32,1],[16,builtin('__Porffor_object_isInextensible')],[4,64],...internalThrow(_,'TypeError',`Cannot add property to inextensible object`),[26],[11],[32,0],[47,0,0],[33,22],[32,0],[32,22],[65,1],[106],[59,0,0],[32,0],[65,8],[106],[32,22],[65,18],[108],[106],[34,8],[65,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_writeKey')],[65,14],[33,9],[5],[32,8],[47,0,16],[34,16],[65,1],[113],[4,64],[32,8],[65,1],[16,builtin('__Porffor_object_accessorSet')],[33,6],[34,17],[69],[4,64],...internalThrow(_,'TypeError',`Cannot set property with no setter of object`),[26],[11],[32,17],[33,23],[65,0],[65,128,1],[33,21],[183],[32,21],[32,0],[34,18],[32,1],[34,19],[33,21],[183],[32,21],[32,4],[32,5],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[65,0],[183],[65,128,1],[32,23],[17,12,0],[33,6],[26],[32,4],[32,5],[15],[26],[11],[32,16],[65,8],[113],[69],[4,64],...internalThrow(_,'TypeError',`Cannot modify read-only property of object`),[26],[11],[32,16],[65,255,1],[113],[33,9],[11],[32,8],[32,4],[57,0,8],[32,8],[32,9],[32,5],[65,8],[116],[106],[59,0,16],[32,4],[32,5],[15]],
125
125
  params:[127,127,127,127,124,127],typedParams:1,returns:[124,127],
126
126
  locals:[127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127],localNames:["obj","obj#type","key","key#type","value","value#type","#last_type","hash","entryPtr","flags","proto","proto#type","#logicinner_tmp","#typeswitch_tmp1","lastProto","lastProto#type","tail","set","#call_val","#call_type","#indirect_5_callee","#swap","size","#indirect_6_callee"],
127
127
  table:1,usesTag:1,
@@ -150,7 +150,7 @@ params:[127,127],typedParams:1,returns:[127],returnType:2,
150
150
  locals:[],localNames:["entryPtr","entryPtr#type"],
151
151
  }
152
152
  this.__Porffor_object_expr_init = {
153
- wasm:(_,{i32ify,makeString,builtin})=>[[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,6],[33,1],[33,0],[11],[32,2],[32,3],[16,builtin('__Porffor_object_hash')],[33,7],[32,0],[32,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[70],[4,64],[32,7],[65,243,234,249,189,126],[70],[4,64],[32,2],[32,3],...i32ify(makeString(_,"__proto__",1)),[65,195,1],[16,builtin('__Porffor_strcmp')],[4,64],[32,0],[32,1],[32,4],[252,2],[32,5],[16,builtin('__Porffor_object_setPrototype')],[15],[26],[11],[11],[32,0],[47,0,0],[33,9],[32,0],[32,9],[65,1],[106],[59,0,0],[32,0],[65,8],[106],[32,9],[65,18],[108],[106],[34,8],[65,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_writeKey')],[11],[32,8],[32,4],[57,0,8],[32,8],[65,14],[32,5],[65,8],[116],[106],[59,0,16],[15]],
153
+ wasm:(_,{i32ify,makeString,builtin})=>[[32,1],[65,7],[71],[4,64],[32,0],[183],[32,1],[16,builtin('__Porffor_object_underlying')],[34,6],[33,1],[33,0],[11],[32,2],[32,3],[16,builtin('__Porffor_object_hash')],[33,7],[32,0],[32,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_lookup')],[34,8],[65,127],[70],[4,64],[32,7],[65,248,187,246,154,2],[70],[4,64],[32,2],[32,3],...i32ify(makeString(_,"__proto__",1)),[65,195,1],[16,builtin('__Porffor_strcmp')],[4,64],[32,0],[32,1],[32,4],[252,2],[32,5],[16,builtin('__Porffor_object_setPrototype')],[15],[26],[11],[11],[32,0],[47,0,0],[33,9],[32,0],[32,9],[65,1],[106],[59,0,0],[32,0],[65,8],[106],[32,9],[65,18],[108],[106],[34,8],[65,1],[32,2],[32,3],[32,7],[65,1],[16,builtin('__Porffor_object_writeKey')],[11],[32,8],[32,4],[57,0,8],[32,8],[65,14],[32,5],[65,8],[116],[106],[59,0,16],[15]],
154
154
  params:[127,127,127,127,124,127],typedParams:1,returns:[],returnType:128,
155
155
  locals:[127,127,127,127],localNames:["obj","obj#type","key","key#type","value","value#type","#last_type","hash","entryPtr","size"],
156
156
  }
@@ -1391,7 +1391,18 @@ const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTy
1391
1391
  }
1392
1392
 
1393
1393
  if (table) funcs.table = true;
1394
- if (usesTag) ensureTag();
1394
+ if (usesTag) {
1395
+ if (Prefs.wasmExceptions === false) {
1396
+ for (let i = 0; i < wasm.length; i++) {
1397
+ const inst = wasm[i];
1398
+ if (inst[0] === Opcodes.throw) {
1399
+ wasm.splice(i, 1, ...generateThrow(func, {}));
1400
+ }
1401
+ }
1402
+ } else {
1403
+ ensureTag();
1404
+ }
1405
+ }
1395
1406
 
1396
1407
  if (returnTypes) {
1397
1408
  for (const x of returnTypes) typeUsed(func, x);
@@ -5279,6 +5290,14 @@ const ensureTag = (exceptionMode = Prefs.exceptionMode ?? 'stack') => {
5279
5290
  };
5280
5291
 
5281
5292
  const generateThrow = (scope, decl) => {
5293
+ if (Prefs.wasmExceptions === false) {
5294
+ return [
5295
+ ...(scope.returns.length === 0 ? [] : [ number(0, scope.returns[0]) ]),
5296
+ ...(scope.returns.length === 0 || scope.returnType != null ? [] : [ number(0, scope.returns[1]) ]),
5297
+ [ Opcodes.return ]
5298
+ ];
5299
+ }
5300
+
5282
5301
  let exceptionMode = Prefs.exceptionMode ?? 'stack';
5283
5302
  if (globalThis.precompile) exceptionMode = decl.argument.callee != null ? 'lut' : 'stack';
5284
5303
  ensureTag(exceptionMode);
@@ -6392,6 +6411,11 @@ const generateTaggedTemplate = (scope, decl, global = false, name = undefined, v
6392
6411
  return funcIndex[x];
6393
6412
  }
6394
6413
 
6414
+ if (Object.hasOwn(importedFuncs, x)) {
6415
+ scope.usesImports = true;
6416
+ return importedFuncs[x];
6417
+ }
6418
+
6395
6419
  return scope.locals[x]?.idx ?? globals[x]?.idx ?? (log.warning('codegen', `unknown immediate in Porffor.wasm: ${x}`) || 0);
6396
6420
  }
6397
6421
 
package/compiler/index.js CHANGED
@@ -33,6 +33,7 @@ let progressLines = 0, progressInterval;
33
33
  let spinner = ['-', '\\', '|', '/'], spin = 0;
34
34
  const progressStart = msg => {
35
35
  if (globalThis.onProgress) return;
36
+ if (!process.stdout.isTTY) return;
36
37
 
37
38
  const log = (extra, after) => {
38
39
  const pre = extra ? `${extra}` : spinner[spin++ % 4];
@@ -49,11 +50,12 @@ const progressDone = (msg, start) => {
49
50
  clearInterval(progressInterval);
50
51
 
51
52
  const timeStr = (performance.now() - start).toFixed(0);
52
- console.log(`\r${' '.repeat(60)}\r\u001b[2m${' '.repeat(10 - timeStr.length)}${timeStr}ms\u001b[0m \u001b[92m${msg}\u001b[0m`);
53
+ console.log(`${process.stdout.isTTY ? `\r${' '.repeat(60)}\r` : ''}\u001b[2m${' '.repeat(10 - timeStr.length)}${timeStr}ms\u001b[0m \u001b[92m${msg}\u001b[0m`);
53
54
  progressLines++;
54
55
  };
55
56
  const progressClear = () => {
56
57
  if (globalThis.onProgress) return;
58
+ if (!process.stdout.isTTY) return;
57
59
 
58
60
  process.stdout.write(`\u001b[${progressLines}F\u001b[0J`);
59
61
  progressLines = 0;
package/compiler/log.js CHANGED
@@ -12,5 +12,5 @@ const areaColors = {
12
12
  wrap: [ 250, 100, 20 ]
13
13
  };
14
14
 
15
- export const log = (area, ...args) => console.log(`\u001b[90m[\u001b[0m${rgb(...areaColors[area], area)}\u001b[90m]\u001b[0m`, ...args);
15
+ export const log = (area, ...args) => console.log(`\u001b[90m[\u001b[0m${rgb(...areaColors[area] ?? areaColors.parse, area)}\u001b[90m]\u001b[0m`, ...args);
16
16
  log.warning = (area, ...args) => log(area, '\u001b[93m' + args[0], ...args.slice(1), '\u001b[0m');
package/foo.js CHANGED
@@ -1,17 +1 @@
1
- import compile from './compiler/wrap.js';
2
- import { Worker, isMainThread } from 'node:worker_threads';
3
-
4
- import { join } from 'node:path';
5
- const __dirname = import.meta.dirname;
6
- const __filename = join(__dirname, 'foo.js');
7
-
8
- if (isMainThread) {
9
- const worker = new Worker(__filename);
10
- } else {
11
- for (let i = 0; i < 500; i++) {
12
- const js = `console.log(globalThis);`;
13
- const out = compile(js);
14
- out.exports.main();
15
- console.log(i);
16
- }
17
- }
1
+ console.log(await Promise.resolve(5));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "An ahead-of-time JavaScript compiler",
4
- "version": "0.57.21",
4
+ "version": "0.57.22",
5
5
  "author": "Oliver Medhurst <honk@goose.icu>",
6
6
  "license": "MIT",
7
7
  "scripts": {},
@@ -0,0 +1,558 @@
1
+ // Copyright 2006-2008 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ // This is a JavaScript implementation of the Richards
29
+ // benchmark from:
30
+ //
31
+ // http://www.cl.cam.ac.uk/~mr10/Bench.html
32
+ //
33
+ // The benchmark was originally implemented in BCPL by
34
+ // Martin Richards.
35
+
36
+ /**
37
+ * The Richards benchmark simulates the task dispatcher of an
38
+ * operating system.
39
+ **/
40
+ function runRichards() {
41
+ var scheduler = new Scheduler();
42
+ scheduler_addIdleTask.call(scheduler, ID_IDLE, 0, null, COUNT);
43
+
44
+ var queue = new Packet(null, ID_WORKER, KIND_WORK);
45
+ queue = new Packet(queue, ID_WORKER, KIND_WORK);
46
+ scheduler_addWorkerTask.call(scheduler, ID_WORKER, 1000, queue);
47
+
48
+ queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE);
49
+ queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
50
+ queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
51
+ scheduler_addHandlerTask.call(scheduler, ID_HANDLER_A, 2000, queue);
52
+
53
+ queue = new Packet(null, ID_DEVICE_B, KIND_DEVICE);
54
+ queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
55
+ queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
56
+ scheduler_addHandlerTask.call(scheduler, ID_HANDLER_B, 3000, queue);
57
+
58
+ scheduler_addDeviceTask.call(scheduler, ID_DEVICE_A, 4000, null);
59
+
60
+ scheduler_addDeviceTask.call(scheduler, ID_DEVICE_B, 5000, null);
61
+
62
+ scheduler_schedule.call(scheduler);
63
+
64
+ if (scheduler.queueCount != EXPECTED_QUEUE_COUNT || scheduler.holdCount != EXPECTED_HOLD_COUNT) {
65
+ var msg =
66
+ "Error during execution: queueCount = " + scheduler.queueCount + ", holdCount = " + scheduler.holdCount + ".";
67
+ throw new Error(msg);
68
+ }
69
+ }
70
+
71
+ var COUNT = 1000;
72
+
73
+ /**
74
+ * These two constants specify how many times a packet is queued and
75
+ * how many times a task is put on hold in a correct run of richards.
76
+ * They don't have any meaning a such but are characteristic of a
77
+ * correct run so if the actual queue or hold count is different from
78
+ * the expected there must be a bug in the implementation.
79
+ **/
80
+ var EXPECTED_QUEUE_COUNT = 2322;
81
+ var EXPECTED_HOLD_COUNT = 928;
82
+
83
+ /**
84
+ * A scheduler can be used to schedule a set of tasks based on their relative
85
+ * priorities. Scheduling is done by maintaining a list of task control blocks
86
+ * which holds tasks and the data queue they are processing.
87
+ * @constructor
88
+ */
89
+ function Scheduler() {
90
+ this.queueCount = 0;
91
+ this.holdCount = 0;
92
+ this.blocks = new Array(NUMBER_OF_IDS);
93
+ this.list = null;
94
+ this.currentTcb = null;
95
+ this.currentId = null;
96
+ }
97
+
98
+ var ID_IDLE = 0;
99
+ var ID_WORKER = 1;
100
+ var ID_HANDLER_A = 2;
101
+ var ID_HANDLER_B = 3;
102
+ var ID_DEVICE_A = 4;
103
+ var ID_DEVICE_B = 5;
104
+ var NUMBER_OF_IDS = 6;
105
+
106
+ var KIND_DEVICE = 0;
107
+ var KIND_WORK = 1;
108
+
109
+ /**
110
+ * Add an idle task to this scheduler.
111
+ * @param {int} id the identity of the task
112
+ * @param {int} priority the task's priority
113
+ * @param {Packet} queue the queue of work to be processed by the task
114
+ * @param {int} count the number of times to schedule the task
115
+ */
116
+ function scheduler_addIdleTask(id, priority, queue, count) {
117
+ scheduler_addRunningTask.call(this, id, priority, queue, new IdleTask(this, 1, count));
118
+ };
119
+
120
+ /**
121
+ * Add a work task to this scheduler.
122
+ * @param {int} id the identity of the task
123
+ * @param {int} priority the task's priority
124
+ * @param {Packet} queue the queue of work to be processed by the task
125
+ */
126
+ function scheduler_addWorkerTask(id, priority, queue) {
127
+ scheduler_addTask.call(this, id, priority, queue, new WorkerTask(this, ID_HANDLER_A, 0));
128
+ };
129
+
130
+ /**
131
+ * Add a handler task to this scheduler.
132
+ * @param {int} id the identity of the task
133
+ * @param {int} priority the task's priority
134
+ * @param {Packet} queue the queue of work to be processed by the task
135
+ */
136
+ function scheduler_addHandlerTask(id, priority, queue) {
137
+ scheduler_addTask.call(this, id, priority, queue, new HandlerTask(this));
138
+ };
139
+
140
+ /**
141
+ * Add a handler task to this scheduler.
142
+ * @param {int} id the identity of the task
143
+ * @param {int} priority the task's priority
144
+ * @param {Packet} queue the queue of work to be processed by the task
145
+ */
146
+ function scheduler_addDeviceTask(id, priority, queue) {
147
+ scheduler_addTask.call(this, id, priority, queue, new DeviceTask(this));
148
+ };
149
+
150
+ /**
151
+ * Add the specified task and mark it as running.
152
+ * @param {int} id the identity of the task
153
+ * @param {int} priority the task's priority
154
+ * @param {Packet} queue the queue of work to be processed by the task
155
+ * @param {Task} task the task to add
156
+ */
157
+ function scheduler_addRunningTask(id, priority, queue, task) {
158
+ scheduler_addTask.call(this, id, priority, queue, task);
159
+ tcb_setRunning.call(this.currentTcb);
160
+ };
161
+
162
+ /**
163
+ * Add the specified task to this scheduler.
164
+ * @param {int} id the identity of the task
165
+ * @param {int} priority the task's priority
166
+ * @param {Packet} queue the queue of work to be processed by the task
167
+ * @param {Task} task the task to add
168
+ */
169
+ function scheduler_addTask(id, priority, queue, task) {
170
+ this.currentTcb = new TaskControlBlock(this.list, id, priority, queue, task);
171
+ this.list = this.currentTcb;
172
+ this.blocks[id] = this.currentTcb;
173
+ };
174
+
175
+ /**
176
+ * Execute the tasks managed by this scheduler.
177
+ */
178
+ function scheduler_schedule() {
179
+ this.currentTcb = this.list;
180
+ while (this.currentTcb != null) {
181
+ if (tcb_isHeldOrSuspended.call(this.currentTcb)) {
182
+ this.currentTcb = this.currentTcb.link;
183
+ } else {
184
+ this.currentId = this.currentTcb.id;
185
+ this.currentTcb = tcb_run.call(this.currentTcb);
186
+ }
187
+ }
188
+ };
189
+
190
+ /**
191
+ * Release a task that is currently blocked and return the next block to run.
192
+ * @param {int} id the id of the task to suspend
193
+ */
194
+ function scheduler_release(id) {
195
+ var tcb = this.blocks[id];
196
+ if (tcb == null) return tcb;
197
+ tcb_markAsNotHeld.call(tcb);
198
+ if (tcb.priority > this.currentTcb.priority) {
199
+ return tcb;
200
+ } else {
201
+ return this.currentTcb;
202
+ }
203
+ };
204
+
205
+ /**
206
+ * Block the currently executing task and return the next task control block
207
+ * to run. The blocked task will not be made runnable until it is explicitly
208
+ * released, even if new work is added to it.
209
+ */
210
+ function scheduler_holdCurrent() {
211
+ this.holdCount++;
212
+ tcb_markAsHeld.call(this.currentTcb);
213
+ return this.currentTcb.link;
214
+ };
215
+
216
+ /**
217
+ * Suspend the currently executing task and return the next task control block
218
+ * to run. If new work is added to the suspended task it will be made runnable.
219
+ */
220
+ function scheduler_suspendCurrent() {
221
+ tcb_markAsSuspended.call(this.currentTcb);
222
+ return this.currentTcb;
223
+ };
224
+
225
+ /**
226
+ * Add the specified packet to the end of the worklist used by the task
227
+ * associated with the packet and make the task runnable if it is currently
228
+ * suspended.
229
+ * @param {Packet} packet the packet to add
230
+ */
231
+ function scheduler_queue(packet) {
232
+ var t = this.blocks[packet.id];
233
+ if (t == null) return t;
234
+ this.queueCount++;
235
+ packet.link = null;
236
+ packet.id = this.currentId;
237
+ return tcb_checkPriorityAdd.call(t, this.currentTcb, packet);
238
+ };
239
+
240
+ /**
241
+ * A task control block manages a task and the queue of work packages associated
242
+ * with it.
243
+ * @param {TaskControlBlock} link the preceding block in the linked block list
244
+ * @param {int} id the id of this block
245
+ * @param {int} priority the priority of this block
246
+ * @param {Packet} queue the queue of packages to be processed by the task
247
+ * @param {Task} task the task
248
+ * @constructor
249
+ */
250
+ function TaskControlBlock(link, id, priority, queue, task) {
251
+ this.link = link;
252
+ this.id = id;
253
+ this.priority = priority;
254
+ this.queue = queue;
255
+ this.task = task;
256
+ if (queue == null) {
257
+ this.state = STATE_SUSPENDED;
258
+ } else {
259
+ this.state = STATE_SUSPENDED_RUNNABLE;
260
+ }
261
+ }
262
+
263
+ /**
264
+ * The task is running and is currently scheduled.
265
+ */
266
+ var STATE_RUNNING = 0;
267
+
268
+ /**
269
+ * The task has packets left to process.
270
+ */
271
+ var STATE_RUNNABLE = 1;
272
+
273
+ /**
274
+ * The task is not currently running. The task is not blocked as such and may
275
+ * be started by the scheduler.
276
+ */
277
+ var STATE_SUSPENDED = 2;
278
+
279
+ /**
280
+ * The task is blocked and cannot be run until it is explicitly released.
281
+ */
282
+ var STATE_HELD = 4;
283
+
284
+ var STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE;
285
+ var STATE_NOT_HELD = ~STATE_HELD;
286
+
287
+ function tcb_setRunning() {
288
+ this.state = STATE_RUNNING;
289
+ };
290
+
291
+ function tcb_markAsNotHeld() {
292
+ this.state = this.state & STATE_NOT_HELD;
293
+ };
294
+
295
+ function tcb_markAsHeld() {
296
+ this.state = this.state | STATE_HELD;
297
+ };
298
+
299
+ function tcb_isHeldOrSuspended() {
300
+ return (this.state & STATE_HELD) != 0 || this.state == STATE_SUSPENDED;
301
+ };
302
+
303
+ function tcb_markAsSuspended() {
304
+ this.state = this.state | STATE_SUSPENDED;
305
+ };
306
+
307
+ function tcb_markAsRunnable() {
308
+ this.state = this.state | STATE_RUNNABLE;
309
+ };
310
+
311
+ /**
312
+ * Runs this task, if it is ready to be run, and returns the next task to run.
313
+ */
314
+ function tcb_run() {
315
+ var packet;
316
+ if (this.state == STATE_SUSPENDED_RUNNABLE) {
317
+ packet = this.queue;
318
+ this.queue = packet.link;
319
+ if (this.queue == null) {
320
+ this.state = STATE_RUNNING;
321
+ } else {
322
+ this.state = STATE_RUNNABLE;
323
+ }
324
+ } else {
325
+ packet = null;
326
+ }
327
+ // Note: This remains a dynamic dispatch call as the task type isn't
328
+ // known statically here.
329
+ return this.task.run(packet);
330
+ };
331
+
332
+ /**
333
+ * Adds a packet to the worklist of this block's task, marks this as runnable if
334
+ * necessary, and returns the next runnable object to run (the one
335
+ * with the highest priority).
336
+ */
337
+ function tcb_checkPriorityAdd(task, packet) {
338
+ if (this.queue == null) {
339
+ this.queue = packet;
340
+ tcb_markAsRunnable.call(this);
341
+ if (this.priority > task.priority) return this;
342
+ } else {
343
+ this.queue = packet_addTo.call(packet, this.queue);
344
+ }
345
+ return task;
346
+ };
347
+
348
+ function tcb_toString() {
349
+ return "tcb { " + this.task + "@" + this.state + " }";
350
+ };
351
+
352
+ /**
353
+ * An idle task doesn't do any work itself but cycles control between the two
354
+ * device tasks.
355
+ * @param {Scheduler} scheduler the scheduler that manages this task
356
+ * @param {int} v1 a seed value that controls how the device tasks are scheduled
357
+ * @param {int} count the number of times this task should be scheduled
358
+ * @constructor
359
+ */
360
+ function IdleTask(scheduler, v1, count) {
361
+ this.scheduler = scheduler;
362
+ this.v1 = v1;
363
+ this.count = count;
364
+ }
365
+
366
+ function idleTask_run(packet) {
367
+ this.count--;
368
+ if (this.count == 0) return scheduler_holdCurrent.call(this.scheduler);
369
+ if ((this.v1 & 1) == 0) {
370
+ this.v1 = this.v1 >> 1;
371
+ return scheduler_release.call(this.scheduler, ID_DEVICE_A);
372
+ } else {
373
+ this.v1 = (this.v1 >> 1) ^ 0xd008;
374
+ return scheduler_release.call(this.scheduler, ID_DEVICE_B);
375
+ }
376
+ };
377
+ // Assign the run method to the prototype for dynamic dispatch in tcb_run
378
+ IdleTask.prototype.run = idleTask_run;
379
+
380
+
381
+ function idleTask_toString() {
382
+ return "IdleTask";
383
+ };
384
+ IdleTask.prototype.toString = idleTask_toString;
385
+
386
+ /**
387
+ * A task that suspends itself after each time it has been run to simulate
388
+ * waiting for data from an external device.
389
+ * @param {Scheduler} scheduler the scheduler that manages this task
390
+ * @constructor
391
+ */
392
+ function DeviceTask(scheduler) {
393
+ this.scheduler = scheduler;
394
+ this.v1 = null;
395
+ }
396
+
397
+ function deviceTask_run(packet) {
398
+ if (packet == null) {
399
+ if (this.v1 == null) return scheduler_suspendCurrent.call(this.scheduler);
400
+ var v = this.v1;
401
+ this.v1 = null;
402
+ return scheduler_queue.call(this.scheduler, v);
403
+ } else {
404
+ this.v1 = packet;
405
+ return scheduler_holdCurrent.call(this.scheduler);
406
+ }
407
+ };
408
+ // Assign the run method to the prototype for dynamic dispatch in tcb_run
409
+ DeviceTask.prototype.run = deviceTask_run;
410
+
411
+
412
+ function deviceTask_toString() {
413
+ return "DeviceTask";
414
+ };
415
+ DeviceTask.prototype.toString = deviceTask_toString;
416
+
417
+ /**
418
+ * A task that manipulates work packets.
419
+ * @param {Scheduler} scheduler the scheduler that manages this task
420
+ * @param {int} v1 a seed used to specify how work packets are manipulated
421
+ * @param {int} v2 another seed used to specify how work packets are manipulated
422
+ * @constructor
423
+ */
424
+ function WorkerTask(scheduler, v1, v2) {
425
+ this.scheduler = scheduler;
426
+ this.v1 = v1;
427
+ this.v2 = v2;
428
+ }
429
+
430
+ function workerTask_run(packet) {
431
+ if (packet == null) {
432
+ return scheduler_suspendCurrent.call(this.scheduler);
433
+ } else {
434
+ if (this.v1 == ID_HANDLER_A) {
435
+ this.v1 = ID_HANDLER_B;
436
+ } else {
437
+ this.v1 = ID_HANDLER_A;
438
+ }
439
+ packet.id = this.v1;
440
+ packet.a1 = 0;
441
+ for (var i = 0; i < DATA_SIZE; i++) {
442
+ this.v2++;
443
+ if (this.v2 > 26) this.v2 = 1;
444
+ packet.a2[i] = this.v2;
445
+ }
446
+ return scheduler_queue.call(this.scheduler, packet);
447
+ }
448
+ };
449
+ // Assign the run method to the prototype for dynamic dispatch in tcb_run
450
+ WorkerTask.prototype.run = workerTask_run;
451
+
452
+
453
+ function workerTask_toString() {
454
+ return "WorkerTask";
455
+ };
456
+ WorkerTask.prototype.toString = workerTask_toString;
457
+
458
+ /**
459
+ * A task that manipulates work packets and then suspends itself.
460
+ * @param {Scheduler} scheduler the scheduler that manages this task
461
+ * @constructor
462
+ */
463
+ function HandlerTask(scheduler) {
464
+ this.scheduler = scheduler;
465
+ this.v1 = null;
466
+ this.v2 = null;
467
+ }
468
+
469
+ function handlerTask_run(packet) {
470
+ if (packet != null) {
471
+ if (packet.kind == KIND_WORK) {
472
+ this.v1 = packet_addTo.call(packet, this.v1);
473
+ } else {
474
+ this.v2 = packet_addTo.call(packet, this.v2);
475
+ }
476
+ }
477
+ if (this.v1 != null) {
478
+ var count = this.v1.a1;
479
+ var v;
480
+ if (count < DATA_SIZE) {
481
+ if (this.v2 != null) {
482
+ v = this.v2;
483
+ this.v2 = this.v2.link;
484
+ v.a1 = this.v1.a2[count];
485
+ this.v1.a1 = count + 1;
486
+ return scheduler_queue.call(this.scheduler, v);
487
+ }
488
+ } else {
489
+ v = this.v1;
490
+ this.v1 = this.v1.link;
491
+ return scheduler_queue.call(this.scheduler, v);
492
+ }
493
+ }
494
+ return scheduler_suspendCurrent.call(this.scheduler);
495
+ };
496
+ // Assign the run method to the prototype for dynamic dispatch in tcb_run
497
+ HandlerTask.prototype.run = handlerTask_run;
498
+
499
+
500
+ function handlerTask_toString() {
501
+ return "HandlerTask";
502
+ };
503
+ HandlerTask.prototype.toString = handlerTask_toString;
504
+
505
+
506
+ /* --- *
507
+ * P a c k e t
508
+ * --- */
509
+
510
+ var DATA_SIZE = 4;
511
+
512
+ /**
513
+ * A simple package of data that is manipulated by the tasks. The exact layout
514
+ * of the payload data carried by a packet is not importaint, and neither is the
515
+ * nature of the work performed on packets by the tasks.
516
+ *
517
+ * Besides carrying data, packets form linked lists and are hence used both as
518
+ * data and worklists.
519
+ * @param {Packet} link the tail of the linked list of packets
520
+ * @param {int} id an ID for this packet
521
+ * @param {int} kind the type of this packet
522
+ * @constructor
523
+ */
524
+ function Packet(link, id, kind) {
525
+ this.link = link;
526
+ this.id = id;
527
+ this.kind = kind;
528
+ this.a1 = 0;
529
+ this.a2 = new Array(DATA_SIZE);
530
+ }
531
+
532
+ /**
533
+ * Add this packet to the end of a worklist, and return the worklist.
534
+ * @param {Packet} queue the worklist to add this packet to
535
+ */
536
+ function packet_addTo(queue) {
537
+ this.link = null;
538
+ if (queue == null) return this;
539
+ var peek,
540
+ next = queue;
541
+ while ((peek = next.link) != null) next = peek;
542
+ next.link = this;
543
+ return queue;
544
+ };
545
+
546
+
547
+ function packet_toString() {
548
+ return "Packet";
549
+ };
550
+ Packet.prototype.toString = packet_toString;
551
+
552
+
553
+ const start = Date.now();
554
+ for (let i = 0; i < 100; i++) {
555
+ runRichards();
556
+ }
557
+
558
+ console.log(Date.now() - start);
package/runtime/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.57.21';
3
+ globalThis.version = '0.57.22';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
package/r.js DELETED
@@ -1,243 +0,0 @@
1
- function isConfigurable(obj, name) {
2
- if (Object.hasOwn(obj, name)) return Object.getOwnPropertyDescriptor(obj, name).configurable;
3
- return true;
4
- }
5
-
6
- function isEnumerable(obj, name) {
7
- return Object.hasOwn(obj, name) && Object.getOwnPropertyDescriptor(obj, name).enumerable;
8
- }
9
-
10
- function isSameValue(a, b) {
11
- if (a === 0 && b === 0) return 1 / a === 1 / b;
12
- if (a !== a && b !== b) return true;
13
-
14
- return a === b;
15
- }
16
-
17
- function isWritable(obj, name, verifyProp, value) {
18
- if (Object.hasOwn(obj, name) && Object.getOwnPropertyDescriptor(obj, name).writable != null) return Object.getOwnPropertyDescriptor(obj, name).writable;
19
- if (!Object.hasOwn(obj, name) && Object.isExtensible(obj)) return true;
20
-
21
- var unlikelyValue = Array.isArray(obj) && name === "length" ?
22
- Math.pow(2, 32) - 1 :
23
- "unlikelyValue";
24
- var newValue = value || unlikelyValue;
25
- var hadValue = Object.hasOwn(obj, name);
26
- var oldValue = obj[name];
27
- var writeSucceeded;
28
-
29
- try {
30
- obj[name] = newValue;
31
- } catch {}
32
-
33
- writeSucceeded = isSameValue(obj[verifyProp || name], newValue);
34
-
35
- if (writeSucceeded) {
36
- if (hadValue) {
37
- obj[name] = oldValue;
38
- } else {
39
- delete obj[name];
40
- }
41
- }
42
-
43
- return writeSucceeded;
44
- }
45
-
46
- function verifyProperty(obj, name, desc, options) {
47
- var originalDesc = Object.getOwnPropertyDescriptor(obj, name);
48
-
49
- if (desc === undefined) {
50
- if (originalDesc !== undefined) {
51
- throw new Test262Error('verifyProperty: expected undefined descriptor');
52
- }
53
-
54
- return true;
55
- }
56
-
57
- if (!Object.hasOwn(obj, name)) throw new Test262Error('verifyProperty: obj should have own property');
58
-
59
- if (Object.hasOwn(desc, 'value')) {
60
- const v = desc.value;
61
- if (!isSameValue(originalDesc.value, v)) throw new Test262Error('verifyProperty: descriptor value mismatch');
62
- // if (!isSameValue(obj[name], v)) throw new Test262Error('verifyProperty: object value mismatch');
63
- }
64
-
65
- if (Object.hasOwn(desc, 'enumerable')) {
66
- if (desc.enumerable !== originalDesc.enumerable ||
67
- desc.enumerable !== isEnumerable(obj, name)) {
68
- throw new Test262Error('enumerable fail');
69
- }
70
- }
71
-
72
- if (Object.hasOwn(desc, 'writable')) {
73
- if (desc.writable !== originalDesc.writable ||
74
- desc.writable !== isWritable(obj, name)) {
75
- throw new Test262Error('writable fail');
76
- }
77
- }
78
-
79
- if (Object.hasOwn(desc, 'configurable')) {
80
- if (desc.configurable !== originalDesc.configurable ||
81
- desc.configurable !== isConfigurable(obj, name)) {
82
- throw new Test262Error('configurable fail');
83
- }
84
- }
85
-
86
- if (options && options.restore) {
87
- Object.defineProperty(obj, name, originalDesc);
88
- }
89
-
90
- return true;
91
- }
92
-
93
- function verifyEqualTo(obj, name, value) {
94
- if (!isSameValue(obj[name], value)) {
95
- throw new Test262Error('propertyHelper verifyEqualTo failed');
96
- }
97
- }
98
-
99
- function verifyWritable(obj, name, verifyProp, value) {
100
- if (!verifyProp) {
101
- if (!Object.getOwnPropertyDescriptor(obj, name).writable)
102
- throw new Test262Error('propertyHelper verifyWritable failed');
103
- }
104
-
105
- if (!isWritable(obj, name, verifyProp, value)) {
106
- throw new Test262Error('propertyHelper verifyWritable failed');
107
- }
108
- }
109
-
110
- function verifyNotWritable(obj, name, verifyProp, value) {
111
- if (!verifyProp) {
112
- if (Object.getOwnPropertyDescriptor(obj, name).writable)
113
- throw new Test262Error('propertyHelper verifyNotWritable failed');
114
- }
115
-
116
- if (isWritable(obj, name, verifyProp)) {
117
- throw new Test262Error('propertyHelper verifyNotWritable failed');
118
- }
119
- }
120
-
121
- function verifyEnumerable(obj, name) {
122
- if (!isEnumerable(obj, name)) {
123
- throw new Test262Error('propertyHelper verifyEnumerable failed');
124
- }
125
- }
126
-
127
- function verifyNotEnumerable(obj, name) {
128
- if (isEnumerable(obj, name)) {
129
- throw new Test262Error('propertyHelper verifyNotEnumerable failed');
130
- }
131
- }
132
-
133
- function verifyConfigurable(obj, name) {
134
- if (!isConfigurable(obj, name)) {
135
- throw new Test262Error('propertyHelper verifyConfigurable failed');
136
- }
137
- }
138
-
139
- function verifyNotConfigurable(obj, name) {
140
- if (isConfigurable(obj, name)) {
141
- throw new Test262Error('propertyHelper verifyNotConfigurable failed');
142
- }
143
- }
144
- var assert = mustBeTrue => {
145
- if (mustBeTrue === true) {
146
- return;
147
- }
148
-
149
- throw new Test262Error('assert failed');
150
- };
151
- assert; // idk why exactly but this fixes many tests by forcing indirect ref
152
-
153
- var __assert_throws = (expectedErrorConstructor, func) => {
154
- if (typeof func !== 'function') {
155
- throw new Test262Error('assert.throws invoked with a non-function value');
156
- }
157
-
158
- try {
159
- func();
160
- } catch {
161
- return;
162
- }
163
-
164
- throw new Test262Error('assert.throws failed');
165
- };
166
-
167
- var __assert__isSameValue = (a, b) => {
168
- if (a === b) {
169
- // Handle +/-0 vs. -/+0
170
- return a !== 0 || 1 / a === 1 / b;
171
- }
172
-
173
- // Handle NaN vs. NaN
174
- return a !== a && b !== b;
175
- };
176
-
177
- var __assert_sameValue = (actual, expected) => {
178
- if (assert._isSameValue(actual, expected)) {
179
- return;
180
- }
181
-
182
- throw new Test262Error('assert.sameValue failed');
183
- };
184
-
185
- var __assert_notSameValue = (actual, unexpected) => {
186
- if (!assert._isSameValue(actual, unexpected)) {
187
- return;
188
- }
189
-
190
- throw new Test262Error('assert.notSameValue failed');
191
- };
192
- // define our $262 here too
193
- // var $262 = {
194
- // global: globalThis,
195
- // gc() { /* noop */ },
196
- // detachArrayBuffer(buffer) {
197
- // return Porffor.arraybuffer.detach(buffer);
198
- // },
199
- // getGlobal(name) {
200
- // return globalThis[name];
201
- // },
202
- // // todo: setGlobal
203
- // destroy() { /* noop */ },
204
- // agent: {}
205
- // };
206
-
207
- // function Test262Error(message) {
208
- // this.message = message;
209
- // this.name = 'Test262Error';
210
- // }
211
-
212
- // var __Test262Error_thrower = message => {
213
- // throw new Test262Error(message);
214
- // };
215
-
216
- var $DONOTEVALUATE = () => {
217
- throw 'Test262: This statement should not be evaluated.';
218
- };
219
- // Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
220
- // This code is governed by the BSD license found in the LICENSE file.
221
- /*---
222
- esid: sec-array-constructor
223
- description: >
224
- Property descriptor of Array
225
- info: |
226
- 22.1.1 The Array Constructor
227
-
228
- * is the initial value of the Array property of the global object.
229
-
230
- 17 ECMAScript Standard Built-in Objects
231
-
232
- Every other data property described in clauses 18 through 26 and in Annex B.2
233
- has the attributes { [[Writable]]: true, [[Enumerable]]: false,
234
- [[Configurable]]: true } unless otherwise specified.
235
- includes: [propertyHelper.js]
236
- ---*/
237
-
238
- verifyProperty(this, 'Array', {
239
- value: Array,
240
- writable: true,
241
- enumerable: false,
242
- configurable: true,
243
- });