[dataview]: Move DataView setters to Torque.

This CL completely reimplements the DataView setters in Torque, and
removes the former C++ runtime implementation.

Change-Id: I66cdd35712e46f3931d6530a4512fa3c8eb3b3bf
Reviewed-on: https://chromium-review.googlesource.com/1104162
Commit-Queue: Théotime Grohens <theotime@google.com>
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53800}
This commit is contained in:
Théotime Grohens 2018-06-18 16:16:44 +02:00 committed by Commit Bot
parent 8f8c53ba75
commit e947d21e3d
7 changed files with 303 additions and 301 deletions

View File

@ -2277,7 +2277,6 @@ v8_source_set("v8_base") {
"src/runtime/runtime-classes.cc",
"src/runtime/runtime-collections.cc",
"src/runtime/runtime-compiler.cc",
"src/runtime/runtime-dataview.cc",
"src/runtime/runtime-date.cc",
"src/runtime/runtime-debug.cc",
"src/runtime/runtime-forin.cc",

View File

@ -201,11 +201,14 @@ extern macro IsDoubleElementsKind(constexpr ElementsKind): constexpr bool;
extern macro SmiAbove(Smi, Smi): bool;
extern operator '==' macro WordEqual(intptr, intptr): bool;
extern operator '==' macro WordEqual(uintptr, uintptr): bool;
extern operator '!=' macro WordNotEqual(intptr, intptr): bool;
extern operator '!=' macro WordNotEqual(uintptr, uintptr): bool;
extern operator '<' macro IntPtrLessThan(intptr, intptr): bool;
extern operator '>' macro IntPtrGreaterThan(intptr, intptr): bool;
extern operator '<=' macro IntPtrLessThanOrEqual(intptr, intptr): bool;
extern operator '>=' macro IntPtrGreaterThanOrEqual(intptr, intptr): bool;
extern operator '>=' macro UintPtrGreaterThanOrEqual(uintptr, uintptr): bool;
extern operator '==' macro Float64Equal(float64, float64): bool;
extern operator '!=' macro Float64NotEqual(float64, float64): bool;
@ -233,6 +236,7 @@ extern operator '>>>' macro SmiShr(Smi, constexpr int31): Smi;
extern operator '+' macro IntPtrAdd(intptr, intptr): intptr;
extern operator '-' macro IntPtrSub(intptr, intptr): intptr;
extern operator '>>>' macro WordShr(intptr, intptr): intptr;
extern operator '>>>' macro WordShr(uintptr, uintptr): uintptr;
extern operator '<<' macro WordShl(intptr, intptr): intptr;
extern operator '&' macro WordAnd(intptr, intptr): intptr;
@ -240,10 +244,11 @@ extern operator '+' macro Int32Add(int32, int32): int32;
extern operator '-' macro Int32Sub(int32, int32): int32;
extern operator '*' macro Int32Mul(int32, int32): int32;
extern operator '%' macro Int32Mod(int32, int32): int32;
extern operator '&' macro Word32And(int32, int32): int32;
extern operator '&' macro Word32And(word32, word32): int32;
extern operator '==' macro Word32Equal(word32, word32): bool;
extern operator '!=' macro Word32NotEqual(word32, word32): bool;
extern operator '>>>' macro Word32Shr(word32, word32): word32;
extern operator '<<' macro Word32Shl(word32, word32): word32;
extern operator '|' macro Word32Or(word32, word32): word32;
@ -347,6 +352,9 @@ from_constexpr<int32>(i: constexpr int31): int32 {
from_constexpr<word32>(i: constexpr int31): word32 {
return from_constexpr<int32>(i);
}
from_constexpr<uintptr>(i: constexpr int31): uintptr {
return ChangeUint32ToWord(i);
}
from_constexpr<Smi>(i: constexpr int31): Smi {
return SmiConstant(i);
}
@ -400,7 +408,7 @@ macro convert<A : type>(ui: uint32): A;
convert<Number>(ui: uint32): Number {
return ChangeUint32ToTagged(ui);
}
macro convert<A: type>(word: word32): A;
macro convert<A : type>(word: word32): A;
convert<int32>(word: word32): int32 {
return Signed(word);
}
@ -411,7 +419,7 @@ convert<uintptr>(word: word32): uintptr {
return ChangeUint32ToWord(word);
}
macro convert<A : type>(i: intptr): A;
convert<int32>(i: intptr): int32 {
convert<word32>(i: intptr): word32 {
return TruncateIntPtrToInt32(i);
}
convert<uintptr>(i: intptr): uintptr {
@ -420,10 +428,13 @@ convert<uintptr>(i: intptr): uintptr {
convert<Smi>(i: intptr): Smi {
return SmiTag(i);
}
macro convert<A: type>(ui: uintptr): A;
macro convert<A : type>(ui: uintptr): A;
convert<intptr>(ui: uintptr): intptr {
return Signed(ui);
}
convert<word32>(ui: uintptr): word32 {
return TruncateIntPtrToInt32(Signed(ui));
}
macro convert<A : type>(s: Smi): A;
convert<intptr>(s: Smi): intptr {
return SmiUntag(s);

View File

@ -18,15 +18,15 @@ class DataViewBuiltinsAssembler : public BaseBuiltinsFromDSLAssembler {
: BaseBuiltinsFromDSLAssembler(state) {}
TNode<Smi> LoadDataViewByteOffset(TNode<JSDataView> data_view) {
return LoadObjectField<Smi>(data_view, JSDataView::kByteOffsetOffset);
return CAST(LoadObjectField(data_view, JSDataView::kByteOffsetOffset));
}
TNode<Smi> LoadDataViewByteLength(TNode<JSDataView> data_view) {
return LoadObjectField<Smi>(data_view, JSDataView::kByteLengthOffset);
return CAST(LoadObjectField(data_view, JSDataView::kByteLengthOffset));
}
TNode<Uint32T> LoadUint8(TNode<RawPtrT> data_pointer, TNode<IntPtrT> offset) {
return UncheckedCast<Uint32T>(
TNode<Int32T> LoadUint8(TNode<RawPtrT> data_pointer, TNode<IntPtrT> offset) {
return UncheckedCast<Int32T>(
Load(MachineType::Uint8(), data_pointer, offset));
}
@ -35,6 +35,12 @@ class DataViewBuiltinsAssembler : public BaseBuiltinsFromDSLAssembler {
Load(MachineType::Int8(), data_pointer, offset));
}
void StoreWord8(TNode<RawPtrT> data_pointer, TNode<IntPtrT> offset,
TNode<Word32T> value) {
StoreNoWriteBarrier(MachineRepresentation::kWord8, data_pointer, offset,
value);
}
int32_t DataViewElementSize(ElementsKind elements_kind) {
return ElementsKindToByteSize(elements_kind);
}
@ -43,6 +49,16 @@ class DataViewBuiltinsAssembler : public BaseBuiltinsFromDSLAssembler {
return IntPtrConstant(BigInt::SignBits::encode(sign) |
BigInt::LengthBits::encode(digits));
}
TNode<UintPtrT> DataViewDecodeBigIntLength(TNode<BigInt> value) {
TNode<WordT> bitfield = LoadBigIntBitfield(value);
return DecodeWord<BigIntBase::LengthBits>(bitfield);
}
TNode<UintPtrT> DataViewDecodeBigIntSign(TNode<BigInt> value) {
TNode<WordT> bitfield = LoadBigIntBitfield(value);
return DecodeWord<BigIntBase::SignBits>(bitfield);
}
};
} // namespace internal

View File

@ -74,28 +74,31 @@ module data_view {
}
extern macro BitcastInt32ToFloat32(word32): float32;
extern macro BitcastFloat32ToInt32(float32): word32;
extern macro Float64ExtractLowWord32(float64): word32;
extern macro Float64ExtractHighWord32(float64): word32;
extern macro Float64InsertLowWord32(float64, word32): float64;
extern macro Float64InsertHighWord32(float64, word32): float64;
extern macro LoadUint8(RawPtr, intptr): int32;
extern macro LoadInt8(RawPtr, intptr): int32;
macro LoadDataViewUint8(data_pointer: RawPtr, offset: intptr): Smi {
return convert<Smi>(LoadUint8(data_pointer, offset));
macro LoadDataViewUint8(buffer: JSArrayBuffer, offset: intptr): Smi {
return convert<Smi>(LoadUint8(buffer.backing_store, offset));
}
macro LoadDataViewInt8(data_pointer: RawPtr, offset: intptr): Smi {
return convert<Smi>(LoadInt8(data_pointer, offset));
macro LoadDataViewInt8(buffer: JSArrayBuffer, offset: intptr): Smi {
return convert<Smi>(LoadInt8(buffer.backing_store, offset));
}
macro LoadDataView16(data_pointer: RawPtr, offset: intptr,
macro LoadDataView16(buffer: JSArrayBuffer, offset: intptr,
requested_little_endian: bool,
signed: constexpr bool): Number {
let data_pointer: RawPtr = buffer.backing_store;
let b0: int32;
let b1: int32;
let result: int32;
// Sign-extend the most significant byte by loading it as an Int8.
if (requested_little_endian) {
b0 = LoadUint8(data_pointer, offset);
@ -114,9 +117,10 @@ module data_view {
}
}
macro LoadDataView32(data_pointer: RawPtr, offset: intptr,
macro LoadDataView32(buffer: JSArrayBuffer, offset: intptr,
requested_little_endian: bool,
signed: constexpr bool): Number {
let data_pointer: RawPtr = buffer.backing_store;
let b0: word32 = LoadUint8(data_pointer, offset);
let b1: word32 = LoadUint8(data_pointer, offset + 1);
let b2: word32 = LoadUint8(data_pointer, offset + 2);
@ -139,8 +143,9 @@ module data_view {
}
}
macro LoadDataViewFloat32(data_pointer: RawPtr, offset: intptr,
macro LoadDataViewFloat32(buffer: JSArrayBuffer, offset: intptr,
requested_little_endian: bool): HeapNumber {
let data_pointer: RawPtr = buffer.backing_store;
let b0: word32 = LoadUint8(data_pointer, offset);
let b1: word32 = LoadUint8(data_pointer, offset + 1);
let b2: word32 = LoadUint8(data_pointer, offset + 2);
@ -161,8 +166,9 @@ module data_view {
return AllocateHeapNumberWithValue(float_res);
}
macro LoadDataViewFloat64(data_pointer: RawPtr, offset: intptr,
macro LoadDataViewFloat64(buffer: JSArrayBuffer, offset: intptr,
requested_little_endian: bool): HeapNumber {
let data_pointer: RawPtr = buffer.backing_store;
let b0: word32 = LoadUint8(data_pointer, offset);
let b1: word32 = LoadUint8(data_pointer, offset + 1);
let b2: word32 = LoadUint8(data_pointer, offset + 2);
@ -293,9 +299,10 @@ module data_view {
return result;
}
macro LoadDataViewBigInt(data_pointer: RawPtr, offset: intptr,
macro LoadDataViewBigInt(buffer: JSArrayBuffer, offset: intptr,
requested_little_endian: bool,
signed: constexpr bool): BigInt {
let data_pointer: RawPtr = buffer.backing_store;
let b0: word32 = LoadUint8(data_pointer, offset);
let b1: word32 = LoadUint8(data_pointer, offset + 1);
let b2: word32 = LoadUint8(data_pointer, offset + 2);
@ -345,13 +352,14 @@ module data_view {
let data_view: JSDataView = ValidateDataView(
context, receiver, 'get DataView.prototype.get');
let getIndex: Smi;
let getIndexSmi: Smi;
try {
getIndex = ToSmiIndex(offset, context) otherwise RangeError;
getIndexSmi = ToSmiIndex(offset, context) otherwise RangeError;
}
label RangeError {
ThrowRangeError(context, kInvalidDataViewAccessorOffset);
}
let getIndex: intptr = convert<intptr>(getIndexSmi);
let littleEndian: bool = ToBoolean(requested_little_endian);
let buffer: JSArrayBuffer = data_view.buffer;
@ -360,39 +368,36 @@ module data_view {
ThrowTypeError(context, kDetachedOperation, 'DataView.prototype.get');
}
let viewOffset: Smi = data_view.byte_offset;
let viewSize: Smi = data_view.byte_length;
let elementSize: Smi = DataViewElementSize(kind);
let viewOffset: intptr = convert<intptr>(data_view.byte_offset);
let viewSize: intptr = convert<intptr>(data_view.byte_length);
let elementSize: intptr = DataViewElementSize(kind);
if (getIndex + elementSize > viewSize ||
getIndex + elementSize < getIndex) {
// TODO(theotime): do we really need to check for overflow here?
if (getIndex + elementSize > viewSize) {
ThrowRangeError(context, kInvalidDataViewAccessorOffset);
}
let bufferIndex: intptr = convert<intptr>(getIndex + viewOffset);
let data_pointer: RawPtr = buffer.backing_store;
let bufferIndex: intptr = getIndex + viewOffset;
if constexpr (kind == UINT8_ELEMENTS) {
return LoadDataViewUint8(data_pointer, bufferIndex);
return LoadDataViewUint8(buffer, bufferIndex);
} else if constexpr (kind == INT8_ELEMENTS) {
return LoadDataViewInt8(data_pointer, bufferIndex);
return LoadDataViewInt8(buffer, bufferIndex);
} else if constexpr (kind == UINT16_ELEMENTS) {
return LoadDataView16(data_pointer, bufferIndex, littleEndian, false);
return LoadDataView16(buffer, bufferIndex, littleEndian, false);
} else if constexpr (kind == INT16_ELEMENTS) {
return LoadDataView16(data_pointer, bufferIndex, littleEndian, true);
return LoadDataView16(buffer, bufferIndex, littleEndian, true);
} else if constexpr (kind == UINT32_ELEMENTS) {
return LoadDataView32(data_pointer, bufferIndex, littleEndian, false);
return LoadDataView32(buffer, bufferIndex, littleEndian, false);
} else if constexpr (kind == INT32_ELEMENTS) {
return LoadDataView32(data_pointer, bufferIndex, littleEndian, true);
return LoadDataView32(buffer, bufferIndex, littleEndian, true);
} else if constexpr (kind == FLOAT32_ELEMENTS) {
return LoadDataViewFloat32(data_pointer, bufferIndex, littleEndian);
return LoadDataViewFloat32(buffer, bufferIndex, littleEndian);
} else if constexpr (kind == FLOAT64_ELEMENTS) {
return LoadDataViewFloat64(data_pointer, bufferIndex, littleEndian);
return LoadDataViewFloat64(buffer, bufferIndex, littleEndian);
} else if constexpr (kind == BIGINT64_ELEMENTS) {
return LoadDataViewBigInt(data_pointer, bufferIndex, littleEndian, true);
return LoadDataViewBigInt(buffer, bufferIndex, littleEndian, true);
} else if constexpr (kind == BIGUINT64_ELEMENTS) {
return LoadDataViewBigInt(data_pointer, bufferIndex, littleEndian, false);
return LoadDataViewBigInt(buffer, bufferIndex, littleEndian, false);
} else {
unreachable;
}
@ -510,27 +515,218 @@ module data_view {
BIGUINT64_ELEMENTS);
}
// Context, receiver, byteOffset, value, littleEndian
extern runtime
DataViewSetInt8(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetUint8(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetInt16(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetUint16(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetInt32(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetUint32(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetFloat32(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetFloat64(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetBigInt64(Context, Object, Object, Object, Object): Object;
extern runtime
DataViewSetBigUint64(Context, Object, Object, Object, Object): Object;
extern macro ToNumber(Context, Object): Number;
extern macro ToBigInt(Context, Object): BigInt;
extern macro TruncateFloat64ToFloat32(float64): float32;
extern macro TruncateFloat64ToWord32(float64): word32;
extern macro StoreWord8(RawPtr, intptr, word32): void;
macro StoreDataView8(buffer: JSArrayBuffer, offset: intptr,
value: word32): void {
StoreWord8(buffer.backing_store, offset, value & 0xFF);
}
macro StoreDataView16(buffer: JSArrayBuffer, offset: intptr, value: word32,
requested_little_endian: bool): void {
let b0: word32 = value & 0xFF;
let b1: word32 = (value >>> 8) & 0xFF;
let data_pointer: RawPtr = buffer.backing_store;
if (requested_little_endian) {
StoreWord8(data_pointer, offset, b0);
StoreWord8(data_pointer, offset + 1, b1);
} else {
StoreWord8(data_pointer, offset, b1);
StoreWord8(data_pointer, offset + 1, b0);
}
}
macro StoreDataView32(buffer: JSArrayBuffer, offset: intptr, value: word32,
requested_little_endian: bool): void {
let b0: word32 = value & 0xFF;
let b1: word32 = (value >>> 8) & 0xFF;
let b2: word32 = (value >>> 16) & 0xFF;
let b3: word32 = value >>> 24; // We don't need to mask here.
let data_pointer: RawPtr = buffer.backing_store;
if (requested_little_endian) {
StoreWord8(data_pointer, offset, b0);
StoreWord8(data_pointer, offset + 1, b1);
StoreWord8(data_pointer, offset + 2, b2);
StoreWord8(data_pointer, offset + 3, b3);
} else {
StoreWord8(data_pointer, offset, b3);
StoreWord8(data_pointer, offset + 1, b2);
StoreWord8(data_pointer, offset + 2, b1);
StoreWord8(data_pointer, offset + 3, b0);
}
}
macro StoreDataView64(buffer: JSArrayBuffer, offset: intptr,
low_word: word32, high_word: word32,
requested_little_endian: bool): void {
let b0: word32 = low_word & 0xFF;
let b1: word32 = (low_word >>> 8) & 0xFF;
let b2: word32 = (low_word >>> 16) & 0xFF;
let b3: word32 = low_word >>> 24;
let b4: word32 = high_word & 0xFF;
let b5: word32 = (high_word >>> 8) & 0xFF;
let b6: word32 = (high_word >>> 16) & 0xFF;
let b7: word32 = high_word >>> 24;
let data_pointer: RawPtr = buffer.backing_store;
if (requested_little_endian) {
StoreWord8(data_pointer, offset, b0);
StoreWord8(data_pointer, offset + 1, b1);
StoreWord8(data_pointer, offset + 2, b2);
StoreWord8(data_pointer, offset + 3, b3);
StoreWord8(data_pointer, offset + 4, b4);
StoreWord8(data_pointer, offset + 5, b5);
StoreWord8(data_pointer, offset + 6, b6);
StoreWord8(data_pointer, offset + 7, b7);
} else {
StoreWord8(data_pointer, offset, b7);
StoreWord8(data_pointer, offset + 1, b6);
StoreWord8(data_pointer, offset + 2, b5);
StoreWord8(data_pointer, offset + 3, b4);
StoreWord8(data_pointer, offset + 4, b3);
StoreWord8(data_pointer, offset + 5, b2);
StoreWord8(data_pointer, offset + 6, b1);
StoreWord8(data_pointer, offset + 7, b0);
}
}
extern macro DataViewDecodeBigIntLength(BigInt): uintptr;
extern macro DataViewDecodeBigIntSign(BigInt): uintptr;
extern macro LoadBigIntDigit(BigInt, constexpr int31): uintptr;
// We might get here a BigInt that is bigger than 64 bits, but we're only
// interested in the 64 lowest ones. This means the lowest BigInt digit
// on 64-bit platforms, and the 2 lowest BigInt digits on 32-bit ones.
macro StoreDataViewBigInt(buffer: JSArrayBuffer, offset: intptr,
bigint_value: BigInt,
requested_little_endian: bool): void {
let length: uintptr = DataViewDecodeBigIntLength(bigint_value);
let sign: uintptr = DataViewDecodeBigIntSign(bigint_value);
// The 32-bit words that will hold the BigInt's value in
// two's complement representation.
let low_word: word32 = 0;
let high_word: word32 = 0;
// The length is nonzero if and only if the BigInt's value is nonzero.
if (length != 0) {
if constexpr (Is64()) {
// There is always exactly 1 BigInt digit to load in this case.
let value: uintptr = LoadBigIntDigit(bigint_value, 0);
low_word = convert<word32>(value); // Truncates value to 32 bits.
high_word = convert<word32>(value >>> 32);
}
else { // There might be either 1 or 2 BigInt digits we need to load.
low_word = convert<word32>(LoadBigIntDigit(bigint_value, 0));
if (length >= 2) { // Only load the second digit if there is one.
high_word = convert<word32>(LoadBigIntDigit(bigint_value, 1));
}
}
}
if (sign != 0) { // The number is negative, convert it.
high_word = 0 - convert<int32>(high_word);
if (low_word != 0) {
high_word = convert<int32>(high_word) - 1;
}
low_word = 0 - convert<int32>(low_word);
}
StoreDataView64(buffer, offset, low_word, high_word,
requested_little_endian);
}
macro DataViewSet(context: Context,
receiver: Object,
offset: Object,
value: Object,
requested_little_endian: Object,
kind: constexpr ElementsKind): Object {
// TODO(theotime): add more specific method name to match
// the former implementation.
let data_view: JSDataView = ValidateDataView(
context, receiver, 'get DataView.prototype.get');
let getIndexSmi: Smi;
try {
getIndexSmi = ToSmiIndex(offset, context) otherwise RangeError;
}
label RangeError {
ThrowRangeError(context, kInvalidDataViewAccessorOffset);
}
let getIndex: intptr = convert<intptr>(getIndexSmi);
let littleEndian: bool = ToBoolean(requested_little_endian);
let buffer: JSArrayBuffer = data_view.buffer;
let bigint_value: BigInt;
let num_value: Number;
// According to ES6 section 24.2.1.2 SetViewValue, we must perform
// the conversion before doing the bounds check.
if constexpr (kind == BIGUINT64_ELEMENTS || kind == BIGINT64_ELEMENTS) {
bigint_value = ToBigInt(context, value);
} else {
num_value = ToNumber(context, value);
}
if (IsDetachedBuffer(buffer)) {
ThrowTypeError(context, kDetachedOperation, 'DataView.prototype.get');
}
let viewOffset: intptr = convert<intptr>(data_view.byte_offset);
let viewSize: intptr = convert<intptr>(data_view.byte_length);
let elementSize: intptr = DataViewElementSize(kind);
if (getIndex + elementSize > viewSize) {
ThrowRangeError(context, kInvalidDataViewAccessorOffset);
}
let bufferIndex: intptr = getIndex + viewOffset;
if constexpr (kind == BIGUINT64_ELEMENTS || kind == BIGINT64_ELEMENTS) {
StoreDataViewBigInt(buffer, bufferIndex, bigint_value,
littleEndian);
}
else {
let double_value: float64 = ChangeNumberToFloat64(num_value);
if constexpr (kind == UINT8_ELEMENTS || kind == INT8_ELEMENTS) {
StoreDataView8(buffer, bufferIndex,
TruncateFloat64ToWord32(double_value));
}
else if constexpr (kind == UINT16_ELEMENTS || kind == INT16_ELEMENTS) {
StoreDataView16(buffer, bufferIndex,
TruncateFloat64ToWord32(double_value), littleEndian);
}
else if constexpr (kind == UINT32_ELEMENTS || kind == INT32_ELEMENTS) {
StoreDataView32(buffer, bufferIndex,
TruncateFloat64ToWord32(double_value), littleEndian);
}
else if constexpr (kind == FLOAT32_ELEMENTS) {
let float_value: float32 = TruncateFloat64ToFloat32(double_value);
StoreDataView32(buffer, bufferIndex,
BitcastFloat32ToInt32(float_value), littleEndian);
}
else if constexpr (kind == FLOAT64_ELEMENTS) {
let low_word: word32 = Float64ExtractLowWord32(double_value);
let high_word: word32 = Float64ExtractHighWord32(double_value);
StoreDataView64(buffer, bufferIndex, low_word, high_word,
littleEndian);
}
}
return Undefined;
}
javascript builtin DataViewPrototypeSetInt8(
context: Context, receiver: Object, ...arguments): Object {
@ -540,7 +736,8 @@ module data_view {
let value : Object = arguments.length > 1 ?
arguments[1] :
Undefined;
return DataViewSetInt8(context, receiver, offset, value, Undefined);
return DataViewSet(context, receiver, offset, value, Undefined,
INT8_ELEMENTS);
}
javascript builtin DataViewPrototypeSetUint8(
@ -551,7 +748,8 @@ module data_view {
let value : Object = arguments.length > 1 ?
arguments[1] :
Undefined;
return DataViewSetUint8(context, receiver, offset, value, Undefined);
return DataViewSet(context, receiver, offset, value, Undefined,
UINT8_ELEMENTS);
}
javascript builtin DataViewPrototypeSetInt16(
@ -565,8 +763,8 @@ module data_view {
let is_little_endian : Object = arguments.length > 2 ?
arguments[2] :
Undefined;
return DataViewSetInt16(context, receiver, offset, value,
is_little_endian);
return DataViewSet(context, receiver, offset, value,
is_little_endian, INT16_ELEMENTS);
}
javascript builtin DataViewPrototypeSetUint16(
@ -580,8 +778,8 @@ module data_view {
let is_little_endian : Object = arguments.length > 2 ?
arguments[2] :
Undefined;
return DataViewSetUint16(context, receiver, offset, value,
is_little_endian);
return DataViewSet(context, receiver, offset, value,
is_little_endian, UINT16_ELEMENTS);
}
javascript builtin DataViewPrototypeSetInt32(
@ -595,8 +793,8 @@ module data_view {
let is_little_endian : Object = arguments.length > 2 ?
arguments[2] :
Undefined;
return DataViewSetInt32(context, receiver, offset, value,
is_little_endian);
return DataViewSet(context, receiver, offset, value,
is_little_endian, INT32_ELEMENTS);
}
javascript builtin DataViewPrototypeSetUint32(
@ -610,8 +808,8 @@ module data_view {
let is_little_endian : Object = arguments.length > 2 ?
arguments[2] :
Undefined;
return DataViewSetUint32(context, receiver, offset, value,
is_little_endian);
return DataViewSet(context, receiver, offset, value,
is_little_endian, UINT32_ELEMENTS);
}
javascript builtin DataViewPrototypeSetFloat32(
@ -625,8 +823,8 @@ module data_view {
let is_little_endian : Object = arguments.length > 2 ?
arguments[2] :
Undefined;
return DataViewSetFloat32(context, receiver, offset, value,
is_little_endian);
return DataViewSet(context, receiver, offset, value,
is_little_endian, FLOAT32_ELEMENTS);
}
javascript builtin DataViewPrototypeSetFloat64(
@ -640,8 +838,8 @@ module data_view {
let is_little_endian : Object = arguments.length > 2 ?
arguments[2] :
Undefined;
return DataViewSetFloat64(context, receiver, offset, value,
is_little_endian);
return DataViewSet(context, receiver, offset, value,
is_little_endian, FLOAT64_ELEMENTS);
}
javascript builtin DataViewPrototypeSetBigInt64(
@ -655,8 +853,8 @@ module data_view {
let is_little_endian : Object = arguments.length > 2 ?
arguments[2] :
Undefined;
return DataViewSetBigInt64(context, receiver, offset, value,
is_little_endian);
return DataViewSet(context, receiver, offset, value,
is_little_endian, BIGINT64_ELEMENTS);
}
javascript builtin DataViewPrototypeSetBigUint64(
@ -670,8 +868,8 @@ module data_view {
let is_little_endian : Object = arguments.length > 2 ?
arguments[2] :
Undefined;
return DataViewSetBigUint64(context, receiver, offset, value,
is_little_endian);
return DataViewSet(context, receiver, offset, value,
is_little_endian, BIGUINT64_ELEMENTS);
}
}

View File

@ -525,6 +525,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
V(ChangeUint32ToFloat64, Float64T, Word32T) \
V(ChangeUint32ToUint64, Uint64T, Word32T) \
V(BitcastInt32ToFloat32, Float32T, Word32T) \
V(BitcastFloat32ToInt32, Word32T, Float32T) \
V(RoundFloat64ToInt32, Int32T, Float64T) \
V(RoundInt32ToFloat32, Int32T, Float32T) \
V(Float64SilenceNaN, Float64T, Float64T) \

View File

@ -1,210 +0,0 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/runtime/runtime-utils.h"
#include "src/arguments.h"
#include "src/elements.h"
#include "src/heap/factory.h"
#include "src/messages.h"
#include "src/objects-inl.h"
#include "src/runtime/runtime.h"
namespace v8 {
namespace internal {
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--);
}
}
template <typename T>
MaybeHandle<Object> DataViewConvertInput(Isolate* isolate,
Handle<Object> input) {
return Object::ToNumber(input);
}
template <>
MaybeHandle<Object> DataViewConvertInput<int64_t>(Isolate* isolate,
Handle<Object> input) {
return BigInt::FromObject(isolate, input);
}
template <>
MaybeHandle<Object> DataViewConvertInput<uint64_t>(Isolate* isolate,
Handle<Object> input) {
return BigInt::FromObject(isolate, input);
}
template <typename T>
T DataViewConvertValue(Handle<Object> value);
template <>
int8_t DataViewConvertValue<int8_t>(Handle<Object> value) {
return static_cast<int8_t>(DoubleToInt32(value->Number()));
}
template <>
int16_t DataViewConvertValue<int16_t>(Handle<Object> value) {
return static_cast<int16_t>(DoubleToInt32(value->Number()));
}
template <>
int32_t DataViewConvertValue<int32_t>(Handle<Object> value) {
return DoubleToInt32(value->Number());
}
template <>
uint8_t DataViewConvertValue<uint8_t>(Handle<Object> value) {
return static_cast<uint8_t>(DoubleToUint32(value->Number()));
}
template <>
uint16_t DataViewConvertValue<uint16_t>(Handle<Object> value) {
return static_cast<uint16_t>(DoubleToUint32(value->Number()));
}
template <>
uint32_t DataViewConvertValue<uint32_t>(Handle<Object> value) {
return DoubleToUint32(value->Number());
}
template <>
float DataViewConvertValue<float>(Handle<Object> value) {
return static_cast<float>(value->Number());
}
template <>
double DataViewConvertValue<double>(Handle<Object> value) {
return value->Number();
}
template <>
int64_t DataViewConvertValue<int64_t>(Handle<Object> value) {
return BigInt::cast(*value)->AsInt64();
}
template <>
uint64_t DataViewConvertValue<uint64_t>(Handle<Object> value) {
return BigInt::cast(*value)->AsUint64();
}
// 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,
const char* method) {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, request_index,
Object::ToIndex(isolate, request_index,
MessageTemplate::kInvalidDataViewAccessorOffset),
Object);
ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
DataViewConvertInput<T>(isolate, 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);
if (buffer->was_neutered()) {
Handle<String> operation =
isolate->factory()->NewStringFromAsciiChecked(method);
THROW_NEW_ERROR(
isolate, NewTypeError(MessageTemplate::kDetachedOperation, operation),
Object);
}
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);
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 CHECK_RECEIVER_OBJECT(method) \
Handle<Object> receiver = args.at<Object>(0); \
if (!receiver->IsJSDataView()) { \
THROW_NEW_ERROR_RETURN_FAILURE( \
isolate, \
NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \
isolate->factory()->NewStringFromAsciiChecked(method), \
receiver)); \
} \
Handle<JSDataView> data_view = Handle<JSDataView>::cast(receiver);
#define DATA_VIEW_PROTOTYPE_SET(Type, type) \
RUNTIME_FUNCTION(Runtime_DataViewSet##Type) { \
HandleScope scope(isolate); \
CHECK_RECEIVER_OBJECT("DataView.prototype.set" #Type); \
Handle<Object> byte_offset = args.at<Object>(1); \
Handle<Object> value = args.at<Object>(2); \
Handle<Object> is_little_endian = args.at<Object>(3); \
Handle<Object> result; \
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \
isolate, result, \
SetViewValue<type>(isolate, data_view, byte_offset, \
is_little_endian->BooleanValue(isolate), value, \
"DataView.prototype.set" #Type)); \
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)
DATA_VIEW_PROTOTYPE_SET(BigInt64, int64_t)
DATA_VIEW_PROTOTYPE_SET(BigUint64, uint64_t)
#undef DATA_VIEW_PROTOTYPE_SET
#undef CHECK_RECEIVER_OBJECT
} // namespace internal
} // namespace v8

View File

@ -569,18 +569,6 @@ namespace internal {
F(TypedArraySet, 2, 1) \
F(TypedArraySortFast, 1, 1)
#define FOR_EACH_INTRINSIC_DATAVIEW(F) \
F(DataViewSetInt8, 2, 1) \
F(DataViewSetUint8, 2, 1) \
F(DataViewSetInt16, 3, 1) \
F(DataViewSetUint16, 3, 1) \
F(DataViewSetInt32, 3, 1) \
F(DataViewSetUint32, 3, 1) \
F(DataViewSetFloat32, 3, 1) \
F(DataViewSetFloat64, 3, 1) \
F(DataViewSetBigInt64, 3, 1) \
F(DataViewSetBigUint64, 3, 1)
#define FOR_EACH_INTRINSIC_WASM(F) \
F(ThrowWasmError, 1, 1) \
F(ThrowWasmStackOverflow, 0, 1) \
@ -649,7 +637,6 @@ namespace internal {
FOR_EACH_INTRINSIC_SYMBOL(F) \
FOR_EACH_INTRINSIC_TEST(F) \
FOR_EACH_INTRINSIC_TYPEDARRAY(F) \
FOR_EACH_INTRINSIC_DATAVIEW(F) \
FOR_EACH_INTRINSIC_WASM(F)
// FOR_EACH_INTRINSIC defines the list of all intrinsics, coming in 2 flavors,