Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1648)

Unified Diff: src/runtime.cc

Issue 17153011: DataView implementation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.h ('k') | src/typedarray.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « src/runtime.h ('k') | src/typedarray.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698