function test(op) { | |
let test = ` | |
function runTest(iters) { | |
let shouldThrow = false; | |
let a = { | |
valueOf() { | |
if (shouldThrow) | |
throw "a"; | |
return 0; | |
} | |
}; | |
let {proxy: b, revoke} = Proxy.revocable({}, { | |
get: function(target, prop) { | |
if (prop === "valueOf") { | |
if (shouldThrow) | |
throw new Error("Should not be here!"); | |
return function() { | |
return 0; | |
} | |
} | |
} | |
}); | |
function f(a, b) { | |
return a ${op} b; | |
} | |
noInline(f); | |
for (let i = 0; i < iters; i++) { | |
f(a, b); | |
} | |
shouldThrow = true; | |
let validException = false; | |
let exception = null; | |
revoke(); | |
try { | |
f(a, b); | |
} catch(e) { | |
validException = e === "a"; | |
exception = e; | |
} | |
if (!validException) | |
throw new Error("Bad operation: " + exception.toString() + " with iters: " + iters); | |
} | |
runTest(2); | |
runTest(10); | |
runTest(50); | |
runTest(1000); | |
runTest(10000); | |
`; | |
eval(test); | |
} | |
let ops = [ | |
"+" | |
, "-" | |
, "*" | |
, "**" | |
, "/" | |
, "%" | |
, "&" | |
, "|" | |
, "^" | |
, ">>" | |
, ">>>" | |
, "<<" | |
]; | |
for (let op of ops) | |
test(op); | |
function test2(op) { | |
function runTest(iters) { | |
let test = ` | |
let shouldThrow = false; | |
let a = { | |
valueOf() { | |
if (shouldThrow) | |
throw "a"; | |
return 0; | |
} | |
}; | |
let {proxy: b, revoke} = Proxy.revocable({}, { | |
get: function(target, prop) { | |
if (prop === "valueOf") { | |
if (shouldThrow) | |
throw new Error("Should not be here!"); | |
return function() { | |
return 0; | |
} | |
} | |
} | |
}); | |
function f(a, b) { | |
return a ${op} b; | |
} | |
noInline(f); | |
for (let i = 0; i < ${iters}; i++) { | |
f(a, b); | |
} | |
shouldThrow = true; | |
let validException = false; | |
let exception = null; | |
revoke(); | |
try { | |
f(a, b); | |
} catch(e) { | |
validException = e === "a"; | |
exception = e; | |
} | |
if (!validException) | |
throw new Error("Bad operation: " + exception.toString() + " with iters: " + ${iters}); | |
`; | |
eval(Math.random() + ";" + test); | |
} | |
runTest(2); | |
runTest(10); | |
runTest(50); | |
runTest(1000); | |
runTest(10000); | |
} | |
for (let op of ops) | |
test2(op); |