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

Unified Diff: src/builtins/builtins-dataview.cc

Issue 2306033002: [turbofan] Migrate remaining DataView builtins to C++. (Closed)
Patch Set: Created 4 years, 3 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/builtins/builtins.h ('k') | src/js/typedarray.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-dataview.cc
diff --git a/src/builtins/builtins-dataview.cc b/src/builtins/builtins-dataview.cc
index 32c5a83d2f9cd6f0a2e939881e51fc3e871b4e47..3d14e31d3a3ba377f47eb2dc2b46e66461169849 100644
--- a/src/builtins/builtins-dataview.cc
+++ b/src/builtins/builtins-dataview.cc
@@ -129,5 +129,209 @@ BUILTIN(DataViewPrototypeGetByteOffset) {
return data_view->byte_offset();
}
+namespace {
+
+bool NeedToFlipBytes(bool is_little_endian) {
+#ifdef V8_TARGET_LITTLE_ENDIAN
+ return !is_little_endian;
+#else
+ return is_little_endian;
+#endif
+}
+
+template <size_t n>
+void CopyBytes(uint8_t* target, uint8_t const* source) {
+ for (size_t i = 0; i < n; i++) {
+ *(target++) = *(source++);
+ }
+}
+
+template <size_t n>
+void FlipBytes(uint8_t* target, uint8_t const* source) {
+ source = source + (n - 1);
+ for (size_t i = 0; i < n; i++) {
+ *(target++) = *(source--);
+ }
+}
+
+// ES6 section 24.2.1.1 GetViewValue (view, requestIndex, isLittleEndian, type)
+template <typename T>
+MaybeHandle<Object> GetViewValue(Isolate* isolate, Handle<JSDataView> data_view,
+ Handle<Object> request_index,
+ bool is_little_endian) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, request_index,
+ Object::ToIndex(isolate, request_index,
+ MessageTemplate::kInvalidDataViewAccessorOffset),
+ Object);
+ size_t get_index = 0;
+ if (!TryNumberToSize(*request_index, &get_index)) {
+ THROW_NEW_ERROR(
+ isolate, NewRangeError(MessageTemplate::kInvalidDataViewAccessorOffset),
+ Object);
+ }
+ Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()),
+ isolate);
+ size_t const data_view_byte_offset = NumberToSize(data_view->byte_offset());
+ size_t const data_view_byte_length = NumberToSize(data_view->byte_length());
+ if (get_index + sizeof(T) > data_view_byte_length ||
+ get_index + sizeof(T) < get_index) { // overflow
+ THROW_NEW_ERROR(
+ isolate, NewRangeError(MessageTemplate::kInvalidDataViewAccessorOffset),
+ Object);
+ }
+ union {
+ T data;
+ uint8_t bytes[sizeof(T)];
+ } v;
+ size_t const buffer_offset = data_view_byte_offset + get_index;
+ DCHECK_GE(NumberToSize(buffer->byte_length()), buffer_offset + sizeof(T));
+ uint8_t const* const source =
+ static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
+ if (NeedToFlipBytes(is_little_endian)) {
+ FlipBytes<sizeof(T)>(v.bytes, source);
+ } else {
+ CopyBytes<sizeof(T)>(v.bytes, source);
+ }
+ return isolate->factory()->NewNumber(v.data);
+}
+
+template <typename T>
+T DataViewConvertValue(double value);
+
+template <>
+int8_t DataViewConvertValue<int8_t>(double value) {
+ return static_cast<int8_t>(DoubleToInt32(value));
+}
+
+template <>
+int16_t DataViewConvertValue<int16_t>(double value) {
+ return static_cast<int16_t>(DoubleToInt32(value));
+}
+
+template <>
+int32_t DataViewConvertValue<int32_t>(double value) {
+ return DoubleToInt32(value);
+}
+
+template <>
+uint8_t DataViewConvertValue<uint8_t>(double value) {
+ return static_cast<uint8_t>(DoubleToUint32(value));
+}
+
+template <>
+uint16_t DataViewConvertValue<uint16_t>(double value) {
+ return static_cast<uint16_t>(DoubleToUint32(value));
+}
+
+template <>
+uint32_t DataViewConvertValue<uint32_t>(double value) {
+ return DoubleToUint32(value);
+}
+
+template <>
+float DataViewConvertValue<float>(double value) {
+ return static_cast<float>(value);
+}
+
+template <>
+double DataViewConvertValue<double>(double value) {
+ return value;
+}
+
+// ES6 section 24.2.1.2 SetViewValue (view, requestIndex, isLittleEndian, type,
+// value)
+template <typename T>
+MaybeHandle<Object> SetViewValue(Isolate* isolate, Handle<JSDataView> data_view,
+ Handle<Object> request_index,
+ bool is_little_endian, Handle<Object> value) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, request_index,
+ Object::ToIndex(isolate, request_index,
+ MessageTemplate::kInvalidDataViewAccessorOffset),
+ Object);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::ToNumber(value), Object);
+ size_t get_index = 0;
+ if (!TryNumberToSize(*request_index, &get_index)) {
+ THROW_NEW_ERROR(
+ isolate, NewRangeError(MessageTemplate::kInvalidDataViewAccessorOffset),
+ Object);
+ }
+ Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()),
+ isolate);
+ size_t const data_view_byte_offset = NumberToSize(data_view->byte_offset());
+ size_t const data_view_byte_length = NumberToSize(data_view->byte_length());
+ if (get_index + sizeof(T) > data_view_byte_length ||
+ get_index + sizeof(T) < get_index) { // overflow
+ THROW_NEW_ERROR(
+ isolate, NewRangeError(MessageTemplate::kInvalidDataViewAccessorOffset),
+ Object);
+ }
+ union {
+ T data;
+ uint8_t bytes[sizeof(T)];
+ } v;
+ v.data = DataViewConvertValue<T>(value->Number());
+ size_t const buffer_offset = data_view_byte_offset + get_index;
+ DCHECK(NumberToSize(buffer->byte_length()) >= buffer_offset + sizeof(T));
+ uint8_t* const target =
+ static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
+ if (NeedToFlipBytes(is_little_endian)) {
+ FlipBytes<sizeof(T)>(target, v.bytes);
+ } else {
+ CopyBytes<sizeof(T)>(target, v.bytes);
+ }
+ return isolate->factory()->undefined_value();
+}
+
+} // namespace
+
+#define DATA_VIEW_PROTOTYPE_GET(Type, type) \
+ BUILTIN(DataViewPrototypeGet##Type) { \
+ HandleScope scope(isolate); \
+ CHECK_RECEIVER(JSDataView, data_view, "DataView.prototype.get" #Type); \
+ Handle<Object> byte_offset = args.atOrUndefined(isolate, 1); \
+ Handle<Object> is_little_endian = args.atOrUndefined(isolate, 2); \
+ Handle<Object> result; \
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \
+ isolate, result, \
+ GetViewValue<type>(isolate, data_view, byte_offset, \
+ is_little_endian->BooleanValue())); \
+ return *result; \
+ }
+DATA_VIEW_PROTOTYPE_GET(Int8, int8_t)
+DATA_VIEW_PROTOTYPE_GET(Uint8, uint8_t)
+DATA_VIEW_PROTOTYPE_GET(Int16, int16_t)
+DATA_VIEW_PROTOTYPE_GET(Uint16, uint16_t)
+DATA_VIEW_PROTOTYPE_GET(Int32, int32_t)
+DATA_VIEW_PROTOTYPE_GET(Uint32, uint32_t)
+DATA_VIEW_PROTOTYPE_GET(Float32, float)
+DATA_VIEW_PROTOTYPE_GET(Float64, double)
+#undef DATA_VIEW_PROTOTYPE_GET
+
+#define DATA_VIEW_PROTOTYPE_SET(Type, type) \
+ BUILTIN(DataViewPrototypeSet##Type) { \
+ HandleScope scope(isolate); \
+ CHECK_RECEIVER(JSDataView, data_view, "DataView.prototype.set" #Type); \
+ Handle<Object> byte_offset = args.atOrUndefined(isolate, 1); \
+ Handle<Object> value = args.atOrUndefined(isolate, 2); \
+ Handle<Object> is_little_endian = args.atOrUndefined(isolate, 3); \
+ Handle<Object> result; \
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \
+ isolate, result, \
+ SetViewValue<type>(isolate, data_view, byte_offset, \
+ is_little_endian->BooleanValue(), value)); \
+ return *result; \
+ }
+DATA_VIEW_PROTOTYPE_SET(Int8, int8_t)
+DATA_VIEW_PROTOTYPE_SET(Uint8, uint8_t)
+DATA_VIEW_PROTOTYPE_SET(Int16, int16_t)
+DATA_VIEW_PROTOTYPE_SET(Uint16, uint16_t)
+DATA_VIEW_PROTOTYPE_SET(Int32, int32_t)
+DATA_VIEW_PROTOTYPE_SET(Uint32, uint32_t)
+DATA_VIEW_PROTOTYPE_SET(Float32, float)
+DATA_VIEW_PROTOTYPE_SET(Float64, double)
+#undef DATA_VIEW_PROTOTYPE_SET
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/builtins/builtins.h ('k') | src/js/typedarray.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698