Commit f5dcdee1 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

[turbofan] Bounds check when lowering JSStoreProperty.

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
parent a314428a
......@@ -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
......
......@@ -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),
Node* check = graph()->NewNode(machine()->Uint32LessThan(), key,
jsgraph()->Uint32Constant(length));
Node* branch = graph()->NewNode(common()->Branch(), check,
NodeProperties::GetControlInput(node));
return ReplaceEagerly(node, store);
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();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment