[builtins] Tnodify builtins-sharedarraybuffer-gen.cc
Bug: v8:6949 Change-Id: I01cb7180fbeea0a86e4fddc913311d6ece1aa5e7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1876065 Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#64540}
This commit is contained in:
parent
94aa48ef16
commit
39aa9102a2
@ -23,18 +23,23 @@ class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
|
||||
Node* base, Node* offset,
|
||||
Node* value,
|
||||
Node* value_high);
|
||||
void ValidateSharedTypedArray(Node* tagged, Node* context,
|
||||
void ValidateSharedTypedArray(TNode<Object> maybe_array,
|
||||
TNode<Context> context,
|
||||
TNode<Int32T>* out_elements_kind,
|
||||
Node** out_backing_store);
|
||||
Node* ConvertTaggedAtomicIndexToWord32(Node* tagged, Node* context,
|
||||
Node** number_index);
|
||||
void ValidateAtomicIndex(Node* array, Node* index_word, Node* context);
|
||||
#if DEBUG
|
||||
void DebugSanityCheckAtomicIndex(Node* array, Node* index_word,
|
||||
Node* context);
|
||||
#endif
|
||||
void AtomicBinopBuiltinCommon(Node* array, Node* index, Node* value,
|
||||
Node* context, AssemblerFunction function,
|
||||
TNode<RawPtrT>* out_backing_store);
|
||||
// TODO(v8:4153): Support huge SharedTypedArrays.
|
||||
TNode<Uint32T> ConvertTaggedAtomicIndexToWord32(TNode<Object> index,
|
||||
TNode<Context> context,
|
||||
TNode<Smi>* number_index);
|
||||
void ValidateAtomicIndex(TNode<JSTypedArray> array, TNode<Uint32T> index,
|
||||
TNode<Context> context);
|
||||
|
||||
inline void DebugSanityCheckAtomicIndex(TNode<JSTypedArray> array,
|
||||
TNode<Uint32T> index);
|
||||
|
||||
void AtomicBinopBuiltinCommon(TNode<Object> maybe_array, TNode<Object> index,
|
||||
TNode<Object> value, TNode<Context> context,
|
||||
AssemblerFunction function,
|
||||
Runtime::FunctionId runtime_function);
|
||||
|
||||
// Create a BigInt from the result of a 64-bit atomic operation, using
|
||||
@ -43,20 +48,22 @@ class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
|
||||
TNode<BigInt> BigIntFromUnsigned64(Node* unsigned64);
|
||||
};
|
||||
|
||||
// https://tc39.es/ecma262/#sec-validatesharedintegertypedarray
|
||||
void SharedArrayBufferBuiltinsAssembler::ValidateSharedTypedArray(
|
||||
Node* tagged, Node* context, TNode<Int32T>* out_elements_kind,
|
||||
Node** out_backing_store) {
|
||||
TNode<Object> maybe_array, TNode<Context> context,
|
||||
TNode<Int32T>* out_elements_kind, TNode<RawPtrT>* out_backing_store) {
|
||||
Label not_float_or_clamped(this), invalid(this);
|
||||
|
||||
// Fail if it is not a heap object.
|
||||
GotoIf(TaggedIsSmi(tagged), &invalid);
|
||||
GotoIf(TaggedIsSmi(maybe_array), &invalid);
|
||||
|
||||
// Fail if the array's instance type is not JSTypedArray.
|
||||
TNode<Map> tagged_map = LoadMap(tagged);
|
||||
GotoIfNot(IsJSTypedArrayMap(tagged_map), &invalid);
|
||||
TNode<Map> map = LoadMap(CAST(maybe_array));
|
||||
GotoIfNot(IsJSTypedArrayMap(map), &invalid);
|
||||
TNode<JSTypedArray> array = CAST(maybe_array);
|
||||
|
||||
// Fail if the array's JSArrayBuffer is not shared.
|
||||
TNode<JSArrayBuffer> array_buffer = LoadJSArrayBufferViewBuffer(CAST(tagged));
|
||||
TNode<JSArrayBuffer> array_buffer = LoadJSArrayBufferViewBuffer(array);
|
||||
TNode<Uint32T> bitfield = LoadJSArrayBufferBitField(array_buffer);
|
||||
GotoIfNot(IsSetWord32<JSArrayBuffer::IsSharedBit>(bitfield), &invalid);
|
||||
|
||||
@ -67,7 +74,7 @@ void SharedArrayBufferBuiltinsAssembler::ValidateSharedTypedArray(
|
||||
STATIC_ASSERT(UINT8_ELEMENTS < FLOAT32_ELEMENTS);
|
||||
STATIC_ASSERT(UINT16_ELEMENTS < FLOAT32_ELEMENTS);
|
||||
STATIC_ASSERT(UINT32_ELEMENTS < FLOAT32_ELEMENTS);
|
||||
TNode<Int32T> elements_kind = LoadMapElementsKind(tagged_map);
|
||||
TNode<Int32T> elements_kind = LoadMapElementsKind(map);
|
||||
GotoIf(Int32LessThan(elements_kind, Int32Constant(FLOAT32_ELEMENTS)),
|
||||
¬_float_or_clamped);
|
||||
STATIC_ASSERT(BIGINT64_ELEMENTS > UINT8_CLAMPED_ELEMENTS);
|
||||
@ -78,21 +85,22 @@ void SharedArrayBufferBuiltinsAssembler::ValidateSharedTypedArray(
|
||||
BIND(&invalid);
|
||||
{
|
||||
ThrowTypeError(context, MessageTemplate::kNotIntegerSharedTypedArray,
|
||||
tagged);
|
||||
maybe_array);
|
||||
}
|
||||
|
||||
BIND(¬_float_or_clamped);
|
||||
*out_elements_kind = elements_kind;
|
||||
|
||||
TNode<RawPtrT> backing_store = LoadJSArrayBufferBackingStore(array_buffer);
|
||||
TNode<UintPtrT> byte_offset = LoadJSArrayBufferViewByteOffset(CAST(tagged));
|
||||
*out_backing_store = IntPtrAdd(backing_store, byte_offset);
|
||||
TNode<UintPtrT> byte_offset = LoadJSArrayBufferViewByteOffset(array);
|
||||
*out_backing_store = RawPtrAdd(backing_store, Signed(byte_offset));
|
||||
}
|
||||
|
||||
// https://tc39.github.io/ecma262/#sec-validateatomicaccess
|
||||
Node* SharedArrayBufferBuiltinsAssembler::ConvertTaggedAtomicIndexToWord32(
|
||||
Node* tagged, Node* context, Node** number_index) {
|
||||
VARIABLE(var_result, MachineRepresentation::kWord32);
|
||||
TNode<Uint32T>
|
||||
SharedArrayBufferBuiltinsAssembler::ConvertTaggedAtomicIndexToWord32(
|
||||
TNode<Object> index, TNode<Context> context, TNode<Smi>* number_index) {
|
||||
TVARIABLE(Uint32T, var_result);
|
||||
Label done(this), range_error(this);
|
||||
|
||||
// Returns word32 since index cannot be longer than a TypedArray length,
|
||||
@ -100,8 +108,9 @@ Node* SharedArrayBufferBuiltinsAssembler::ConvertTaggedAtomicIndexToWord32(
|
||||
// The |number_index| output parameter is used only for architectures that
|
||||
// don't currently have a TF implementation and forward to runtime functions
|
||||
// instead; they expect the value has already been coerced to an integer.
|
||||
*number_index = ToSmiIndex(CAST(context), CAST(tagged), &range_error);
|
||||
var_result.Bind(SmiToInt32(*number_index));
|
||||
// TODO(v8:4153): Use ToIndex() here.
|
||||
*number_index = ToSmiIndex(context, index, &range_error);
|
||||
var_result = Unsigned(SmiToInt32(*number_index));
|
||||
Goto(&done);
|
||||
|
||||
BIND(&range_error);
|
||||
@ -111,12 +120,11 @@ Node* SharedArrayBufferBuiltinsAssembler::ConvertTaggedAtomicIndexToWord32(
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
void SharedArrayBufferBuiltinsAssembler::ValidateAtomicIndex(Node* array,
|
||||
Node* index,
|
||||
Node* context) {
|
||||
void SharedArrayBufferBuiltinsAssembler::ValidateAtomicIndex(
|
||||
TNode<JSTypedArray> array, TNode<Uint32T> index, TNode<Context> context) {
|
||||
// Check if the index is in bounds. If not, throw RangeError.
|
||||
Label check_passed(this);
|
||||
TNode<UintPtrT> array_length = LoadJSTypedArrayLength(CAST(array));
|
||||
TNode<UintPtrT> array_length = LoadJSTypedArrayLength(array);
|
||||
// TODO(v8:4153): Use UintPtr for the {index} as well.
|
||||
GotoIf(UintPtrLessThan(ChangeUint32ToWord(index), array_length),
|
||||
&check_passed);
|
||||
@ -126,17 +134,15 @@ void SharedArrayBufferBuiltinsAssembler::ValidateAtomicIndex(Node* array,
|
||||
BIND(&check_passed);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
void SharedArrayBufferBuiltinsAssembler::DebugSanityCheckAtomicIndex(
|
||||
Node* array, Node* index_word, Node* context) {
|
||||
TNode<JSTypedArray> array, TNode<Uint32T> index) {
|
||||
// In Debug mode, we re-validate the index as a sanity check because
|
||||
// ToInteger above calls out to JavaScript. A SharedArrayBuffer can't be
|
||||
// detached and the TypedArray length can't change either, so skipping this
|
||||
// check in Release mode is safe.
|
||||
CSA_ASSERT(this, UintPtrLessThan(ChangeUint32ToWord(index_word),
|
||||
LoadJSTypedArrayLength(CAST(array))));
|
||||
CSA_ASSERT(this, UintPtrLessThan(ChangeUint32ToWord(index),
|
||||
LoadJSTypedArrayLength(array)));
|
||||
}
|
||||
#endif
|
||||
|
||||
TNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromSigned64(
|
||||
Node* signed64) {
|
||||
@ -160,17 +166,20 @@ TNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromUnsigned64(
|
||||
}
|
||||
}
|
||||
|
||||
// https://tc39.es/ecma262/#sec-atomicload
|
||||
TF_BUILTIN(AtomicsLoad, SharedArrayBufferBuiltinsAssembler) {
|
||||
Node* array = Parameter(Descriptor::kArray);
|
||||
Node* index = Parameter(Descriptor::kIndex);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Object> maybe_array = CAST(Parameter(Descriptor::kArray));
|
||||
TNode<Object> index = CAST(Parameter(Descriptor::kIndex));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
TNode<Int32T> elements_kind;
|
||||
Node* backing_store;
|
||||
ValidateSharedTypedArray(array, context, &elements_kind, &backing_store);
|
||||
TNode<RawPtrT> backing_store;
|
||||
ValidateSharedTypedArray(maybe_array, context, &elements_kind,
|
||||
&backing_store);
|
||||
TNode<JSTypedArray> array = CAST(maybe_array);
|
||||
|
||||
Node* index_integer;
|
||||
Node* index_word32 =
|
||||
TNode<Smi> index_integer;
|
||||
TNode<Uint32T> index_word32 =
|
||||
ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
|
||||
ValidateAtomicIndex(array, index_word32, context);
|
||||
TNode<UintPtrT> index_word = ChangeUint32ToWord(index_word32);
|
||||
@ -231,20 +240,24 @@ TF_BUILTIN(AtomicsLoad, SharedArrayBufferBuiltinsAssembler) {
|
||||
Unreachable();
|
||||
}
|
||||
|
||||
// https://tc39.es/ecma262/#sec-atomics.store
|
||||
TF_BUILTIN(AtomicsStore, SharedArrayBufferBuiltinsAssembler) {
|
||||
Node* array = Parameter(Descriptor::kArray);
|
||||
Node* index = Parameter(Descriptor::kIndex);
|
||||
Node* value = Parameter(Descriptor::kValue);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Object> maybe_array = CAST(Parameter(Descriptor::kArray));
|
||||
TNode<Object> index = CAST(Parameter(Descriptor::kIndex));
|
||||
TNode<Object> value = CAST(Parameter(Descriptor::kValue));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
TNode<Int32T> elements_kind;
|
||||
Node* backing_store;
|
||||
ValidateSharedTypedArray(array, context, &elements_kind, &backing_store);
|
||||
TNode<RawPtrT> backing_store;
|
||||
ValidateSharedTypedArray(maybe_array, context, &elements_kind,
|
||||
&backing_store);
|
||||
TNode<JSTypedArray> array = CAST(maybe_array);
|
||||
|
||||
Node* index_integer;
|
||||
Node* index_word32 =
|
||||
TNode<Smi> index_integer;
|
||||
TNode<Uint32T> index_word32 =
|
||||
ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
|
||||
ValidateAtomicIndex(array, index_word32, context);
|
||||
|
||||
TNode<UintPtrT> index_word = ChangeUint32ToWord(index_word32);
|
||||
|
||||
Label u8(this), u16(this), u32(this), u64(this), other(this);
|
||||
@ -252,12 +265,10 @@ TF_BUILTIN(AtomicsStore, SharedArrayBufferBuiltinsAssembler) {
|
||||
STATIC_ASSERT(BIGUINT64_ELEMENTS > INT32_ELEMENTS);
|
||||
GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &u64);
|
||||
|
||||
TNode<Number> value_integer = ToInteger_Inline(CAST(context), CAST(value));
|
||||
TNode<Number> value_integer = ToInteger_Inline(context, value);
|
||||
TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer);
|
||||
|
||||
#if DEBUG
|
||||
DebugSanityCheckAtomicIndex(array, index_word32, context);
|
||||
#endif
|
||||
DebugSanityCheckAtomicIndex(array, index_word32);
|
||||
|
||||
int32_t case_values[] = {
|
||||
INT8_ELEMENTS, UINT8_ELEMENTS, INT16_ELEMENTS,
|
||||
@ -287,14 +298,14 @@ TF_BUILTIN(AtomicsStore, SharedArrayBufferBuiltinsAssembler) {
|
||||
Return(CallRuntime(Runtime::kAtomicsStore64, context, array, index_integer,
|
||||
value));
|
||||
#else
|
||||
TNode<BigInt> value_bigint = ToBigInt(CAST(context), CAST(value));
|
||||
#if DEBUG
|
||||
DebugSanityCheckAtomicIndex(array, index_word32, context);
|
||||
#endif
|
||||
TNode<BigInt> value_bigint = ToBigInt(context, value);
|
||||
|
||||
DebugSanityCheckAtomicIndex(array, index_word32);
|
||||
|
||||
TVARIABLE(UintPtrT, var_low);
|
||||
TVARIABLE(UintPtrT, var_high);
|
||||
BigIntToRawBytes(value_bigint, &var_low, &var_high);
|
||||
Node* high = Is64() ? nullptr : static_cast<Node*>(var_high.value());
|
||||
TNode<UintPtrT> high = Is64() ? TNode<UintPtrT>() : var_high.value();
|
||||
AtomicStore(MachineRepresentation::kWord64, backing_store,
|
||||
WordShl(index_word, 3), var_low.value(), high);
|
||||
Return(value_bigint);
|
||||
@ -305,18 +316,21 @@ TF_BUILTIN(AtomicsStore, SharedArrayBufferBuiltinsAssembler) {
|
||||
Unreachable();
|
||||
}
|
||||
|
||||
// https://tc39.es/ecma262/#sec-atomics.exchange
|
||||
TF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) {
|
||||
Node* array = Parameter(Descriptor::kArray);
|
||||
Node* index = Parameter(Descriptor::kIndex);
|
||||
Node* value = Parameter(Descriptor::kValue);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Object> maybe_array = CAST(Parameter(Descriptor::kArray));
|
||||
TNode<Object> index = CAST(Parameter(Descriptor::kIndex));
|
||||
TNode<Object> value = CAST(Parameter(Descriptor::kValue));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
TNode<Int32T> elements_kind;
|
||||
Node* backing_store;
|
||||
ValidateSharedTypedArray(array, context, &elements_kind, &backing_store);
|
||||
TNode<RawPtrT> backing_store;
|
||||
ValidateSharedTypedArray(maybe_array, context, &elements_kind,
|
||||
&backing_store);
|
||||
TNode<JSTypedArray> array = CAST(maybe_array);
|
||||
|
||||
Node* index_integer;
|
||||
Node* index_word32 =
|
||||
TNode<Smi> index_integer;
|
||||
TNode<Uint32T> index_word32 =
|
||||
ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
|
||||
ValidateAtomicIndex(array, index_word32, context);
|
||||
|
||||
@ -332,10 +346,10 @@ TF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) {
|
||||
STATIC_ASSERT(BIGUINT64_ELEMENTS > INT32_ELEMENTS);
|
||||
GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &big);
|
||||
|
||||
TNode<Number> value_integer = ToInteger_Inline(CAST(context), CAST(value));
|
||||
#if DEBUG
|
||||
DebugSanityCheckAtomicIndex(array, index_word32, context);
|
||||
#endif
|
||||
TNode<Number> value_integer = ToInteger_Inline(context, value);
|
||||
|
||||
DebugSanityCheckAtomicIndex(array, index_word32);
|
||||
|
||||
TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer);
|
||||
|
||||
int32_t case_values[] = {
|
||||
@ -375,14 +389,14 @@ TF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) {
|
||||
WordShl(index_word, 2), value_word32)));
|
||||
|
||||
BIND(&big);
|
||||
TNode<BigInt> value_bigint = ToBigInt(CAST(context), CAST(value));
|
||||
#if DEBUG
|
||||
DebugSanityCheckAtomicIndex(array, index_word32, context);
|
||||
#endif
|
||||
TNode<BigInt> value_bigint = ToBigInt(context, value);
|
||||
|
||||
DebugSanityCheckAtomicIndex(array, index_word32);
|
||||
|
||||
TVARIABLE(UintPtrT, var_low);
|
||||
TVARIABLE(UintPtrT, var_high);
|
||||
BigIntToRawBytes(value_bigint, &var_low, &var_high);
|
||||
Node* high = Is64() ? nullptr : static_cast<Node*>(var_high.value());
|
||||
TNode<UintPtrT> high = Is64() ? TNode<UintPtrT>() : var_high.value();
|
||||
GotoIf(Word32Equal(elements_kind, Int32Constant(BIGINT64_ELEMENTS)), &i64);
|
||||
GotoIf(Word32Equal(elements_kind, Int32Constant(BIGUINT64_ELEMENTS)), &u64);
|
||||
Unreachable();
|
||||
@ -406,19 +420,22 @@ TF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) {
|
||||
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
|
||||
}
|
||||
|
||||
// https://tc39.es/ecma262/#sec-atomics.compareexchange
|
||||
TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) {
|
||||
Node* array = Parameter(Descriptor::kArray);
|
||||
Node* index = Parameter(Descriptor::kIndex);
|
||||
Node* old_value = Parameter(Descriptor::kOldValue);
|
||||
Node* new_value = Parameter(Descriptor::kNewValue);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Object> maybe_array = CAST(Parameter(Descriptor::kArray));
|
||||
TNode<Object> index = CAST(Parameter(Descriptor::kIndex));
|
||||
TNode<Object> old_value = CAST(Parameter(Descriptor::kOldValue));
|
||||
TNode<Object> new_value = CAST(Parameter(Descriptor::kNewValue));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
TNode<Int32T> elements_kind;
|
||||
Node* backing_store;
|
||||
ValidateSharedTypedArray(array, context, &elements_kind, &backing_store);
|
||||
TNode<RawPtrT> backing_store;
|
||||
ValidateSharedTypedArray(maybe_array, context, &elements_kind,
|
||||
&backing_store);
|
||||
TNode<JSTypedArray> array = CAST(maybe_array);
|
||||
|
||||
Node* index_integer;
|
||||
Node* index_word32 =
|
||||
TNode<Smi> index_integer;
|
||||
TNode<Uint32T> index_word32 =
|
||||
ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
|
||||
ValidateAtomicIndex(array, index_word32, context);
|
||||
|
||||
@ -435,13 +452,11 @@ TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) {
|
||||
STATIC_ASSERT(BIGUINT64_ELEMENTS > INT32_ELEMENTS);
|
||||
GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &big);
|
||||
|
||||
TNode<Number> old_value_integer =
|
||||
ToInteger_Inline(CAST(context), CAST(old_value));
|
||||
TNode<Number> new_value_integer =
|
||||
ToInteger_Inline(CAST(context), CAST(new_value));
|
||||
#if DEBUG
|
||||
DebugSanityCheckAtomicIndex(array, index_word32, context);
|
||||
#endif
|
||||
TNode<Number> old_value_integer = ToInteger_Inline(context, old_value);
|
||||
TNode<Number> new_value_integer = ToInteger_Inline(context, new_value);
|
||||
|
||||
DebugSanityCheckAtomicIndex(array, index_word32);
|
||||
|
||||
TNode<Word32T> old_value_word32 =
|
||||
TruncateTaggedToWord32(context, old_value_integer);
|
||||
TNode<Word32T> new_value_word32 =
|
||||
@ -488,19 +503,19 @@ TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) {
|
||||
old_value_word32, new_value_word32)));
|
||||
|
||||
BIND(&big);
|
||||
TNode<BigInt> old_value_bigint = ToBigInt(CAST(context), CAST(old_value));
|
||||
TNode<BigInt> new_value_bigint = ToBigInt(CAST(context), CAST(new_value));
|
||||
#if DEBUG
|
||||
DebugSanityCheckAtomicIndex(array, index_word32, context);
|
||||
#endif
|
||||
TNode<BigInt> old_value_bigint = ToBigInt(context, old_value);
|
||||
TNode<BigInt> new_value_bigint = ToBigInt(context, new_value);
|
||||
|
||||
DebugSanityCheckAtomicIndex(array, index_word32);
|
||||
|
||||
TVARIABLE(UintPtrT, var_old_low);
|
||||
TVARIABLE(UintPtrT, var_old_high);
|
||||
TVARIABLE(UintPtrT, var_new_low);
|
||||
TVARIABLE(UintPtrT, var_new_high);
|
||||
BigIntToRawBytes(old_value_bigint, &var_old_low, &var_old_high);
|
||||
BigIntToRawBytes(new_value_bigint, &var_new_low, &var_new_high);
|
||||
Node* old_high = Is64() ? nullptr : static_cast<Node*>(var_old_high.value());
|
||||
Node* new_high = Is64() ? nullptr : static_cast<Node*>(var_new_high.value());
|
||||
TNode<UintPtrT> old_high = Is64() ? TNode<UintPtrT>() : var_old_high.value();
|
||||
TNode<UintPtrT> new_high = Is64() ? TNode<UintPtrT>() : var_new_high.value();
|
||||
GotoIf(Word32Equal(elements_kind, Int32Constant(BIGINT64_ELEMENTS)), &i64);
|
||||
GotoIf(Word32Equal(elements_kind, Int32Constant(BIGUINT64_ELEMENTS)), &u64);
|
||||
Unreachable();
|
||||
@ -525,32 +540,41 @@ TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) {
|
||||
// || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
|
||||
}
|
||||
|
||||
#define BINOP_BUILTIN(op) \
|
||||
TF_BUILTIN(Atomics##op, SharedArrayBufferBuiltinsAssembler) { \
|
||||
Node* array = Parameter(Descriptor::kArray); \
|
||||
Node* index = Parameter(Descriptor::kIndex); \
|
||||
Node* value = Parameter(Descriptor::kValue); \
|
||||
Node* context = Parameter(Descriptor::kContext); \
|
||||
AtomicBinopBuiltinCommon(array, index, value, context, \
|
||||
&CodeAssembler::Atomic##op, \
|
||||
Runtime::kAtomics##op); \
|
||||
#define BINOP_BUILTIN(op) \
|
||||
TF_BUILTIN(Atomics##op, SharedArrayBufferBuiltinsAssembler) { \
|
||||
TNode<Object> array = CAST(Parameter(Descriptor::kArray)); \
|
||||
TNode<Object> index = CAST(Parameter(Descriptor::kIndex)); \
|
||||
TNode<Object> value = CAST(Parameter(Descriptor::kValue)); \
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext)); \
|
||||
AtomicBinopBuiltinCommon(array, index, value, context, \
|
||||
&CodeAssembler::Atomic##op, \
|
||||
Runtime::kAtomics##op); \
|
||||
}
|
||||
// https://tc39.es/ecma262/#sec-atomics.add
|
||||
BINOP_BUILTIN(Add)
|
||||
// https://tc39.es/ecma262/#sec-atomics.sub
|
||||
BINOP_BUILTIN(Sub)
|
||||
// https://tc39.es/ecma262/#sec-atomics.and
|
||||
BINOP_BUILTIN(And)
|
||||
// https://tc39.es/ecma262/#sec-atomics.or
|
||||
BINOP_BUILTIN(Or)
|
||||
// https://tc39.es/ecma262/#sec-atomics.xor
|
||||
BINOP_BUILTIN(Xor)
|
||||
#undef BINOP_BUILTIN
|
||||
|
||||
// https://tc39.es/ecma262/#sec-atomicreadmodifywrite
|
||||
void SharedArrayBufferBuiltinsAssembler::AtomicBinopBuiltinCommon(
|
||||
Node* array, Node* index, Node* value, Node* context,
|
||||
AssemblerFunction function, Runtime::FunctionId runtime_function) {
|
||||
TNode<Object> maybe_array, TNode<Object> index, TNode<Object> value,
|
||||
TNode<Context> context, AssemblerFunction function,
|
||||
Runtime::FunctionId runtime_function) {
|
||||
TNode<Int32T> elements_kind;
|
||||
Node* backing_store;
|
||||
ValidateSharedTypedArray(array, context, &elements_kind, &backing_store);
|
||||
TNode<RawPtrT> backing_store;
|
||||
ValidateSharedTypedArray(maybe_array, context, &elements_kind,
|
||||
&backing_store);
|
||||
TNode<JSTypedArray> array = CAST(maybe_array);
|
||||
|
||||
Node* index_integer;
|
||||
Node* index_word32 =
|
||||
TNode<Smi> index_integer;
|
||||
TNode<Uint32T> index_word32 =
|
||||
ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
|
||||
ValidateAtomicIndex(array, index_word32, context);
|
||||
|
||||
@ -567,10 +591,10 @@ void SharedArrayBufferBuiltinsAssembler::AtomicBinopBuiltinCommon(
|
||||
STATIC_ASSERT(BIGUINT64_ELEMENTS > INT32_ELEMENTS);
|
||||
GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &big);
|
||||
|
||||
TNode<Number> value_integer = ToInteger_Inline(CAST(context), CAST(value));
|
||||
#if DEBUG
|
||||
DebugSanityCheckAtomicIndex(array, index_word32, context);
|
||||
#endif
|
||||
TNode<Number> value_integer = ToInteger_Inline(context, value);
|
||||
|
||||
DebugSanityCheckAtomicIndex(array, index_word32);
|
||||
|
||||
TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer);
|
||||
|
||||
int32_t case_values[] = {
|
||||
@ -612,14 +636,14 @@ void SharedArrayBufferBuiltinsAssembler::AtomicBinopBuiltinCommon(
|
||||
WordShl(index_word, 2), value_word32, nullptr)));
|
||||
|
||||
BIND(&big);
|
||||
TNode<BigInt> value_bigint = ToBigInt(CAST(context), CAST(value));
|
||||
#if DEBUG
|
||||
DebugSanityCheckAtomicIndex(array, index_word32, context);
|
||||
#endif
|
||||
TNode<BigInt> value_bigint = ToBigInt(context, value);
|
||||
|
||||
DebugSanityCheckAtomicIndex(array, index_word32);
|
||||
|
||||
TVARIABLE(UintPtrT, var_low);
|
||||
TVARIABLE(UintPtrT, var_high);
|
||||
BigIntToRawBytes(value_bigint, &var_low, &var_high);
|
||||
Node* high = Is64() ? nullptr : static_cast<Node*>(var_high.value());
|
||||
TNode<UintPtrT> high = Is64() ? TNode<UintPtrT>() : var_high.value();
|
||||
GotoIf(Word32Equal(elements_kind, Int32Constant(BIGINT64_ELEMENTS)), &i64);
|
||||
GotoIf(Word32Equal(elements_kind, Int32Constant(BIGUINT64_ELEMENTS)), &u64);
|
||||
Unreachable();
|
||||
|
@ -7322,8 +7322,8 @@ TNode<Number> CodeStubAssembler::ToNumber(SloppyTNode<Context> context,
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
TNode<BigInt> CodeStubAssembler::ToBigInt(SloppyTNode<Context> context,
|
||||
SloppyTNode<Object> input) {
|
||||
TNode<BigInt> CodeStubAssembler::ToBigInt(TNode<Context> context,
|
||||
TNode<Object> input) {
|
||||
TVARIABLE(BigInt, var_result);
|
||||
Label if_bigint(this), done(this), if_throw(this);
|
||||
|
||||
|
@ -2637,8 +2637,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
// Try to convert an object to a BigInt. Throws on failure (e.g. for Numbers).
|
||||
// https://tc39.github.io/proposal-bigint/#sec-to-bigint
|
||||
TNode<BigInt> ToBigInt(SloppyTNode<Context> context,
|
||||
SloppyTNode<Object> input);
|
||||
TNode<BigInt> ToBigInt(TNode<Context> context, TNode<Object> input);
|
||||
|
||||
// Converts |input| to one of 2^32 integer values in the range 0 through
|
||||
// 2^32-1, inclusive.
|
||||
|
Loading…
Reference in New Issue
Block a user