forked from chakra-core/ChakraCore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemset_invariant.js
More file actions
145 lines (132 loc) · 4.83 KB
/
memset_invariant.js
File metadata and controls
145 lines (132 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
function* makeValueGen(a, b) {
// return a for profiling
yield a;
// return b to bailout
yield b;
// return b again to compare with non jit function
yield b;
}
function* makeStartGen(a, b) {
yield 0; // for interpreter
yield 32; // for jitted version
yield 32; // for jitted version
}
function makeTest(name, config) {
const f1 = `function ${name}(arr) {
for(var i = -5; i < 15; ++i) {arr[i] = ${config.v1};}
return arr;
}`;
const f2 = customName => `function ${customName}P(arr, v) {
for(var i = 1; i < 8; ++i) {arr[i] = v;}
return arr;
}`;
const f3 = `function ${name}V(arr) {
const v = ${config.v1};
for(var i = -2; i < 17; ++i) {arr[i] = v;}
return arr;
}`;
const f4 = customName => `function ${customName}Z(arr, start) {
const v = ${config.v1};
for(var i = start; i < 5; ++i) {arr[i] = v;}
return arr;
}`;
const extraTests = (config.wrongTypes || []).map((wrongType, i) => {
const difValue = {f: f2(`${name}W${i}`), compare: f2(`${name}WC${i}`)};
const genValue = makeValueGen(config.v1, wrongType);
Reflect.defineProperty(difValue, "v", {
get: () => genValue.next().value
});
return difValue;
});
const negativeLengthTest = {f: f4(name), compare: f4(`${name}C`), newForCompare: true};
const genIndex = makeStartGen();
Reflect.defineProperty(negativeLengthTest, "v", {
get: () => genIndex.next().value
});
const tests = [
{f: f1},
{f: f2(name), v: config.v2 !== undefined ? config.v2 : config.v1},
{f: f3},
negativeLengthTest
].concat(extraTests);
const convertTest = function(fnText) {
var fn;
eval(`fn = ${fnText}`);
return fn;
};
for(const t of tests) {
t.f = convertTest(t.f);
t.compare = t.compare && convertTest(t.compare);
}
return tests;
}
const allTypes = [0, 1.5, undefined, null, 9223372036854775807, "string", {a: null, b: "b"}];
const tests = [
{name: "memsetUndefined", v1: undefined, wrongTypes: allTypes},
{name: "memsetNull", v1: null, wrongTypes: allTypes},
{name: "memsetFloat", v1: 3.14, v2: -87.684, wrongTypes: allTypes},
{name: "memsetNumber", v1: 9223372036854775807, v2: -987654987654987, wrongTypes: allTypes},
{name: "memsetBoolean", v1: true, v2: false, wrongTypes: allTypes},
{name: "memsetString", v1: "\"thatString\"", v2: "`A template string`", wrongTypes: allTypes},
{name: "memsetObject", v1: "{test: 1}", v2: [1, 2, 3], wrongTypes: allTypes},
];
const types = "Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Array".split(" ");
const global = this;
let passed = true;
for(const test of tests) {
for(const t of types) {
const fns = makeTest(`${test.name}${t}`, test);
for(const detail of fns) {
const fn = detail.f;
let a1 = fn(new global[t](10), detail.v);
const a2 = fn(new global[t](10), detail.v);
if(detail.compare) {
// the optimized version ran with a different value. Run again with a clean function to compare=
a1 = detail.compare(detail.newForCompare ? new global[t](10) : a1, detail.v);
}
if(a1.length !== a2.length) {
passed = false;
print(`${fn.name} (${t}) didn't return arrays with same length`);
continue;
}
for(let i = 0; i < a1.length; ++i) {
if(a1[i] !== a2[i] && !(isNaN(a1[i]) && isNaN(a2[i]))) {
passed = false;
print(`${fn.name} (${t}): a1[${i}](${a1[i]}) != a2[${i}](${a2[i]})`);
break;
}
}
}
}
}
function memsetSymbol() {const s = Symbol(); const arr = new Array(10); for(let i = 0; i < 10; ++i) {arr[i] = s;} return arr;}
function memsetSymbolV(v) {const arr = new Array(10); for(let i = 0; i < 10; ++i) {arr[i] = v;} return arr;}
function checkSymbols() {
const s = Symbol();
// Since symbol are unique, and we want to compare the result, we have to pass the same symbol everytime
const a1 = memsetSymbolV(s);
const a2 = memsetSymbolV(s);
for(let i = 0; i < a1.length; ++i) {
if(a1[i] !== a2[i]) {
passed = false;
// need explicit toString() for Symbol
print(`memsetSymbolV: a1[${i}](${a1[i].toString()}) != a2[${i}](${a2 && a2[i].toString() || ""})`);
break;
}
}
memsetSymbol();
const symbolArray = memsetSymbol();
for(let i = 0; i < symbolArray.length; ++i) {
if(typeof symbolArray[i] !== typeof s) {
passed = false;
print(`memsetSymbol: symbolArray[${i}] is not a Symbol`);
break;
}
}
}
checkSymbols();
print(passed ? "PASSED" : "FAILED");