Commit e947d21e authored by Théotime Grohens's avatar Théotime Grohens Committed by Commit Bot

[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: 's avatarMichael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53800}
parent 8f8c53ba
......@@ -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",
......
......@@ -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);
......
......@@ -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
......
This diff is collapsed.
......@@ -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) \
......
// 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
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment