Share code between Factory::NewJSTypedArray and API
authordslomov@chromium.org <dslomov@chromium.org>
Fri, 17 Oct 2014 09:04:58 +0000 (09:04 +0000)
committerdslomov@chromium.org <dslomov@chromium.org>
Fri, 17 Oct 2014 09:04:58 +0000 (09:04 +0000)
R=bmeurer@chromium.org

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

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

src/api.cc
src/factory.cc
src/factory.h
test/unittests/compiler/js-typed-lowering-unittest.cc

index 4929fda..b190925 100644 (file)
@@ -6100,78 +6100,22 @@ size_t v8::TypedArray::Length() {
 }
 
 
-static inline void SetupArrayBufferView(
-    i::Isolate* isolate,
-    i::Handle<i::JSArrayBufferView> obj,
-    i::Handle<i::JSArrayBuffer> buffer,
-    size_t byte_offset,
-    size_t byte_length) {
-  DCHECK(byte_offset + byte_length <=
-         static_cast<size_t>(buffer->byte_length()->Number()));
-
-  obj->set_buffer(*buffer);
-
-  obj->set_weak_next(buffer->weak_first_view());
-  buffer->set_weak_first_view(*obj);
-
-  i::Handle<i::Object> byte_offset_object =
-      isolate->factory()->NewNumberFromSize(byte_offset);
-  obj->set_byte_offset(*byte_offset_object);
-
-  i::Handle<i::Object> byte_length_object =
-      isolate->factory()->NewNumberFromSize(byte_length);
-  obj->set_byte_length(*byte_length_object);
-}
-
-template<typename ElementType,
-         ExternalArrayType array_type,
-         i::ElementsKind elements_kind>
-i::Handle<i::JSTypedArray> NewTypedArray(
-    i::Isolate* isolate,
-    Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
-  i::Handle<i::JSTypedArray> obj =
-      isolate->factory()->NewJSTypedArray(array_type);
-  i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
-
-  DCHECK(byte_offset % sizeof(ElementType) == 0);
-
-  CHECK(length <= (std::numeric_limits<size_t>::max() / sizeof(ElementType)));
-  CHECK(length <= static_cast<size_t>(i::Smi::kMaxValue));
-  size_t byte_length = length * sizeof(ElementType);
-  SetupArrayBufferView(
-      isolate, obj, buffer, byte_offset, byte_length);
-
-  i::Handle<i::Object> length_object =
-      isolate->factory()->NewNumberFromSize(length);
-  obj->set_length(*length_object);
-
-  i::Handle<i::ExternalArray> elements =
-      isolate->factory()->NewExternalArray(
-          static_cast<int>(length), array_type,
-          static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
-  i::Handle<i::Map> map =
-      i::JSObject::GetElementsTransitionMap(obj, elements_kind);
-  i::JSObject::SetMapAndElements(obj, map, elements);
-  return obj;
-}
-
-
 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size)                       \
   Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer,      \
-                                    size_t byte_offset, size_t length) {     \
+                                      size_t byte_offset, size_t length) {   \
     i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate();    \
     LOG_API(isolate,                                                         \
-        "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)");     \
+            "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
     ENTER_V8(isolate);                                                       \
     if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue),   \
-            "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)",  \
-            "length exceeds max allowed value")) {                           \
-      return Local<Type##Array>();                                          \
+                         "v8::" #Type                                        \
+                         "Array::New(Handle<ArrayBuffer>, size_t, size_t)",  \
+                         "length exceeds max allowed value")) {              \
+      return Local<Type##Array>();                                           \
     }                                                                        \
-    i::Handle<i::JSTypedArray> obj =                                         \
-        NewTypedArray<ctype, v8::kExternal##Type##Array,                     \
-                      i::EXTERNAL_##TYPE##_ELEMENTS>(                        \
-            isolate, array_buffer, byte_offset, length);                     \
+    i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);   \
+    i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(    \
+        v8::kExternal##Type##Array, buffer, byte_offset, length);            \
     return Utils::ToLocal##Type##Array(obj);                                 \
   }
 
@@ -6185,9 +6129,8 @@ Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
   i::Isolate* isolate = buffer->GetIsolate();
   LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
   ENTER_V8(isolate);
-  i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
-  SetupArrayBufferView(
-      isolate, obj, buffer, byte_offset, byte_length);
+  i::Handle<i::JSDataView> obj =
+      isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
   return Utils::ToLocal(obj);
 }
 
index d1deb75..e284382 100644 (file)
@@ -1766,6 +1766,29 @@ JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) {
   }
 }
 
+
+void SetupArrayBufferView(i::Isolate* isolate,
+                          i::Handle<i::JSArrayBufferView> obj,
+                          i::Handle<i::JSArrayBuffer> buffer,
+                          size_t byte_offset, size_t byte_length) {
+  DCHECK(byte_offset + byte_length <=
+         static_cast<size_t>(buffer->byte_length()->Number()));
+
+  obj->set_buffer(*buffer);
+
+  obj->set_weak_next(buffer->weak_first_view());
+  buffer->set_weak_first_view(*obj);
+
+  i::Handle<i::Object> byte_offset_object =
+      isolate->factory()->NewNumberFromSize(byte_offset);
+  obj->set_byte_offset(*byte_offset_object);
+
+  i::Handle<i::Object> byte_length_object =
+      isolate->factory()->NewNumberFromSize(byte_length);
+  obj->set_byte_length(*byte_length_object);
+}
+
+
 }  // namespace
 
 
@@ -1781,25 +1804,38 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) {
 
 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
                                               Handle<JSArrayBuffer> buffer,
+                                              size_t byte_offset,
                                               size_t length) {
-  DCHECK(length <= static_cast<size_t>(kMaxInt));
-  Handle<JSTypedArray> array = NewJSTypedArray(type);
-  array->set_buffer(*buffer);
-  array->set_weak_next(buffer->weak_first_view());
-  buffer->set_weak_first_view(*array);
-  array->set_byte_offset(Smi::FromInt(0));
-  Handle<Object> byte_length_handle =
-      NewNumberFromSize(length * GetExternalArrayElementSize(type));
-  array->set_byte_length(*byte_length_handle);
-  Handle<Object> length_handle = NewNumberFromSize(length);
-  array->set_length(*length_handle);
-  Handle<ExternalArray> elements =
-      NewExternalArray(static_cast<int>(length), type, buffer->backing_store());
-  JSObject::SetMapAndElements(array,
-                              JSObject::GetElementsTransitionMap(
-                                  array, GetExternalArrayElementsKind(type)),
-                              elements);
-  return array;
+  Handle<JSTypedArray> obj = NewJSTypedArray(type);
+
+  size_t element_size = GetExternalArrayElementSize(type);
+  ElementsKind elements_kind = GetExternalArrayElementsKind(type);
+
+  CHECK(byte_offset % element_size == 0);
+
+  CHECK(length <= (std::numeric_limits<size_t>::max() / element_size));
+  CHECK(length <= static_cast<size_t>(Smi::kMaxValue));
+  size_t byte_length = length * element_size;
+  SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
+
+  Handle<Object> length_object = NewNumberFromSize(length);
+  obj->set_length(*length_object);
+
+  Handle<ExternalArray> elements = NewExternalArray(
+      static_cast<int>(length), type,
+      static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
+  Handle<Map> map = JSObject::GetElementsTransitionMap(obj, elements_kind);
+  JSObject::SetMapAndElements(obj, map, elements);
+  return obj;
+}
+
+
+Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
+                                          size_t byte_offset,
+                                          size_t byte_length) {
+  Handle<JSDataView> obj = NewJSDataView();
+  SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
+  return obj;
 }
 
 
index 089ab97..1a658d1 100644 (file)
@@ -439,9 +439,11 @@ class Factory FINAL {
   // Creates a new JSTypedArray with the specified buffer.
   Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type,
                                        Handle<JSArrayBuffer> buffer,
-                                       size_t length);
+                                       size_t byte_offset, size_t length);
 
   Handle<JSDataView> NewJSDataView();
+  Handle<JSDataView> NewJSDataView(Handle<JSArrayBuffer> buffer,
+                                   size_t byte_offset, size_t byte_length);
 
   // Allocates a Harmony proxy.
   Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);
index 3ef5bdc..194591a 100644 (file)
@@ -81,7 +81,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
                           FeedbackVectorSlot::Invalid());
   TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
     Handle<JSTypedArray> array =
-        factory()->NewJSTypedArray(type, buffer, kLength);
+        factory()->NewJSTypedArray(type, buffer, 0, kLength);
 
     Node* key = Parameter(Type::Integral32());
     Node* base = HeapConstant(array);
@@ -120,7 +120,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
   TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
     TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
       Handle<JSTypedArray> array =
-          factory()->NewJSTypedArray(type, buffer, kLength);
+          factory()->NewJSTypedArray(type, buffer, 0, kLength);
 
       Node* key = Parameter(Type::Integral32());
       Node* base = HeapConstant(array);