Title: [161392] branches/jsCStack
Revision
161392
Author
[email protected]
Date
2014-01-06 19:17:11 -0800 (Mon, 06 Jan 2014)

Log Message

Source/_javascript_Core: Merge trunk r160238, r160242, r160246, r160252, r160257.

LayoutTests: Merge trunk r160242, r160246, r160252, r160257.

Modified Paths

Added Paths

Diff

Modified: branches/jsCStack/LayoutTests/ChangeLog (161391 => 161392)


--- branches/jsCStack/LayoutTests/ChangeLog	2014-01-07 02:04:20 UTC (rev 161391)
+++ branches/jsCStack/LayoutTests/ChangeLog	2014-01-07 03:17:11 UTC (rev 161392)
@@ -1,3 +1,7 @@
+2014-01-06  Filip Pizlo  <[email protected]>
+
+        Merge trunk r160242, r160246, r160252, r160257.
+
 2013-12-06  Michał Pakuła vel Rutka  <[email protected]>
 
         Unreviewed EFL gardening

Added: branches/jsCStack/LayoutTests/js/regress/by-val-generic-expected.txt (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/by-val-generic-expected.txt	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/by-val-generic-expected.txt	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,10 @@
+JSRegress/by-val-generic
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/jsCStack/LayoutTests/js/regress/by-val-generic.html (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/by-val-generic.html	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/by-val-generic.html	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: branches/jsCStack/LayoutTests/js/regress/double-get-by-val-out-of-bounds-expected.txt (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/double-get-by-val-out-of-bounds-expected.txt	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/double-get-by-val-out-of-bounds-expected.txt	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,10 @@
+JSRegress/double-get-by-val-out-of-bounds
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/jsCStack/LayoutTests/js/regress/double-get-by-val-out-of-bounds.html (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/double-get-by-val-out-of-bounds.html	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/double-get-by-val-out-of-bounds.html	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: branches/jsCStack/LayoutTests/js/regress/get-by-val-out-of-bounds-expected.txt (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/get-by-val-out-of-bounds-expected.txt	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/get-by-val-out-of-bounds-expected.txt	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,10 @@
+JSRegress/get-by-val-out-of-bounds
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/jsCStack/LayoutTests/js/regress/get-by-val-out-of-bounds.html (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/get-by-val-out-of-bounds.html	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/get-by-val-out-of-bounds.html	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: branches/jsCStack/LayoutTests/js/regress/logical-not-expected.txt (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/logical-not-expected.txt	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/logical-not-expected.txt	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,10 @@
+JSRegress/logical-not
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/jsCStack/LayoutTests/js/regress/logical-not.html (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/logical-not.html	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/logical-not.html	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: branches/jsCStack/LayoutTests/js/regress/put-by-val-machine-int-expected.txt (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/put-by-val-machine-int-expected.txt	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/put-by-val-machine-int-expected.txt	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,10 @@
+JSRegress/put-by-val-machine-int
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/jsCStack/LayoutTests/js/regress/put-by-val-machine-int.html (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/put-by-val-machine-int.html	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/put-by-val-machine-int.html	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: branches/jsCStack/LayoutTests/js/regress/script-tests/by-val-generic.js (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/script-tests/by-val-generic.js	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/script-tests/by-val-generic.js	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,12 @@
+function foo(a, b, c) {
+    a[b] = c;
+    return a[b];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo({}, "foo", "bar");
+    if (result !== "bar")
+        throw "Error: bad result: " + result;
+}

Added: branches/jsCStack/LayoutTests/js/regress/script-tests/double-get-by-val-out-of-bounds.js (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/script-tests/double-get-by-val-out-of-bounds.js	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/script-tests/double-get-by-val-out-of-bounds.js	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,11 @@
+function foo(a) {
+    return a[1];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo([42.5]);
+    if (result !== void 0)
+        throw "Error: bad value: " + result;
+}

Added: branches/jsCStack/LayoutTests/js/regress/script-tests/get-by-val-out-of-bounds.js (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/script-tests/get-by-val-out-of-bounds.js	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/script-tests/get-by-val-out-of-bounds.js	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,11 @@
+function foo(a) {
+    return a[1];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo([42]);
+    if (result !== void 0)
+        throw "Error: bad value: " + result;
+}

Added: branches/jsCStack/LayoutTests/js/regress/script-tests/logical-not.js (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/script-tests/logical-not.js	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/script-tests/logical-not.js	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,14 @@
+function foo(v) {
+    return !v;
+}
+
+noInline(foo);
+
+var array = ["foo", 42, null, {}, true, false];
+var expected = [false, false, true, false, false, true];
+
+for (var i = 0; i < 200000; ++i) {
+    var result = foo(array[i % array.length]);
+    if (result !== expected[i % array.length])
+        throw "Error: bad result at " + i + ": " + result;
+}

Added: branches/jsCStack/LayoutTests/js/regress/script-tests/put-by-val-machine-int.js (0 => 161392)


--- branches/jsCStack/LayoutTests/js/regress/script-tests/put-by-val-machine-int.js	                        (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/script-tests/put-by-val-machine-int.js	2014-01-07 03:17:11 UTC (rev 161392)
@@ -0,0 +1,12 @@
+function foo(a, v) {
+    a[0] = v + 2000000000;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var a = new Int32Array(1);
+    foo(a, 2000000000);
+    if (a[0] != -294967296)
+        throw "Error: bad value: " + a[0];
+}

Modified: branches/jsCStack/Source/_javascript_Core/ChangeLog (161391 => 161392)


--- branches/jsCStack/Source/_javascript_Core/ChangeLog	2014-01-07 02:04:20 UTC (rev 161391)
+++ branches/jsCStack/Source/_javascript_Core/ChangeLog	2014-01-07 03:17:11 UTC (rev 161392)
@@ -1,3 +1,7 @@
+2014-01-06  Filip Pizlo  <[email protected]>
+
+        Merge trunk r160238, r160242, r160246, r160252, r160257.
+
 2014-01-06  Michael Saboff  <[email protected]>
 
         CStack Branch: Disable JIT stack alignment check for ARM64

Modified: branches/jsCStack/Source/_javascript_Core/dfg/DFGGraph.h (161391 => 161392)


--- branches/jsCStack/Source/_javascript_Core/dfg/DFGGraph.h	2014-01-07 02:04:20 UTC (rev 161391)
+++ branches/jsCStack/Source/_javascript_Core/dfg/DFGGraph.h	2014-01-07 03:17:11 UTC (rev 161392)
@@ -428,6 +428,18 @@
         return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, m_profiledBlock);
     }
     
+    bool isStrictModeFor(CodeOrigin codeOrigin)
+    {
+        if (!codeOrigin.inlineCallFrame)
+            return m_codeBlock->isStrictMode();
+        return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->isStrictMode();
+    }
+    
+    ECMAMode ecmaModeFor(CodeOrigin codeOrigin)
+    {
+        return isStrictModeFor(codeOrigin) ? StrictMode : NotStrictMode;
+    }
+    
     bool masqueradesAsUndefinedWatchpointIsStillValid(const CodeOrigin& codeOrigin)
     {
         return m_plan.watchpoints.isStillValid(

Modified: branches/jsCStack/Source/_javascript_Core/ftl/FTLCapabilities.cpp (161391 => 161392)


--- branches/jsCStack/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2014-01-07 02:04:20 UTC (rev 161391)
+++ branches/jsCStack/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2014-01-07 03:17:11 UTC (rev 161392)
@@ -105,6 +105,9 @@
     case NotifyWrite:
     case Call:
     case Construct:
+    case ValueToInt32:
+    case Branch:
+    case LogicalNot:
         // These are OK.
         break;
     case GetById:
@@ -146,8 +149,8 @@
     case GetByVal:
         switch (node->arrayMode().type()) {
         case Array::ForceExit:
+        case Array::Generic:
         case Array::String:
-            return CanCompileAndOSREnter;
         case Array::Int32:
         case Array::Double:
         case Array::Contiguous:
@@ -157,19 +160,13 @@
                 return CanCompileAndOSREnter;
             return CannotCompile;
         }
-        switch (node->arrayMode().speculation()) {
-        case Array::SaneChain:
-        case Array::InBounds:
-            break;
-        default:
-            return CannotCompile;
-        }
         break;
     case PutByVal:
     case PutByValAlias:
+    case PutByValDirect:
         switch (node->arrayMode().type()) {
         case Array::ForceExit:
-            return CanCompileAndOSREnter;
+        case Array::Generic:
         case Array::Int32:
         case Array::Double:
         case Array::Contiguous:
@@ -202,19 +199,6 @@
         if (node->isBinaryUseKind(NumberUse))
             break;
         return CannotCompile;
-    case Branch:
-    case LogicalNot:
-        switch (node->child1().useKind()) {
-        case BooleanUse:
-        case Int32Use:
-        case NumberUse:
-        case StringUse:
-        case ObjectOrOtherUse:
-            break;
-        default:
-            return CannotCompile;
-        }
-        break;
     case Switch:
         switch (node->switchData()->kind) {
         case SwitchImm:
@@ -224,10 +208,6 @@
             return CannotCompile;
         }
         break;
-    case ValueToInt32:
-        if (node->child1().useKind() != BooleanUse)
-            return CannotCompile;
-        break;
     default:
         // Don't know how to handle anything else.
         return CannotCompile;

Modified: branches/jsCStack/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h (161391 => 161392)


--- branches/jsCStack/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h	2014-01-07 02:04:20 UTC (rev 161391)
+++ branches/jsCStack/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h	2014-01-07 03:17:11 UTC (rev 161392)
@@ -55,6 +55,8 @@
     macro(C_JITOperation_ESt, functionType(intPtr, intPtr, intPtr)) \
     macro(I_JITOperation_EJss, functionType(intPtr, intPtr, intPtr)) \
     macro(J_JITOperation_E, functionType(int64, intPtr)) \
+    macro(J_JITOperation_EAZ, functionType(int64, intPtr, intPtr, int32)) \
+    macro(J_JITOperation_EJJ, functionType(int64, intPtr, int64, int64)) \
     macro(J_JITOperation_EJssZ, functionType(int64, intPtr, intPtr, int32)) \
     macro(J_JITOperation_ESsiJI, functionType(int64, intPtr, intPtr, int64, intPtr)) \
     macro(Jss_JITOperation_EZ, functionType(intPtr, intPtr, int32)) \
@@ -65,6 +67,8 @@
     macro(P_JITOperation_EStPS, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
     macro(P_JITOperation_EStSS, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
     macro(P_JITOperation_EStZ, functionType(intPtr, intPtr, intPtr, int32)) \
+    macro(S_JITOperation_EJ, functionType(intPtr, intPtr, int64)) \
+    macro(V_JITOperation_EJJJ, functionType(voidType, intPtr, int64, int64, int64)) \
     macro(V_JITOperation_EOZD, functionType(voidType, intPtr, intPtr, int32, doubleType)) \
     macro(V_JITOperation_EOZJ, functionType(voidType, intPtr, intPtr, int32, int64)) \
     macro(V_JITOperation_EVws, functionType(voidType, intPtr, intPtr)) \

Modified: branches/jsCStack/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (161391 => 161392)


--- branches/jsCStack/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2014-01-07 02:04:20 UTC (rev 161391)
+++ branches/jsCStack/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2014-01-07 03:17:11 UTC (rev 161392)
@@ -387,6 +387,7 @@
             break;
         case PutByVal:
         case PutByValAlias:
+        case PutByValDirect:
             compilePutByVal();
             break;
         case NewObject:
@@ -509,8 +510,96 @@
 
     void compileValueToInt32()
     {
-        ASSERT(m_node->child1().useKind() == BooleanUse);
-        setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), m_out.int32));
+        switch (m_node->child1().useKind()) {
+        case Int32Use:
+            setInt32(lowInt32(m_node->child1()));
+            break;
+            
+        case MachineIntUse:
+            setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
+            break;
+            
+        case NumberUse:
+        case NotCellUse: {
+            LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
+            if (isValid(value)) {
+                setInt32(value.value());
+                break;
+            }
+            
+            value = m_jsValueValues.get(m_node->child1().node());
+            if (isValid(value)) {
+                LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 int case"));
+                LBasicBlock notIntCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 not int case"));
+                LBasicBlock doubleCase = 0;
+                LBasicBlock notNumberCase = 0;
+                if (m_node->child1().useKind() == NotCellUse) {
+                    doubleCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 double case"));
+                    notNumberCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 not number case"));
+                }
+                LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ValueToInt32 continuation"));
+                
+                Vector<ValueFromBlock> results;
+                
+                m_out.branch(isNotInt32(value.value()), notIntCase, intCase);
+                
+                LBasicBlock lastNext = m_out.appendTo(intCase, notIntCase);
+                results.append(m_out.anchor(unboxInt32(value.value())));
+                m_out.jump(continuation);
+                
+                if (m_node->child1().useKind() == NumberUse) {
+                    m_out.appendTo(notIntCase, continuation);
+                    FTL_TYPE_CHECK(
+                        jsValueValue(value.value()), m_node->child1(), SpecFullNumber,
+                        isCellOrMisc(value.value()));
+                    results.append(m_out.anchor(doubleToInt32(unboxDouble(value.value()))));
+                    m_out.jump(continuation);
+                } else {
+                    m_out.appendTo(notIntCase, doubleCase);
+                    m_out.branch(isCellOrMisc(value.value()), notNumberCase, doubleCase);
+                    
+                    m_out.appendTo(doubleCase, notNumberCase);
+                    results.append(m_out.anchor(doubleToInt32(unboxDouble(value.value()))));
+                    m_out.jump(continuation);
+                    
+                    m_out.appendTo(notNumberCase, continuation);
+                    
+                    FTL_TYPE_CHECK(
+                        jsValueValue(value.value()), m_node->child1(), ~SpecCell,
+                        isCell(value.value()));
+                    
+                    LValue specialResult = m_out.select(
+                        m_out.equal(
+                            value.value(),
+                            m_out.constInt64(JSValue::encode(jsBoolean(true)))),
+                        m_out.int32One, m_out.int32Zero);
+                    results.append(m_out.anchor(specialResult));
+                    m_out.jump(continuation);
+                }
+                
+                m_out.appendTo(continuation, lastNext);
+                setInt32(m_out.phi(m_out.int32, results));
+                break;
+            }
+            
+            value = m_doubleValues.get(m_node->child1().node());
+            if (isValid(value)) {
+                setInt32(doubleToInt32(value.value()));
+                break;
+            }
+            
+            terminate(Uncountable);
+            break;
+        }
+            
+        case BooleanUse:
+            setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), m_out.int32));
+            break;
+            
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
     }
 
     void compileInt52ToValue()
@@ -1422,25 +1511,45 @@
             LValue index = lowInt32(m_node->child2());
             LValue storage = lowStorage(m_node->child3());
             
+            IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
+                m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
+            
             if (m_node->arrayMode().isInBounds()) {
                 speculate(
                     OutOfBounds, noValue(), 0,
                     m_out.aboveOrEqual(
                         index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
                 
-                LValue result = m_out.load64(m_out.baseIndex(
-                    m_node->arrayMode().type() == Array::Int32 ?
-                        m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
-                    storage, m_out.zeroExt(index, m_out.intPtr),
-                    m_state.forNode(m_node->child2()).m_value));
+                LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
                 speculate(LoadFromHole, noValue(), 0, m_out.isZero64(result));
                 setJSValue(result);
                 return;
             }
             
-            // FIXME: Implement hole/OOB loads in the FTL.
-            // https://bugs.webkit.org/show_bug.cgi?id=118077
-            RELEASE_ASSERT_NOT_REACHED();
+            LValue base = lowCell(m_node->child1());
+            
+            LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous fast case"));
+            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous slow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous continuation"));
+            
+            m_out.branch(
+                m_out.aboveOrEqual(
+                    index, m_out.load32(storage, m_heaps.Butterfly_publicLength)),
+                slowCase, fastCase);
+            
+            LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
+            
+            ValueFromBlock fastResult = m_out.anchor(
+                m_out.load64(baseIndex(heap, storage, index, m_node->child2())));
+            m_out.branch(m_out.isZero64(fastResult.value()), slowCase, continuation);
+            
+            m_out.appendTo(slowCase, continuation);
+            ValueFromBlock slowResult = m_out.anchor(
+                vmCall(m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
             return;
         }
             
@@ -1448,16 +1557,16 @@
             LValue index = lowInt32(m_node->child2());
             LValue storage = lowStorage(m_node->child3());
             
+            IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
+            
             if (m_node->arrayMode().isInBounds()) {
                 speculate(
                     OutOfBounds, noValue(), 0,
                     m_out.aboveOrEqual(
                         index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
                 
-                LValue result = m_out.loadDouble(m_out.baseIndex(
-                    m_heaps.indexedDoubleProperties,
-                    storage, m_out.zeroExt(index, m_out.intPtr),
-                    m_state.forNode(m_node->child2()).m_value));
+                LValue result = m_out.loadDouble(
+                    baseIndex(heap, storage, index, m_node->child2()));
                 
                 if (!m_node->arrayMode().isSaneChain()) {
                     speculate(
@@ -1468,12 +1577,45 @@
                 break;
             }
             
-            // FIXME: Implement hole/OOB loads in the FTL.
-            // https://bugs.webkit.org/show_bug.cgi?id=118077
-            RELEASE_ASSERT_NOT_REACHED();
+            LValue base = lowCell(m_node->child1());
+            
+            LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetByVal double in bounds"));
+            LBasicBlock boxPath = FTL_NEW_BLOCK(m_out, ("GetByVal double boxing"));
+            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal double slow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal double continuation"));
+            
+            m_out.branch(
+                m_out.aboveOrEqual(
+                    index, m_out.load32(storage, m_heaps.Butterfly_publicLength)),
+                slowCase, inBounds);
+            
+            LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
+            LValue doubleValue = m_out.loadDouble(
+                baseIndex(heap, storage, index, m_node->child2()));
+            m_out.branch(
+                m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue), slowCase, boxPath);
+            
+            m_out.appendTo(boxPath, slowCase);
+            ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(slowCase, continuation);
+            ValueFromBlock slowResult = m_out.anchor(
+                vmCall(m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
             return;
         }
             
+        case Array::Generic: {
+            setJSValue(vmCall(
+                m_out.operation(operationGetByVal), m_callFrame,
+                lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
+            return;
+        }
+            
         case Array::String: {
             compileStringCharAt();
             return;
@@ -1572,6 +1714,31 @@
         Edge child2 = m_graph.varArgChild(m_node, 1);
         Edge child3 = m_graph.varArgChild(m_node, 2);
         Edge child4 = m_graph.varArgChild(m_node, 3);
+        
+        switch (m_node->arrayMode().type()) {
+        case Array::Generic: {
+            V_JITOperation_EJJJ operation;
+            if (m_node->op() == PutByValDirect) {
+                if (m_graph.isStrictModeFor(m_node->codeOrigin))
+                    operation = operationPutByValDirectStrict;
+                else
+                    operation = operationPutByValDirectNonStrict;
+            } else {
+                if (m_graph.isStrictModeFor(m_node->codeOrigin))
+                    operation = operationPutByValStrict;
+                else
+                    operation = operationPutByValNonStrict;
+            }
+                
+            vmCall(
+                m_out.operation(operation), m_callFrame,
+                lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
+            return;
+        }
+            
+        default:
+            break;
+        }
 
         LValue base = lowCell(child1);
         LValue index = lowInt32(child2);
@@ -1653,7 +1820,7 @@
             TypedArrayType type = m_node->arrayMode().typedArrayType();
             
             if (isTypedView(type)) {
-                if (m_node->op() == PutByVal) {
+                if (m_node->op() != PutByValAlias) {
                     speculate(
                         OutOfBounds, noValue(), 0,
                         m_out.aboveOrEqual(
@@ -1677,7 +1844,7 @@
                         if (child3.useKind() == Int32Use)
                             intValue = lowInt32(child3);
                         else
-                            intValue = m_out.castToInt32(lowInt52(child3));
+                            intValue = m_out.castToInt32(lowStrictInt52(child3));
 
                         if (isClamped(type)) {
                             ASSERT(elementSize(type) == 1);
@@ -1733,10 +1900,8 @@
                             
                             m_out.appendTo(continuation, lastNext);
                             intValue = m_out.phi(m_out.int32, intValues);
-                        } else if (isSigned(type))
+                        } else
                             intValue = doubleToInt32(doubleValue);
-                        else
-                            intValue = doubleToUInt32(doubleValue);
                         break;
                     }
                         
@@ -2659,6 +2824,13 @@
         info.m_isInvalidationPoint = true;
     }
     
+    TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge)
+    {
+        return m_out.baseIndex(
+            heap, storage, m_out.zeroExt(index, m_out.intPtr),
+            m_state.forNode(edge).m_value);
+    }
+    
     LValue allocateCell(LValue allocator, LValue structure, LBasicBlock slowPath)
     {
         LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
@@ -2832,6 +3004,27 @@
             LValue length = m_out.load32(stringValue, m_heaps.JSString_length);
             return m_out.notEqual(length, m_out.int32Zero);
         }
+        case UntypedUse: {
+            LValue value = lowJSValue(m_node->child1());
+            
+            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped slow case"));
+            LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped fast case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Boolify untyped continuation"));
+            
+            m_out.branch(isNotBoolean(value), slowCase, fastCase);
+            
+            LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
+            ValueFromBlock fastResult = m_out.anchor(unboxBoolean(value));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(slowCase, continuation);
+            ValueFromBlock slowResult = m_out.anchor(m_out.notNull(vmCall(
+                m_out.operation(operationConvertJSValueToBoolean), m_callFrame, value)));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            return m_out.phi(m_out.boolean, fastResult, slowResult);
+        }
         default:
             RELEASE_ASSERT_NOT_REACHED();
             return 0;
@@ -3048,14 +3241,6 @@
         return doubleToInt32(doubleValue, -limit, limit);
     }
     
-    LValue doubleToUInt32(LValue doubleValue)
-    {
-        if (Output::hasSensibleDoubleToInt())
-            return sensibleDoubleToInt32(doubleValue);
-        
-        return doubleToInt32(doubleValue, 0, pow(2, 32) - 1, false);
-    }
-    
     LValue sensibleDoubleToInt32(LValue doubleValue)
     {
         LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("sensible doubleToInt32 slow path"));
@@ -3286,7 +3471,7 @@
     
     LValue lowCell(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     {
-        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
+        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || DFG::isCell(edge.useKind()));
         
         if (edge->op() == JSConstant) {
             JSValue value = m_graph.valueOfJSConstant(edge.node());
@@ -3595,6 +3780,11 @@
         return m_out.testNonZero64(jsValue, m_tagMask);
     }
     
+    LValue isCell(LValue jsValue)
+    {
+        return m_out.testIsZero64(jsValue, m_tagMask);
+    }
+    
     LValue isNotBoolean(LValue jsValue)
     {
         return m_out.testNonZero64(
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to