 Chromium Code Reviews
 Chromium Code Reviews Issue 14195034:
  First cut at API for native Typed Arrays.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 14195034:
  First cut at API for native Typed Arrays.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| Index: src/api.cc | 
| diff --git a/src/api.cc b/src/api.cc | 
| index 2b24ab07f64fa25763a73ebac503d89508567dae..188b86ee444008022105806c8c052526622c1379 100644 | 
| --- a/src/api.cc | 
| +++ b/src/api.cc | 
| @@ -2755,6 +2755,39 @@ void v8::ArrayBuffer::CheckCast(Value* that) { | 
| } | 
| +void v8::TypedArray::CheckCast(Value* that) { | 
| + if (IsDeadCheck(i::Isolate::Current(), "v8::TypedArray::Cast()")) return; | 
| + i::Handle<i::Object> obj = Utils::OpenHandle(that); | 
| + ApiCheck(obj->IsJSTypedArray(), | 
| + "v8::TypedArray::Cast()", | 
| + "Could not convert to TypedArray"); | 
| +} | 
| + | 
| + | 
| +#define CHECK_TYPED_ARRAY_CAST(ApiClass, typeConst) \ | 
| + void v8::ApiClass::CheckCast(Value* that) { \ | 
| + if (IsDeadCheck(i::Isolate::Current(), "v8::" #ApiClass "::Cast()")) \ | 
| + return; \ | 
| + i::Handle<i::Object> obj = Utils::OpenHandle(that); \ | 
| + ApiCheck(obj->IsJSTypedArray() \ | 
| + && i::JSTypedArray::cast(*obj)->type() == typeConst, \ | 
| 
rossberg
2013/04/29 10:50:27
Nit: indentation (also, we usually put the && on t
 
Dmitry Lomov (no reviews)
2013/04/29 11:08:53
Done.
 | 
| + "v8::" #ApiClass "::Cast()", \ | 
| + "Could not convert to " #ApiClass); \ | 
| + } | 
| + | 
| + | 
| +CHECK_TYPED_ARRAY_CAST(Uint8Array, kExternalUnsignedByteArray) | 
| +CHECK_TYPED_ARRAY_CAST(Int8Array, kExternalByteArray) | 
| +CHECK_TYPED_ARRAY_CAST(Uint16Array, kExternalUnsignedShortArray) | 
| +CHECK_TYPED_ARRAY_CAST(Int16Array, kExternalShortArray) | 
| +CHECK_TYPED_ARRAY_CAST(Uint32Array, kExternalUnsignedIntArray) | 
| +CHECK_TYPED_ARRAY_CAST(Int32Array, kExternalIntArray) | 
| +CHECK_TYPED_ARRAY_CAST(Float32Array, kExternalFloatArray) | 
| +CHECK_TYPED_ARRAY_CAST(Float64Array, kExternalDoubleArray) | 
| + | 
| +#undef CHECK_TYPED_ARRAY_CAST | 
| + | 
| + | 
| void v8::Date::CheckCast(v8::Value* that) { | 
| i::Isolate* isolate = i::Isolate::Current(); | 
| if (IsDeadCheck(isolate, "v8::Date::Cast()")) return; | 
| @@ -5806,6 +5839,129 @@ Local<ArrayBuffer> v8::ArrayBuffer::New(void* data, size_t byte_length) { | 
| } | 
| +Local<ArrayBuffer> v8::TypedArray::Buffer() { | 
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 
| + if (IsDeadCheck(isolate, "v8::TypedArray::Buffer()")) | 
| + return Local<ArrayBuffer>(); | 
| + i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this); | 
| + ASSERT(obj->buffer()->IsJSArrayBuffer()); | 
| + i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(obj->buffer())); | 
| + return Utils::ToLocal(buffer); | 
| +} | 
| + | 
| + | 
| +size_t v8::TypedArray::ByteOffset() { | 
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 
| + if (IsDeadCheck(isolate, "v8::TypedArray::ByteOffset()")) return 0; | 
| + i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this); | 
| + return static_cast<size_t>(obj->byte_offset()->Number()); | 
| +} | 
| + | 
| + | 
| +size_t v8::TypedArray::ByteLength() { | 
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 
| + if (IsDeadCheck(isolate, "v8::TypedArray::ByteLength()")) return 0; | 
| + i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this); | 
| + return static_cast<size_t>(obj->byte_length()->Number()); | 
| +} | 
| + | 
| + | 
| +size_t v8::TypedArray::Length() { | 
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 
| + if (IsDeadCheck(isolate, "v8::TypedArray::Length()")) return 0; | 
| + i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this); | 
| + return static_cast<size_t>(obj->length()->Number()); | 
| +} | 
| + | 
| + | 
| +void* v8::TypedArray::BaseAddress() { | 
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 
| + if (IsDeadCheck(isolate, "v8::TypedArray::BaseAddress()")) return 0; | 
| 
rossberg
2013/04/29 10:50:27
Nit: NULL not 0
 
Dmitry Lomov (no reviews)
2013/04/29 11:08:53
Done.
 | 
| + i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this); | 
| + i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(obj->buffer())); | 
| + void* buffer_data = buffer->backing_store(); | 
| + size_t byte_offset = static_cast<size_t>(obj->byte_offset()->Number()); | 
| + return static_cast<uint8_t*>(buffer_data) + byte_offset; | 
| +} | 
| + | 
| + | 
| +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); | 
| + | 
| + ASSERT(byte_offset % sizeof(ElementType) == 0); | 
| + ASSERT(byte_offset + length * sizeof(ElementType) <= | 
| + static_cast<size_t>(buffer->byte_length()->Number())); | 
| + | 
| + obj->set_buffer(*buffer); | 
| + | 
| + i::Handle<i::Object> byte_offset_object = isolate->factory()->NewNumber( | 
| + static_cast<double>(byte_offset)); | 
| + obj->set_byte_offset(*byte_offset_object); | 
| + | 
| + i::Handle<i::Object> byte_length_object = isolate->factory()->NewNumber( | 
| + static_cast<double>(length*sizeof(ElementType))); | 
| 
rossberg
2013/04/29 10:50:27
Nit: space around *
 
Dmitry Lomov (no reviews)
2013/04/29 11:08:53
Done.
 | 
| + obj->set_byte_length(*byte_length_object); | 
| + | 
| + i::Handle<i::Object> length_object = isolate->factory()->NewNumber( | 
| + static_cast<double>(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 = | 
| + isolate->factory()->GetElementsTransitionMap( | 
| + obj, elements_kind); | 
| + obj->set_map(*map); | 
| + obj->set_elements(*elements); | 
| + return obj; | 
| +} | 
| + | 
| + | 
| +#define TYPED_ARRAY_NEW(TypedArray, elementType, arrayType, elementsKind) \ | 
| 
rossberg
2013/04/29 10:50:27
Nit: ElementType, array_type, elements_kind
 
Dmitry Lomov (no reviews)
2013/04/29 11:08:53
Done.
 | 
| + Local<TypedArray> TypedArray::New(Handle<ArrayBuffer> array_buffer, \ | 
| + size_t byte_offset, size_t length) { \ | 
| + i::Isolate* isolate = i::Isolate::Current(); \ | 
| + EnsureInitializedForIsolate(isolate, \ | 
| + "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \ | 
| + LOG_API(isolate, \ | 
| + "v8::" #TypedArray "::New(Handle<ArrayBuffer>, size_t, size_t)"); \ | 
| + ENTER_V8(isolate); \ | 
| + i::Handle<i::JSTypedArray> obj = \ | 
| + NewTypedArray<elementType, arrayType, elementsKind>( \ | 
| + isolate, array_buffer, byte_offset, length); \ | 
| + return Utils::ToLocal##TypedArray(obj); \ | 
| + } | 
| + | 
| + | 
| +TYPED_ARRAY_NEW(Uint8Array, uint8_t, kExternalUnsignedByteArray, | 
| + i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS) | 
| +TYPED_ARRAY_NEW(Int8Array, int8_t, kExternalByteArray, | 
| + i::EXTERNAL_BYTE_ELEMENTS) | 
| +TYPED_ARRAY_NEW(Uint16Array, uint16_t, kExternalUnsignedShortArray, | 
| + i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS) | 
| +TYPED_ARRAY_NEW(Int16Array, int16_t, kExternalShortArray, | 
| + i::EXTERNAL_SHORT_ELEMENTS) | 
| +TYPED_ARRAY_NEW(Uint32Array, uint32_t, kExternalUnsignedIntArray, | 
| + i::EXTERNAL_UNSIGNED_INT_ELEMENTS) | 
| +TYPED_ARRAY_NEW(Int32Array, int32_t, kExternalIntArray, | 
| + i::EXTERNAL_INT_ELEMENTS) | 
| +TYPED_ARRAY_NEW(Float32Array, float, kExternalFloatArray, | 
| + i::EXTERNAL_FLOAT_ELEMENTS) | 
| +TYPED_ARRAY_NEW(Float64Array, double, kExternalDoubleArray, | 
| + i::EXTERNAL_DOUBLE_ELEMENTS) | 
| + | 
| +#undef TYPED_ARRAY_NEW | 
| + | 
| + | 
| Local<Symbol> v8::Symbol::New(Isolate* isolate) { | 
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 
| EnsureInitializedForIsolate(i_isolate, "v8::Symbol::New()"); |