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.
- package/compiler/builtins/_internal_object.ts +58 -55
- package/compiler/builtins_precompiled.js +6 -6
- package/compiler/codegen.js +25 -1
- package/compiler/index.js +3 -1
- package/compiler/log.js +1 -1
- package/foo.js +1 -17
- package/package.json +1 -1
- package/richards_direct.js +558 -0
- package/runtime/index.js +1 -1
- package/r.js +0 -243
@@ -25,76 +25,79 @@ export const __Porffor_object_hash = (key: any): i32 => {
|
|
25
25
|
return 0;
|
26
26
|
}
|
27
27
|
|
28
|
-
// bytestring or string,
|
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
|
34
|
-
|
35
|
-
|
36
|
-
let hash: i32 =
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
43
|
-
local.get
|
44
|
-
|
45
|
-
|
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
|
-
|
57
|
-
i32.
|
58
|
-
i32.
|
59
|
-
i32.const 16777619
|
45
|
+
i32.add
|
46
|
+
i32.const 17
|
47
|
+
i32.rotl
|
48
|
+
i32.const 668265263
|
60
49
|
i32.mul
|
61
|
-
|
62
|
-
|
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
|
-
|
68
|
-
|
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
|
-
|
71
|
-
local.get
|
72
|
-
local.get
|
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
|
-
|
77
|
-
|
66
|
+
i32.shl
|
67
|
+
i32.const 1
|
68
|
+
i32.sub
|
69
|
+
i32.and
|
78
70
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
85
|
-
local.get
|
86
|
-
|
87
|
-
|
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
|
85
|
+
i32.const 2246822519
|
91
86
|
i32.mul
|
87
|
+
local.tee hash
|
92
88
|
|
93
|
-
local.get
|
94
|
-
i32.
|
89
|
+
local.get hash
|
90
|
+
i32.const 13
|
91
|
+
i32.shr_u
|
95
92
|
i32.xor
|
96
|
-
i32.const
|
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 ==
|
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 ==
|
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 ==
|
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 ==
|
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,
|
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
|
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,
|
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,
|
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,
|
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,
|
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
|
}
|
package/compiler/codegen.js
CHANGED
@@ -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)
|
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
|
-
|
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
@@ -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
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
|
-
});
|