From 38cfd30b69dfe90bdf37323f410140c35832248d Mon Sep 17 00:00:00 2001 From: "jkummerow@chromium.org" Date: Wed, 21 May 2014 12:36:37 +0000 Subject: [PATCH] Reorder checks in Runtime_TypedArrayInitialize* All checks must be performed before any side effects, so we get atomic transactions BUG=chromium:374443 LOG=n R=dslomov@chromium.org Review URL: https://codereview.chromium.org/298843003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21410 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/runtime.cc | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/runtime.cc b/src/runtime.cc index 631c2b79b3..29a3efe736 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -960,13 +960,6 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && arrayId <= Runtime::ARRAY_ID_LAST); - RUNTIME_ASSERT(maybe_buffer->IsNull() || maybe_buffer->IsJSArrayBuffer()); - - ASSERT(holder->GetInternalFieldCount() == - v8::ArrayBufferView::kInternalFieldCount); - for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { - holder->SetInternalField(i, Smi::FromInt(0)); - } ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. size_t element_size = 1; // Bogus initialization. @@ -978,7 +971,6 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { &external_elements_kind, &fixed_elements_kind, &element_size); - RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); size_t byte_offset = 0; @@ -986,8 +978,15 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset)); RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length)); - holder->set_byte_offset(*byte_offset_object); - holder->set_byte_length(*byte_length_object); + if (maybe_buffer->IsJSArrayBuffer()) { + Handle buffer = Handle::cast(maybe_buffer); + size_t array_buffer_byte_length = + NumberToSize(isolate, buffer->byte_length()); + RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length); + RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length); + } else { + RUNTIME_ASSERT(maybe_buffer->IsNull()); + } RUNTIME_ASSERT(byte_length % element_size == 0); size_t length = byte_length / element_size; @@ -998,16 +997,20 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { HandleVector(NULL, 0))); } + // All checks are done, now we can modify objects. + + ASSERT(holder->GetInternalFieldCount() == + v8::ArrayBufferView::kInternalFieldCount); + for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { + holder->SetInternalField(i, Smi::FromInt(0)); + } Handle length_obj = isolate->factory()->NewNumberFromSize(length); holder->set_length(*length_obj); + holder->set_byte_offset(*byte_offset_object); + holder->set_byte_length(*byte_length_object); + if (!maybe_buffer->IsNull()) { - Handle buffer(JSArrayBuffer::cast(*maybe_buffer)); - - size_t array_buffer_byte_length = - NumberToSize(isolate, buffer->byte_length()); - RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length); - RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length); - + Handle buffer = Handle::cast(maybe_buffer); holder->set_buffer(*buffer); holder->set_weak_next(buffer->weak_first_view()); buffer->set_weak_first_view(*holder); @@ -1048,12 +1051,6 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && arrayId <= Runtime::ARRAY_ID_LAST); - ASSERT(holder->GetInternalFieldCount() == - v8::ArrayBufferView::kInternalFieldCount); - for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { - holder->SetInternalField(i, Smi::FromInt(0)); - } - ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. size_t element_size = 1; // Bogus initialization. ElementsKind external_elements_kind = @@ -1083,6 +1080,12 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { } size_t byte_length = length * element_size; + ASSERT(holder->GetInternalFieldCount() == + v8::ArrayBufferView::kInternalFieldCount); + for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { + holder->SetInternalField(i, Smi::FromInt(0)); + } + // NOTE: not initializing backing store. // We assume that the caller of this function will initialize holder // with the loop