Share code between Factory::NewJSTypedArray and API
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
This commit is contained in:
parent
23da1cebec
commit
7cf9d1c807
79
src/api.cc
79
src/api.cc
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user