Title: [134303] branches/safari-536.28-branch

Diff

Modified: branches/safari-536.28-branch/LayoutTests/ChangeLog (134302 => 134303)


--- branches/safari-536.28-branch/LayoutTests/ChangeLog	2012-11-12 22:21:18 UTC (rev 134302)
+++ branches/safari-536.28-branch/LayoutTests/ChangeLog	2012-11-12 22:21:47 UTC (rev 134303)
@@ -1,5 +1,22 @@
 2012-11-12  Lucas Forschler  <[email protected]>
 
+        Merge r126718
+
+    2012-08-26  Filip Pizlo  <[email protected]>
+
+            Finally inlining should correctly track the catch context
+            https://bugs.webkit.org/show_bug.cgi?id=94986
+            <rdar://problem/11753784>
+
+            Reviewed by Sam Weinig.
+
+            * fast/js/jsc-test-list:
+            * fast/js/script-tests/throw-from-finally.js: Added.
+            * fast/js/throw-from-finally.html: Added.
+            * fast/js/throw-from-finally-expected.txt: Added.
+
+2012-11-12  Lucas Forschler  <[email protected]>
+
         Merge r131077
 
     2012-10-11  Dan Bernstein  <[email protected]>
@@ -11357,3 +11374,4 @@
 .
 .
 .
+.

Modified: branches/safari-536.28-branch/LayoutTests/fast/js/jsc-test-list (134302 => 134303)


--- branches/safari-536.28-branch/LayoutTests/fast/js/jsc-test-list	2012-11-12 22:21:18 UTC (rev 134302)
+++ branches/safari-536.28-branch/LayoutTests/fast/js/jsc-test-list	2012-11-12 22:21:47 UTC (rev 134303)
@@ -258,6 +258,7 @@
 fast/js/string-trim
 fast/js/string_replace
 fast/js/this-non-object-proto
+fast/js/throw-from-finally
 fast/js/ToNumber
 fast/js/toString-elision-trailing-comma
 fast/js/tostring-exception-in-property-access

Copied: branches/safari-536.28-branch/LayoutTests/fast/js/script-tests/throw-from-finally.js (from rev 126718, trunk/LayoutTests/fast/js/script-tests/throw-from-finally.js) (0 => 134303)


--- branches/safari-536.28-branch/LayoutTests/fast/js/script-tests/throw-from-finally.js	                        (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/fast/js/script-tests/throw-from-finally.js	2012-11-12 22:21:47 UTC (rev 134303)
@@ -0,0 +1,58 @@
+description(
+"This tests that throwing from a finally block has the expected effect."
+);
+
+var events = [];
+
+try {
+    events.push("1:try");
+} finally {
+    events.push("1:finally");
+}
+
+try {
+    try {
+        throw "2:thingy";
+    } finally {
+        events.push("2:finally");
+    }
+} catch (e) {
+    events.push(e);
+}
+
+try {
+    throw "3:thingy";
+} catch (e) {
+    events.push(e);
+} finally {
+    events.push("3:finally");
+}
+
+try {
+    try {
+        throw "4:thingy";
+    } catch (e) {
+        events.push(e);
+    } finally {
+        events.push("4:finally");
+        throw "4:another thingy";
+    }
+} catch (e) {
+    events.push(e);
+}
+
+try {
+    for (;;) {
+        try {
+            continue;
+        } finally {
+            events.push("5:hi");
+            throw "5:wat";
+        }
+    }
+} catch (e) {
+    events.push(e);
+}
+
+shouldBe("\"\" + events", "\"1:try,1:finally,2:finally,2:thingy,3:thingy,3:finally,4:thingy,4:finally,4:another thingy,5:hi,5:wat\"");
+

Copied: branches/safari-536.28-branch/LayoutTests/fast/js/throw-from-finally-expected.txt (from rev 126718, trunk/LayoutTests/fast/js/throw-from-finally-expected.txt) (0 => 134303)


--- branches/safari-536.28-branch/LayoutTests/fast/js/throw-from-finally-expected.txt	                        (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/fast/js/throw-from-finally-expected.txt	2012-11-12 22:21:47 UTC (rev 134303)
@@ -0,0 +1,10 @@
+This tests that throwing from a finally block has the expected effect.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS "" + events is "1:try,1:finally,2:finally,2:thingy,3:thingy,3:finally,4:thingy,4:finally,4:another thingy,5:hi,5:wat"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Copied: branches/safari-536.28-branch/LayoutTests/fast/js/throw-from-finally.html (from rev 126718, trunk/LayoutTests/fast/js/throw-from-finally.html) (0 => 134303)


--- branches/safari-536.28-branch/LayoutTests/fast/js/throw-from-finally.html	                        (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/fast/js/throw-from-finally.html	2012-11-12 22:21:47 UTC (rev 134303)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Modified: branches/safari-536.28-branch/Source/_javascript_Core/ChangeLog (134302 => 134303)


--- branches/safari-536.28-branch/Source/_javascript_Core/ChangeLog	2012-11-12 22:21:18 UTC (rev 134302)
+++ branches/safari-536.28-branch/Source/_javascript_Core/ChangeLog	2012-11-12 22:21:47 UTC (rev 134303)
@@ -1,5 +1,44 @@
 2012-11-12  Lucas Forschler  <[email protected]>
 
+        Merge r126718
+
+    2012-08-24  Filip Pizlo  <[email protected]>
+
+            Finally inlining should correctly track the catch context
+            https://bugs.webkit.org/show_bug.cgi?id=94986
+            <rdar://problem/11753784>
+
+            Reviewed by Sam Weinig.
+
+            This fixes two behaviors:
+
+            1) Throwing from a finally block. Previously, we would seem to reenter the finally
+               block - though only once.
+
+            2) Executing a finally block from some nested context, for example due to a
+               'continue', 'break', or 'return' in the try. This would execute the finally
+               block in the context of of the try block, which could lead to either scope depth
+               mismatches or reexecutions of the finally block on throw, similarly to (1) but
+               for different reasons.
+
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC):
+            (JSC::BytecodeGenerator::pushFinallyContext):
+            (JSC::BytecodeGenerator::emitComplexJumpScopes):
+            (JSC::BytecodeGenerator::pushTry):
+            (JSC::BytecodeGenerator::popTryAndEmitCatch):
+            * bytecompiler/BytecodeGenerator.h:
+            (FinallyContext):
+            (TryData):
+            (JSC):
+            (TryContext):
+            (TryRange):
+            (BytecodeGenerator):
+            * bytecompiler/NodesCodegen.cpp:
+            (JSC::TryNode::emitBytecode):
+
+2012-11-12  Lucas Forschler  <[email protected]>
+
         Merge r129577
 
     2012-09-25  Filip Pizlo  <[email protected]>
@@ -69259,3 +69298,4 @@
 .
 .
 .
+.

Modified: branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (134302 => 134303)


--- branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2012-11-12 22:21:18 UTC (rev 134302)
+++ branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2012-11-12 22:21:47 UTC (rev 134303)
@@ -146,6 +146,24 @@
 
     m_scopeNode->emitBytecode(*this);
     
+    for (unsigned i = 0; i < m_tryRanges.size(); ++i) {
+        TryRange& range = m_tryRanges[i];
+        ASSERT(range.tryData->targetScopeDepth != UINT_MAX);
+        HandlerInfo info = {
+            range.start->bind(0, 0), range.end->bind(0, 0),
+            range.tryData->target->bind(0, 0), range.tryData->targetScopeDepth
+#if ENABLE(JIT)
+            ,
+#if ENABLE(LLINT)
+            CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(bitwise_cast<void*>(&llint_op_catch)))
+#else
+            CodeLocationLabel()
+#endif
+#endif
+        };
+        m_codeBlock->addExceptionHandler(info);
+    }
+    
     m_codeBlock->instructions() = RefCountedArray<Instruction>(m_instructions);
 
     if (s_dumpsGeneratedCode)
@@ -2019,6 +2037,7 @@
         m_scopeContextStack.size(),
         m_switchContextStack.size(),
         m_forInContextStack.size(),
+        m_tryContextStack.size(),
         m_labelScopes.size(),
         m_finallyDepth,
         m_dynamicScopeDepth
@@ -2152,14 +2171,18 @@
         Vector<ControlFlowContext> savedScopeContextStack;
         Vector<SwitchInfo> savedSwitchContextStack;
         Vector<ForInContext> savedForInContextStack;
+        Vector<TryContext> poppedTryContexts;
         SegmentedVector<LabelScope, 8> savedLabelScopes;
         while (topScope > bottomScope && topScope->isFinallyBlock) {
+            RefPtr<Label> beforeFinally = emitLabel(newLabel().get());
+            
             // Save the current state of the world while instating the state of the world
             // for the finally block.
             FinallyContext finallyContext = topScope->finallyContext;
             bool flipScopes = finallyContext.scopeContextStackSize != m_scopeContextStack.size();
             bool flipSwitches = finallyContext.switchContextStackSize != m_switchContextStack.size();
             bool flipForIns = finallyContext.forInContextStackSize != m_forInContextStack.size();
+            bool flipTries = finallyContext.tryContextStackSize != m_tryContextStack.size();
             bool flipLabelScopes = finallyContext.labelScopesSize != m_labelScopes.size();
             int topScopeIndex = -1;
             int bottomScopeIndex = -1;
@@ -2177,6 +2200,19 @@
                 savedForInContextStack = m_forInContextStack;
                 m_forInContextStack.shrink(finallyContext.forInContextStackSize);
             }
+            if (flipTries) {
+                while (m_tryContextStack.size() != finallyContext.tryContextStackSize) {
+                    ASSERT(m_tryContextStack.size() > finallyContext.tryContextStackSize);
+                    TryContext context = m_tryContextStack.last();
+                    m_tryContextStack.removeLast();
+                    TryRange range;
+                    range.start = context.start;
+                    range.end = beforeFinally;
+                    range.tryData = context.tryData;
+                    m_tryRanges.append(range);
+                    poppedTryContexts.append(context);
+                }
+            }
             if (flipLabelScopes) {
                 savedLabelScopes = m_labelScopes;
                 while (m_labelScopes.size() > finallyContext.labelScopesSize)
@@ -2190,6 +2226,8 @@
             // Emit the finally block.
             emitNode(finallyContext.finallyBlock);
             
+            RefPtr<Label> afterFinally = emitLabel(newLabel().get());
+            
             // Restore the state of the world.
             if (flipScopes) {
                 m_scopeContextStack = savedScopeContextStack;
@@ -2200,6 +2238,14 @@
                 m_switchContextStack = savedSwitchContextStack;
             if (flipForIns)
                 m_forInContextStack = savedForInContextStack;
+            if (flipTries) {
+                ASSERT(m_tryContextStack.size() == finallyContext.tryContextStackSize);
+                for (unsigned i = poppedTryContexts.size(); i--;) {
+                    TryContext context = poppedTryContexts[i];
+                    context.start = afterFinally;
+                    m_tryContextStack.append(context);
+                }
+            }
             if (flipLabelScopes)
                 m_labelScopes = savedLabelScopes;
             m_finallyDepth = savedFinallyDepth;
@@ -2259,20 +2305,39 @@
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
+TryData* BytecodeGenerator::pushTry(Label* start)
 {
+    TryData tryData;
+    tryData.target = newLabel();
+    tryData.targetScopeDepth = UINT_MAX;
+    m_tryData.append(tryData);
+    TryData* result = &m_tryData.last();
+    
+    TryContext tryContext;
+    tryContext.start = start;
+    tryContext.tryData = result;
+    
+    m_tryContextStack.append(tryContext);
+    
+    return result;
+}
+
+RegisterID* BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID* targetRegister, Label* end)
+{
     m_usesExceptions = true;
-#if ENABLE(JIT)
-#if ENABLE(LLINT)
-    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(bitwise_cast<void*>(&llint_op_catch))) };
-#else
-    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
-#endif
-#else
-    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
-#endif
+    
+    ASSERT_UNUSED(tryData, m_tryContextStack.last().tryData == tryData);
+    
+    TryRange tryRange;
+    tryRange.start = m_tryContextStack.last().start;
+    tryRange.end = end;
+    tryRange.tryData = m_tryContextStack.last().tryData;
+    m_tryRanges.append(tryRange);
+    m_tryContextStack.removeLast();
+    
+    emitLabel(tryRange.tryData->target.get());
+    tryRange.tryData->targetScopeDepth = m_dynamicScopeDepth + m_baseScopeDepth;
 
-    m_codeBlock->addExceptionHandler(info);
     emitOpcode(op_catch);
     instructions().append(targetRegister->index());
     return targetRegister;

Modified: branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (134302 => 134303)


--- branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2012-11-12 22:21:18 UTC (rev 134302)
+++ branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2012-11-12 22:21:47 UTC (rev 134303)
@@ -74,6 +74,7 @@
         unsigned scopeContextStackSize;
         unsigned switchContextStackSize;
         unsigned forInContextStackSize;
+        unsigned tryContextStackSize;
         unsigned labelScopesSize;
         int finallyDepth;
         int dynamicScopeDepth;
@@ -90,6 +91,22 @@
         RefPtr<RegisterID> indexRegister;
         RefPtr<RegisterID> propertyRegister;
     };
+    
+    struct TryData { 
+        RefPtr<Label> target; 
+        unsigned targetScopeDepth; 
+     }; 
+     
+     struct TryContext { 
+        RefPtr<Label> start; 
+        TryData* tryData; 
+     }; 
+     
+     struct TryRange { 
+        RefPtr<Label> start; 
+        RefPtr<Label> end; 
+        TryData* tryData;
+    };
 
     class BytecodeGenerator {
         WTF_MAKE_FAST_ALLOCATED;
@@ -362,7 +379,11 @@
         RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget);
         RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target);
 
-        RegisterID* emitCatch(RegisterID*, Label* start, Label* end);
+        // Start a try block. 'start' must have been emitted. 
+         TryData* pushTry(Label* start); 
+         // End a try block. 'end' must have been emitted. 
+         RegisterID* popTryAndEmitCatch(TryData*, RegisterID* targetRegister, Label* end); 
+
         void emitThrow(RegisterID* exc)
         { 
             m_usesExceptions = true;
@@ -490,8 +511,9 @@
         }
 
         RegisterID* emitInitLazyRegister(RegisterID*);
-
+    public:
         Vector<Instruction>& instructions() { return m_instructions; }
+        
         SymbolTable& symbolTable() { return *m_symbolTable; }
 
         bool shouldOptimizeLocals()
@@ -557,7 +579,11 @@
         Vector<ControlFlowContext> m_scopeContextStack;
         Vector<SwitchInfo> m_switchContextStack;
         Vector<ForInContext> m_forInContextStack;
+        Vector<TryContext> m_tryContextStack; 
 
+        Vector<TryRange> m_tryRanges; 
+        SegmentedVector<TryData, 8> m_tryData;
+
         int m_firstConstantIndex;
         int m_nextConstantOffset;
         unsigned m_globalConstantIndex;

Modified: branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (134302 => 134303)


--- branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2012-11-12 22:21:18 UTC (rev 134302)
+++ branches/safari-536.28-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2012-11-12 22:21:47 UTC (rev 134303)
@@ -1973,11 +1973,15 @@
 
     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
 
+    ASSERT(m_catchBlock || m_finallyBlock);
+
     RefPtr<Label> tryStartLabel = generator.newLabel();
+    generator.emitLabel(tryStartLabel.get());
+    
     if (m_finallyBlock)
         generator.pushFinallyContext(m_finallyBlock);
+    TryData* tryData = generator.pushTry(tryStartLabel.get());
 
-    generator.emitLabel(tryStartLabel.get());
     generator.emitNode(dst, m_tryBlock);
 
     if (m_catchBlock) {
@@ -1988,7 +1992,14 @@
 
         // Uncaught exception path: the catch block.
         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
-        RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
+        RefPtr<RegisterID> exceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), here.get());
+        
+        if (m_finallyBlock) {
+            // If the catch block throws an exception and we have a finally block, then the finally
+            // block should "catch" that exception.
+            tryData = generator.pushTry(here.get());
+        }
+        
         generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
         generator.emitNode(dst, m_catchBlock);
         generator.emitPopScope();
@@ -1996,6 +2007,8 @@
     }
 
     if (m_finallyBlock) {
+        RefPtr<Label> preFinallyLabel = generator.emitLabel(generator.newLabel().get());
+        
         generator.popFinallyContext();
 
         RefPtr<Label> finallyEndLabel = generator.newLabel();
@@ -2005,8 +2018,7 @@
         generator.emitJump(finallyEndLabel.get());
 
         // Uncaught exception path: invoke the finally block, then re-throw the exception.
-        RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
-        RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
+        RefPtr<RegisterID> tempExceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), preFinallyLabel.get());
         generator.emitNode(dst, m_finallyBlock);
         generator.emitThrow(tempExceptionRegister.get());
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to