Index: src/compiler/js-typed-lowering.cc |
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc |
index 9f1e7eb8914b5ae824a080718fcebee55c70d58a..bb5b18cb50f2eec58bbaece2993e8d1e8cda92f1 100644 |
--- a/src/compiler/js-typed-lowering.cc |
+++ b/src/compiler/js-typed-lowering.cc |
@@ -558,13 +558,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, |
@@ -578,11 +579,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(); |
} |