Chromium Code Reviews| Index: src/api.cc |
| diff --git a/src/api.cc b/src/api.cc |
| index 5fb810312ac3631dd0e12363a8ca5c036fdaaad2..4b5be3a6bcd76e91d068ca812947169eca413d64 100644 |
| --- a/src/api.cc |
| +++ b/src/api.cc |
| @@ -2587,6 +2587,13 @@ bool Value::IsArrayBuffer() const { |
| } |
| +bool Value::IsDataView() const { |
| + if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsDataView()")) |
| + return false; |
| + return Utils::OpenHandle(this)->IsJSDataView(); |
| +} |
| + |
| + |
| bool Value::IsTypedArray() const { |
| if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsArrayBuffer()")) |
| return false; |
| @@ -2966,6 +2973,15 @@ void v8::ArrayBuffer::CheckCast(Value* that) { |
| } |
| +void v8::DataView::CheckCast(Value* that) { |
| + if (IsDeadCheck(i::Isolate::Current(), "v8::DataView::Cast()")) return; |
| + i::Handle<i::Object> obj = Utils::OpenHandle(that); |
| + ApiCheck(obj->IsJSDataView(), |
| + "v8::DataView::Cast()", |
| + "Could not convert to DataView"); |
| +} |
| + |
| + |
| void v8::TypedArray::CheckCast(Value* that) { |
| if (IsDeadCheck(i::Isolate::Current(), "v8::TypedArray::Cast()")) return; |
| i::Handle<i::Object> obj = Utils::OpenHandle(that); |
| @@ -6074,6 +6090,170 @@ Local<ArrayBuffer> v8::ArrayBuffer::New(void* data, size_t byte_length) { |
| } |
| +Local<DataView> v8::DataView::New(Handle<ArrayBuffer> array_buffer, |
| + size_t byte_offset, |
| + size_t byte_length) { |
| + i::Isolate* isolate = i::Isolate::Current(); |
| + i::Handle<i::JSDataView> obj = |
| + isolate->factory()->NewJSDataView(); |
| + i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); |
| + ASSERT(byte_offset + byte_length <= |
| + 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>(byte_length)); |
| + obj->set_byte_length(*byte_length_object); |
| + i::Handle<i::ExternalArray> elements = |
| + isolate->factory()->NewExternalArray( |
| + static_cast<int>(byte_length), |
| + kExternalUnsignedByteArray, |
| + static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); |
| + i::Handle<i::Map> map = |
| + isolate->factory()->GetElementsTransitionMap( |
| + obj, i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS); |
| + obj->set_map(*map); |
| + obj->set_elements(*elements); |
| + return Utils::ToLocal(obj); |
| +} |
| + |
| + |
| +Local<ArrayBuffer> v8::DataView::Buffer() { |
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
| + if (IsDeadCheck(isolate, "v8::DataView::Buffer()")) |
| + return Local<ArrayBuffer>(); |
| + i::Handle<i::JSDataView> 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::DataView::ByteOffset() const { |
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
| + if (IsDeadCheck(isolate, "v8::DataView::ByteOffset()")) return 0; |
| + i::Handle<i::JSDataView> obj = Utils::OpenHandle(this); |
| + return static_cast<size_t>(obj->byte_offset()->Number()); |
| +} |
| + |
| + |
| +size_t v8::DataView::ByteLength() const { |
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
| + if (IsDeadCheck(isolate, "v8::DataView::ByteLength()")) return 0; |
| + i::Handle<i::JSDataView> obj = Utils::OpenHandle(this); |
| + return static_cast<size_t>(obj->byte_length()->Number()); |
| +} |
| + |
| + |
| +void* v8::DataView::Data() const { |
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
| + if (IsDeadCheck(isolate, "v8::DataView::BaseAddress()")) return NULL; |
| + i::Handle<i::JSDataView> 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; |
| +} |
| + |
| + |
| +#define DATA_VIEW_GETTER(FunctionName, TypeName) \ |
|
Sven Panne
2013/05/24 06:58:25
Don't duplicate tons of code here, just make swizz
bnoordhuis
2013/05/24 11:49:03
That means adding a `bool little_endian` to the Ge
|
| + TypeName v8::DataView::FunctionName(size_t byte_offset) const { \ |
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); \ |
| + if (IsDeadCheck(isolate, "v8::DataView::" # FunctionName)) return 0; \ |
| + i::Handle<i::JSDataView> obj = Utils::OpenHandle(this); \ |
| + size_t byte_length = static_cast<size_t>(obj->byte_length()->Number()); \ |
| + if (byte_offset + sizeof(TypeName) > byte_length) return 0; \ |
| + if (byte_offset + sizeof(TypeName) < byte_offset) return 0; \ |
| + i::Handle<i::JSArrayBuffer> buffer( \ |
| + i::JSArrayBuffer::cast(obj->buffer())); \ |
| + uint8_t* data = static_cast<uint8_t*>(buffer->backing_store()) + \ |
| + static_cast<size_t>(obj->byte_offset()->Number()) + \ |
| + byte_offset; \ |
| + return *reinterpret_cast<TypeName*>(data); \ |
| + } |
| + |
| +#define DATA_VIEW_GETTER_SWIZZLE(FunctionName, TypeName) \ |
| + TypeName v8::DataView::FunctionName(size_t byte_offset, \ |
| + bool little_endian) const { \ |
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); \ |
| + if (IsDeadCheck(isolate, "v8::DataView::" # FunctionName)) return 0; \ |
| + i::Handle<i::JSDataView> obj = Utils::OpenHandle(this); \ |
| + size_t byte_length = static_cast<size_t>(obj->byte_length()->Number()); \ |
| + if (byte_offset + sizeof(TypeName) > byte_length) return 0; \ |
| + if (byte_offset + sizeof(TypeName) < byte_offset) return 0; \ |
| + i::Handle<i::JSArrayBuffer> buffer( \ |
| + i::JSArrayBuffer::cast(obj->buffer())); \ |
| + uint8_t* data = static_cast<uint8_t*>(buffer->backing_store()) + \ |
| + static_cast<size_t>(obj->byte_offset()->Number()) + \ |
| + byte_offset; \ |
| + TypeName value; \ |
| + i::OS::MemCopy(&value, data, sizeof(value)); \ |
| + if (little_endian ^ i::IsLittleEndian()) i::Swizzle(&value); \ |
| + return value; \ |
| + } |
| + |
| +#define DATA_VIEW_SETTER(FunctionName, TypeName) \ |
|
Sven Panne
2013/05/24 06:58:25
Same here.
|
| + void v8::DataView::FunctionName(size_t byte_offset, TypeName value) { \ |
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); \ |
| + if (IsDeadCheck(isolate, "v8::DataView::" # FunctionName)) return; \ |
| + i::Handle<i::JSDataView> obj = Utils::OpenHandle(this); \ |
| + size_t byte_length = static_cast<size_t>(obj->byte_length()->Number()); \ |
| + if (byte_offset + sizeof(TypeName) > byte_length) return; \ |
| + if (byte_offset + sizeof(TypeName) < byte_offset) return; \ |
| + i::Handle<i::JSArrayBuffer> buffer( \ |
| + i::JSArrayBuffer::cast(obj->buffer())); \ |
| + uint8_t* data = static_cast<uint8_t*>(buffer->backing_store()) + \ |
| + static_cast<size_t>(obj->byte_offset()->Number()) + \ |
| + byte_offset; \ |
| + i::OS::MemCopy(data, &value, sizeof(value)); \ |
| + } |
| + |
| + |
| +#define DATA_VIEW_SETTER_SWIZZLE(FunctionName, TypeName) \ |
|
Sven Panne
2013/05/24 12:19:20
Can't we make this macro a template and simply del
|
| + void v8::DataView::FunctionName(size_t byte_offset, \ |
| + TypeName value, \ |
| + bool little_endian) { \ |
| + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); \ |
| + if (IsDeadCheck(isolate, "v8::DataView::" # FunctionName)) return; \ |
| + i::Handle<i::JSDataView> obj = Utils::OpenHandle(this); \ |
| + size_t byte_length = static_cast<size_t>(obj->byte_length()->Number()); \ |
| + if (byte_offset + sizeof(TypeName) > byte_length) return; \ |
| + if (byte_offset + sizeof(TypeName) < byte_offset) return; \ |
| + i::Handle<i::JSArrayBuffer> buffer( \ |
| + i::JSArrayBuffer::cast(obj->buffer())); \ |
| + uint8_t* data = static_cast<uint8_t*>(buffer->backing_store()) + \ |
| + static_cast<size_t>(obj->byte_offset()->Number()) + \ |
| + byte_offset; \ |
| + if (little_endian ^ i::IsLittleEndian()) i::Swizzle(&value); \ |
| + i::OS::MemCopy(data, &value, sizeof(value)); \ |
| + } |
| + |
| +DATA_VIEW_GETTER(GetInt8, int8_t) |
|
Sven Panne
2013/05/24 12:19:20
These and the following lines would simply delegat
|
| +DATA_VIEW_GETTER(GetUint8, uint8_t) |
| +DATA_VIEW_GETTER_SWIZZLE(GetInt16, int16_t) |
| +DATA_VIEW_GETTER_SWIZZLE(GetUint16, uint16_t) |
| +DATA_VIEW_GETTER_SWIZZLE(GetInt32, int32_t) |
| +DATA_VIEW_GETTER_SWIZZLE(GetUint32, uint32_t) |
| +DATA_VIEW_GETTER_SWIZZLE(GetFloat32, float) |
| +DATA_VIEW_GETTER_SWIZZLE(GetFloat64, double) |
| + |
| +DATA_VIEW_SETTER(SetInt8, int8_t) |
| +DATA_VIEW_SETTER(SetUint8, uint8_t) |
| +DATA_VIEW_SETTER_SWIZZLE(SetInt16, int16_t) |
| +DATA_VIEW_SETTER_SWIZZLE(SetUint16, uint16_t) |
| +DATA_VIEW_SETTER_SWIZZLE(SetInt32, int32_t) |
| +DATA_VIEW_SETTER_SWIZZLE(SetUint32, uint32_t) |
| +DATA_VIEW_SETTER_SWIZZLE(SetFloat32, float) |
| +DATA_VIEW_SETTER_SWIZZLE(SetFloat64, double) |
| + |
| +#undef DATA_VIEW_GETTER_SWIZZLE |
| +#undef DATA_VIEW_SETTER_SWIZZLE |
| +#undef DATA_VIEW_GETTER |
| +#undef DATA_VIEW_SETTER |
| + |
| + |
| Local<ArrayBuffer> v8::TypedArray::Buffer() { |
| i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
| if (IsDeadCheck(isolate, "v8::TypedArray::Buffer()")) |