From 1c2d005b3cb238028030dcbe1ef2e2477a219be7 Mon Sep 17 00:00:00 2001 From: "dslomov@chromium.org" Date: Mon, 15 Jul 2013 09:32:15 +0000 Subject: [PATCH] Use corerct conversions for DataView accessors. 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 | 55 +++++++++++++++++++- test/mjsunit/harmony/dataview-accessors.js | 83 +++++++++++++++++++++++++++++- 2 files changed, 136 insertions(+), 2 deletions(-) diff --git a/src/runtime.cc b/src/runtime.cc index 3bc9439..7229018 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -1216,6 +1216,59 @@ DATA_VIEW_GETTER(Float64, double, NumberFromDouble) #undef DATA_VIEW_GETTER + +template +static T DataViewConvertValue(double value); + + +template <> +int8_t DataViewConvertValue(double value) { + return static_cast(DoubleToInt32(value)); +} + + +template <> +int16_t DataViewConvertValue(double value) { + return static_cast(DoubleToInt32(value)); +} + + +template <> +int32_t DataViewConvertValue(double value) { + return DoubleToInt32(value); +} + + +template <> +uint8_t DataViewConvertValue(double value) { + return static_cast(DoubleToUint32(value)); +} + + +template <> +uint16_t DataViewConvertValue(double value) { + return static_cast(DoubleToUint32(value)); +} + + +template <> +uint32_t DataViewConvertValue(double value) { + return DoubleToUint32(value); +} + + +template <> +float DataViewConvertValue(double value) { + return static_cast(value); +} + + +template <> +double DataViewConvertValue(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(value->Number()); \ + Type v = DataViewConvertValue(value->Number()); \ if (DataViewSetValue( \ isolate, holder, offset, is_little_endian, v)) { \ return isolate->heap()->undefined_value(); \ diff --git a/test/mjsunit/harmony/dataview-accessors.js b/test/mjsunit/harmony/dataview-accessors.js index b655a41..c57841c 100644 --- a/test/mjsunit/harmony/dataview-accessors.js +++ b/test/mjsunit/harmony/dataview-accessors.js @@ -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) { -- 2.7.4