//------------------------------------------------------------------------------------------------------- // 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() { yield 0; // for interpreter yield 32; // for jitted version yield 32; // for jitted version } const global = this; function RunMemsetTest(tests, arrayTypes, allTypes) { function makeTest(name, config) { const f1 = `function ${name}(arr) { for(var i = 0; i < 15; ++i) {arr[i] = ${config.stringValue};} 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.stringValue}; for(var i = -2; i < 17; ++i) {arr[i] = v;} return arr; }`; const f4 = customName => `function ${customName}Z(arr, start) { const v = ${config.stringValue}; for(var i = start; i < 5; ++i) {arr[i] = v;} return arr; }`; const extraTests = allTypes.map((diffType, i) => { const difValue = {f: f2(`${name}W${i}`), compare: f2(`${name}WC${i}`)}; const genValue = makeValueGen(config.stringValue, diffType); 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.stringValue}, {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; } let passed = true; for(const test of tests) { for(const t of arrayTypes) { const set1 = makeTest(`${test.name}${t}`, test); const testSets = [{ set: set1, getArray() {return new global[t](10);} }].concat(allTypes.map((diffType, iType) => { return { set: makeTest(`${test.name}${t}${iType}`, test).slice(0, 1), getArray() {const arr = new global[t](10); for(let i = 0; i < 10; ++i) arr[i] = diffType; return arr;} }; })); for(const testSet of testSets) { for(const detail of testSet.set) { const fn = detail.f; try { let a1 = fn(testSet.getArray(), detail.v); const a2 = fn(testSet.getArray(), 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 ? testSet.getArray() : 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; } } } catch(e) { if (e.message.indexOf("Number Expected") !== -1) { print(e.message); passed = false; } } } } } } return passed; }