Revision: 21410
Author:   [email protected]
Date:     Wed May 21 12:36:37 2014 UTC
Log:      Reorder checks in Runtime_TypedArrayInitialize*

All checks must be performed before any side effects, so we get atomic transactions

BUG=chromium:374443
LOG=n
[email protected]

Review URL: https://codereview.chromium.org/298843003
http://code.google.com/p/v8/source/detail?r=21410

Modified:
 /branches/bleeding_edge/src/runtime.cc

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Wed May 21 12:16:47 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Wed May 21 12:36:37 2014 UTC
@@ -960,13 +960,6 @@

   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 @@
       &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_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<JSArrayBuffer> buffer = Handle<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);
+  } else {
+    RUNTIME_ASSERT(maybe_buffer->IsNull());
+  }

   RUNTIME_ASSERT(byte_length % element_size == 0);
   size_t length = byte_length / element_size;
@@ -998,16 +997,20 @@
                                            HandleVector<Object>(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<Object> 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<JSArrayBuffer> 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<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
     holder->set_buffer(*buffer);
     holder->set_weak_next(buffer->weak_first_view());
     buffer->set_weak_first_view(*holder);
@@ -1047,12 +1050,6 @@

   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.
@@ -1082,6 +1079,12 @@
             HandleVector<Object>(NULL, 0)));
   }
   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

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to