Out of bounds write in vmEntryToJavaScript / JSC::JITCode::execute
https://bugs.webkit.org/show_bug.cgi?id=136305
Reviewed by Filip Pizlo.
Source/JavaScriptCore:
While preparing the callee's CallFrame, ProtoCallFrame fixes any arity mismatch
and then JITCode::execute() calls the normal entrypoint. This is incompatible
with the expectation of FTL generated functions. Changed ProtoCallFrame to not
perform the arity fix, but just flag an arity mismatch. now JITCode::execute()
uses that arity mismatch condition to select the normal or arity check
entrypoint. The entrypoint selection is only done for functions, programs
and eval always have one parameter.
* interpreter/ProtoCallFrame.cpp:
(JSC::ProtoCallFrame::init): Changed to flag arity mismatch instead of fixing it.
* interpreter/ProtoCallFrame.h:
(JSC::ProtoCallFrame::needArityCheck): New boolean to signify what entrypoint
should be called.
* jit/JITCode.cpp:
(JSC::JITCode::execute): Select normal or arity check entrypoint as appropriate.
LayoutTests:
* js/arity-mismatch-at-vmentry-expected.txt: Added.
* js/arity-mismatch-at-vmentry.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@173178 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/js/arity-mismatch-at-vmentry.html b/LayoutTests/js/arity-mismatch-at-vmentry.html
new file mode 100644
index 0000000..b183bee
--- /dev/null
+++ b/LayoutTests/js/arity-mismatch-at-vmentry.html
@@ -0,0 +1,42 @@
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<span id="span">
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+ description("This tests that vm entry to a JS function with arity mismatch doesn't crash (bug 136305).");
+
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ window.jsTestIsAsync = true;
+
+ function marsaglia(m_z, m_w, n) {
+ var result;
+ for (var i = 0; i < n; ++i) {
+ }
+ }
+
+ var result = 0;
+ for (var i = 0; i < 100; ++i)
+ result += marsaglia(i, i + 1, 1000000);
+
+ document.getElementById("span").addEventListener("readystatechange", marsaglia);
+
+ var dispatch_fn = function() {
+ evt = document.createEvent("Event");
+ evt.initEvent("readystatechange");
+ document.getElementById("span").dispatchEvent(evt);
+ }
+
+ window.setInterval(dispatch_fn, 0);
+ window.setTimeout('finishJSTest()', 1);
+</script>
+
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>