Use corerct conversions for DataView accessors.
authordslomov@chromium.org <dslomov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 15 Jul 2013 09:32:15 +0000 (09:32 +0000)
committerdslomov@chromium.org <dslomov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 15 Jul 2013 09:32:15 +0000 (09:32 +0000)
We now use DoubleTo(U)Int32 that follows ES specification.

R=titzer@chromium.org,rossberg@chromium.org

Review URL: https://codereview.chromium.org/18703007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15659 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/runtime.cc
test/mjsunit/harmony/dataview-accessors.js

index 3bc9439..7229018 100644 (file)
@@ -1216,6 +1216,59 @@ DATA_VIEW_GETTER(Float64, double, NumberFromDouble)
 
 #undef DATA_VIEW_GETTER
 
+
+template <typename T>
+static 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;
+}
+
+
 #define DATA_VIEW_SETTER(TypeName, Type)                                      \
   RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) {             \
     HandleScope scope(isolate);                                               \
@@ -1224,7 +1277,7 @@ DATA_VIEW_GETTER(Float64, double, NumberFromDouble)
     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());                              \
+    Type v = DataViewConvertValue<Type>(value->Number());                     \
     if (DataViewSetValue(                                                     \
           isolate, holder, offset, is_little_endian, v)) {                    \
       return isolate->heap()->undefined_value();                              \
index b655a41..c57841c 100644 (file)
@@ -294,12 +294,93 @@ function TestSetters() {
   runFloatTestCases(false, 7);
 
   runNegativeIndexTests(false);
-
 }
 
 TestGetters();
 TestSetters();
 
+function CheckOutOfRangeInt8(value, expected) {
+  var view = new DataView(new ArrayBuffer(100));
+  assertSame(undefined, view.setInt8(0, value));
+  assertSame(expected, view.getInt8(0));
+  assertSame(undefined, view.setInt8(0, value, true));
+  assertSame(expected, view.getInt8(0, true));
+}
+
+function CheckOutOfRangeUint8(value, expected) {
+  var view = new DataView(new ArrayBuffer(100));
+  assertSame(undefined, view.setUint8(0, value));
+  assertSame(expected, view.getUint8(0));
+  assertSame(undefined, view.setUint8(0, value, true));
+  assertSame(expected, view.getUint8(0, true));
+}
+
+function CheckOutOfRangeInt16(value, expected) {
+  var view = new DataView(new ArrayBuffer(100));
+  assertSame(undefined, view.setInt16(0, value));
+  assertSame(expected, view.getInt16(0));
+  assertSame(undefined, view.setInt16(0, value, true));
+  assertSame(expected, view.getInt16(0, true));
+}
+
+function CheckOutOfRangeUint16(value, expected) {
+  var view = new DataView(new ArrayBuffer(100));
+  assertSame(undefined, view.setUint16(0, value));
+  assertSame(expected, view.getUint16(0));
+  assertSame(undefined, view.setUint16(0, value, true));
+  assertSame(expected, view.getUint16(0, true));
+}
+
+function CheckOutOfRangeInt32(value, expected) {
+  var view = new DataView(new ArrayBuffer(100));
+  assertSame(undefined, view.setInt32(0, value));
+  assertSame(expected, view.getInt32(0));
+  assertSame(undefined, view.setInt32(0, value, true));
+  assertSame(expected, view.getInt32(0, true));
+}
+
+function CheckOutOfRangeUint32(value, expected) {
+  var view = new DataView(new ArrayBuffer(100));
+  assertSame(undefined, view.setUint32(0, value));
+  assertSame(expected, view.getUint32(0));
+  assertSame(undefined, view.setUint32(0, value, true));
+  assertSame(expected, view.getUint32(0, true));
+}
+
+function TestOutOfRange() {
+  CheckOutOfRangeInt8(0x80,   -0x80);
+  CheckOutOfRangeInt8(0x1000, 0);
+  CheckOutOfRangeInt8(-0x81,  0x7F);
+
+  CheckOutOfRangeUint8(0x100,  0);
+  CheckOutOfRangeUint8(0x1000, 0);
+  CheckOutOfRangeUint8(-0x80,  0x80);
+  CheckOutOfRangeUint8(-1,     0xFF);
+  CheckOutOfRangeUint8(-0xFF,  1);
+
+  CheckOutOfRangeInt16(0x8000,  -0x8000);
+  CheckOutOfRangeInt16(0x10000, 0);
+  CheckOutOfRangeInt16(-0x8001, 0x7FFF);
+
+  CheckOutOfRangeUint16(0x10000,  0);
+  CheckOutOfRangeUint16(0x100000, 0);
+  CheckOutOfRangeUint16(-0x8000,  0x8000);
+  CheckOutOfRangeUint16(-1,       0xFFFF);
+  CheckOutOfRangeUint16(-0xFFFF,  1);
+
+  CheckOutOfRangeInt32(0x80000000,  -0x80000000);
+  CheckOutOfRangeInt32(0x100000000, 0);
+  CheckOutOfRangeInt32(-0x80000001, 0x7FFFFFFF);
+
+  CheckOutOfRangeUint32(0x100000000,  0);
+  CheckOutOfRangeUint32(0x1000000000, 0);
+  CheckOutOfRangeUint32(-0x80000000,  0x80000000);
+  CheckOutOfRangeUint32(-1,           0xFFFFFFFF);
+  CheckOutOfRangeUint32(-0xFFFFFFFF,  1);
+}
+
+TestOutOfRange();
+
 function TestGeneralAccessors() {
   var a = new DataView(new ArrayBuffer(256));
   function CheckAccessor(name) {