Commit ec47ab66 authored by fpizlo@apple.com's avatar fpizlo@apple.com

JIT and DFG should NaN-check loads from Float32 arrays

https://bugs.webkit.org/show_bug.cgi?id=113462
<rdar://problem/13490804>

Reviewed by Mark Hahnenberg.

Source/JavaScriptCore: 

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitFloatTypedArrayGetByVal):

LayoutTests: 

* fast/js/dfg-float32-array-nan-expected.txt: Added.
* fast/js/dfg-float32-array-nan.html: Added.
* fast/js/jit-float32-array-nan-expected.txt: Added.
* fast/js/jit-float32-array-nan.html: Added.
* fast/js/jsc-test-list:
* fast/js/script-tests/dfg-float32-array-nan.js: Added.
(foo):
* fast/js/script-tests/jit-float32-array-nan.js: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@147047 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9ccd1fe3
2013-03-27 Filip Pizlo <fpizlo@apple.com>
JIT and DFG should NaN-check loads from Float32 arrays
https://bugs.webkit.org/show_bug.cgi?id=113462
<rdar://problem/13490804>
Reviewed by Mark Hahnenberg.
* fast/js/dfg-float32-array-nan-expected.txt: Added.
* fast/js/dfg-float32-array-nan.html: Added.
* fast/js/jit-float32-array-nan-expected.txt: Added.
* fast/js/jit-float32-array-nan.html: Added.
* fast/js/jsc-test-list:
* fast/js/script-tests/dfg-float32-array-nan.js: Added.
(foo):
* fast/js/script-tests/jit-float32-array-nan.js: Added.
2013-03-27 Beth Dakin <bdakin@apple.com>
Need WK2 API to give a WebView a header and footer
Tests what happens in the DFG JIT if we load from a Float32 array that contains a weirdly formatted NaN.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-4587521
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
NaN
PASS "" + foo(floatView) is "NaN"
I didn't crash, which is a good thing.
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="resources/js-test-pre.js"></script>
</head>
<body>
<script src="script-tests/dfg-float32-array-nan.js"></script>
<script src="resources/js-test-post.js"></script>
</body>
</html>
Tests what happens in the Baseline JIT if we load from a Float32 array that contains a weirdly formatted NaN.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-4587521
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
NaN
PASS "" + floatView[0] is "NaN"
I didn't crash, which is a good thing.
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="resources/js-test-pre.js"></script>
</head>
<body>
<script src="script-tests/jit-float32-array-nan.js"></script>
<script src="resources/js-test-post.js"></script>
</body>
</html>
......@@ -129,6 +129,7 @@ fast/js/dfg-double-vote-fuzz
fast/js/dfg-ensure-array-storage-on-string
fast/js/dfg-ensure-contiguous-on-string
fast/js/dfg-exception
fast/js/dfg-float32-array-nan
fast/js/dfg-float32array
fast/js/dfg-float64array
fast/js/dfg-flush-get-local
......@@ -278,6 +279,7 @@ fast/js/integer-extremes
fast/js/interpreter-no-activation
fast/js/invalid-callframe-during-unwind
fast/js/isPrototypeOf
fast/js/jit-float32-array-nan
fast/js/js-continue-break-restrictions
fast/js/JSON-parse-reviver
fast/js/JSON-stringify-replacer
......
description(
"Tests what happens in the DFG JIT if we load from a Float32 array that contains a weirdly formatted NaN."
);
var buffer = new ArrayBuffer(4);
var int32View = new Int32Array(buffer);
var floatView = new Float32Array(buffer);
int32View[0] = -4587521;
debug(int32View[0]);
function foo(o) {
debug(o[0]);
return o[0];
}
for (var i = 0; i < 100; ++i)
shouldBe("\"\" + foo(floatView)", "\"NaN\"");
debug("I didn't crash, which is a good thing.");
description(
"Tests what happens in the Baseline JIT if we load from a Float32 array that contains a weirdly formatted NaN."
);
var buffer = new ArrayBuffer(4);
var int32View = new Int32Array(buffer);
var floatView = new Float32Array(buffer);
int32View[0] = -4587521;
debug(int32View[0]);
for (var i = 0; i < 100; ++i) {
debug(floatView[0]);
shouldBe("\"\" + floatView[0]", "\"NaN\"");
}
debug("I didn't crash, which is a good thing.");
2013-03-27 Filip Pizlo <fpizlo@apple.com>
JIT and DFG should NaN-check loads from Float32 arrays
https://bugs.webkit.org/show_bug.cgi?id=113462
<rdar://problem/13490804>
Reviewed by Mark Hahnenberg.
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitFloatTypedArrayGetByVal):
2013-03-27 Mark Hahnenberg <mhahnenberg@apple.com>
CodeCache::m_capacity can becoming negative, producing undefined results in pruneSlowCase
......
......@@ -2674,15 +2674,17 @@ void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor
break;
case 8: {
m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
static const double NaN = QNaN;
m_jit.loadDouble(&NaN, resultReg);
notNaN.link(&m_jit);
break;
}
default:
RELEASE_ASSERT_NOT_REACHED();
}
MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
static const double NaN = QNaN;
m_jit.loadDouble(&NaN, resultReg);
notNaN.link(&m_jit);
doubleResult(resultReg, node);
}
......
......@@ -1636,16 +1636,17 @@ JIT::JumpList JIT::emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badT
break;
case 8: {
loadDouble(BaseIndex(base, property, TimesEight), fpRegT0);
Jump notNaN = branchDouble(DoubleEqual, fpRegT0, fpRegT0);
static const double NaN = QNaN;
loadDouble(&NaN, fpRegT0);
notNaN.link(this);
break;
}
default:
CRASH();
}
Jump notNaN = branchDouble(DoubleEqual, fpRegT0, fpRegT0);
static const double NaN = QNaN;
loadDouble(&NaN, fpRegT0);
notNaN.link(this);
#if USE(JSVALUE64)
moveDoubleTo64(fpRegT0, resultPayload);
sub64(tagTypeNumberRegister, resultPayload);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment