[bigint] Add BigInt64Array, BigUint64Array
Bug: v8:6791 Tbr: hpayer@chromium.org Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: I637e9084d2fe4869ad0be2fb996149ab9940f346 Reviewed-on: https://chromium-review.googlesource.com/914513 Commit-Queue: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#51342}
This commit is contained in:
parent
77290e0d7f
commit
dda0419ecd
41
include/v8.h
41
include/v8.h
@ -2318,6 +2318,16 @@ class V8_EXPORT Value : public Data {
|
||||
*/
|
||||
bool IsFloat64Array() const;
|
||||
|
||||
/**
|
||||
* Returns true if this value is a BigInt64Array.
|
||||
*/
|
||||
bool IsBigInt64Array() const;
|
||||
|
||||
/**
|
||||
* Returns true if this value is a BigUint64Array.
|
||||
*/
|
||||
bool IsBigUint64Array() const;
|
||||
|
||||
/**
|
||||
* Returns true if this value is a DataView.
|
||||
*/
|
||||
@ -4626,6 +4636,37 @@ class V8_EXPORT Float64Array : public TypedArray {
|
||||
static void CheckCast(Value* obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* An instance of BigInt64Array constructor.
|
||||
*/
|
||||
class V8_EXPORT BigInt64Array : public TypedArray {
|
||||
public:
|
||||
static Local<BigInt64Array> New(Local<ArrayBuffer> array_buffer,
|
||||
size_t byte_offset, size_t length);
|
||||
static Local<BigInt64Array> New(Local<SharedArrayBuffer> shared_array_buffer,
|
||||
size_t byte_offset, size_t length);
|
||||
V8_INLINE static BigInt64Array* Cast(Value* obj);
|
||||
|
||||
private:
|
||||
BigInt64Array();
|
||||
static void CheckCast(Value* obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* An instance of BigUint64Array constructor.
|
||||
*/
|
||||
class V8_EXPORT BigUint64Array : public TypedArray {
|
||||
public:
|
||||
static Local<BigUint64Array> New(Local<ArrayBuffer> array_buffer,
|
||||
size_t byte_offset, size_t length);
|
||||
static Local<BigUint64Array> New(Local<SharedArrayBuffer> shared_array_buffer,
|
||||
size_t byte_offset, size_t length);
|
||||
V8_INLINE static BigUint64Array* Cast(Value* obj);
|
||||
|
||||
private:
|
||||
BigUint64Array();
|
||||
static void CheckCast(Value* obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* An instance of DataView constructor (ES6 draft 15.13.7).
|
||||
|
@ -180,6 +180,10 @@ class Utils {
|
||||
v8::internal::Handle<v8::internal::JSTypedArray> obj);
|
||||
static inline Local<Float64Array> ToLocalFloat64Array(
|
||||
v8::internal::Handle<v8::internal::JSTypedArray> obj);
|
||||
static inline Local<BigInt64Array> ToLocalBigInt64Array(
|
||||
v8::internal::Handle<v8::internal::JSTypedArray> obj);
|
||||
static inline Local<BigUint64Array> ToLocalBigUint64Array(
|
||||
v8::internal::Handle<v8::internal::JSTypedArray> obj);
|
||||
|
||||
static inline Local<SharedArrayBuffer> ToLocalShared(
|
||||
v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
|
||||
|
@ -1787,6 +1787,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
V(FLOAT32_ARRAY, KEY_VALUE, float32_array, key_value) \
|
||||
V(FLOAT64_ARRAY, KEY_VALUE, float64_array, key_value) \
|
||||
V(UINT8_CLAMPED_ARRAY, KEY_VALUE, uint8_clamped_array, key_value) \
|
||||
V(BIGUINT64_ARRAY, KEY_VALUE, biguint64_array, key_value) \
|
||||
V(BIGINT64_ARRAY, KEY_VALUE, bigint64_array, key_value) \
|
||||
V(FAST_SMI_ARRAY, KEY_VALUE, fast_smi_array, key_value) \
|
||||
V(FAST_HOLEY_SMI_ARRAY, KEY_VALUE, fast_holey_smi_array, key_value) \
|
||||
V(FAST_ARRAY, KEY_VALUE, fast_array, key_value) \
|
||||
@ -1803,6 +1805,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
V(FLOAT32_ARRAY, VALUE, float32_array, value) \
|
||||
V(FLOAT64_ARRAY, VALUE, float64_array, value) \
|
||||
V(UINT8_CLAMPED_ARRAY, VALUE, uint8_clamped_array, value) \
|
||||
V(BIGUINT64_ARRAY, VALUE, biguint64_array, value) \
|
||||
V(BIGINT64_ARRAY, VALUE, bigint64_array, value) \
|
||||
V(FAST_SMI_ARRAY, VALUE, fast_smi_array, value) \
|
||||
V(FAST_HOLEY_SMI_ARRAY, VALUE, fast_holey_smi_array, value) \
|
||||
V(FAST_ARRAY, VALUE, fast_array, value) \
|
||||
@ -4404,10 +4408,19 @@ void Genesis::InitializeGlobal_harmony_promise_finally() {
|
||||
}
|
||||
|
||||
void Genesis::InitializeGlobal_harmony_bigint() {
|
||||
if (!FLAG_harmony_bigint) return;
|
||||
|
||||
Factory* factory = isolate()->factory();
|
||||
Handle<JSGlobalObject> global(native_context()->global_object());
|
||||
if (!FLAG_harmony_bigint) {
|
||||
// Typed arrays are installed by default; remove them if the flag is off.
|
||||
CHECK(JSObject::DeleteProperty(
|
||||
global, factory->InternalizeUtf8String("BigInt64Array"))
|
||||
.ToChecked());
|
||||
CHECK(JSObject::DeleteProperty(
|
||||
global, factory->InternalizeUtf8String("BigUint64Array"))
|
||||
.ToChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
Handle<JSFunction> bigint_fun =
|
||||
InstallFunction(global, "BigInt", JS_VALUE_TYPE, JSValue::kSize, 0,
|
||||
factory->the_hole_value(), Builtins::kBigIntConstructor);
|
||||
|
@ -339,11 +339,21 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
|
||||
Branch(fast_typed_array_target_, &fast, &slow);
|
||||
|
||||
BIND(&fast);
|
||||
// #sec-integerindexedelementset 3. Let numValue be ? ToNumber(value).
|
||||
Node* num_value = ToNumber_Inline(context(), mapped_value);
|
||||
// #sec-integerindexedelementset
|
||||
// 5. If arrayTypeName is "BigUint64Array" or "BigInt64Array", let
|
||||
// numValue be ? ToBigInt(v).
|
||||
// 6. Otherwise, let numValue be ? ToNumber(value).
|
||||
Node* num_value;
|
||||
if (source_elements_kind_ == BIGINT64_ELEMENTS ||
|
||||
source_elements_kind_ == BIGUINT64_ELEMENTS) {
|
||||
num_value = ToBigInt(context(), mapped_value);
|
||||
} else {
|
||||
num_value = ToNumber_Inline(context(), mapped_value);
|
||||
}
|
||||
// The only way how this can bailout is because of a detached buffer.
|
||||
EmitElementStore(a(), k, num_value, false, source_elements_kind_,
|
||||
KeyedAccessStoreMode::STANDARD_STORE, &detached);
|
||||
KeyedAccessStoreMode::STANDARD_STORE, &detached,
|
||||
context());
|
||||
Goto(&done);
|
||||
|
||||
BIND(&slow);
|
||||
@ -353,7 +363,7 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
|
||||
|
||||
BIND(&detached);
|
||||
// tc39.github.io/ecma262/#sec-integerindexedelementset
|
||||
// 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||
// 8. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||
ThrowTypeError(context_, MessageTemplate::kDetachedOperation, name_);
|
||||
|
||||
BIND(&done);
|
||||
@ -3661,6 +3671,8 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
|
||||
JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
|
||||
JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
|
||||
JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE,
|
||||
JS_BIGUINT64_ARRAY_KEY_VALUE_ITERATOR_TYPE,
|
||||
JS_BIGINT64_ARRAY_KEY_VALUE_ITERATOR_TYPE,
|
||||
JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
JS_INT8_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
@ -3670,19 +3682,23 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
|
||||
JS_INT32_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
JS_BIGUINT64_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
JS_BIGINT64_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
};
|
||||
|
||||
Label uint8_values(this), int8_values(this), uint16_values(this),
|
||||
int16_values(this), uint32_values(this), int32_values(this),
|
||||
float32_values(this), float64_values(this);
|
||||
float32_values(this), float64_values(this), biguint64_values(this),
|
||||
bigint64_values(this);
|
||||
Label* kInstanceTypeHandlers[] = {
|
||||
&allocate_key_result, &uint8_values, &uint8_values,
|
||||
&int8_values, &uint16_values, &int16_values,
|
||||
&uint32_values, &int32_values, &float32_values,
|
||||
&float64_values, &uint8_values, &uint8_values,
|
||||
&int8_values, &uint16_values, &int16_values,
|
||||
&uint32_values, &int32_values, &float32_values,
|
||||
&float64_values,
|
||||
&allocate_key_result, &uint8_values, &uint8_values,
|
||||
&int8_values, &uint16_values, &int16_values,
|
||||
&uint32_values, &int32_values, &float32_values,
|
||||
&float64_values, &biguint64_values, &bigint64_values,
|
||||
&uint8_values, &uint8_values, &int8_values,
|
||||
&uint16_values, &int16_values, &uint32_values,
|
||||
&int32_values, &float32_values, &float64_values,
|
||||
&biguint64_values, &bigint64_values,
|
||||
};
|
||||
|
||||
var_done.Bind(FalseConstant());
|
||||
@ -3746,6 +3762,18 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
|
||||
var_value.Bind(AllocateHeapNumberWithValue(value_float64));
|
||||
Goto(&allocate_entry_if_needed);
|
||||
}
|
||||
BIND(&biguint64_values);
|
||||
{
|
||||
var_value.Bind(LoadFixedTypedArrayElementAsTagged(
|
||||
data_ptr, index, BIGUINT64_ELEMENTS, SMI_PARAMETERS));
|
||||
Goto(&allocate_entry_if_needed);
|
||||
}
|
||||
BIND(&bigint64_values);
|
||||
{
|
||||
var_value.Bind(LoadFixedTypedArrayElementAsTagged(
|
||||
data_ptr, index, BIGINT64_ELEMENTS, SMI_PARAMETERS));
|
||||
Goto(&allocate_entry_if_needed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,10 +835,15 @@ TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind(
|
||||
Word32Equal(kind, Int32Constant(UINT8_CLAMPED_ELEMENTS)));
|
||||
}
|
||||
|
||||
TNode<Word32T> TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind(
|
||||
TNode<Word32T> kind) {
|
||||
return Word32Or(Word32Equal(kind, Int32Constant(BIGINT64_ELEMENTS)),
|
||||
Word32Equal(kind, Int32Constant(BIGUINT64_ELEMENTS)));
|
||||
}
|
||||
|
||||
TNode<Word32T> TypedArrayBuiltinsAssembler::LoadElementsKind(
|
||||
TNode<Object> typed_array) {
|
||||
CSA_ASSERT(this, IsJSTypedArray(typed_array));
|
||||
return LoadMapElementsKind(LoadMap(CAST(typed_array)));
|
||||
TNode<JSTypedArray> typed_array) {
|
||||
return LoadMapElementsKind(LoadMap(typed_array));
|
||||
}
|
||||
|
||||
TNode<IntPtrT> TypedArrayBuiltinsAssembler::GetTypedArrayElementSize(
|
||||
@ -1023,7 +1028,7 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
|
||||
CSA_ASSERT(this,
|
||||
UintPtrGreaterThanOrEqual(source_byte_length, IntPtrConstant(0)));
|
||||
|
||||
Label call_memmove(this), fast_c_call(this), out(this);
|
||||
Label call_memmove(this), fast_c_call(this), out(this), exception(this);
|
||||
|
||||
// A fast memmove call can be used when the source and target types are are
|
||||
// the same or either Uint8 or Uint8Clamped.
|
||||
@ -1045,6 +1050,10 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
|
||||
this, UintPtrGreaterThanOrEqual(
|
||||
IntPtrMul(target_length, target_el_size), IntPtrConstant(0)));
|
||||
|
||||
GotoIf(Word32NotEqual(IsBigInt64ElementsKind(source_el_kind),
|
||||
IsBigInt64ElementsKind(target_el_kind)),
|
||||
&exception);
|
||||
|
||||
TNode<IntPtrT> source_length =
|
||||
LoadAndUntagObjectField(source, JSTypedArray::kLengthOffset);
|
||||
CallCCopyTypedArrayElementsToTypedArray(source, target, source_length,
|
||||
@ -1052,6 +1061,9 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
|
||||
Goto(&out);
|
||||
}
|
||||
|
||||
BIND(&exception);
|
||||
ThrowTypeError(context, MessageTemplate::kBigIntMixedTypes);
|
||||
|
||||
BIND(&out);
|
||||
}
|
||||
|
||||
@ -1093,6 +1105,7 @@ void TypedArrayBuiltinsAssembler::SetJSArraySource(
|
||||
}
|
||||
|
||||
BIND(&fast_c_call);
|
||||
GotoIf(IsBigInt64ElementsKind(LoadElementsKind(target)), call_runtime);
|
||||
CallCCopyFastNumberJSArrayElementsToTypedArray(context, source, target,
|
||||
source_length, offset);
|
||||
Goto(&out);
|
||||
@ -1115,6 +1128,7 @@ void TypedArrayBuiltinsAssembler::
|
||||
TNode<JSTypedArray> dest,
|
||||
TNode<IntPtrT> source_length,
|
||||
TNode<IntPtrT> offset) {
|
||||
CSA_ASSERT(this, Word32Not(IsBigInt64ElementsKind(LoadElementsKind(dest))));
|
||||
TNode<ExternalReference> f = ExternalConstant(
|
||||
ExternalReference::copy_fast_number_jsarray_elements_to_typed_array(
|
||||
isolate()));
|
||||
@ -1582,22 +1596,28 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) {
|
||||
[&](Node* index) {
|
||||
TNode<Object> item =
|
||||
args.AtIndex(index, ParameterMode::SMI_PARAMETERS);
|
||||
TNode<Number> number = ToNumber_Inline(context, item);
|
||||
if (kind == BIGINT64_ELEMENTS || kind == BIGUINT64_ELEMENTS) {
|
||||
// TODO(jkummerow): Add inline support.
|
||||
CallRuntime(Runtime::kSetProperty, context, new_typed_array,
|
||||
index, item, SmiConstant(LanguageMode::kSloppy));
|
||||
} else {
|
||||
TNode<Number> number = ToNumber_Inline(context, item);
|
||||
|
||||
// ToNumber may execute JavaScript code, but it cannot access
|
||||
// arguments array and new typed array.
|
||||
DebugSanityCheckTypedArrayIndex(new_typed_array, index);
|
||||
// ToNumber may execute JavaScript code, but it cannot access
|
||||
// arguments array and new typed array.
|
||||
DebugSanityCheckTypedArrayIndex(new_typed_array, index);
|
||||
|
||||
// Since we can guarantee that "number" is Number type,
|
||||
// PrepareValueForWriteToTypedArray cannot bail out.
|
||||
Node* value =
|
||||
PrepareValueForWriteToTypedArray(number, kind, &unreachable);
|
||||
// Since we can guarantee that "number" is Number type,
|
||||
// PrepareValueForWriteToTypedArray cannot bail out.
|
||||
Node* value = PrepareValueForWriteToTypedArray(number, kind,
|
||||
&unreachable);
|
||||
|
||||
// GC may move backing store in ToNumber, thus load backing store
|
||||
// everytime in this loop.
|
||||
TNode<IntPtrT> backing_store =
|
||||
UncheckedCast<IntPtrT>(LoadDataPtr(new_typed_array));
|
||||
StoreElement(backing_store, kind, index, value, SMI_PARAMETERS);
|
||||
// GC may move backing store in ToNumber, thus load backing
|
||||
// store everytime in this loop.
|
||||
TNode<IntPtrT> backing_store =
|
||||
UncheckedCast<IntPtrT>(LoadDataPtr(new_typed_array));
|
||||
StoreElement(backing_store, kind, index, value, SMI_PARAMETERS);
|
||||
}
|
||||
},
|
||||
1, ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost);
|
||||
});
|
||||
@ -1656,7 +1676,7 @@ TF_BUILTIN(TypedArrayPrototypeFilter, TypedArrayBuiltinsAssembler) {
|
||||
[&](Node* index) {
|
||||
GotoIf(IsDetachedBuffer(source_buffer), &detached);
|
||||
|
||||
TVARIABLE(Number, value);
|
||||
TVARIABLE(Numeric, value);
|
||||
// a. Let Pk be ! ToString(k).
|
||||
// b. Let kValue be ? Get(O, Pk).
|
||||
DispatchTypedArrayByElementsKind(
|
||||
|
@ -61,8 +61,11 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
|
||||
// Returns true if kind is either UINT8_ELEMENTS or UINT8_CLAMPED_ELEMENTS.
|
||||
TNode<Word32T> IsUint8ElementsKind(TNode<Word32T> kind);
|
||||
|
||||
// Returns true if kind is either BIGINT64_ELEMENTS or BIGUINT64_ELEMENTS.
|
||||
TNode<Word32T> IsBigInt64ElementsKind(TNode<Word32T> kind);
|
||||
|
||||
// Loads the element kind of TypedArray instance.
|
||||
TNode<Word32T> LoadElementsKind(TNode<Object> typed_array);
|
||||
TNode<Word32T> LoadElementsKind(TNode<JSTypedArray> typed_array);
|
||||
|
||||
// Returns the byte size of an element for a TypedArray elements kind.
|
||||
TNode<IntPtrT> GetTypedArrayElementSize(TNode<Word32T> elements_kind);
|
||||
|
@ -114,10 +114,16 @@ BUILTIN(TypedArrayPrototypeFill) {
|
||||
const char* method = "%TypedArray%.prototype.fill";
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method));
|
||||
ElementsKind kind = array->GetElementsKind();
|
||||
|
||||
Handle<Object> obj_value = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, obj_value, Object::ToNumber(obj_value));
|
||||
if (kind == BIGINT64_ELEMENTS || kind == BIGUINT64_ELEMENTS) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj_value,
|
||||
BigInt::FromObject(isolate, obj_value));
|
||||
} else {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj_value,
|
||||
Object::ToNumber(obj_value));
|
||||
}
|
||||
|
||||
int64_t len = array->length_value();
|
||||
int64_t start = 0;
|
||||
@ -151,9 +157,9 @@ BUILTIN(TypedArrayPrototypeFill) {
|
||||
DCHECK_LE(end, len);
|
||||
DCHECK_LE(count, len);
|
||||
|
||||
return array->GetElementsAccessor()->Fill(isolate, array, obj_value,
|
||||
static_cast<uint32_t>(start),
|
||||
static_cast<uint32_t>(end));
|
||||
return ElementsAccessor::ForKind(kind)->Fill(isolate, array, obj_value,
|
||||
static_cast<uint32_t>(start),
|
||||
static_cast<uint32_t>(end));
|
||||
}
|
||||
|
||||
BUILTIN(TypedArrayPrototypeIncludes) {
|
||||
|
@ -1738,6 +1738,154 @@ Node* CodeStubAssembler::LoadFixedTypedArrayElement(
|
||||
Node* CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
|
||||
Node* data_pointer, Node* index_node, ElementsKind elements_kind,
|
||||
ParameterMode parameter_mode) {
|
||||
if (elements_kind == BIGINT64_ELEMENTS) {
|
||||
Node* offset =
|
||||
ElementOffsetFromIndex(index_node, elements_kind, parameter_mode, 0);
|
||||
TVARIABLE(BigInt, var_result);
|
||||
Label done(this), if_zero(this);
|
||||
if (Is64()) {
|
||||
TNode<IntPtrT> value = UncheckedCast<IntPtrT>(
|
||||
Load(MachineType::IntPtr(), data_pointer, offset));
|
||||
Label if_positive(this), if_negative(this);
|
||||
GotoIf(IntPtrEqual(value, IntPtrConstant(0)), &if_zero);
|
||||
var_result = AllocateRawBigInt(IntPtrConstant(1));
|
||||
Branch(IntPtrGreaterThan(value, IntPtrConstant(0)), &if_positive,
|
||||
&if_negative);
|
||||
|
||||
BIND(&if_positive);
|
||||
{
|
||||
StoreBigIntBitfield(var_result.value(),
|
||||
IntPtrConstant(BigInt::SignBits::encode(false) |
|
||||
BigInt::LengthBits::encode(1)));
|
||||
StoreBigIntDigit(var_result.value(), 0, Unsigned(value));
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
BIND(&if_negative);
|
||||
{
|
||||
StoreBigIntBitfield(var_result.value(),
|
||||
IntPtrConstant(BigInt::SignBits::encode(true) |
|
||||
BigInt::LengthBits::encode(1)));
|
||||
StoreBigIntDigit(var_result.value(), 0,
|
||||
Unsigned(IntPtrSub(IntPtrConstant(0), value)));
|
||||
Goto(&done);
|
||||
}
|
||||
} else {
|
||||
DCHECK(!Is64());
|
||||
TVARIABLE(WordT, var_sign,
|
||||
IntPtrConstant(BigInt::SignBits::encode(false)));
|
||||
TVARIABLE(IntPtrT, var_low);
|
||||
TVARIABLE(IntPtrT, var_high);
|
||||
var_low = UncheckedCast<IntPtrT>(
|
||||
Load(MachineType::UintPtr(), data_pointer, offset));
|
||||
var_high = UncheckedCast<IntPtrT>(
|
||||
Load(MachineType::UintPtr(), data_pointer,
|
||||
Int32Add(offset, Int32Constant(kPointerSize))));
|
||||
|
||||
Label high_zero(this), negative(this), allocate_one_digit(this),
|
||||
allocate_two_digits(this);
|
||||
|
||||
GotoIf(WordEqual(var_high.value(), IntPtrConstant(0)), &high_zero);
|
||||
Branch(IntPtrLessThan(var_high.value(), IntPtrConstant(0)), &negative,
|
||||
&allocate_two_digits);
|
||||
|
||||
BIND(&high_zero);
|
||||
Branch(WordEqual(var_low.value(), IntPtrConstant(0)), &if_zero,
|
||||
&allocate_one_digit);
|
||||
|
||||
BIND(&negative);
|
||||
{
|
||||
var_sign = IntPtrConstant(BigInt::SignBits::encode(true));
|
||||
// We must negate the value by computing "0 - (high|low)", performing
|
||||
// both parts of the subtraction separately and manually taking care
|
||||
// of the carry bit (which is 1 iff low != 0).
|
||||
var_high = IntPtrSub(IntPtrConstant(0), var_high.value());
|
||||
Label carry(this), no_carry(this);
|
||||
Branch(WordEqual(var_low.value(), IntPtrConstant(0)), &no_carry,
|
||||
&carry);
|
||||
BIND(&carry);
|
||||
var_high = IntPtrSub(var_high.value(), IntPtrConstant(1));
|
||||
Goto(&no_carry);
|
||||
BIND(&no_carry);
|
||||
var_low = IntPtrSub(IntPtrConstant(0), var_low.value());
|
||||
// var_high was non-zero going into this block, but subtracting the
|
||||
// carry bit from it could bring us back onto the "one digit" path.
|
||||
Branch(WordEqual(var_high.value(), IntPtrConstant(0)),
|
||||
&allocate_one_digit, &allocate_two_digits);
|
||||
}
|
||||
|
||||
BIND(&allocate_one_digit);
|
||||
{
|
||||
var_result = AllocateRawBigInt(IntPtrConstant(1));
|
||||
StoreBigIntBitfield(
|
||||
var_result.value(),
|
||||
WordOr(var_sign.value(),
|
||||
IntPtrConstant(BigInt::LengthBits::encode(1))));
|
||||
StoreBigIntDigit(var_result.value(), 0, Unsigned(var_low.value()));
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
BIND(&allocate_two_digits);
|
||||
{
|
||||
var_result = AllocateRawBigInt(IntPtrConstant(2));
|
||||
StoreBigIntBitfield(
|
||||
var_result.value(),
|
||||
WordOr(var_sign.value(),
|
||||
IntPtrConstant(BigInt::LengthBits::encode(2))));
|
||||
StoreBigIntDigit(var_result.value(), 0, Unsigned(var_low.value()));
|
||||
StoreBigIntDigit(var_result.value(), 1, Unsigned(var_high.value()));
|
||||
Goto(&done);
|
||||
}
|
||||
}
|
||||
BIND(&if_zero);
|
||||
var_result = AllocateBigInt(IntPtrConstant(0));
|
||||
Goto(&done);
|
||||
|
||||
BIND(&done);
|
||||
return var_result.value();
|
||||
} else if (elements_kind == BIGUINT64_ELEMENTS) {
|
||||
Node* offset =
|
||||
ElementOffsetFromIndex(index_node, elements_kind, parameter_mode, 0);
|
||||
TVARIABLE(BigInt, var_result);
|
||||
Label if_zero(this), done(this);
|
||||
if (Is64()) {
|
||||
TNode<UintPtrT> value = UncheckedCast<UintPtrT>(
|
||||
Load(MachineType::UintPtr(), data_pointer, offset));
|
||||
GotoIf(IntPtrEqual(value, IntPtrConstant(0)), &if_zero);
|
||||
var_result = AllocateBigInt(IntPtrConstant(1));
|
||||
StoreBigIntDigit(var_result.value(), 0, value);
|
||||
Goto(&done);
|
||||
} else {
|
||||
DCHECK(!Is64());
|
||||
Label high_zero(this);
|
||||
|
||||
TNode<UintPtrT> low = UncheckedCast<UintPtrT>(
|
||||
Load(MachineType::UintPtr(), data_pointer, offset));
|
||||
TNode<UintPtrT> high = UncheckedCast<UintPtrT>(
|
||||
Load(MachineType::UintPtr(), data_pointer,
|
||||
Int32Add(offset, Int32Constant(kPointerSize))));
|
||||
|
||||
GotoIf(WordEqual(high, IntPtrConstant(0)), &high_zero);
|
||||
var_result = AllocateBigInt(IntPtrConstant(2));
|
||||
StoreBigIntDigit(var_result.value(), 0, low);
|
||||
StoreBigIntDigit(var_result.value(), 1, high);
|
||||
Goto(&done);
|
||||
|
||||
BIND(&high_zero);
|
||||
GotoIf(WordEqual(low, IntPtrConstant(0)), &if_zero);
|
||||
var_result = AllocateBigInt(IntPtrConstant(1));
|
||||
StoreBigIntDigit(var_result.value(), 0, low);
|
||||
Goto(&done);
|
||||
}
|
||||
BIND(&if_zero);
|
||||
var_result = AllocateBigInt(IntPtrConstant(0));
|
||||
Goto(&done);
|
||||
|
||||
BIND(&done);
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
// TODO(jkummerow): Inline this call, and unify a bit more with the above.
|
||||
Node* value = LoadFixedTypedArrayElement(data_pointer, index_node,
|
||||
elements_kind, parameter_mode);
|
||||
switch (elements_kind) {
|
||||
@ -2254,6 +2402,38 @@ TNode<HeapNumber> CodeStubAssembler::AllocateHeapNumberWithValue(
|
||||
return result;
|
||||
}
|
||||
|
||||
TNode<BigInt> CodeStubAssembler::AllocateBigInt(TNode<IntPtrT> length) {
|
||||
TNode<BigInt> result = AllocateRawBigInt(length);
|
||||
STATIC_ASSERT(BigInt::LengthBits::kShift == 0);
|
||||
StoreBigIntBitfield(result, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
TNode<BigInt> CodeStubAssembler::AllocateRawBigInt(TNode<IntPtrT> length) {
|
||||
// This is currently used only for 64-bit wide BigInts. If more general
|
||||
// applicability is required, a large-object check must be added.
|
||||
CSA_ASSERT(this, UintPtrLessThan(length, IntPtrConstant(3)));
|
||||
|
||||
TNode<IntPtrT> size = IntPtrAdd(IntPtrConstant(BigInt::kHeaderSize),
|
||||
Signed(WordShl(length, kPointerSizeLog2)));
|
||||
Node* raw_result = Allocate(size, kNone);
|
||||
StoreMapNoWriteBarrier(raw_result, Heap::kBigIntMapRootIndex);
|
||||
return UncheckedCast<BigInt>(raw_result);
|
||||
}
|
||||
|
||||
void CodeStubAssembler::StoreBigIntBitfield(TNode<BigInt> bigint,
|
||||
TNode<WordT> bitfield) {
|
||||
StoreObjectFieldNoWriteBarrier(bigint, BigInt::kBitfieldOffset, bitfield,
|
||||
MachineType::PointerRepresentation());
|
||||
}
|
||||
|
||||
void CodeStubAssembler::StoreBigIntDigit(TNode<BigInt> bigint, int digit_index,
|
||||
TNode<UintPtrT> digit) {
|
||||
StoreObjectFieldNoWriteBarrier(
|
||||
bigint, BigInt::kDigitsOffset + digit_index * kPointerSize, digit,
|
||||
UintPtrT::kMachineRepresentation);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::AllocateSeqOneByteString(int length,
|
||||
AllocationFlags flags) {
|
||||
Comment("AllocateSeqOneByteString");
|
||||
@ -5672,6 +5852,27 @@ TNode<Number> CodeStubAssembler::ToNumber(SloppyTNode<Context> context,
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
TNode<BigInt> CodeStubAssembler::ToBigInt(SloppyTNode<Context> context,
|
||||
SloppyTNode<Object> input) {
|
||||
TVARIABLE(BigInt, var_result);
|
||||
Label if_bigint(this), done(this), if_throw(this);
|
||||
|
||||
GotoIf(TaggedIsSmi(input), &if_throw);
|
||||
GotoIf(IsBigInt(input), &if_bigint);
|
||||
var_result = CAST(CallRuntime(Runtime::kToBigInt, context, input));
|
||||
Goto(&done);
|
||||
|
||||
BIND(&if_bigint);
|
||||
var_result = CAST(input);
|
||||
Goto(&done);
|
||||
|
||||
BIND(&if_throw);
|
||||
ThrowTypeError(context, MessageTemplate::kBigIntFromObject, input);
|
||||
|
||||
BIND(&done);
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
void CodeStubAssembler::TaggedToNumeric(Node* context, Node* value, Label* done,
|
||||
Variable* var_numeric) {
|
||||
TaggedToNumeric(context, value, done, var_numeric, nullptr);
|
||||
@ -7138,6 +7339,8 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
|
||||
FLOAT32_ELEMENTS,
|
||||
FLOAT64_ELEMENTS,
|
||||
UINT8_CLAMPED_ELEMENTS,
|
||||
BIGUINT64_ELEMENTS,
|
||||
BIGINT64_ELEMENTS,
|
||||
};
|
||||
Label* labels[] = {
|
||||
&if_isobjectorsmi, &if_isobjectorsmi, &if_isobjectorsmi,
|
||||
@ -7156,6 +7359,8 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
|
||||
&if_typedarray,
|
||||
&if_typedarray,
|
||||
&if_typedarray,
|
||||
&if_typedarray,
|
||||
&if_typedarray,
|
||||
};
|
||||
// clang-format on
|
||||
STATIC_ASSERT(arraysize(values) == arraysize(labels));
|
||||
@ -7868,6 +8073,7 @@ Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
|
||||
// same layout as the HeapNumber for the HeapNumber::value field. This
|
||||
// way we can also properly optimize stores of oddballs to typed arrays.
|
||||
GotoIf(IsHeapNumber(input), &if_heapnumber);
|
||||
STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
|
||||
Branch(HasInstanceType(input, ODDBALL_TYPE), &if_heapnumber, bailout);
|
||||
|
||||
BIND(&if_heapnumber);
|
||||
@ -7913,7 +8119,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
|
||||
bool is_jsarray,
|
||||
ElementsKind elements_kind,
|
||||
KeyedAccessStoreMode store_mode,
|
||||
Label* bailout) {
|
||||
Label* bailout, Node* context) {
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsJSProxy(object)));
|
||||
|
||||
Node* elements = LoadElements(object);
|
||||
@ -7925,9 +8131,16 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
|
||||
|
||||
// TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode().
|
||||
ParameterMode parameter_mode = INTPTR_PARAMETERS;
|
||||
key = TryToIntptr(key, bailout);
|
||||
Node* intptr_key = TryToIntptr(key, bailout);
|
||||
|
||||
if (IsFixedTypedArrayElementsKind(elements_kind)) {
|
||||
if (elements_kind == BIGINT64_ELEMENTS ||
|
||||
elements_kind == BIGUINT64_ELEMENTS) {
|
||||
// TODO(jkummerow): Add inline support.
|
||||
CallRuntime(Runtime::kSetProperty, context, object, key, value,
|
||||
SmiConstant(LanguageMode::kSloppy));
|
||||
return;
|
||||
}
|
||||
Label done(this);
|
||||
// TODO(ishell): call ToNumber() on value and don't bailout but be careful
|
||||
// to call it only once if we decide to bailout because of bounds checks.
|
||||
@ -7951,10 +8164,10 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
|
||||
if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
|
||||
// Skip the store if we write beyond the length or
|
||||
// to a property with a negative integer index.
|
||||
GotoIfNot(UintPtrLessThan(key, length), &done);
|
||||
GotoIfNot(UintPtrLessThan(intptr_key, length), &done);
|
||||
} else {
|
||||
DCHECK_EQ(STANDARD_STORE, store_mode);
|
||||
GotoIfNot(UintPtrLessThan(key, length), bailout);
|
||||
GotoIfNot(UintPtrLessThan(intptr_key, length), bailout);
|
||||
}
|
||||
|
||||
// Backing store = external_pointer + base_pointer.
|
||||
@ -7965,7 +8178,8 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
|
||||
LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
|
||||
Node* backing_store =
|
||||
IntPtrAdd(external_pointer, BitcastTaggedToWord(base_pointer));
|
||||
StoreElement(backing_store, elements_kind, key, value, parameter_mode);
|
||||
StoreElement(backing_store, elements_kind, intptr_key, value,
|
||||
parameter_mode);
|
||||
Goto(&done);
|
||||
|
||||
BIND(&done);
|
||||
@ -7988,11 +8202,11 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
|
||||
}
|
||||
|
||||
if (IsGrowStoreMode(store_mode)) {
|
||||
elements =
|
||||
CheckForCapacityGrow(object, elements, elements_kind, store_mode,
|
||||
length, key, parameter_mode, is_jsarray, bailout);
|
||||
elements = CheckForCapacityGrow(object, elements, elements_kind, store_mode,
|
||||
length, intptr_key, parameter_mode,
|
||||
is_jsarray, bailout);
|
||||
} else {
|
||||
GotoIfNot(UintPtrLessThan(key, length), bailout);
|
||||
GotoIfNot(UintPtrLessThan(intptr_key, length), bailout);
|
||||
}
|
||||
|
||||
// If we didn't grow {elements}, it might still be COW, in which case we
|
||||
@ -8005,7 +8219,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
|
||||
}
|
||||
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsFixedCOWArrayMap(LoadMap(elements))));
|
||||
StoreElement(elements, elements_kind, key, value, parameter_mode);
|
||||
StoreElement(elements, elements_kind, intptr_key, value, parameter_mode);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::CheckForCapacityGrow(
|
||||
|
@ -751,6 +751,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
// Allocate a HeapNumber with a specific value.
|
||||
TNode<HeapNumber> AllocateHeapNumberWithValue(SloppyTNode<Float64T> value,
|
||||
MutableMode mode = IMMUTABLE);
|
||||
// Allocate a BigInt with {length} digits. Sets the sign bit to {false}.
|
||||
// Does not initialize the digits.
|
||||
TNode<BigInt> AllocateBigInt(TNode<IntPtrT> length);
|
||||
// Like above, but allowing custom bitfield initialization.
|
||||
TNode<BigInt> AllocateRawBigInt(TNode<IntPtrT> length);
|
||||
void StoreBigIntBitfield(TNode<BigInt> bigint, TNode<WordT> bitfield);
|
||||
void StoreBigIntDigit(TNode<BigInt> bigint, int digit_index,
|
||||
TNode<UintPtrT> digit);
|
||||
// Allocate a SeqOneByteString with the given length.
|
||||
Node* AllocateSeqOneByteString(int length, AllocationFlags flags = kNone);
|
||||
Node* AllocateSeqOneByteString(Node* context, TNode<Smi> length,
|
||||
@ -1251,6 +1259,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
TNode<Number> ToNumber_Inline(SloppyTNode<Context> context,
|
||||
SloppyTNode<Object> input);
|
||||
|
||||
// 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);
|
||||
|
||||
// Converts |input| to one of 2^32 integer values in the range 0 through
|
||||
// 2^32-1, inclusive.
|
||||
// ES#sec-touint32
|
||||
@ -1745,7 +1758,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
|
||||
void EmitElementStore(Node* object, Node* key, Node* value, bool is_jsarray,
|
||||
ElementsKind elements_kind,
|
||||
KeyedAccessStoreMode store_mode, Label* bailout);
|
||||
KeyedAccessStoreMode store_mode, Label* bailout,
|
||||
Node* context);
|
||||
|
||||
Node* CheckForCapacityGrow(Node* object, Node* elements, ElementsKind kind,
|
||||
KeyedAccessStoreMode store_mode, Node* length,
|
||||
|
@ -332,7 +332,7 @@ TF_STUB(ElementsTransitionAndStoreStub, CodeStubAssembler) {
|
||||
TransitionElementsKind(receiver, map, stub->from_kind(), stub->to_kind(),
|
||||
stub->is_jsarray(), &miss);
|
||||
EmitElementStore(receiver, key, value, stub->is_jsarray(), stub->to_kind(),
|
||||
stub->store_mode(), &miss);
|
||||
stub->store_mode(), &miss, context);
|
||||
Return(value);
|
||||
}
|
||||
|
||||
@ -524,7 +524,7 @@ TF_STUB(StoreFastElementStub, CodeStubAssembler) {
|
||||
Label miss(this);
|
||||
|
||||
EmitElementStore(receiver, key, value, stub->is_js_array(),
|
||||
stub->elements_kind(), stub->store_mode(), &miss);
|
||||
stub->elements_kind(), stub->store_mode(), &miss, context);
|
||||
Return(value);
|
||||
|
||||
BIND(&miss);
|
||||
|
@ -1001,6 +1001,10 @@ ElementAccess AccessBuilder::ForTypedArrayElement(ExternalArrayType type,
|
||||
MachineType::Float64(), kNoWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
case kExternalBigInt64Array:
|
||||
case kExternalBigUint64Array:
|
||||
// TODO(neis/jkummerow): Define appropriate types.
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -25,7 +25,11 @@ bool CanInlineElementAccess(Handle<Map> map) {
|
||||
if (map->has_indexed_interceptor()) return false;
|
||||
ElementsKind const elements_kind = map->elements_kind();
|
||||
if (IsFastElementsKind(elements_kind)) return true;
|
||||
if (IsFixedTypedArrayElementsKind(elements_kind)) return true;
|
||||
if (IsFixedTypedArrayElementsKind(elements_kind) &&
|
||||
elements_kind != BIGUINT64_ELEMENTS &&
|
||||
elements_kind != BIGINT64_ELEMENTS) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,7 @@ Reduction JSBuiltinReducer::ReduceArrayIterator(Handle<Map> receiver_map,
|
||||
map_index = Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX;
|
||||
} else {
|
||||
DCHECK_GE(receiver_map->elements_kind(), UINT8_ELEMENTS);
|
||||
DCHECK_LE(receiver_map->elements_kind(), UINT8_CLAMPED_ELEMENTS);
|
||||
DCHECK_LE(receiver_map->elements_kind(), BIGINT64_ELEMENTS);
|
||||
map_index = (kind == IterationKind::kValues
|
||||
? Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX
|
||||
: Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX) +
|
||||
|
@ -82,6 +82,9 @@ MachineRepresentation MachineRepresentationFromArrayType(
|
||||
return MachineRepresentation::kFloat32;
|
||||
case kExternalFloat64Array:
|
||||
return MachineRepresentation::kFloat64;
|
||||
case kExternalBigInt64Array:
|
||||
case kExternalBigUint64Array:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ class TypeCache final {
|
||||
Type* const kUint32 = Type::Unsigned32();
|
||||
Type* const kFloat32 = Type::Number();
|
||||
Type* const kFloat64 = Type::Number();
|
||||
Type* const kBigInt64 = Type::BigInt();
|
||||
Type* const kBigUint64 = Type::BigInt();
|
||||
|
||||
Type* const kHoleySmi =
|
||||
Type::Union(Type::SignedSmall(), Type::Hole(), zone());
|
||||
|
@ -116,6 +116,8 @@ enum ContextLookupFlags {
|
||||
V(WEAKMAP_SET_INDEX, JSFunction, weakmap_set) \
|
||||
V(WEAKSET_ADD_INDEX, JSFunction, weakset_add)
|
||||
|
||||
// If you add something here, also add it to ARRAY_ITERATOR_LIST in
|
||||
// bootstrapper.cc.
|
||||
#define NATIVE_CONTEXT_JS_ARRAY_ITERATOR_MAPS(V) \
|
||||
V(TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX, Map, typed_array_key_iterator_map) \
|
||||
V(FAST_ARRAY_KEY_ITERATOR_MAP_INDEX, Map, fast_array_key_iterator_map) \
|
||||
@ -139,6 +141,10 @@ enum ContextLookupFlags {
|
||||
float64_array_key_value_iterator_map) \
|
||||
V(UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
|
||||
uint8_clamped_array_key_value_iterator_map) \
|
||||
V(BIGUINT64_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
|
||||
biguint64_array_key_value_iterator_map) \
|
||||
V(BIGINT64_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
|
||||
bigint64_array_key_value_iterator_map) \
|
||||
\
|
||||
V(FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
|
||||
fast_smi_array_key_value_iterator_map) \
|
||||
@ -169,6 +175,10 @@ enum ContextLookupFlags {
|
||||
float64_array_value_iterator_map) \
|
||||
V(UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
|
||||
uint8_clamped_array_value_iterator_map) \
|
||||
V(BIGUINT64_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
|
||||
biguint64_array_value_iterator_map) \
|
||||
V(BIGINT64_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
|
||||
bigint64_array_value_iterator_map) \
|
||||
\
|
||||
V(FAST_SMI_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
|
||||
fast_smi_array_value_iterator_map) \
|
||||
@ -215,6 +225,8 @@ enum ContextLookupFlags {
|
||||
async_generator_return_closed_reject_shared_fun) \
|
||||
V(ATOMICS_OBJECT, JSObject, atomics_object) \
|
||||
V(BIGINT_FUNCTION_INDEX, JSFunction, bigint_function) \
|
||||
V(BIGINT64_ARRAY_FUN_INDEX, JSFunction, bigint64_array_fun) \
|
||||
V(BIGUINT64_ARRAY_FUN_INDEX, JSFunction, biguint64_array_fun) \
|
||||
V(BOOLEAN_FUNCTION_INDEX, JSFunction, boolean_function) \
|
||||
V(BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX, Map, \
|
||||
bound_function_with_constructor_map) \
|
||||
|
@ -692,6 +692,8 @@ class RuntimeCallTimer final {
|
||||
V(ArrayBuffer_New) \
|
||||
V(Array_CloneElementAt) \
|
||||
V(Array_New) \
|
||||
V(BigInt64Array_New) \
|
||||
V(BigUint64Array_New) \
|
||||
V(BooleanObject_BooleanValue) \
|
||||
V(BooleanObject_New) \
|
||||
V(Context_New) \
|
||||
|
@ -30,6 +30,8 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) {
|
||||
case PACKED_DOUBLE_ELEMENTS:
|
||||
case HOLEY_DOUBLE_ELEMENTS:
|
||||
case FLOAT64_ELEMENTS:
|
||||
case BIGINT64_ELEMENTS:
|
||||
case BIGUINT64_ELEMENTS:
|
||||
return 3;
|
||||
case PACKED_SMI_ELEMENTS:
|
||||
case PACKED_ELEMENTS:
|
||||
|
@ -49,17 +49,19 @@ enum ElementsKind {
|
||||
FLOAT32_ELEMENTS,
|
||||
FLOAT64_ELEMENTS,
|
||||
UINT8_CLAMPED_ELEMENTS,
|
||||
BIGUINT64_ELEMENTS,
|
||||
BIGINT64_ELEMENTS,
|
||||
|
||||
// Sentinel ElementsKind for objects with no elements.
|
||||
NO_ELEMENTS,
|
||||
|
||||
// Derived constants from ElementsKind.
|
||||
FIRST_ELEMENTS_KIND = PACKED_SMI_ELEMENTS,
|
||||
LAST_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
|
||||
LAST_ELEMENTS_KIND = BIGINT64_ELEMENTS,
|
||||
FIRST_FAST_ELEMENTS_KIND = PACKED_SMI_ELEMENTS,
|
||||
LAST_FAST_ELEMENTS_KIND = HOLEY_DOUBLE_ELEMENTS,
|
||||
FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_ELEMENTS,
|
||||
LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
|
||||
LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = BIGINT64_ELEMENTS,
|
||||
TERMINAL_FAST_ELEMENTS_KIND = HOLEY_ELEMENTS
|
||||
};
|
||||
|
||||
|
189
src/elements.cc
189
src/elements.cc
@ -38,6 +38,8 @@
|
||||
// - FixedFloat32ElementsAccessor
|
||||
// - FixedFloat64ElementsAccessor
|
||||
// - FixedUint8ClampedElementsAccessor
|
||||
// - FixedBigUint64ElementsAccessor
|
||||
// - FixedBigInt64ElementsAccessor
|
||||
// - DictionaryElementsAccessor
|
||||
// - SloppyArgumentsElementsAccessor
|
||||
// - FastSloppyArgumentsElementsAccessor
|
||||
@ -89,7 +91,9 @@ enum Where { AT_START, AT_END };
|
||||
V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
|
||||
V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
|
||||
V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
|
||||
FixedUint8ClampedArray)
|
||||
FixedUint8ClampedArray) \
|
||||
V(FixedBigUint64ElementsAccessor, BIGUINT64_ELEMENTS, FixedBigUint64Array) \
|
||||
V(FixedBigInt64ElementsAccessor, BIGINT64_ELEMENTS, FixedBigInt64Array)
|
||||
|
||||
template<ElementsKind Kind> class ElementsKindTraits {
|
||||
public:
|
||||
@ -2994,15 +2998,9 @@ class TypedElementsAccessor
|
||||
uint32_t end) {
|
||||
Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
|
||||
DCHECK(!array->WasNeutered());
|
||||
DCHECK(obj_value->IsNumber());
|
||||
DCHECK(obj_value->IsNumeric());
|
||||
|
||||
ctype value;
|
||||
if (obj_value->IsSmi()) {
|
||||
value = BackingStore::from(Smi::ToInt(*obj_value));
|
||||
} else {
|
||||
DCHECK(obj_value->IsHeapNumber());
|
||||
value = BackingStore::from(HeapNumber::cast(*obj_value)->value());
|
||||
}
|
||||
ctype value = BackingStore::FromHandle(obj_value);
|
||||
|
||||
// Ensure indexes are within array bounds
|
||||
DCHECK_LE(0, start);
|
||||
@ -3033,41 +3031,49 @@ class TypedElementsAccessor
|
||||
length > static_cast<uint32_t>(elements->length())) {
|
||||
return Just(true);
|
||||
}
|
||||
if (!value->IsNumber()) return Just(false);
|
||||
|
||||
double search_value = value->Number();
|
||||
|
||||
if (!std::isfinite(search_value)) {
|
||||
// Integral types cannot represent +Inf or NaN
|
||||
if (AccessorClass::kind() < FLOAT32_ELEMENTS ||
|
||||
AccessorClass::kind() > FLOAT64_ELEMENTS) {
|
||||
return Just(false);
|
||||
}
|
||||
} else if (search_value < std::numeric_limits<ctype>::lowest() ||
|
||||
search_value > std::numeric_limits<ctype>::max()) {
|
||||
// Return false if value can't be represented in this space
|
||||
return Just(false);
|
||||
}
|
||||
|
||||
ctype typed_search_value;
|
||||
// Prototype has no elements, and not searching for the hole --- limit
|
||||
// search to backing store length.
|
||||
if (static_cast<uint32_t>(elements->length()) < length) {
|
||||
length = elements->length();
|
||||
}
|
||||
|
||||
if (!std::isnan(search_value)) {
|
||||
for (uint32_t k = start_from; k < length; ++k) {
|
||||
double element_k = elements->get_scalar(k);
|
||||
if (element_k == search_value) return Just(true);
|
||||
}
|
||||
return Just(false);
|
||||
if (Kind == BIGINT64_ELEMENTS || Kind == BIGUINT64_ELEMENTS) {
|
||||
if (!value->IsBigInt()) return Just(false);
|
||||
bool lossless;
|
||||
typed_search_value = BackingStore::FromHandle(value, &lossless);
|
||||
if (!lossless) return Just(false);
|
||||
} else {
|
||||
for (uint32_t k = start_from; k < length; ++k) {
|
||||
double element_k = elements->get_scalar(k);
|
||||
if (std::isnan(element_k)) return Just(true);
|
||||
if (!value->IsNumber()) return Just(false);
|
||||
double search_value = value->Number();
|
||||
if (!std::isfinite(search_value)) {
|
||||
// Integral types cannot represent +Inf or NaN.
|
||||
if (Kind < FLOAT32_ELEMENTS || Kind > FLOAT64_ELEMENTS) {
|
||||
return Just(false);
|
||||
}
|
||||
if (std::isnan(search_value)) {
|
||||
for (uint32_t k = start_from; k < length; ++k) {
|
||||
double element_k = elements->get_scalar(k);
|
||||
if (std::isnan(element_k)) return Just(true);
|
||||
}
|
||||
return Just(false);
|
||||
}
|
||||
} else if (search_value < std::numeric_limits<ctype>::lowest() ||
|
||||
search_value > std::numeric_limits<ctype>::max()) {
|
||||
// Return false if value can't be represented in this space.
|
||||
return Just(false);
|
||||
}
|
||||
typed_search_value = static_cast<ctype>(search_value);
|
||||
if (static_cast<double>(typed_search_value) != search_value) {
|
||||
return Just(false); // Loss of precision.
|
||||
}
|
||||
return Just(false);
|
||||
}
|
||||
|
||||
for (uint32_t k = start_from; k < length; ++k) {
|
||||
ctype element_k = elements->get_scalar(k);
|
||||
if (element_k == typed_search_value) return Just(true);
|
||||
}
|
||||
return Just(false);
|
||||
}
|
||||
|
||||
static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate,
|
||||
@ -3079,20 +3085,33 @@ class TypedElementsAccessor
|
||||
if (WasNeutered(*receiver)) return Just<int64_t>(-1);
|
||||
|
||||
BackingStore* elements = BackingStore::cast(receiver->elements());
|
||||
if (!value->IsNumber()) return Just<int64_t>(-1);
|
||||
ctype typed_search_value;
|
||||
|
||||
double search_value = value->Number();
|
||||
|
||||
if (!std::isfinite(search_value)) {
|
||||
// Integral types cannot represent +Inf or NaN.
|
||||
if (AccessorClass::kind() < FLOAT32_ELEMENTS ||
|
||||
AccessorClass::kind() > FLOAT64_ELEMENTS) {
|
||||
if (Kind == BIGINT64_ELEMENTS || Kind == BIGUINT64_ELEMENTS) {
|
||||
if (!value->IsBigInt()) return Just<int64_t>(-1);
|
||||
bool lossless;
|
||||
typed_search_value = BackingStore::FromHandle(value, &lossless);
|
||||
if (!lossless) return Just<int64_t>(-1);
|
||||
} else {
|
||||
if (!value->IsNumber()) return Just<int64_t>(-1);
|
||||
double search_value = value->Number();
|
||||
if (!std::isfinite(search_value)) {
|
||||
// Integral types cannot represent +Inf or NaN.
|
||||
if (Kind < FLOAT32_ELEMENTS || Kind > FLOAT64_ELEMENTS) {
|
||||
return Just<int64_t>(-1);
|
||||
}
|
||||
if (std::isnan(search_value)) {
|
||||
return Just<int64_t>(-1);
|
||||
}
|
||||
} else if (search_value < std::numeric_limits<ctype>::lowest() ||
|
||||
search_value > std::numeric_limits<ctype>::max()) {
|
||||
// Return false if value can't be represented in this ElementsKind.
|
||||
return Just<int64_t>(-1);
|
||||
}
|
||||
} else if (search_value < std::numeric_limits<ctype>::lowest() ||
|
||||
search_value > std::numeric_limits<ctype>::max()) {
|
||||
// Return false if value can't be represented in this ElementsKind.
|
||||
return Just<int64_t>(-1);
|
||||
typed_search_value = static_cast<ctype>(search_value);
|
||||
if (static_cast<double>(typed_search_value) != search_value) {
|
||||
return Just<int64_t>(-1); // Loss of precision.
|
||||
}
|
||||
}
|
||||
|
||||
// Prototype has no elements, and not searching for the hole --- limit
|
||||
@ -3101,15 +3120,6 @@ class TypedElementsAccessor
|
||||
length = elements->length();
|
||||
}
|
||||
|
||||
if (std::isnan(search_value)) {
|
||||
return Just<int64_t>(-1);
|
||||
}
|
||||
|
||||
ctype typed_search_value = static_cast<ctype>(search_value);
|
||||
if (static_cast<double>(typed_search_value) != search_value) {
|
||||
return Just<int64_t>(-1); // Loss of precision.
|
||||
}
|
||||
|
||||
for (uint32_t k = start_from; k < length; ++k) {
|
||||
ctype element_k = elements->get_scalar(k);
|
||||
if (element_k == typed_search_value) return Just<int64_t>(k);
|
||||
@ -3124,28 +3134,34 @@ class TypedElementsAccessor
|
||||
DisallowHeapAllocation no_gc;
|
||||
DCHECK(!WasNeutered(*receiver));
|
||||
|
||||
if (!value->IsNumber()) return Just<int64_t>(-1);
|
||||
BackingStore* elements = BackingStore::cast(receiver->elements());
|
||||
ctype typed_search_value;
|
||||
|
||||
double search_value = value->Number();
|
||||
|
||||
if (!std::isfinite(search_value)) {
|
||||
if (std::is_integral<ctype>::value) {
|
||||
// Integral types cannot represent +Inf or NaN.
|
||||
return Just<int64_t>(-1);
|
||||
} else if (std::isnan(search_value)) {
|
||||
// Strict Equality Comparison of NaN is always false.
|
||||
if (Kind == BIGINT64_ELEMENTS || Kind == BIGUINT64_ELEMENTS) {
|
||||
if (!value->IsBigInt()) return Just<int64_t>(-1);
|
||||
bool lossless;
|
||||
typed_search_value = BackingStore::FromHandle(value, &lossless);
|
||||
if (!lossless) return Just<int64_t>(-1);
|
||||
} else {
|
||||
if (!value->IsNumber()) return Just<int64_t>(-1);
|
||||
double search_value = value->Number();
|
||||
if (!std::isfinite(search_value)) {
|
||||
if (std::is_integral<ctype>::value) {
|
||||
// Integral types cannot represent +Inf or NaN.
|
||||
return Just<int64_t>(-1);
|
||||
} else if (std::isnan(search_value)) {
|
||||
// Strict Equality Comparison of NaN is always false.
|
||||
return Just<int64_t>(-1);
|
||||
}
|
||||
} else if (search_value < std::numeric_limits<ctype>::lowest() ||
|
||||
search_value > std::numeric_limits<ctype>::max()) {
|
||||
// Return -1 if value can't be represented in this ElementsKind.
|
||||
return Just<int64_t>(-1);
|
||||
}
|
||||
} else if (search_value < std::numeric_limits<ctype>::lowest() ||
|
||||
search_value > std::numeric_limits<ctype>::max()) {
|
||||
// Return -1 if value can't be represented in this ElementsKind.
|
||||
return Just<int64_t>(-1);
|
||||
}
|
||||
|
||||
ctype typed_search_value = static_cast<ctype>(search_value);
|
||||
if (static_cast<double>(typed_search_value) != search_value) {
|
||||
return Just<int64_t>(-1); // Loss of precision.
|
||||
typed_search_value = static_cast<ctype>(search_value);
|
||||
if (static_cast<double>(typed_search_value) != search_value) {
|
||||
return Just<int64_t>(-1); // Loss of precision.
|
||||
}
|
||||
}
|
||||
|
||||
DCHECK_LT(start_from, elements->length());
|
||||
@ -3349,6 +3365,7 @@ class TypedElementsAccessor
|
||||
static bool TryCopyElementsFastNumber(Context* context, JSArray* source,
|
||||
JSTypedArray* destination,
|
||||
size_t length, uint32_t offset) {
|
||||
if (Kind == BIGINT64_ELEMENTS || Kind == BIGUINT64_ELEMENTS) return false;
|
||||
Isolate* isolate = source->GetIsolate();
|
||||
DisallowHeapAllocation no_gc;
|
||||
DisallowJavascriptExecution no_js(isolate);
|
||||
@ -3429,7 +3446,13 @@ class TypedElementsAccessor
|
||||
Handle<Object> elem;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, elem,
|
||||
Object::GetProperty(&it));
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, elem, Object::ToNumber(elem));
|
||||
if (Kind == BIGINT64_ELEMENTS || Kind == BIGUINT64_ELEMENTS) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, elem,
|
||||
BigInt::FromObject(isolate, elem));
|
||||
} else {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, elem,
|
||||
Object::ToNumber(elem));
|
||||
}
|
||||
|
||||
if (V8_UNLIKELY(destination->WasNeutered())) {
|
||||
const char* op = "set";
|
||||
@ -3463,6 +3486,24 @@ class TypedElementsAccessor
|
||||
// All conversions from TypedArrays can be done without allocation.
|
||||
if (source->IsJSTypedArray()) {
|
||||
Handle<JSTypedArray> source_ta = Handle<JSTypedArray>::cast(source);
|
||||
ElementsKind source_kind = source_ta->GetElementsKind();
|
||||
bool source_is_bigint =
|
||||
source_kind == BIGINT64_ELEMENTS || source_kind == BIGUINT64_ELEMENTS;
|
||||
bool target_is_bigint =
|
||||
Kind == BIGINT64_ELEMENTS || Kind == BIGUINT64_ELEMENTS;
|
||||
if (target_is_bigint) {
|
||||
if (V8_UNLIKELY(!source_is_bigint)) {
|
||||
Handle<Object> first =
|
||||
JSReceiver::GetElement(isolate, source_ta, 0).ToHandleChecked();
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kBigIntFromObject, first));
|
||||
}
|
||||
} else {
|
||||
if (V8_UNLIKELY(source_is_bigint)) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kBigIntToNumber));
|
||||
}
|
||||
}
|
||||
CopyElementsFromTypedArray(*source_ta, *destination_ta, length, offset);
|
||||
return *isolate->factory()->undefined_value();
|
||||
}
|
||||
|
@ -1405,6 +1405,8 @@ enum ExternalArrayType {
|
||||
kExternalFloat32Array,
|
||||
kExternalFloat64Array,
|
||||
kExternalUint8ClampedArray,
|
||||
kExternalBigInt64Array,
|
||||
kExternalBigUint64Array,
|
||||
};
|
||||
|
||||
struct AssemblerDebugInfo {
|
||||
|
@ -22,6 +22,8 @@
|
||||
V(await_string, "await") \
|
||||
V(BigInt_string, "BigInt") \
|
||||
V(bigint_string, "bigint") \
|
||||
V(BigInt64Array_string, "BigInt64Array") \
|
||||
V(BigUint64Array_string, "BigUint64Array") \
|
||||
V(bind_string, "bind") \
|
||||
V(Boolean_string, "Boolean") \
|
||||
V(boolean_string, "boolean") \
|
||||
|
@ -169,6 +169,8 @@ using v8::MemoryPressureLevel;
|
||||
V(Map, fixed_float32_array_map, FixedFloat32ArrayMap) \
|
||||
V(Map, fixed_float64_array_map, FixedFloat64ArrayMap) \
|
||||
V(Map, fixed_uint8_clamped_array_map, FixedUint8ClampedArrayMap) \
|
||||
V(Map, fixed_biguint64_array_map, FixedBigUint64ArrayMap) \
|
||||
V(Map, fixed_bigint64_array_map, FixedBigInt64ArrayMap) \
|
||||
/* Oddball maps */ \
|
||||
V(Map, undefined_map, UndefinedMap) \
|
||||
V(Map, the_hole_map, TheHoleMap) \
|
||||
@ -194,6 +196,9 @@ using v8::MemoryPressureLevel;
|
||||
V(FixedTypedArrayBase, empty_fixed_float64_array, EmptyFixedFloat64Array) \
|
||||
V(FixedTypedArrayBase, empty_fixed_uint8_clamped_array, \
|
||||
EmptyFixedUint8ClampedArray) \
|
||||
V(FixedTypedArrayBase, empty_fixed_biguint64_array, \
|
||||
EmptyFixedBigUint64Array) \
|
||||
V(FixedTypedArrayBase, empty_fixed_bigint64_array, EmptyFixedBigInt64Array) \
|
||||
V(Script, empty_script, EmptyScript) \
|
||||
V(Cell, undefined_cell, UndefinedCell) \
|
||||
V(FixedArray, empty_sloppy_arguments_elements, EmptySloppyArgumentsElements) \
|
||||
|
@ -1625,15 +1625,18 @@ void AccessorAssembler::EmitElementLoad(
|
||||
|
||||
Label uint8_elements(this), int8_elements(this), uint16_elements(this),
|
||||
int16_elements(this), uint32_elements(this), int32_elements(this),
|
||||
float32_elements(this), float64_elements(this);
|
||||
float32_elements(this), float64_elements(this), bigint64_elements(this),
|
||||
biguint64_elements(this);
|
||||
Label* elements_kind_labels[] = {
|
||||
&uint8_elements, &uint8_elements, &int8_elements,
|
||||
&uint16_elements, &int16_elements, &uint32_elements,
|
||||
&int32_elements, &float32_elements, &float64_elements};
|
||||
&uint8_elements, &uint8_elements, &int8_elements,
|
||||
&uint16_elements, &int16_elements, &uint32_elements,
|
||||
&int32_elements, &float32_elements, &float64_elements,
|
||||
&bigint64_elements, &biguint64_elements};
|
||||
int32_t elements_kinds[] = {
|
||||
UINT8_ELEMENTS, UINT8_CLAMPED_ELEMENTS, INT8_ELEMENTS,
|
||||
UINT16_ELEMENTS, INT16_ELEMENTS, UINT32_ELEMENTS,
|
||||
INT32_ELEMENTS, FLOAT32_ELEMENTS, FLOAT64_ELEMENTS};
|
||||
UINT8_ELEMENTS, UINT8_CLAMPED_ELEMENTS, INT8_ELEMENTS,
|
||||
UINT16_ELEMENTS, INT16_ELEMENTS, UINT32_ELEMENTS,
|
||||
INT32_ELEMENTS, FLOAT32_ELEMENTS, FLOAT64_ELEMENTS,
|
||||
BIGINT64_ELEMENTS, BIGUINT64_ELEMENTS};
|
||||
const size_t kTypedElementsKindCount =
|
||||
LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
|
||||
FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 1;
|
||||
@ -1697,6 +1700,18 @@ void AccessorAssembler::EmitElementLoad(
|
||||
var_double_value->Bind(element);
|
||||
Goto(rebox_double);
|
||||
}
|
||||
BIND(&bigint64_elements);
|
||||
{
|
||||
Comment("BIGINT64_ELEMENTS");
|
||||
exit_point->Return(LoadFixedTypedArrayElementAsTagged(
|
||||
backing_store, intptr_index, BIGINT64_ELEMENTS, INTPTR_PARAMETERS));
|
||||
}
|
||||
BIND(&biguint64_elements);
|
||||
{
|
||||
Comment("BIGUINT64_ELEMENTS");
|
||||
exit_point->Return(LoadFixedTypedArrayElementAsTagged(
|
||||
backing_store, intptr_index, BIGUINT64_ELEMENTS, INTPTR_PARAMETERS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ FUNCTION(Int32Array, 4)
|
||||
FUNCTION(Float32Array, 4)
|
||||
FUNCTION(Float64Array, 8)
|
||||
FUNCTION(Uint8ClampedArray, 1)
|
||||
FUNCTION(BigUint64Array, 8)
|
||||
FUNCTION(BigInt64Array, 8)
|
||||
endmacro
|
||||
|
||||
macro DECLARE_GLOBALS(NAME, SIZE)
|
||||
|
@ -3224,6 +3224,8 @@ VisitorId Map::GetVisitorId(Map* map) {
|
||||
case FIXED_INT32_ARRAY_TYPE:
|
||||
case FIXED_FLOAT32_ARRAY_TYPE:
|
||||
case FIXED_UINT8_CLAMPED_ARRAY_TYPE:
|
||||
case FIXED_BIGUINT64_ARRAY_TYPE:
|
||||
case FIXED_BIGINT64_ARRAY_TYPE:
|
||||
return kVisitFixedTypedArrayBase;
|
||||
|
||||
case FIXED_FLOAT64_ARRAY_TYPE:
|
||||
@ -5115,7 +5117,19 @@ Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) {
|
||||
Handle<Object> to_assign = value;
|
||||
// Convert the incoming value to a number for storing into typed arrays.
|
||||
if (it->IsElement() && receiver->HasFixedTypedArrayElements()) {
|
||||
if (!value->IsNumber() && !value->IsUndefined(it->isolate())) {
|
||||
ElementsKind elements_kind = receiver->GetElementsKind();
|
||||
if (elements_kind == BIGINT64_ELEMENTS ||
|
||||
elements_kind == BIGUINT64_ELEMENTS) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(it->isolate(), to_assign,
|
||||
BigInt::FromObject(it->isolate(), value),
|
||||
Nothing<bool>());
|
||||
// We have to recheck the length. However, it can only change if the
|
||||
// underlying buffer was neutered, so just check that.
|
||||
if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) {
|
||||
return Just(true);
|
||||
// TODO(neis): According to the spec, this should throw a TypeError.
|
||||
}
|
||||
} else if (!value->IsNumber() && !value->IsUndefined(it->isolate())) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
it->isolate(), to_assign, Object::ToNumber(value), Nothing<bool>());
|
||||
// We have to recheck the length. However, it can only change if the
|
||||
@ -19588,7 +19602,7 @@ ElementsKind JSArrayIterator::ElementsKindForInstanceType(InstanceType type) {
|
||||
DCHECK_LE(type, LAST_ARRAY_ITERATOR_TYPE);
|
||||
}
|
||||
|
||||
if (type <= JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE) {
|
||||
if (type <= JS_BIGINT64_ARRAY_VALUE_ITERATOR_TYPE) {
|
||||
kind =
|
||||
static_cast<ElementsKind>(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
|
||||
(type - FIRST_ARRAY_VALUE_ITERATOR_TYPE));
|
||||
|
@ -355,6 +355,8 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(FIXED_FLOAT32_ARRAY_TYPE) \
|
||||
V(FIXED_FLOAT64_ARRAY_TYPE) \
|
||||
V(FIXED_UINT8_CLAMPED_ARRAY_TYPE) \
|
||||
V(FIXED_BIGINT64_ARRAY_TYPE) \
|
||||
V(FIXED_BIGUINT64_ARRAY_TYPE) \
|
||||
\
|
||||
V(FIXED_DOUBLE_ARRAY_TYPE) \
|
||||
V(FILLER_TYPE) \
|
||||
@ -517,6 +519,8 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_BIGUINT64_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_BIGINT64_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
|
||||
\
|
||||
V(JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
|
||||
@ -535,6 +539,8 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_BIGUINT64_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_BIGINT64_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
\
|
||||
V(JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
@ -737,7 +743,9 @@ enum InstanceType : uint16_t {
|
||||
FIXED_UINT32_ARRAY_TYPE,
|
||||
FIXED_FLOAT32_ARRAY_TYPE,
|
||||
FIXED_FLOAT64_ARRAY_TYPE,
|
||||
FIXED_UINT8_CLAMPED_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
|
||||
FIXED_UINT8_CLAMPED_ARRAY_TYPE,
|
||||
FIXED_BIGINT64_ARRAY_TYPE,
|
||||
FIXED_BIGUINT64_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
|
||||
FIXED_DOUBLE_ARRAY_TYPE,
|
||||
FILLER_TYPE, // LAST_DATA_TYPE
|
||||
|
||||
@ -865,7 +873,7 @@ enum InstanceType : uint16_t {
|
||||
LAST_MICROTASK_TYPE = PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE,
|
||||
// Boundaries for testing for a fixed typed array.
|
||||
FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
|
||||
LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
|
||||
LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_BIGUINT64_ARRAY_TYPE,
|
||||
// Boundary for promotion to old space.
|
||||
LAST_DATA_TYPE = FILLER_TYPE,
|
||||
// Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
|
||||
@ -1019,6 +1027,8 @@ template <class C> inline bool Is(Object* obj);
|
||||
V(FixedArray) \
|
||||
V(FixedArrayBase) \
|
||||
V(FixedArrayExact) \
|
||||
V(FixedBigInt64Array) \
|
||||
V(FixedBigUint64Array) \
|
||||
V(FixedDoubleArray) \
|
||||
V(FixedFloat32Array) \
|
||||
V(FixedFloat64Array) \
|
||||
@ -2314,6 +2324,8 @@ class JSObject: public JSReceiver {
|
||||
inline bool HasFixedUint32Elements();
|
||||
inline bool HasFixedFloat32Elements();
|
||||
inline bool HasFixedFloat64Elements();
|
||||
inline bool HasFixedBigInt64Elements();
|
||||
inline bool HasFixedBigUint64Elements();
|
||||
|
||||
inline bool HasFastArgumentsElements();
|
||||
inline bool HasSlowArgumentsElements();
|
||||
|
@ -145,6 +145,10 @@ class MutableBigInt : public FreshlyAllocatedBigInt {
|
||||
static Rounding DecideRounding(Handle<BigIntBase> x, int mantissa_bits_unset,
|
||||
int digit_index, uint64_t current_digit);
|
||||
|
||||
// Returns the least significant 64 bits, simulating two's complement
|
||||
// representation.
|
||||
static uint64_t GetRawBits(BigIntBase* x, bool* lossless);
|
||||
|
||||
// Digit arithmetic helpers.
|
||||
static inline digit_t digit_add(digit_t a, digit_t b, digit_t* carry);
|
||||
static inline digit_t digit_sub(digit_t a, digit_t b, digit_t* borrow);
|
||||
@ -174,6 +178,8 @@ class MutableBigInt : public FreshlyAllocatedBigInt {
|
||||
(*reinterpret_cast<digit_t*>(reinterpret_cast<intptr_t>(address))) = value;
|
||||
}
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
void set_64_bits(uint64_t bits);
|
||||
};
|
||||
|
||||
MaybeHandle<MutableBigInt> MutableBigInt::New(Isolate* isolate, int length) {
|
||||
@ -218,13 +224,7 @@ Handle<BigInt> MutableBigInt::NewFromSafeInteger(Isolate* isolate,
|
||||
Handle<MutableBigInt> result = Cast(isolate->factory()->NewBigInt(length));
|
||||
result->set_length(length);
|
||||
result->set_sign(value < 0); // Treats -0 like 0.
|
||||
if (kDigitBits == 64) {
|
||||
result->set_digit(0, absolute);
|
||||
} else {
|
||||
DCHECK_EQ(kDigitBits, 32);
|
||||
result->set_digit(0, absolute);
|
||||
result->set_digit(1, absolute >> 32);
|
||||
}
|
||||
result->set_64_bits(absolute);
|
||||
return MakeImmutable(result);
|
||||
}
|
||||
|
||||
@ -2079,6 +2079,68 @@ Handle<BigInt> MutableBigInt::TruncateAndSubFromPowerOfTwo(int n,
|
||||
return MakeImmutable(result);
|
||||
}
|
||||
|
||||
Handle<BigInt> BigInt::FromInt64(Isolate* isolate, int64_t n) {
|
||||
if (n == 0) return MutableBigInt::Zero(isolate);
|
||||
STATIC_ASSERT(kDigitBits == 64 || kDigitBits == 32);
|
||||
int length = 64 / kDigitBits;
|
||||
Handle<MutableBigInt> result =
|
||||
MutableBigInt::Cast(isolate->factory()->NewBigInt(length));
|
||||
result->set_length(length);
|
||||
uint64_t absolute;
|
||||
if (n > 0) {
|
||||
result->set_sign(false);
|
||||
absolute = static_cast<uint64_t>(n);
|
||||
} else {
|
||||
result->set_sign(true);
|
||||
if (n == std::numeric_limits<int64_t>::min()) {
|
||||
absolute = static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1;
|
||||
} else {
|
||||
absolute = static_cast<uint64_t>(-n);
|
||||
}
|
||||
}
|
||||
result->set_64_bits(absolute);
|
||||
return MutableBigInt::MakeImmutable(result);
|
||||
}
|
||||
|
||||
Handle<BigInt> BigInt::FromUint64(Isolate* isolate, uint64_t n) {
|
||||
if (n == 0) return MutableBigInt::Zero(isolate);
|
||||
STATIC_ASSERT(kDigitBits == 64 || kDigitBits == 32);
|
||||
int length = 64 / kDigitBits;
|
||||
Handle<MutableBigInt> result =
|
||||
MutableBigInt::Cast(isolate->factory()->NewBigInt(length));
|
||||
result->set_length(length);
|
||||
result->set_sign(false);
|
||||
result->set_64_bits(n);
|
||||
return MutableBigInt::MakeImmutable(result);
|
||||
}
|
||||
|
||||
uint64_t MutableBigInt::GetRawBits(BigIntBase* x, bool* lossless) {
|
||||
if (lossless != nullptr) *lossless = true;
|
||||
if (x->is_zero()) return 0;
|
||||
int len = x->length();
|
||||
STATIC_ASSERT(kDigitBits == 64 || kDigitBits == 32);
|
||||
if (lossless != nullptr && len > 64 / kDigitBits) *lossless = false;
|
||||
uint64_t raw = static_cast<uint64_t>(x->digit(0));
|
||||
if (kDigitBits == 32 && len > 1) {
|
||||
raw |= static_cast<uint64_t>(x->digit(1)) << 32;
|
||||
}
|
||||
// Simulate two's complement.
|
||||
return x->sign() ? -raw : raw;
|
||||
}
|
||||
|
||||
int64_t BigInt::AsInt64(bool* lossless) {
|
||||
uint64_t raw = MutableBigInt::GetRawBits(this, lossless);
|
||||
int64_t result = static_cast<int64_t>(raw);
|
||||
if (lossless != nullptr && (result < 0) != sign()) *lossless = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t BigInt::AsUint64(bool* lossless) {
|
||||
uint64_t result = MutableBigInt::GetRawBits(this, lossless);
|
||||
if (lossless != nullptr && sign()) *lossless = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Digit arithmetic helpers.
|
||||
|
||||
#if V8_TARGET_ARCH_32_BIT
|
||||
@ -2240,20 +2302,30 @@ BigInt::digit_t MutableBigInt::digit_pow(digit_t base, digit_t exponent) {
|
||||
|
||||
#undef HAVE_TWODIGIT_T
|
||||
|
||||
void MutableBigInt::set_64_bits(uint64_t bits) {
|
||||
STATIC_ASSERT(kDigitBits == 64 || kDigitBits == 32);
|
||||
if (kDigitBits == 64) {
|
||||
set_digit(0, static_cast<digit_t>(bits));
|
||||
} else {
|
||||
set_digit(0, static_cast<digit_t>(bits & 0xFFFFFFFFu));
|
||||
set_digit(1, static_cast<digit_t>(bits >> 32));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OBJECT_PRINT
|
||||
void BigInt::BigIntPrint(std::ostream& os) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
HeapObject::PrintHeader(os, "BigInt");
|
||||
int len = length();
|
||||
os << "- length: " << len << "\n";
|
||||
os << "- sign: " << sign() << "\n";
|
||||
os << "\n- length: " << len;
|
||||
os << "\n- sign: " << sign();
|
||||
if (len > 0) {
|
||||
os << "- digits:";
|
||||
os << "\n- digits:";
|
||||
for (int i = 0; i < len; i++) {
|
||||
os << "\n 0x" << std::hex << digit(i);
|
||||
}
|
||||
os << std::dec << "\n";
|
||||
}
|
||||
os << std::dec << "\n";
|
||||
}
|
||||
#endif // OBJECT_PRINT
|
||||
|
||||
|
@ -137,6 +137,11 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase {
|
||||
static Handle<BigInt> AsIntN(uint64_t n, Handle<BigInt> x);
|
||||
static MaybeHandle<BigInt> AsUintN(uint64_t n, Handle<BigInt> x);
|
||||
|
||||
static Handle<BigInt> FromInt64(Isolate* isolate, int64_t n);
|
||||
static Handle<BigInt> FromUint64(Isolate* isolate, uint64_t n);
|
||||
int64_t AsInt64(bool* lossless = nullptr);
|
||||
uint64_t AsUint64(bool* lossless = nullptr);
|
||||
|
||||
DECL_CAST(BigInt)
|
||||
DECL_VERIFIER(BigInt)
|
||||
DECL_PRINTER(BigInt)
|
||||
|
@ -496,6 +496,16 @@ inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(int value) {
|
||||
return static_cast<uint8_t>(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(int value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(int value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
typename Traits::ElementType FixedTypedArray<Traits>::from(uint32_t value) {
|
||||
return static_cast<ElementType>(value);
|
||||
@ -509,6 +519,16 @@ inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(uint32_t value) {
|
||||
return static_cast<uint8_t>(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(uint32_t value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(uint32_t value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
typename Traits::ElementType FixedTypedArray<Traits>::from(double value) {
|
||||
return static_cast<ElementType>(DoubleToInt32(value));
|
||||
@ -522,6 +542,16 @@ inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(double value) {
|
||||
return static_cast<uint8_t>(lrint(value));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(double value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(double value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float FixedTypedArray<Float32ArrayTraits>::from(double value) {
|
||||
return static_cast<float>(value);
|
||||
@ -532,6 +562,60 @@ inline double FixedTypedArray<Float64ArrayTraits>::from(double value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
typename Traits::ElementType FixedTypedArray<Traits>::from(int64_t value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
typename Traits::ElementType FixedTypedArray<Traits>::from(uint64_t value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(int64_t value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(uint64_t value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(int64_t value) {
|
||||
return static_cast<uint64_t>(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(uint64_t value) {
|
||||
return static_cast<int64_t>(value);
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
typename Traits::ElementType FixedTypedArray<Traits>::FromHandle(
|
||||
Handle<Object> value, bool* lossless) {
|
||||
if (value->IsSmi()) {
|
||||
return from(Smi::ToInt(*value));
|
||||
}
|
||||
DCHECK(value->IsHeapNumber());
|
||||
return from(HeapNumber::cast(*value)->value());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t FixedTypedArray<BigInt64ArrayTraits>::FromHandle(
|
||||
Handle<Object> value, bool* lossless) {
|
||||
DCHECK(value->IsBigInt());
|
||||
return BigInt::cast(*value)->AsInt64(lossless);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::FromHandle(
|
||||
Handle<Object> value, bool* lossless) {
|
||||
DCHECK(value->IsBigInt());
|
||||
return BigInt::cast(*value)->AsUint64(lossless);
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
Handle<Object> FixedTypedArray<Traits>::get(FixedTypedArray<Traits>* array,
|
||||
int index) {
|
||||
@ -555,6 +639,20 @@ void FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) {
|
||||
set(index, cast_value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void FixedTypedArray<BigInt64ArrayTraits>::SetValue(uint32_t index,
|
||||
Object* value) {
|
||||
DCHECK(value->IsBigInt());
|
||||
set(index, BigInt::cast(value)->AsInt64());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void FixedTypedArray<BigUint64ArrayTraits>::SetValue(uint32_t index,
|
||||
Object* value) {
|
||||
DCHECK(value->IsBigInt());
|
||||
set(index, BigInt::cast(value)->AsUint64());
|
||||
}
|
||||
|
||||
Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) {
|
||||
return handle(Smi::FromInt(scalar), isolate);
|
||||
}
|
||||
@ -592,6 +690,15 @@ Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
|
||||
return isolate->factory()->NewNumber(scalar);
|
||||
}
|
||||
|
||||
Handle<Object> BigInt64ArrayTraits::ToHandle(Isolate* isolate, int64_t scalar) {
|
||||
return BigInt::FromInt64(isolate, scalar);
|
||||
}
|
||||
|
||||
Handle<Object> BigUint64ArrayTraits::ToHandle(Isolate* isolate,
|
||||
uint64_t scalar) {
|
||||
return BigInt::FromUint64(isolate, scalar);
|
||||
}
|
||||
|
||||
// static
|
||||
template <class Traits>
|
||||
STATIC_CONST_MEMBER_DEFINITION const InstanceType
|
||||
|
@ -467,16 +467,18 @@ class PodArray : public ByteArray {
|
||||
};
|
||||
|
||||
// V has parameters (Type, type, TYPE, C type, element_size)
|
||||
#define TYPED_ARRAYS(V) \
|
||||
V(Uint8, uint8, UINT8, uint8_t, 1) \
|
||||
V(Int8, int8, INT8, int8_t, 1) \
|
||||
V(Uint16, uint16, UINT16, uint16_t, 2) \
|
||||
V(Int16, int16, INT16, int16_t, 2) \
|
||||
V(Uint32, uint32, UINT32, uint32_t, 4) \
|
||||
V(Int32, int32, INT32, int32_t, 4) \
|
||||
V(Float32, float32, FLOAT32, float, 4) \
|
||||
V(Float64, float64, FLOAT64, double, 8) \
|
||||
V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
|
||||
#define TYPED_ARRAYS(V) \
|
||||
V(Uint8, uint8, UINT8, uint8_t, 1) \
|
||||
V(Int8, int8, INT8, int8_t, 1) \
|
||||
V(Uint16, uint16, UINT16, uint16_t, 2) \
|
||||
V(Int16, int16, INT16, int16_t, 2) \
|
||||
V(Uint32, uint32, UINT32, uint32_t, 4) \
|
||||
V(Int32, int32, INT32, int32_t, 4) \
|
||||
V(Float32, float32, FLOAT32, float, 4) \
|
||||
V(Float64, float64, FLOAT64, double, 8) \
|
||||
V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1) \
|
||||
V(BigUint64, biguint64, BIGUINT64, uint64_t, 8) \
|
||||
V(BigInt64, bigint64, BIGINT64, int64_t, 8)
|
||||
|
||||
class FixedTypedArrayBase : public FixedArrayBase {
|
||||
public:
|
||||
@ -549,6 +551,11 @@ class FixedTypedArray : public FixedTypedArrayBase {
|
||||
static inline ElementType from(int value);
|
||||
static inline ElementType from(uint32_t value);
|
||||
static inline ElementType from(double value);
|
||||
static inline ElementType from(int64_t value);
|
||||
static inline ElementType from(uint64_t value);
|
||||
|
||||
static inline ElementType FromHandle(Handle<Object> value,
|
||||
bool* lossless = nullptr);
|
||||
|
||||
// This accessor applies the correct conversion from Smi, HeapNumber
|
||||
// and undefined.
|
||||
|
@ -75,6 +75,13 @@ RUNTIME_FUNCTION(Runtime_BigIntToNumber) {
|
||||
return *BigInt::ToNumber(x);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ToBigInt) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
|
||||
RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromObject(isolate, x));
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(3, args.length());
|
||||
|
@ -204,6 +204,14 @@ RUNTIME_FUNCTION(Runtime_TypedArraySlice) {
|
||||
DCHECK(!result->WasNeutered());
|
||||
DCHECK_LE(start->value(), end->value());
|
||||
|
||||
ElementsKind source_kind = source->GetElementsKind();
|
||||
ElementsKind result_kind = result->GetElementsKind();
|
||||
if ((source_kind == BIGINT64_ELEMENTS || source_kind == BIGUINT64_ELEMENTS) !=
|
||||
(result_kind == BIGINT64_ELEMENTS || result_kind == BIGUINT64_ELEMENTS)) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes));
|
||||
}
|
||||
|
||||
ElementsAccessor* accessor = source->GetElementsAccessor();
|
||||
return *accessor->Slice(source, start->value(), end->value(), result);
|
||||
}
|
||||
|
@ -75,7 +75,8 @@ namespace internal {
|
||||
F(BigIntEqualToString, 2, 1) \
|
||||
F(BigIntToBoolean, 1, 1) \
|
||||
F(BigIntToNumber, 1, 1) \
|
||||
F(BigIntUnaryOp, 2, 1)
|
||||
F(BigIntUnaryOp, 2, 1) \
|
||||
F(ToBigInt, 1, 1)
|
||||
|
||||
#define FOR_EACH_INTRINSIC_CLASSES(F) \
|
||||
F(ThrowUnsupportedSuperError, 0, 1) \
|
||||
@ -574,6 +575,8 @@ namespace internal {
|
||||
F(HasDoubleElements, 1, 1) \
|
||||
F(HasFastElements, 1, 1) \
|
||||
F(HasFastProperties, 1, 1) \
|
||||
F(HasFixedBigInt64Elements, 1, 1) \
|
||||
F(HasFixedBigUint64Elements, 1, 1) \
|
||||
F(HasFixedFloat32Elements, 1, 1) \
|
||||
F(HasFixedFloat64Elements, 1, 1) \
|
||||
F(HasFixedInt16Elements, 1, 1) \
|
||||
|
@ -161,6 +161,8 @@ enum class ArrayBufferViewTag : uint8_t {
|
||||
kUint32Array = 'D',
|
||||
kFloat32Array = 'f',
|
||||
kFloat64Array = 'F',
|
||||
kBigInt64Array = 'q',
|
||||
kBigUint64Array = 'Q',
|
||||
kDataView = '?',
|
||||
};
|
||||
|
||||
@ -1644,6 +1646,16 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
|
||||
uint32_t id = next_id_++;
|
||||
ExternalArrayType external_array_type = kExternalInt8Array;
|
||||
unsigned element_size = 0;
|
||||
|
||||
if (!FLAG_harmony_bigint) {
|
||||
// Refuse to construct BigInt64Arrays unless the flag is on.
|
||||
ArrayBufferViewTag cast_tag = static_cast<ArrayBufferViewTag>(tag);
|
||||
if (cast_tag == ArrayBufferViewTag::kBigInt64Array ||
|
||||
cast_tag == ArrayBufferViewTag::kBigUint64Array) {
|
||||
return MaybeHandle<JSArrayBufferView>();
|
||||
}
|
||||
}
|
||||
|
||||
switch (static_cast<ArrayBufferViewTag>(tag)) {
|
||||
case ArrayBufferViewTag::kDataView: {
|
||||
Handle<JSDataView> data_view =
|
||||
|
@ -1142,6 +1142,8 @@ TEST(SubclassArrayBuiltinNoInlineNew) {
|
||||
TEST(SubclassTypedArrayBuiltin) {
|
||||
// Avoid eventual completion of in-object slack tracking.
|
||||
FLAG_always_opt = false;
|
||||
// Make BigInt64Array/BigUint64Array available for testing.
|
||||
FLAG_harmony_bigint = true;
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
|
||||
|
@ -87,6 +87,8 @@ TEST(AllocateNotExternal) {
|
||||
|
||||
void TestSpeciesProtector(char* code,
|
||||
bool invalidates_species_protector = true) {
|
||||
// Make BigInt64Array/BigUint64Array available for testing.
|
||||
FLAG_harmony_bigint = true;
|
||||
v8::Isolate::CreateParams create_params;
|
||||
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
||||
std::string typed_array_constructors[] = {
|
||||
|
238
test/mjsunit/harmony/bigint/typedarray.js
Normal file
238
test/mjsunit/harmony/bigint/typedarray.js
Normal file
@ -0,0 +1,238 @@
|
||||
// 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.
|
||||
|
||||
// Flags: --harmony-bigint --allow-natives-syntax
|
||||
|
||||
var intarray = new BigInt64Array(8);
|
||||
var uintarray = new BigUint64Array(8);
|
||||
|
||||
function test(f) {
|
||||
f();
|
||||
f(); // Make sure we test ICs.
|
||||
f();
|
||||
%OptimizeFunctionOnNextCall(f);
|
||||
f();
|
||||
}
|
||||
|
||||
function test_both(f) {
|
||||
test(() => f(BigInt64Array));
|
||||
test(() => f(BigUint64Array));
|
||||
}
|
||||
|
||||
test(function basic_assignment() {
|
||||
const x = 0x1234567890abcdefn;
|
||||
intarray[0] = x;
|
||||
assertEquals(x, intarray[0]);
|
||||
uintarray[0] = x;
|
||||
assertEquals(x, uintarray[0]);
|
||||
const y = -0x76543210fedcba98n;
|
||||
intarray[0] = y;
|
||||
assertEquals(y, intarray[0]);
|
||||
});
|
||||
|
||||
test(function construct() {
|
||||
var a = new BigInt64Array([1n, -2n, {valueOf: () => 3n}]);
|
||||
assertArrayEquals([1n, -2n, 3n], a);
|
||||
assertThrows(() => new BigInt64Array([4, 5]), TypeError);
|
||||
var b = new BigUint64Array([6n, -7n]);
|
||||
assertArrayEquals([6n, 0xfffffffffffffff9n], b);
|
||||
var c = new BigUint64Array(new BigInt64Array([8n, -9n]));
|
||||
assertArrayEquals([8n, 0xfffffffffffffff7n], c);
|
||||
var d = new BigInt64Array(new BigUint64Array([10n, 0xfffffffffffffff5n]));
|
||||
assertArrayEquals([10n, -11n], d);
|
||||
assertThrows(() => new BigInt64Array(new Int32Array([12, 13])), TypeError);
|
||||
assertThrows(() => new Int32Array(new BigInt64Array([14n, -15n])), TypeError);
|
||||
});
|
||||
|
||||
test_both(function copyWithin(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
a.copyWithin(0, 1, 3);
|
||||
assertArrayEquals([2n, 3n, 3n], a);
|
||||
});
|
||||
|
||||
test_both(function entries(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
var it = a.entries();
|
||||
assertEquals([0, 1n], it.next().value);
|
||||
assertEquals([1, 2n], it.next().value);
|
||||
assertEquals([2, 3n], it.next().value);
|
||||
assertTrue(it.next().done);
|
||||
});
|
||||
|
||||
test_both(function every(BigArray) {
|
||||
var a = BigArray.of(2n, 3n, 4n);
|
||||
var seen = [];
|
||||
assertTrue(a.every((x) => {seen.push(x); return x > 1n}));
|
||||
assertEquals([2n, 3n, 4n], seen);
|
||||
});
|
||||
|
||||
test_both(function fill(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n, 4n);
|
||||
a.fill(7n, 1, 3);
|
||||
assertArrayEquals([1n, 7n, 7n, 4n], a);
|
||||
assertThrows(() => (new BigArray(3).fill(1)), TypeError);
|
||||
});
|
||||
|
||||
test_both(function filter(BigArray) {
|
||||
var a = BigArray.of(1n, 3n, 4n, 2n);
|
||||
var b = a.filter((x) => x > 2n);
|
||||
assertArrayEquals([3n, 4n], b);
|
||||
});
|
||||
|
||||
test_both(function find(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
assertEquals(2n, a.find((x) => x === 2n));
|
||||
assertEquals(undefined, a.find((x) => x === 2));
|
||||
});
|
||||
|
||||
test_both(function findIndex(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
assertEquals(1, a.findIndex((x) => x === 2n));
|
||||
assertEquals(-1, a.findIndex((x) => x === 2));
|
||||
});
|
||||
|
||||
test_both(function forEach(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
var seen = [];
|
||||
a.forEach((x) => seen.push(x));
|
||||
assertEquals([1n, 2n, 3n], seen);
|
||||
});
|
||||
|
||||
test_both(function from(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
var b = BigArray.from(a);
|
||||
assertArrayEquals([1n, 2n, 3n], b);
|
||||
assertThrows(() => BigArray.from([4, 5]), TypeError);
|
||||
var c = BigArray.from([6, 7], BigInt);
|
||||
assertArrayEquals([6n, 7n], c);
|
||||
});
|
||||
|
||||
test(function from_mixed() {
|
||||
var contents = [1n, 2n, 3n];
|
||||
var a = new BigInt64Array(contents);
|
||||
var b = BigUint64Array.from(a);
|
||||
assertArrayEquals(contents, b);
|
||||
var c = BigInt64Array.from(b);
|
||||
assertArrayEquals(contents, c);
|
||||
});
|
||||
|
||||
test_both(function includes(BigArray) {
|
||||
var a = BigArray.of(0n, 1n, 2n);
|
||||
assertTrue(a.includes(1n));
|
||||
assertFalse(a.includes(undefined));
|
||||
assertFalse(a.includes(1));
|
||||
assertFalse(a.includes(0x1234567890abcdef123n)); // More than 64 bits.
|
||||
});
|
||||
|
||||
test_both(function indexOf(BigArray) {
|
||||
var a = BigArray.of(0n, 1n, 2n);
|
||||
assertEquals(1, a.indexOf(1n));
|
||||
assertEquals(-1, a.indexOf(undefined));
|
||||
assertEquals(-1, a.indexOf(1));
|
||||
assertEquals(-1, a.indexOf(0x1234567890abcdef123n)); // More than 64 bits.
|
||||
});
|
||||
|
||||
test_both(function join(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
assertEquals("1-2-3", a.join("-"));
|
||||
});
|
||||
|
||||
test_both(function keys(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
var it = a.keys();
|
||||
assertEquals(0, it.next().value);
|
||||
assertEquals(1, it.next().value);
|
||||
assertEquals(2, it.next().value);
|
||||
assertTrue(it.next().done);
|
||||
});
|
||||
|
||||
test_both(function lastIndexOf(BigArray) {
|
||||
var a = BigArray.of(0n, 1n, 2n);
|
||||
assertEquals(1, a.lastIndexOf(1n));
|
||||
assertEquals(-1, a.lastIndexOf(undefined));
|
||||
assertEquals(-1, a.lastIndexOf(1));
|
||||
assertEquals(-1, a.lastIndexOf(0x1234567890abcdef123n)); // > 64 bits.
|
||||
});
|
||||
|
||||
test_both(function map(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
var b = a.map((x) => 2n * x);
|
||||
assertEquals(BigArray, b.constructor);
|
||||
assertArrayEquals([2n, 4n, 6n], b);
|
||||
});
|
||||
|
||||
test_both(function of(BigArray) {
|
||||
var a = BigArray.of(true, 2n, {valueOf: () => 3n}, "4");
|
||||
assertArrayEquals([1n, 2n, 3n, 4n], a);
|
||||
assertThrows(() => BigArray.of(1), TypeError)
|
||||
assertThrows(() => BigArray.of(undefined), TypeError)
|
||||
});
|
||||
|
||||
test_both(function reduce(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
assertEquals(6n, a.reduce((sum, x) => sum + x, 0n));
|
||||
});
|
||||
|
||||
test_both(function reduceRight(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
assertEquals(6n, a.reduce((sum, x) => sum + x, 0n));
|
||||
});
|
||||
|
||||
test_both(function reverse(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
a.reverse();
|
||||
assertArrayEquals([3n, 2n, 1n], a);
|
||||
});
|
||||
|
||||
test_both(function set(BigArray) {
|
||||
var a = new BigArray(7);
|
||||
a.set(BigArray.of(1n, 2n, 3n), 2);
|
||||
assertArrayEquals([0n, 0n, 1n, 2n, 3n, 0n, 0n], a);
|
||||
a.set([4n, 5n, 6n], 1);
|
||||
assertArrayEquals([0n, 4n, 5n, 6n, 3n, 0n, 0n], a);
|
||||
assertThrows(() => a.set([7, 8, 9], 3), TypeError);
|
||||
assertThrows(() => a.set(Int32Array.of(10, 11), 2), TypeError);
|
||||
|
||||
var Other = BigArray == BigInt64Array ? BigUint64Array : BigInt64Array;
|
||||
a.set(Other.of(12n, 13n), 4);
|
||||
assertArrayEquals([0n, 4n, 5n, 6n, 12n, 13n, 0n], a);
|
||||
});
|
||||
|
||||
test_both(function slice(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n, 4n);
|
||||
var b = a.slice(1, 3);
|
||||
assertArrayEquals([2n, 3n], b);
|
||||
});
|
||||
|
||||
test_both(function some(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
assertTrue(a.some((x) => x === 2n));
|
||||
});
|
||||
|
||||
test_both(function sort(BigArray) {
|
||||
var a = BigArray.of(7n, 2n, 5n, 3n);
|
||||
a.sort();
|
||||
assertArrayEquals([2n, 3n, 5n, 7n], a);
|
||||
});
|
||||
|
||||
test_both(function subarray(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n, 4n);
|
||||
var b = a.subarray(1, 3);
|
||||
assertEquals(BigArray, b.constructor);
|
||||
assertArrayEquals([2n, 3n], b);
|
||||
});
|
||||
|
||||
test_both(function toString(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
assertEquals("1,2,3", a.toString());
|
||||
});
|
||||
|
||||
test_both(function values(BigArray) {
|
||||
var a = BigArray.of(1n, 2n, 3n);
|
||||
var it = a.values();
|
||||
assertEquals(1n, it.next().value);
|
||||
assertEquals(2n, it.next().value);
|
||||
assertEquals(3n, it.next().value);
|
||||
assertTrue(it.next().done);
|
||||
});
|
@ -32,6 +32,8 @@ TestWithIsolate::~TestWithIsolate() {}
|
||||
void TestWithIsolate::SetUpTestCase() {
|
||||
Test::SetUpTestCase();
|
||||
EXPECT_EQ(NULL, isolate_);
|
||||
// Make BigInt64Array / BigUint64Array available for testing.
|
||||
i::FLAG_harmony_bigint = true;
|
||||
v8::Isolate::CreateParams create_params;
|
||||
array_buffer_allocator_ = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
create_params.array_buffer_allocator = array_buffer_allocator_;
|
||||
|
@ -49,50 +49,52 @@ INSTANCE_TYPES = {
|
||||
145: "FIXED_FLOAT32_ARRAY_TYPE",
|
||||
146: "FIXED_FLOAT64_ARRAY_TYPE",
|
||||
147: "FIXED_UINT8_CLAMPED_ARRAY_TYPE",
|
||||
148: "FIXED_DOUBLE_ARRAY_TYPE",
|
||||
149: "FILLER_TYPE",
|
||||
150: "ACCESS_CHECK_INFO_TYPE",
|
||||
151: "ACCESSOR_INFO_TYPE",
|
||||
152: "ACCESSOR_PAIR_TYPE",
|
||||
153: "ALIASED_ARGUMENTS_ENTRY_TYPE",
|
||||
154: "ALLOCATION_MEMENTO_TYPE",
|
||||
155: "ALLOCATION_SITE_TYPE",
|
||||
156: "ASYNC_GENERATOR_REQUEST_TYPE",
|
||||
157: "CONTEXT_EXTENSION_TYPE",
|
||||
158: "DEBUG_INFO_TYPE",
|
||||
159: "FUNCTION_TEMPLATE_INFO_TYPE",
|
||||
160: "INTERCEPTOR_INFO_TYPE",
|
||||
161: "MODULE_INFO_ENTRY_TYPE",
|
||||
162: "MODULE_TYPE",
|
||||
163: "OBJECT_TEMPLATE_INFO_TYPE",
|
||||
164: "PROMISE_CAPABILITY_TYPE",
|
||||
165: "PROMISE_REACTION_TYPE",
|
||||
166: "PROTOTYPE_INFO_TYPE",
|
||||
167: "SCRIPT_TYPE",
|
||||
168: "STACK_FRAME_INFO_TYPE",
|
||||
169: "TUPLE2_TYPE",
|
||||
170: "TUPLE3_TYPE",
|
||||
171: "CALLABLE_TASK_TYPE",
|
||||
172: "CALLBACK_TASK_TYPE",
|
||||
173: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE",
|
||||
174: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE",
|
||||
175: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE",
|
||||
176: "FIXED_ARRAY_TYPE",
|
||||
177: "DESCRIPTOR_ARRAY_TYPE",
|
||||
178: "HASH_TABLE_TYPE",
|
||||
179: "SCOPE_INFO_TYPE",
|
||||
180: "TRANSITION_ARRAY_TYPE",
|
||||
181: "CELL_TYPE",
|
||||
182: "CODE_DATA_CONTAINER_TYPE",
|
||||
183: "FEEDBACK_VECTOR_TYPE",
|
||||
184: "LOAD_HANDLER_TYPE",
|
||||
185: "PROPERTY_ARRAY_TYPE",
|
||||
186: "PROPERTY_CELL_TYPE",
|
||||
187: "SHARED_FUNCTION_INFO_TYPE",
|
||||
188: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
189: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
190: "STORE_HANDLER_TYPE",
|
||||
191: "WEAK_CELL_TYPE",
|
||||
148: "FIXED_BIGINT64_ARRAY_TYPE",
|
||||
149: "FIXED_BIGUINT64_ARRAY_TYPE",
|
||||
150: "FIXED_DOUBLE_ARRAY_TYPE",
|
||||
151: "FILLER_TYPE",
|
||||
152: "ACCESS_CHECK_INFO_TYPE",
|
||||
153: "ACCESSOR_INFO_TYPE",
|
||||
154: "ACCESSOR_PAIR_TYPE",
|
||||
155: "ALIASED_ARGUMENTS_ENTRY_TYPE",
|
||||
156: "ALLOCATION_MEMENTO_TYPE",
|
||||
157: "ALLOCATION_SITE_TYPE",
|
||||
158: "ASYNC_GENERATOR_REQUEST_TYPE",
|
||||
159: "CONTEXT_EXTENSION_TYPE",
|
||||
160: "DEBUG_INFO_TYPE",
|
||||
161: "FUNCTION_TEMPLATE_INFO_TYPE",
|
||||
162: "INTERCEPTOR_INFO_TYPE",
|
||||
163: "MODULE_INFO_ENTRY_TYPE",
|
||||
164: "MODULE_TYPE",
|
||||
165: "OBJECT_TEMPLATE_INFO_TYPE",
|
||||
166: "PROMISE_CAPABILITY_TYPE",
|
||||
167: "PROMISE_REACTION_TYPE",
|
||||
168: "PROTOTYPE_INFO_TYPE",
|
||||
169: "SCRIPT_TYPE",
|
||||
170: "STACK_FRAME_INFO_TYPE",
|
||||
171: "TUPLE2_TYPE",
|
||||
172: "TUPLE3_TYPE",
|
||||
173: "CALLABLE_TASK_TYPE",
|
||||
174: "CALLBACK_TASK_TYPE",
|
||||
175: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE",
|
||||
176: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE",
|
||||
177: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE",
|
||||
178: "FIXED_ARRAY_TYPE",
|
||||
179: "DESCRIPTOR_ARRAY_TYPE",
|
||||
180: "HASH_TABLE_TYPE",
|
||||
181: "SCOPE_INFO_TYPE",
|
||||
182: "TRANSITION_ARRAY_TYPE",
|
||||
183: "CELL_TYPE",
|
||||
184: "CODE_DATA_CONTAINER_TYPE",
|
||||
185: "FEEDBACK_VECTOR_TYPE",
|
||||
186: "LOAD_HANDLER_TYPE",
|
||||
187: "PROPERTY_ARRAY_TYPE",
|
||||
188: "PROPERTY_CELL_TYPE",
|
||||
189: "SHARED_FUNCTION_INFO_TYPE",
|
||||
190: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
191: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
192: "STORE_HANDLER_TYPE",
|
||||
193: "WEAK_CELL_TYPE",
|
||||
1024: "JS_PROXY_TYPE",
|
||||
1025: "JS_GLOBAL_OBJECT_TYPE",
|
||||
1026: "JS_GLOBAL_PROXY_TYPE",
|
||||
@ -137,35 +139,39 @@ INSTANCE_TYPES = {
|
||||
1091: "JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1092: "JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1093: "JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1094: "JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1095: "JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1096: "JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1097: "JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1098: "JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1099: "JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1100: "JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1101: "JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1102: "JS_INT8_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1103: "JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1104: "JS_INT16_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1105: "JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1106: "JS_INT32_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1107: "JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1108: "JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1109: "JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1110: "JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1111: "JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1112: "JS_FAST_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1113: "JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1114: "JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1115: "JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1116: "JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1117: "WASM_INSTANCE_TYPE",
|
||||
1118: "WASM_MEMORY_TYPE",
|
||||
1119: "WASM_MODULE_TYPE",
|
||||
1120: "WASM_TABLE_TYPE",
|
||||
1121: "JS_BOUND_FUNCTION_TYPE",
|
||||
1122: "JS_FUNCTION_TYPE",
|
||||
1094: "JS_BIGUINT64_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1095: "JS_BIGINT64_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1096: "JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1097: "JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1098: "JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1099: "JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1100: "JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1101: "JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1102: "JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE",
|
||||
1103: "JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1104: "JS_INT8_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1105: "JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1106: "JS_INT16_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1107: "JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1108: "JS_INT32_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1109: "JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1110: "JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1111: "JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1112: "JS_BIGUINT64_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1113: "JS_BIGINT64_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1114: "JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1115: "JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1116: "JS_FAST_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1117: "JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1118: "JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1119: "JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1120: "JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
1121: "WASM_INSTANCE_TYPE",
|
||||
1122: "WASM_MEMORY_TYPE",
|
||||
1123: "WASM_MODULE_TYPE",
|
||||
1124: "WASM_TABLE_TYPE",
|
||||
1125: "JS_BOUND_FUNCTION_TYPE",
|
||||
1126: "JS_FUNCTION_TYPE",
|
||||
}
|
||||
|
||||
# List of known V8 maps.
|
||||
@ -173,10 +179,10 @@ KNOWN_MAPS = {
|
||||
0x02201: (138, "FreeSpaceMap"),
|
||||
0x02251: (132, "MetaMap"),
|
||||
0x022a1: (131, "NullMap"),
|
||||
0x022f1: (177, "DescriptorArrayMap"),
|
||||
0x02341: (176, "FixedArrayMap"),
|
||||
0x02391: (149, "OnePointerFillerMap"),
|
||||
0x023e1: (149, "TwoPointerFillerMap"),
|
||||
0x022f1: (179, "DescriptorArrayMap"),
|
||||
0x02341: (178, "FixedArrayMap"),
|
||||
0x02391: (151, "OnePointerFillerMap"),
|
||||
0x023e1: (151, "TwoPointerFillerMap"),
|
||||
0x02431: (131, "UninitializedMap"),
|
||||
0x02481: (8, "OneByteInternalizedStringMap"),
|
||||
0x024d1: (131, "UndefinedMap"),
|
||||
@ -184,57 +190,57 @@ KNOWN_MAPS = {
|
||||
0x02571: (131, "TheHoleMap"),
|
||||
0x025c1: (131, "BooleanMap"),
|
||||
0x02611: (136, "ByteArrayMap"),
|
||||
0x02661: (176, "FixedCOWArrayMap"),
|
||||
0x026b1: (178, "HashTableMap"),
|
||||
0x02661: (178, "FixedCOWArrayMap"),
|
||||
0x026b1: (180, "HashTableMap"),
|
||||
0x02701: (128, "SymbolMap"),
|
||||
0x02751: (72, "OneByteStringMap"),
|
||||
0x027a1: (179, "ScopeInfoMap"),
|
||||
0x027f1: (187, "SharedFunctionInfoMap"),
|
||||
0x027a1: (181, "ScopeInfoMap"),
|
||||
0x027f1: (189, "SharedFunctionInfoMap"),
|
||||
0x02841: (133, "CodeMap"),
|
||||
0x02891: (176, "FunctionContextMap"),
|
||||
0x028e1: (181, "CellMap"),
|
||||
0x02931: (191, "WeakCellMap"),
|
||||
0x02981: (186, "GlobalPropertyCellMap"),
|
||||
0x02891: (178, "FunctionContextMap"),
|
||||
0x028e1: (183, "CellMap"),
|
||||
0x02931: (193, "WeakCellMap"),
|
||||
0x02981: (188, "GlobalPropertyCellMap"),
|
||||
0x029d1: (135, "ForeignMap"),
|
||||
0x02a21: (180, "TransitionArrayMap"),
|
||||
0x02a71: (183, "FeedbackVectorMap"),
|
||||
0x02a21: (182, "TransitionArrayMap"),
|
||||
0x02a71: (185, "FeedbackVectorMap"),
|
||||
0x02ac1: (131, "ArgumentsMarkerMap"),
|
||||
0x02b11: (131, "ExceptionMap"),
|
||||
0x02b61: (131, "TerminationExceptionMap"),
|
||||
0x02bb1: (131, "OptimizedOutMap"),
|
||||
0x02c01: (131, "StaleRegisterMap"),
|
||||
0x02c51: (176, "NativeContextMap"),
|
||||
0x02ca1: (176, "ModuleContextMap"),
|
||||
0x02cf1: (176, "EvalContextMap"),
|
||||
0x02d41: (176, "ScriptContextMap"),
|
||||
0x02d91: (176, "BlockContextMap"),
|
||||
0x02de1: (176, "CatchContextMap"),
|
||||
0x02e31: (176, "WithContextMap"),
|
||||
0x02e81: (176, "DebugEvaluateContextMap"),
|
||||
0x02ed1: (176, "ScriptContextTableMap"),
|
||||
0x02f21: (176, "ArrayListMap"),
|
||||
0x02f71: (148, "FixedDoubleArrayMap"),
|
||||
0x02c51: (178, "NativeContextMap"),
|
||||
0x02ca1: (178, "ModuleContextMap"),
|
||||
0x02cf1: (178, "EvalContextMap"),
|
||||
0x02d41: (178, "ScriptContextMap"),
|
||||
0x02d91: (178, "BlockContextMap"),
|
||||
0x02de1: (178, "CatchContextMap"),
|
||||
0x02e31: (178, "WithContextMap"),
|
||||
0x02e81: (178, "DebugEvaluateContextMap"),
|
||||
0x02ed1: (178, "ScriptContextTableMap"),
|
||||
0x02f21: (178, "ArrayListMap"),
|
||||
0x02f71: (150, "FixedDoubleArrayMap"),
|
||||
0x02fc1: (134, "MutableHeapNumberMap"),
|
||||
0x03011: (178, "OrderedHashMapMap"),
|
||||
0x03061: (178, "OrderedHashSetMap"),
|
||||
0x030b1: (178, "NameDictionaryMap"),
|
||||
0x03101: (178, "GlobalDictionaryMap"),
|
||||
0x03151: (178, "NumberDictionaryMap"),
|
||||
0x031a1: (178, "SimpleNumberDictionaryMap"),
|
||||
0x031f1: (178, "StringTableMap"),
|
||||
0x03241: (178, "WeakHashTableMap"),
|
||||
0x03291: (176, "SloppyArgumentsElementsMap"),
|
||||
0x032e1: (188, "SmallOrderedHashMapMap"),
|
||||
0x03331: (189, "SmallOrderedHashSetMap"),
|
||||
0x03381: (182, "CodeDataContainerMap"),
|
||||
0x03011: (180, "OrderedHashMapMap"),
|
||||
0x03061: (180, "OrderedHashSetMap"),
|
||||
0x030b1: (180, "NameDictionaryMap"),
|
||||
0x03101: (180, "GlobalDictionaryMap"),
|
||||
0x03151: (180, "NumberDictionaryMap"),
|
||||
0x031a1: (180, "SimpleNumberDictionaryMap"),
|
||||
0x031f1: (180, "StringTableMap"),
|
||||
0x03241: (180, "WeakHashTableMap"),
|
||||
0x03291: (178, "SloppyArgumentsElementsMap"),
|
||||
0x032e1: (190, "SmallOrderedHashMapMap"),
|
||||
0x03331: (191, "SmallOrderedHashSetMap"),
|
||||
0x03381: (184, "CodeDataContainerMap"),
|
||||
0x033d1: (1071, "JSMessageObjectMap"),
|
||||
0x03421: (1057, "ExternalMap"),
|
||||
0x03471: (137, "BytecodeArrayMap"),
|
||||
0x034c1: (176, "ModuleInfoMap"),
|
||||
0x03511: (181, "NoClosuresCellMap"),
|
||||
0x03561: (181, "OneClosureCellMap"),
|
||||
0x035b1: (181, "ManyClosuresCellMap"),
|
||||
0x03601: (185, "PropertyArrayMap"),
|
||||
0x034c1: (178, "ModuleInfoMap"),
|
||||
0x03511: (183, "NoClosuresCellMap"),
|
||||
0x03561: (183, "OneClosureCellMap"),
|
||||
0x035b1: (183, "ManyClosuresCellMap"),
|
||||
0x03601: (187, "PropertyArrayMap"),
|
||||
0x03651: (130, "BigIntMap"),
|
||||
0x036a1: (106, "NativeSourceStringMap"),
|
||||
0x036f1: (64, "StringMap"),
|
||||
@ -266,32 +272,34 @@ KNOWN_MAPS = {
|
||||
0x03f11: (145, "FixedFloat32ArrayMap"),
|
||||
0x03f61: (146, "FixedFloat64ArrayMap"),
|
||||
0x03fb1: (147, "FixedUint8ClampedArrayMap"),
|
||||
0x04001: (169, "Tuple2Map"),
|
||||
0x04051: (167, "ScriptMap"),
|
||||
0x040a1: (160, "InterceptorInfoMap"),
|
||||
0x040f1: (151, "AccessorInfoMap"),
|
||||
0x04141: (150, "AccessCheckInfoMap"),
|
||||
0x04191: (152, "AccessorPairMap"),
|
||||
0x041e1: (153, "AliasedArgumentsEntryMap"),
|
||||
0x04231: (154, "AllocationMementoMap"),
|
||||
0x04281: (155, "AllocationSiteMap"),
|
||||
0x042d1: (156, "AsyncGeneratorRequestMap"),
|
||||
0x04321: (157, "ContextExtensionMap"),
|
||||
0x04371: (158, "DebugInfoMap"),
|
||||
0x043c1: (159, "FunctionTemplateInfoMap"),
|
||||
0x04411: (161, "ModuleInfoEntryMap"),
|
||||
0x04461: (162, "ModuleMap"),
|
||||
0x044b1: (163, "ObjectTemplateInfoMap"),
|
||||
0x04501: (164, "PromiseCapabilityMap"),
|
||||
0x04551: (165, "PromiseReactionMap"),
|
||||
0x045a1: (166, "PrototypeInfoMap"),
|
||||
0x045f1: (168, "StackFrameInfoMap"),
|
||||
0x04641: (170, "Tuple3Map"),
|
||||
0x04691: (171, "CallableTaskMap"),
|
||||
0x046e1: (172, "CallbackTaskMap"),
|
||||
0x04731: (173, "PromiseFulfillReactionJobTaskMap"),
|
||||
0x04781: (174, "PromiseRejectReactionJobTaskMap"),
|
||||
0x047d1: (175, "PromiseResolveThenableJobTaskMap"),
|
||||
0x04001: (149, "FixedBigUint64ArrayMap"),
|
||||
0x04051: (148, "FixedBigInt64ArrayMap"),
|
||||
0x040a1: (171, "Tuple2Map"),
|
||||
0x040f1: (169, "ScriptMap"),
|
||||
0x04141: (162, "InterceptorInfoMap"),
|
||||
0x04191: (153, "AccessorInfoMap"),
|
||||
0x041e1: (152, "AccessCheckInfoMap"),
|
||||
0x04231: (154, "AccessorPairMap"),
|
||||
0x04281: (155, "AliasedArgumentsEntryMap"),
|
||||
0x042d1: (156, "AllocationMementoMap"),
|
||||
0x04321: (157, "AllocationSiteMap"),
|
||||
0x04371: (158, "AsyncGeneratorRequestMap"),
|
||||
0x043c1: (159, "ContextExtensionMap"),
|
||||
0x04411: (160, "DebugInfoMap"),
|
||||
0x04461: (161, "FunctionTemplateInfoMap"),
|
||||
0x044b1: (163, "ModuleInfoEntryMap"),
|
||||
0x04501: (164, "ModuleMap"),
|
||||
0x04551: (165, "ObjectTemplateInfoMap"),
|
||||
0x045a1: (166, "PromiseCapabilityMap"),
|
||||
0x045f1: (167, "PromiseReactionMap"),
|
||||
0x04641: (168, "PrototypeInfoMap"),
|
||||
0x04691: (170, "StackFrameInfoMap"),
|
||||
0x046e1: (172, "Tuple3Map"),
|
||||
0x04731: (173, "CallableTaskMap"),
|
||||
0x04781: (174, "CallbackTaskMap"),
|
||||
0x047d1: (175, "PromiseFulfillReactionJobTaskMap"),
|
||||
0x04821: (176, "PromiseRejectReactionJobTaskMap"),
|
||||
0x04871: (177, "PromiseResolveThenableJobTaskMap"),
|
||||
}
|
||||
|
||||
# List of known V8 objects.
|
||||
@ -323,24 +331,24 @@ KNOWN_OBJECTS = {
|
||||
("OLD_SPACE", 0x02721): "EmptyFixedFloat32Array",
|
||||
("OLD_SPACE", 0x02741): "EmptyFixedFloat64Array",
|
||||
("OLD_SPACE", 0x02761): "EmptyFixedUint8ClampedArray",
|
||||
("OLD_SPACE", 0x02781): "EmptyScript",
|
||||
("OLD_SPACE", 0x02809): "UndefinedCell",
|
||||
("OLD_SPACE", 0x02819): "EmptySloppyArgumentsElements",
|
||||
("OLD_SPACE", 0x02839): "EmptySlowElementDictionary",
|
||||
("OLD_SPACE", 0x02881): "EmptyOrderedHashMap",
|
||||
("OLD_SPACE", 0x028a9): "EmptyOrderedHashSet",
|
||||
("OLD_SPACE", 0x028d1): "EmptyPropertyCell",
|
||||
("OLD_SPACE", 0x028f9): "EmptyWeakCell",
|
||||
("OLD_SPACE", 0x02969): "NoElementsProtector",
|
||||
("OLD_SPACE", 0x02991): "IsConcatSpreadableProtector",
|
||||
("OLD_SPACE", 0x029a1): "SpeciesProtector",
|
||||
("OLD_SPACE", 0x029c9): "StringLengthProtector",
|
||||
("OLD_SPACE", 0x029d9): "FastArrayIterationProtector",
|
||||
("OLD_SPACE", 0x029e9): "ArrayIteratorProtector",
|
||||
("OLD_SPACE", 0x02a11): "ArrayBufferNeuteringProtector",
|
||||
("OLD_SPACE", 0x02a89): "InfinityValue",
|
||||
("OLD_SPACE", 0x02a99): "MinusZeroValue",
|
||||
("OLD_SPACE", 0x02aa9): "MinusInfinityValue",
|
||||
("OLD_SPACE", 0x027c1): "EmptyScript",
|
||||
("OLD_SPACE", 0x02849): "UndefinedCell",
|
||||
("OLD_SPACE", 0x02859): "EmptySloppyArgumentsElements",
|
||||
("OLD_SPACE", 0x02879): "EmptySlowElementDictionary",
|
||||
("OLD_SPACE", 0x028c1): "EmptyOrderedHashMap",
|
||||
("OLD_SPACE", 0x028e9): "EmptyOrderedHashSet",
|
||||
("OLD_SPACE", 0x02911): "EmptyPropertyCell",
|
||||
("OLD_SPACE", 0x02939): "EmptyWeakCell",
|
||||
("OLD_SPACE", 0x029a9): "NoElementsProtector",
|
||||
("OLD_SPACE", 0x029d1): "IsConcatSpreadableProtector",
|
||||
("OLD_SPACE", 0x029e1): "SpeciesProtector",
|
||||
("OLD_SPACE", 0x02a09): "StringLengthProtector",
|
||||
("OLD_SPACE", 0x02a19): "FastArrayIterationProtector",
|
||||
("OLD_SPACE", 0x02a29): "ArrayIteratorProtector",
|
||||
("OLD_SPACE", 0x02a51): "ArrayBufferNeuteringProtector",
|
||||
("OLD_SPACE", 0x02ac9): "InfinityValue",
|
||||
("OLD_SPACE", 0x02ad9): "MinusZeroValue",
|
||||
("OLD_SPACE", 0x02ae9): "MinusInfinityValue",
|
||||
}
|
||||
|
||||
# List of known V8 Frame Markers.
|
||||
|
Loading…
Reference in New Issue
Block a user