[turbofan] Bounds check when lowering JSStoreProperty.
authorbmeurer@chromium.org <bmeurer@chromium.org>
Mon, 22 Sep 2014 07:17:13 +0000 (07:17 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org>
Mon, 22 Sep 2014 07:17:13 +0000 (07:17 +0000)
R=titzer@chromium.org

Review URL: https://codereview.chromium.org/559653005

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24105 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/compiler/js-graph.h
src/compiler/js-typed-lowering.cc

index a907bc5..2b2dfd1 100644 (file)
@@ -65,6 +65,9 @@ class JSGraph : public ZoneObject {
 
   // Creates a Int32Constant node, usually canonicalized.
   Node* Int32Constant(int32_t value);
+  Node* Uint32Constant(uint32_t value) {
+    return Int32Constant(bit_cast<int32_t>(value));
+  }
 
   // Creates a Float64Constant node, usually canonicalized.
   Node* Float64Constant(double value);
@@ -109,6 +112,7 @@ class JSGraph : public ZoneObject {
 
   Factory* factory() { return isolate()->factory(); }
 };
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
index bc3ea82..130c5cb 100644 (file)
@@ -571,13 +571,14 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
   // TODO(mstarzinger): This lowering is not correct if:
   //   a) The typed array turns external (i.e. MaterializeArrayBuffer)
   //   b) The typed array or it's buffer is neutered.
-  //   c) The index is out of bounds
   if (key_type->Is(Type::Integral32()) && base_type->IsConstant() &&
       base_type->AsConstant()->Value()->IsJSTypedArray()) {
     // JSStoreProperty(typed-array, int32, value)
     JSTypedArray* array = JSTypedArray::cast(*base_type->AsConstant()->Value());
     ElementsKind elements_kind = array->map()->elements_kind();
     ExternalArrayType type = array->type();
+    uint32_t length;
+    CHECK(array->length()->ToUint32(&length));
     ElementAccess element_access;
     Node* elements = graph()->NewNode(
         simplified()->LoadField(AccessBuilder::ForJSObjectElements()), base,
@@ -591,11 +592,24 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
       DCHECK(IsFixedTypedArrayElementsKind(elements_kind));
       element_access = AccessBuilder::ForTypedArrayElement(type, false);
     }
-    Node* store =
-        graph()->NewNode(simplified()->StoreElement(element_access), elements,
-                         key, value, NodeProperties::GetEffectInput(node),
-                         NodeProperties::GetControlInput(node));
-    return ReplaceEagerly(node, store);
+
+    Node* check = graph()->NewNode(machine()->Uint32LessThan(), key,
+                                   jsgraph()->Uint32Constant(length));
+    Node* branch = graph()->NewNode(common()->Branch(), check,
+                                    NodeProperties::GetControlInput(node));
+
+    Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+    Node* store = graph()->NewNode(
+        simplified()->StoreElement(element_access), elements, key, value,
+        NodeProperties::GetEffectInput(node), if_true);
+
+    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+
+    Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+    Node* phi = graph()->NewNode(common()->EffectPhi(2), store,
+                                 NodeProperties::GetEffectInput(node), merge);
+
+    return ReplaceWith(phi);
   }
   return NoChange();
 }