| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index 0046ff667ead130fd9bb19c70caf972d90e17cd4..863514babdf4ca9f6f288229d5e4bc3e356df65f 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -685,7 +685,7 @@ void Runtime::SetupArrayBuffer(Isolate* isolate,
|
|
|
| array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
|
| isolate->heap()->set_array_buffers_list(*array_buffer);
|
| - array_buffer->set_weak_first_array(isolate->heap()->undefined_value());
|
| + array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
|
| }
|
|
|
|
|
| @@ -850,8 +850,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
|
|
|
| Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
|
| holder->set_length(*length_obj);
|
| - holder->set_weak_next(buffer->weak_first_array());
|
| - buffer->set_weak_first_array(*holder);
|
| + holder->set_weak_next(buffer->weak_first_view());
|
| + buffer->set_weak_first_view(*holder);
|
|
|
| Handle<ExternalArray> elements =
|
| isolate->factory()->NewExternalArray(
|
| @@ -1003,6 +1003,223 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
|
| }
|
|
|
|
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) {
|
| + HandleScope scope(isolate);
|
| + ASSERT(args.length() == 4);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3);
|
| +
|
| + holder->set_buffer(*buffer);
|
| + ASSERT(byte_offset->IsNumber());
|
| + ASSERT(
|
| + NumberToSize(isolate, buffer->byte_length()) >=
|
| + NumberToSize(isolate, *byte_offset)
|
| + + NumberToSize(isolate, *byte_length));
|
| + holder->set_byte_offset(*byte_offset);
|
| + ASSERT(byte_length->IsNumber());
|
| + holder->set_byte_length(*byte_length);
|
| +
|
| + holder->set_weak_next(buffer->weak_first_view());
|
| + buffer->set_weak_first_view(*holder);
|
| +
|
| + return isolate->heap()->undefined_value();
|
| +}
|
| +
|
| +
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetBuffer) {
|
| + HandleScope scope(isolate);
|
| + ASSERT(args.length() == 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
|
| + return data_view->buffer();
|
| +}
|
| +
|
| +
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) {
|
| + HandleScope scope(isolate);
|
| + ASSERT(args.length() == 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
|
| + return data_view->byte_offset();
|
| +}
|
| +
|
| +
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) {
|
| + HandleScope scope(isolate);
|
| + ASSERT(args.length() == 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
|
| + return data_view->byte_length();
|
| +}
|
| +
|
| +
|
| +inline static bool NeedToFlipBytes(bool is_little_endian) {
|
| +#ifdef V8_TARGET_LITTLE_ENDIAN
|
| + return !is_little_endian;
|
| +#else
|
| + return is_little_endian;
|
| +#endif
|
| +}
|
| +
|
| +
|
| +template<int n>
|
| +inline void CopyBytes(uint8_t* target, uint8_t* source) {
|
| + for (int i = 0; i < n; i++) {
|
| + *(target++) = *(source++);
|
| + }
|
| +}
|
| +
|
| +
|
| +template<int n>
|
| +inline void FlipBytes(uint8_t* target, uint8_t* source) {
|
| + source = source + (n-1);
|
| + for (int i = 0; i < n; i++) {
|
| + *(target++) = *(source--);
|
| + }
|
| +}
|
| +
|
| +
|
| +template<typename T>
|
| +inline static bool DataViewGetValue(
|
| + Isolate* isolate,
|
| + Handle<JSDataView> data_view,
|
| + Handle<Object> byte_offset_obj,
|
| + bool is_little_endian,
|
| + T* result) {
|
| + size_t byte_offset = NumberToSize(isolate, *byte_offset_obj);
|
| + Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
|
| +
|
| + size_t data_view_byte_offset =
|
| + NumberToSize(isolate, data_view->byte_offset());
|
| + size_t data_view_byte_length =
|
| + NumberToSize(isolate, data_view->byte_length());
|
| + if (byte_offset + sizeof(T) > data_view_byte_length ||
|
| + byte_offset + sizeof(T) < byte_offset) { // overflow
|
| + return false;
|
| + }
|
| +
|
| + union Value {
|
| + T data;
|
| + uint8_t bytes[sizeof(T)];
|
| + };
|
| +
|
| + Value value;
|
| + size_t buffer_offset = data_view_byte_offset + byte_offset;
|
| + ASSERT(
|
| + NumberToSize(isolate, buffer->byte_length())
|
| + >= buffer_offset + sizeof(T));
|
| + uint8_t* source =
|
| + static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
|
| + if (NeedToFlipBytes(is_little_endian)) {
|
| + FlipBytes<sizeof(T)>(value.bytes, source);
|
| + } else {
|
| + CopyBytes<sizeof(T)>(value.bytes, source);
|
| + }
|
| + *result = value.data;
|
| + return true;
|
| +}
|
| +
|
| +
|
| +template<typename T>
|
| +static bool DataViewSetValue(
|
| + Isolate* isolate,
|
| + Handle<JSDataView> data_view,
|
| + Handle<Object> byte_offset_obj,
|
| + bool is_little_endian,
|
| + T data) {
|
| + size_t byte_offset = NumberToSize(isolate, *byte_offset_obj);
|
| + Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
|
| +
|
| + size_t data_view_byte_offset =
|
| + NumberToSize(isolate, data_view->byte_offset());
|
| + size_t data_view_byte_length =
|
| + NumberToSize(isolate, data_view->byte_length());
|
| + if (byte_offset + sizeof(T) > data_view_byte_length ||
|
| + byte_offset + sizeof(T) < byte_offset) { // overflow
|
| + return false;
|
| + }
|
| +
|
| + union Value {
|
| + T data;
|
| + uint8_t bytes[sizeof(T)];
|
| + };
|
| +
|
| + Value value;
|
| + value.data = data;
|
| + size_t buffer_offset = data_view_byte_offset + byte_offset;
|
| + ASSERT(
|
| + NumberToSize(isolate, buffer->byte_length())
|
| + >= buffer_offset + sizeof(T));
|
| + uint8_t* target =
|
| + static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
|
| + if (NeedToFlipBytes(is_little_endian)) {
|
| + FlipBytes<sizeof(T)>(target, value.bytes);
|
| + } else {
|
| + CopyBytes<sizeof(T)>(target, value.bytes);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +
|
| +#define DATA_VIEW_GETTER(TypeName, Type, Converter) \
|
| + RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGet##TypeName) { \
|
| + HandleScope scope(isolate); \
|
| + ASSERT(args.length() == 3); \
|
| + CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \
|
| + CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \
|
| + Type result; \
|
| + if (DataViewGetValue( \
|
| + isolate, holder, offset, is_little_endian, &result)) { \
|
| + return isolate->heap()->Converter(result); \
|
| + } else { \
|
| + return isolate->Throw(*isolate->factory()->NewRangeError( \
|
| + "invalid_data_view_accessor_offset", \
|
| + HandleVector<Object>(NULL, 0))); \
|
| + } \
|
| + }
|
| +
|
| +DATA_VIEW_GETTER(Uint8, uint8_t, NumberFromUint32)
|
| +DATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32)
|
| +DATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32)
|
| +DATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32)
|
| +DATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32)
|
| +DATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32)
|
| +DATA_VIEW_GETTER(Float32, float, NumberFromDouble)
|
| +DATA_VIEW_GETTER(Float64, double, NumberFromDouble)
|
| +
|
| +#undef DATA_VIEW_GETTER
|
| +
|
| +#define DATA_VIEW_SETTER(TypeName, Type) \
|
| + RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) { \
|
| + HandleScope scope(isolate); \
|
| + ASSERT(args.length() == 4); \
|
| + CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); \
|
| + CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \
|
| + Type v = static_cast<Type>(value->Number()); \
|
| + if (DataViewSetValue( \
|
| + isolate, holder, offset, is_little_endian, v)) { \
|
| + return isolate->heap()->undefined_value(); \
|
| + } else { \
|
| + return isolate->Throw(*isolate->factory()->NewRangeError( \
|
| + "invalid_data_view_accessor_offset", \
|
| + HandleVector<Object>(NULL, 0))); \
|
| + } \
|
| + }
|
| +
|
| +DATA_VIEW_SETTER(Uint8, uint8_t)
|
| +DATA_VIEW_SETTER(Int8, int8_t)
|
| +DATA_VIEW_SETTER(Uint16, uint16_t)
|
| +DATA_VIEW_SETTER(Int16, int16_t)
|
| +DATA_VIEW_SETTER(Uint32, uint32_t)
|
| +DATA_VIEW_SETTER(Int32, int32_t)
|
| +DATA_VIEW_SETTER(Float32, float)
|
| +DATA_VIEW_SETTER(Float64, double)
|
| +
|
| +#undef DATA_VIEW_SETTER
|
| +
|
| +
|
| RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 1);
|
|
|