2011-01-10 Michael Saboff <msaboff@apple.com>
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Jan 2011 18:27:15 +0000 (18:27 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Jan 2011 18:27:15 +0000 (18:27 +0000)
        Reviewed by Geoffrey Garen.

        ASSERTION Failure in JSC::binaryChop
        https://bugs.webkit.org/show_bug.cgi?id=25614

        Changed JITStubs::cti_register_file_check() to use the current stack's
        return PC to find the bytecode for handling the exception in the prior
        frame.  Also added the appropriate arrity check routine call to the
        JIT to bytecode vector (m_callReturnIndexVector) in the CodeBlock.

        * jit/JIT.cpp:
        (JSC::JIT::privateCompile): Changed the arrity check call location
        so that it gets added to the m_calls list so that it's included in
        CodeBlock::m_callReturnIndexVector.
        * jit/JITStubs.cpp:
        (JSC::DEFINE_STUB_FUNCTION): Use the current call frame's return PC.
2011-01-11  Michael Saboff  <msaboff@apple.com>

        Reviewed by Geoffrey Garen.

        ASSERTION Failure in JSC::binaryChop
        https://bugs.webkit.org/show_bug.cgi?id=25614

        Added new test to check for proper handling of stack overflow
        exceptions and arrity exceptions while close to the top of the stack.

        * fast/js/script-tests/stack-overflow-arrity-catch.js: Added.
        (fWithTwoArgs):
        (test):
        * fast/js/script-tests/stack-overflow-catch.js: Added.
        (test):
        * fast/js/stack-overflow-arrity-catch-expected.txt: Added.
        * fast/js/stack-overflow-arrity-catch.html: Added.
        * fast/js/stack-overflow-catch-expected.txt: Added.
        * fast/js/stack-overflow-catch.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@75510 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/js/script-tests/stack-overflow-arrity-catch.js [new file with mode: 0644]
LayoutTests/fast/js/script-tests/stack-overflow-catch.js [new file with mode: 0644]
LayoutTests/fast/js/stack-overflow-arrity-catch-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/stack-overflow-arrity-catch.html [new file with mode: 0644]
LayoutTests/fast/js/stack-overflow-catch-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/stack-overflow-catch.html [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JITStubs.cpp

index da053e825cf93f92b33783469d159e53074a97af..e0eb27ea5a1ddd9752d3a07c9c7163c20075feec 100644 (file)
@@ -1,3 +1,23 @@
+2011-01-11  Michael Saboff  <msaboff@apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        ASSERTION Failure in JSC::binaryChop
+        https://bugs.webkit.org/show_bug.cgi?id=25614
+
+        Added new test to check for proper handling of stack overflow 
+        exceptions and arrity exceptions while close to the top of the stack.
+
+        * fast/js/script-tests/stack-overflow-arrity-catch.js: Added.
+        (fWithTwoArgs):
+        (test):
+        * fast/js/script-tests/stack-overflow-catch.js: Added.
+        (test):
+        * fast/js/stack-overflow-arrity-catch-expected.txt: Added.
+        * fast/js/stack-overflow-arrity-catch.html: Added.
+        * fast/js/stack-overflow-catch-expected.txt: Added.
+        * fast/js/stack-overflow-catch.html: Added.
+
 2011-01-11  Stephen White  <senorblanco@chromium.org>
 
         Unreviewed; new chromium GPU test baselines.
 2011-01-11  Stephen White  <senorblanco@chromium.org>
 
         Unreviewed; new chromium GPU test baselines.
diff --git a/LayoutTests/fast/js/script-tests/stack-overflow-arrity-catch.js b/LayoutTests/fast/js/script-tests/stack-overflow-arrity-catch.js
new file mode 100644 (file)
index 0000000..d990c5b
--- /dev/null
@@ -0,0 +1,58 @@
+description('Test that if an arrity check causes a stack overflow, the exception goes to the right catch');
+
+function funcWith20Args(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+                        arg9, arg10, arg11, arg12, arg13, arg14, arg15,
+                        arg16, arg17, arg18, arg19, arg20)
+{
+    debug("ERROR: Shouldn't arrive in 20 arg function!");
+}
+
+gotRightCatch = false;
+
+function test1()
+{
+    try {
+        test2();
+    } catch (err) {
+        // Should get here because of stack overflow,
+        // now cause a stack overflow exception due to arrity processing
+        try {
+            var dummy = new RegExp('a|b|c');
+        } catch(err) {
+            debug('Should not get here #1!');
+        }
+        
+        try {
+            funcWith20Args(1, 2, 3);
+        } catch (err2) {
+            gotRightCatch = true;
+        }
+    }
+}
+
+function test2()
+{
+    try {
+        var dummy = new Date();
+    } catch(err) {
+        debug('Should not get here #2!');
+    }
+    
+    try {
+        test1();
+    } catch (err) {
+        // Should get here because of stack overflow,
+        // now cause a stack overflow exception due to arrity processing
+        try {
+            funcWith20Args(1, 2, 3, 4, 5, 6);
+        } catch (err2) {
+            gotRightCatch = true;
+        }
+    }
+}
+
+test1();
+
+shouldBeTrue("gotRightCatch");
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/js/script-tests/stack-overflow-catch.js b/LayoutTests/fast/js/script-tests/stack-overflow-catch.js
new file mode 100644 (file)
index 0000000..838adc4
--- /dev/null
@@ -0,0 +1,55 @@
+description('Test that when the stack overflows, the exception goes to the last frame before the overflow');
+
+var level = 0;
+var stackLevel = 0;
+var gotWrongCatch = false;
+
+function test1()
+{
+    var myLevel = level;
+    var dummy;
+
+    try {
+        level = level + 1;
+        // Dummy code to make this funciton different from test2()
+        dummy = level * level + 1;
+        if (dummy == 0)
+            debug('Should never get here!!!!');
+    } catch(err) {
+        gotWrongCatch = true;
+    }
+
+    try {
+        test2();
+    } catch(err) {
+        stackLevel = myLevel;
+    }
+}
+
+function test2()
+{
+    var myLevel = level;
+
+    // Dummy code to make this funciton different from test1()
+    if (gotWrongCatch)
+        debug('Should never get here!!!!');
+
+    try {
+        level = level + 1;
+    } catch(err) {
+        gotWrongCatch = true;
+    }
+
+    try {
+        test1();
+    } catch(err) {
+        stackLevel = myLevel;
+    }
+}
+
+test1();
+
+shouldBeFalse("gotWrongCatch");
+shouldBe("(stackLevel)", "(level - 1)");
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/js/stack-overflow-arrity-catch-expected.txt b/LayoutTests/fast/js/stack-overflow-arrity-catch-expected.txt
new file mode 100644 (file)
index 0000000..19a35e2
--- /dev/null
@@ -0,0 +1,10 @@
+Test that if an arrity check causes a stack overflow, the exception goes to the right catch
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS gotRightCatch is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/stack-overflow-arrity-catch.html b/LayoutTests/fast/js/stack-overflow-arrity-catch.html
new file mode 100644 (file)
index 0000000..c897ee4
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/js-test-style.css">
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/stack-overflow-arrity-catch.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/stack-overflow-catch-expected.txt b/LayoutTests/fast/js/stack-overflow-catch-expected.txt
new file mode 100644 (file)
index 0000000..2b978a3
--- /dev/null
@@ -0,0 +1,11 @@
+Test that when the stack overflows, the exception goes to the last frame before the overflow
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS gotWrongCatch is false
+PASS (stackLevel) is (level - 1)
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/stack-overflow-catch.html b/LayoutTests/fast/js/stack-overflow-catch.html
new file mode 100644 (file)
index 0000000..f9273c6
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/js-test-style.css">
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/stack-overflow-catch.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
index d4d21f7b3fe74a3fc4b5423114a07b076a9bfcf7..e00e45f154031cb49b7c2be830c2300bffc2dc35 100644 (file)
@@ -1,3 +1,22 @@
+2011-01-10  Michael Saboff  <msaboff@apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        ASSERTION Failure in JSC::binaryChop
+        https://bugs.webkit.org/show_bug.cgi?id=25614
+
+        Changed JITStubs::cti_register_file_check() to use the current stack's
+        return PC to find the bytecode for handling the exception in the prior
+        frame.  Also added the appropriate arrity check routine call to the
+        JIT to bytecode vector (m_callReturnIndexVector) in the CodeBlock.
+
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile): Changed the arrity check call location
+        so that it gets added to the m_calls list so that it's included in
+        CodeBlock::m_callReturnIndexVector.
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION): Use the current call frame's return PC.
+
 2011-01-10  Daniel Bates  <dbates@rim.com>
 
         Reviewed by Martin Robinson.
 2011-01-10  Daniel Bates  <dbates@rim.com>
 
         Reviewed by Martin Robinson.
index e66b65e238371d027d845f255567a600530738b8..89b1e30e0751cc233216a35d6fa80aa3d2622095 100644 (file)
@@ -489,7 +489,6 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
     privateCompileSlowCases();
 
     Label arityCheck;
     privateCompileSlowCases();
 
     Label arityCheck;
-    Call callArityCheck;
     if (m_codeBlock->codeType() == FunctionCode) {
         registerFileCheck.link(this);
         m_bytecodeOffset = 0;
     if (m_codeBlock->codeType() == FunctionCode) {
         registerFileCheck.link(this);
         m_bytecodeOffset = 0;
@@ -504,8 +503,9 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
         emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
         branch32(Equal, regT1, Imm32(m_codeBlock->m_numParameters)).linkTo(beginLabel, this);
         restoreArgumentReference();
         emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
         branch32(Equal, regT1, Imm32(m_codeBlock->m_numParameters)).linkTo(beginLabel, this);
         restoreArgumentReference();
-        callArityCheck = call();
-        move(regT0, callFrameRegister);
+
+        JITStubCall(this, m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck).call(callFrameRegister);
+
         jump(beginLabel);
     }
 
         jump(beginLabel);
     }
 
@@ -585,10 +585,8 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
         info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
     }
 
         info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
     }
 
-    if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck) {
-        patchBuffer.link(callArityCheck, FunctionPtr(m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck));
+    if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck)
         *functionEntryArityCheck = patchBuffer.locationOf(arityCheck);
         *functionEntryArityCheck = patchBuffer.locationOf(arityCheck);
-    }
 
     return patchBuffer.finalizeCode();
 }
 
     return patchBuffer.finalizeCode();
 }
index 81c41898241157c321a71029ea768905cdd53684..ded3428e328c1d8f50cfdf99f1ffe5c352457c15 100644 (file)
@@ -1431,7 +1431,7 @@ DEFINE_STUB_FUNCTION(void*, register_file_check)
         // Rewind to the previous call frame because op_call already optimistically
         // moved the call frame forward.
         CallFrame* oldCallFrame = callFrame->callerFrame();
         // Rewind to the previous call frame because op_call already optimistically
         // moved the call frame forward.
         CallFrame* oldCallFrame = callFrame->callerFrame();
-        ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), ReturnAddressPtr(oldCallFrame->returnPC()));
+        ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), ReturnAddressPtr(callFrame->returnPC()));
         STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
         callFrame = handler.callFrame;
     }
         STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
         callFrame = handler.callFrame;
     }