[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

oliver at apple.com oliver at apple.com
Wed Dec 22 11:08:53 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 7709952d09fcb38db704f8913ad99f4f11157e0a
Author: oliver at apple.com <oliver at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jul 13 19:57:08 2010 +0000

    2010-07-12  Oliver Hunt  <oliver at apple.com>
    
            Reviewed by Gavin Barraclough.
    
            REGRESSION: Crash at JSC::JIT::privateCompile(JSC::MacroAssemblerCodePtr*)
            https://bugs.webkit.org/show_bug.cgi?id=41763
    
            There are two parts to this patch, the first is to fix the actual
            problem.  When calling copyStringWithoutBOMs on a string we know
            to contain BOMs we return a value indicating that there are no
            BOMs.
    
            The second part of this fix is simply to harden the path that
            led to a crash when parsing failed.
    
            * jit/JITOpcodes.cpp:
            (JSC::JIT::privateCompileCTIMachineTrampolines):
            * jit/JITOpcodes32_64.cpp:
            (JSC::JIT::privateCompileCTIMachineTrampolines):
            * jit/JITStubs.cpp:
            (JSC::DEFINE_STUB_FUNCTION):
               Harden compilation stubs against parser failure.
            * parser/Lexer.cpp:
            (JSC::Lexer::sourceCode):
               Add assertions to ensure that subranges into a source provider
               are always actually braces.  Hopefully this should catch similar
               failures in future.  These assertions fire on existing tests
               without this fix.
            * runtime/Executable.h:
            (JSC::FunctionExecutable::tryJitCodeForCall):
            (JSC::FunctionExecutable::tryJitCodeForConstruct):
            * wtf/text/StringImpl.h:
            (WebCore::StringImpl::copyStringWithoutBOMs):
               Make copyStringWithBOMs do the right thing.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63237 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 69672c4..f7a6dc8 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,38 @@
+2010-07-12  Oliver Hunt  <oliver at apple.com>
+
+        Reviewed by Gavin Barraclough.
+
+        REGRESSION: Crash at JSC::JIT::privateCompile(JSC::MacroAssemblerCodePtr*)
+        https://bugs.webkit.org/show_bug.cgi?id=41763
+
+        There are two parts to this patch, the first is to fix the actual
+        problem.  When calling copyStringWithoutBOMs on a string we know
+        to contain BOMs we return a value indicating that there are no
+        BOMs.
+
+        The second part of this fix is simply to harden the path that
+        led to a crash when parsing failed.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::privateCompileCTIMachineTrampolines):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::privateCompileCTIMachineTrampolines):
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+           Harden compilation stubs against parser failure.
+        * parser/Lexer.cpp:
+        (JSC::Lexer::sourceCode):
+           Add assertions to ensure that subranges into a source provider
+           are always actually braces.  Hopefully this should catch similar
+           failures in future.  These assertions fire on existing tests
+           without this fix.
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::tryJitCodeForCall):
+        (JSC::FunctionExecutable::tryJitCodeForConstruct):
+        * wtf/text/StringImpl.h:
+        (WebCore::StringImpl::copyStringWithoutBOMs):
+           Make copyStringWithBOMs do the right thing.
+
 2010-07-13  Gabor Loki  <loki at webkit.org>
 
         Reviewed by Gavin Barraclough.
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index 8e86d40..dcd3821 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -73,14 +73,14 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
 
     // VirtualCallLink Trampoline
     // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
-    JumpList callLazyLinkFailures;
+    JumpList callLinkFailures;
     Label virtualCallLinkBegin = align();
     compileOpCallInitializeCallFrame();
     preserveReturnAddressAfterCall(regT3);
     emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
     restoreArgumentReference();
     Call callLazyLinkCall = call();
-    callLazyLinkFailures.append(branchTestPtr(Zero, regT0));
+    callLinkFailures.append(branchTestPtr(Zero, regT0));
     restoreReturnAddressBeforeReturn(regT3);
     emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1);
     jump(regT0);
@@ -93,24 +93,11 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
     restoreArgumentReference();
     Call callLazyLinkConstruct = call();
-    callLazyLinkFailures.append(branchTestPtr(Zero, regT0));
+    callLinkFailures.append(branchTestPtr(Zero, regT0));
     restoreReturnAddressBeforeReturn(regT3);
     emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1);
     jump(regT0);
 
-    // If the parser fails we want to be able to be able to keep going,
-    // So we handle this as a parse failure.
-    callLazyLinkFailures.link(this);
-    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
-    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
-    restoreReturnAddressBeforeReturn(regT1);
-    move(ImmPtr(&globalData->exceptionLocation), regT2);
-    storePtr(regT1, regT2);
-    poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
-    poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
-    ret();
-    
-
     // VirtualCall Trampoline
     // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
     Label virtualCallBegin = align();
@@ -122,6 +109,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     preserveReturnAddressAfterCall(regT3);
     restoreArgumentReference();
     Call callCompileCall = call();
+    callLinkFailures.append(branchTestPtr(Zero, regT0));
     emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1);
     restoreReturnAddressBeforeReturn(regT3);
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
@@ -141,6 +129,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     preserveReturnAddressAfterCall(regT3);
     restoreArgumentReference();
     Call callCompileConstruct = call();
+    callLinkFailures.append(branchTestPtr(Zero, regT0));
     emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1);
     restoreReturnAddressBeforeReturn(regT3);
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
@@ -148,6 +137,18 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
 
     loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCodeForConstructWithArityCheck)), regT0);
     jump(regT0);
+    
+    // If the parser fails we want to be able to be able to keep going,
+    // So we handle this as a parse failure.
+    callLinkFailures.link(this);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+    restoreReturnAddressBeforeReturn(regT1);
+    move(ImmPtr(&globalData->exceptionLocation), regT2);
+    storePtr(regT1, regT2);
+    poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
+    poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
+    ret();
 
     // NativeCall Trampoline
     Label nativeCallThunk = privateCompileCTINativeCall(globalData);    
diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp
index a44a8a1..658ebc5 100644
--- a/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -64,10 +64,10 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
 
     ret();
 #endif
-
+    
+    JumpList callLinkFailures;
     // (2) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
 #if ENABLE(JIT_OPTIMIZE_CALL)
-    JumpList callLazyLinkFailures;
     // VirtualCallLink Trampoline
     // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
     Label virtualCallLinkBegin = align();
@@ -76,7 +76,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
     restoreArgumentReference();
     Call callLazyLinkCall = call();
-    callLazyLinkFailures.append(branchTestPtr(Zero, regT0));
+    callLinkFailures.append(branchTestPtr(Zero, regT0));
     restoreReturnAddressBeforeReturn(regT3);
     emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1);
     jump(regT0);
@@ -90,22 +90,10 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     restoreArgumentReference();
     Call callLazyLinkConstruct = call();
     restoreReturnAddressBeforeReturn(regT3);
-    callLazyLinkFailures.append(branchTestPtr(Zero, regT0));
+    callLinkFailures.append(branchTestPtr(Zero, regT0));
     emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1);
     jump(regT0);
 
-    // If the parser fails we want to be able to be able to keep going,
-    // So we handle this as a parse failure.
-    callLazyLinkFailures.link(this);
-    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
-    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
-    restoreReturnAddressBeforeReturn(regT1);
-    move(ImmPtr(&globalData->exceptionLocation), regT2);
-    storePtr(regT1, regT2);
-    poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
-    poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
-    ret();
-
 #endif // ENABLE(JIT_OPTIMIZE_CALL)
 
     // VirtualCall Trampoline
@@ -119,6 +107,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     preserveReturnAddressAfterCall(regT3);
     restoreArgumentReference();
     Call callCompileCall = call();
+    callLinkFailures.append(branchTestPtr(Zero, regT0));
     emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1);
     restoreReturnAddressBeforeReturn(regT3);
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
@@ -138,6 +127,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     preserveReturnAddressAfterCall(regT3);
     restoreArgumentReference();
     Call callCompileCconstruct = call();
+    callLinkFailures.append(branchTestPtr(Zero, regT0));
     emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1);
     restoreReturnAddressBeforeReturn(regT3);
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
@@ -145,6 +135,18 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
 
     loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCodeForConstructWithArityCheck)), regT0);
     jump(regT0);
+    
+    // If the parser fails we want to be able to be able to keep going,
+    // So we handle this as a parse failure.
+    callLinkFailures.link(this);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+    restoreReturnAddressBeforeReturn(regT1);
+    move(ImmPtr(&globalData->exceptionLocation), regT2);
+    storePtr(regT1, regT2);
+    poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
+    poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
+    ret();
 
     // NativeCall Trampoline
     Label nativeCallThunk = privateCompileCTINativeCall(globalData);    
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index 85bd54f..cab30ca 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1858,8 +1858,10 @@ DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
     ASSERT(!function->isHostFunction());
     FunctionExecutable* executable = function->jsExecutable();
     ScopeChainNode* callDataScopeChain = function->scope().node();
-    executable->jitCodeForCall(stackFrame.callFrame, callDataScopeChain);
-
+    if (!executable->tryJitCodeForCall(stackFrame.callFrame, callDataScopeChain)) {
+        stackFrame.callFrame->globalData().exception = createStackOverflowError(stackFrame.callFrame);
+        return 0;
+    }
     return function;
 }
 
@@ -1876,8 +1878,10 @@ DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
     ASSERT(!function->isHostFunction());
     FunctionExecutable* executable = function->jsExecutable();
     ScopeChainNode* callDataScopeChain = function->scope().node();
-    executable->jitCodeForConstruct(stackFrame.callFrame, callDataScopeChain);
-
+    if (!executable->tryJitCodeForConstruct(stackFrame.callFrame, callDataScopeChain)) {
+        stackFrame.callFrame->globalData().exception = createStackOverflowError(stackFrame.callFrame);
+        return 0;
+    }
     return function;
 }
 
@@ -2050,7 +2054,7 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
         codeBlock = functionExecutable->bytecodeForConstruct(stackFrame.callFrame, callee->scope().node());
         if (!codeBlock) {
             throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS);
-            VM_THROW_EXCEPTION();
+            return 0;
         }
         functionExecutable->jitCodeForConstruct(callFrame, callee->scope().node());
         if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp
index 45fe007..91a87e6 100644
--- a/JavaScriptCore/parser/Lexer.cpp
+++ b/JavaScriptCore/parser/Lexer.cpp
@@ -1157,6 +1157,8 @@ void Lexer::clear()
 
 SourceCode Lexer::sourceCode(int openBrace, int closeBrace, int firstLine)
 {
+    ASSERT(m_source->provider()->data()[openBrace] == '{');
+    ASSERT(m_source->provider()->data()[closeBrace] == '}');
     return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine);
 }
 
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index 516d6ce..ba5fae7 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -414,6 +414,26 @@ namespace JSC {
                 generateJITCodeForConstruct(exec, scopeChainNode);
             return m_jitCodeForConstruct;
         }
+        
+        bool tryJitCodeForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
+        {
+            FunctionCodeBlock* codeBlock = bytecodeForCall(exec, scopeChainNode);
+            if (!codeBlock)
+                return false;
+            if (!m_jitCodeForCall)
+                generateJITCodeForCall(exec, scopeChainNode);
+            return true;
+        }
+        
+        bool tryJitCodeForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
+        {
+            FunctionCodeBlock* codeBlock = bytecodeForConstruct(exec, scopeChainNode);
+            if (!codeBlock)
+                return false;
+            if (!m_jitCodeForConstruct)
+                generateJITCodeForConstruct(exec, scopeChainNode);
+            return true;
+        }
 
         MacroAssemblerCodePtr generatedJITCodeForCallWithArityCheck()
         {
diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h
index a172e2c..17572f1 100644
--- a/JavaScriptCore/wtf/text/StringImpl.h
+++ b/JavaScriptCore/wtf/text/StringImpl.h
@@ -274,6 +274,7 @@ public:
             if (!hasBOMs)
                 return this;
         }
+        hasBOMs = true;
         Vector<UChar> result;
         result.reserveInitialCapacity(m_length);
         size_t firstBOM = i;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list