diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-12-04 08:20:37 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-12-06 15:23:33 +0100 |
commit | 9b4bf7de6c9a7c25f116c7a502384c20b5cfaea3 (patch) | |
tree | 2b0c843168dafb939d8df8a15b2aa72b76dee51d /deps/v8/src/runtime | |
parent | b8fbe69db1292307adb2c2b2e0d5ef48c4ab2faf (diff) | |
download | android-node-v8-9b4bf7de6c9a7c25f116c7a502384c20b5cfaea3.tar.gz android-node-v8-9b4bf7de6c9a7c25f116c7a502384c20b5cfaea3.tar.bz2 android-node-v8-9b4bf7de6c9a7c25f116c7a502384c20b5cfaea3.zip |
deps: update V8 to 7.1.302.28
PR-URL: https://github.com/nodejs/node/pull/23423
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/v8/src/runtime')
25 files changed, 933 insertions, 1446 deletions
diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc index d72159b0ac..abe3883097 100644 --- a/deps/v8/src/runtime/runtime-array.cc +++ b/deps/v8/src/runtime/runtime-array.cc @@ -30,6 +30,16 @@ RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { return *object; } +RUNTIME_FUNCTION(Runtime_TransitionElementsKindWithKind) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); + CONVERT_ARG_HANDLE_CHECKED(Smi, elements_kind_smi, 1); + ElementsKind to_kind = static_cast<ElementsKind>(elements_kind_smi->value()); + JSObject::TransitionElementsKind(object, to_kind); + return *object; +} + namespace { // Find the next free position. undefined and holes are both considered // free spots. Returns "Nothing" if an exception occurred. @@ -313,7 +323,7 @@ Maybe<bool> ConditionalCopy(Isolate* isolate, Handle<JSReceiver> source, Handle<Object> source_element; ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, source_element, JSReceiver::GetElement(isolate, source, index), + isolate, source_element, JSReceiver::GetElement(isolate, target, index), Nothing<bool>()); Handle<Object> set_result; diff --git a/deps/v8/src/runtime/runtime-atomics.cc b/deps/v8/src/runtime/runtime-atomics.cc index 972e48bae6..3fd07af255 100644 --- a/deps/v8/src/runtime/runtime-atomics.cc +++ b/deps/v8/src/runtime/runtime-atomics.cc @@ -17,10 +17,32 @@ namespace v8 { namespace internal { +// Other platforms have CSA support, see builtins-sharedarraybuffer-gen.h. +#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || \ + V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X + namespace { #if V8_CC_GNU +// GCC/Clang helpfully warn us that using 64-bit atomics on 32-bit platforms +// can be slow. Good to know, but we don't have a choice. +#ifdef V8_TARGET_ARCH_32_BIT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Watomic-alignment" +#endif // V8_TARGET_ARCH_32_BIT + +template <typename T> +inline T LoadSeqCst(T* p) { + return __atomic_load_n(p, __ATOMIC_SEQ_CST); +} + +template <typename T> +inline void StoreSeqCst(T* p, T value) { + __atomic_store_n(p, value, __ATOMIC_SEQ_CST); +} + template <typename T> inline T ExchangeSeqCst(T* p, T value) { return __atomic_exchange_n(p, value, __ATOMIC_SEQ_CST); @@ -58,6 +80,10 @@ inline T XorSeqCst(T* p, T value) { return __atomic_fetch_xor(p, value, __ATOMIC_SEQ_CST); } +#ifdef V8_TARGET_ARCH_32_BIT +#pragma GCC diagnostic pop +#endif // V8_TARGET_ARCH_32_BIT + #elif V8_CC_MSVC #define InterlockedExchange32 _InterlockedExchange @@ -67,6 +93,7 @@ inline T XorSeqCst(T* p, T value) { #define InterlockedExchangeAdd16 _InterlockedExchangeAdd16 #define InterlockedExchangeAdd8 _InterlockedExchangeAdd8 #define InterlockedAnd32 _InterlockedAnd +#define InterlockedOr64 _InterlockedOr64 #define InterlockedOr32 _InterlockedOr #define InterlockedXor32 _InterlockedXor @@ -107,6 +134,18 @@ ATOMIC_OPS(int16_t, 16, short) /* NOLINT(runtime/int) */ ATOMIC_OPS(uint16_t, 16, short) /* NOLINT(runtime/int) */ ATOMIC_OPS(int32_t, 32, long) /* NOLINT(runtime/int) */ ATOMIC_OPS(uint32_t, 32, long) /* NOLINT(runtime/int) */ +ATOMIC_OPS(int64_t, 64, __int64) +ATOMIC_OPS(uint64_t, 64, __int64) + +template <typename T> +inline T LoadSeqCst(T* p) { + UNREACHABLE(); +} + +template <typename T> +inline void StoreSeqCst(T* p, T value) { + UNREACHABLE(); +} #undef ATOMIC_OPS @@ -117,6 +156,7 @@ ATOMIC_OPS(uint32_t, 32, long) /* NOLINT(runtime/int) */ #undef InterlockedExchangeAdd16 #undef InterlockedExchangeAdd8 #undef InterlockedAnd32 +#undef InterlockedOr64 #undef InterlockedOr32 #undef InterlockedXor32 @@ -159,6 +199,15 @@ inline int32_t FromObject<int32_t>(Handle<Object> number) { return NumberToInt32(*number); } +template <> +inline uint64_t FromObject<uint64_t>(Handle<Object> bigint) { + return Handle<BigInt>::cast(bigint)->AsUint64(); +} + +template <> +inline int64_t FromObject<int64_t>(Handle<Object> bigint) { + return Handle<BigInt>::cast(bigint)->AsInt64(); +} inline Object* ToObject(Isolate* isolate, int8_t t) { return Smi::FromInt(t); } @@ -178,15 +227,42 @@ inline Object* ToObject(Isolate* isolate, uint32_t t) { return *isolate->factory()->NewNumber(t); } -template <typename T> -inline Object* DoExchange(Isolate* isolate, void* buffer, size_t index, - Handle<Object> obj) { - T value = FromObject<T>(obj); - T result = ExchangeSeqCst(static_cast<T*>(buffer) + index, value); - return ToObject(isolate, result); +inline Object* ToObject(Isolate* isolate, int64_t t) { + return *BigInt::FromInt64(isolate, t); +} + +inline Object* ToObject(Isolate* isolate, uint64_t t) { + return *BigInt::FromUint64(isolate, t); } template <typename T> +struct Load { + static inline Object* Do(Isolate* isolate, void* buffer, size_t index) { + T result = LoadSeqCst(static_cast<T*>(buffer) + index); + return ToObject(isolate, result); + } +}; + +template <typename T> +struct Store { + static inline void Do(Isolate* isolate, void* buffer, size_t index, + Handle<Object> obj) { + T value = FromObject<T>(obj); + StoreSeqCst(static_cast<T*>(buffer) + index, value); + } +}; + +template <typename T> +struct Exchange { + static inline Object* Do(Isolate* isolate, void* buffer, size_t index, + Handle<Object> obj) { + T value = FromObject<T>(obj); + T result = ExchangeSeqCst(static_cast<T*>(buffer) + index, value); + return ToObject(isolate, result); + } +}; + +template <typename T> inline Object* DoCompareExchange(Isolate* isolate, void* buffer, size_t index, Handle<Object> oldobj, Handle<Object> newobj) { T oldval = FromObject<T>(oldobj); @@ -197,44 +273,54 @@ inline Object* DoCompareExchange(Isolate* isolate, void* buffer, size_t index, } template <typename T> -inline Object* DoAdd(Isolate* isolate, void* buffer, size_t index, - Handle<Object> obj) { - T value = FromObject<T>(obj); - T result = AddSeqCst(static_cast<T*>(buffer) + index, value); - return ToObject(isolate, result); -} +struct Add { + static inline Object* Do(Isolate* isolate, void* buffer, size_t index, + Handle<Object> obj) { + T value = FromObject<T>(obj); + T result = AddSeqCst(static_cast<T*>(buffer) + index, value); + return ToObject(isolate, result); + } +}; template <typename T> -inline Object* DoSub(Isolate* isolate, void* buffer, size_t index, - Handle<Object> obj) { - T value = FromObject<T>(obj); - T result = SubSeqCst(static_cast<T*>(buffer) + index, value); - return ToObject(isolate, result); -} +struct Sub { + static inline Object* Do(Isolate* isolate, void* buffer, size_t index, + Handle<Object> obj) { + T value = FromObject<T>(obj); + T result = SubSeqCst(static_cast<T*>(buffer) + index, value); + return ToObject(isolate, result); + } +}; template <typename T> -inline Object* DoAnd(Isolate* isolate, void* buffer, size_t index, - Handle<Object> obj) { - T value = FromObject<T>(obj); - T result = AndSeqCst(static_cast<T*>(buffer) + index, value); - return ToObject(isolate, result); -} +struct And { + static inline Object* Do(Isolate* isolate, void* buffer, size_t index, + Handle<Object> obj) { + T value = FromObject<T>(obj); + T result = AndSeqCst(static_cast<T*>(buffer) + index, value); + return ToObject(isolate, result); + } +}; template <typename T> -inline Object* DoOr(Isolate* isolate, void* buffer, size_t index, - Handle<Object> obj) { - T value = FromObject<T>(obj); - T result = OrSeqCst(static_cast<T*>(buffer) + index, value); - return ToObject(isolate, result); -} +struct Or { + static inline Object* Do(Isolate* isolate, void* buffer, size_t index, + Handle<Object> obj) { + T value = FromObject<T>(obj); + T result = OrSeqCst(static_cast<T*>(buffer) + index, value); + return ToObject(isolate, result); + } +}; template <typename T> -inline Object* DoXor(Isolate* isolate, void* buffer, size_t index, - Handle<Object> obj) { - T value = FromObject<T>(obj); - T result = XorSeqCst(static_cast<T*>(buffer) + index, value); - return ToObject(isolate, result); -} +struct Xor { + static inline Object* Do(Isolate* isolate, void* buffer, size_t index, + Handle<Object> obj) { + T value = FromObject<T>(obj); + T result = XorSeqCst(static_cast<T*>(buffer) + index, value); + return ToObject(isolate, result); + } +}; } // anonymous namespace @@ -248,22 +334,44 @@ inline Object* DoXor(Isolate* isolate, void* buffer, size_t index, V(Uint32, uint32, UINT32, uint32_t) \ V(Int32, int32, INT32, int32_t) -RUNTIME_FUNCTION(Runtime_AtomicsExchange) { +// This is https://tc39.github.io/ecma262/#sec-getmodifysetvalueinbuffer +// but also includes the ToInteger/ToBigInt conversion that's part of +// https://tc39.github.io/ecma262/#sec-atomicreadmodifywrite +template <template <typename> class Op> +Object* GetModifySetValueInBuffer(Arguments args, Isolate* isolate) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); - CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); + CONVERT_ARG_HANDLE_CHECKED(Object, value_obj, 2); CHECK(sta->GetBuffer()->is_shared()); - CHECK_LT(index, NumberToSize(sta->length())); uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) + - NumberToSize(sta->byte_offset()); + sta->byte_offset(); + + if (sta->type() >= kExternalBigInt64Array) { + Handle<BigInt> bigint; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, bigint, + BigInt::FromObject(isolate, value_obj)); + // SharedArrayBuffers are not neuterable. + CHECK_LT(index, NumberToSize(sta->length())); + if (sta->type() == kExternalBigInt64Array) { + return Op<int64_t>::Do(isolate, source, index, bigint); + } + DCHECK(sta->type() == kExternalBigUint64Array); + return Op<uint64_t>::Do(isolate, source, index, bigint); + } + + Handle<Object> value; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, + Object::ToInteger(isolate, value_obj)); + // SharedArrayBuffers are not neuterable. + CHECK_LT(index, NumberToSize(sta->length())); switch (sta->type()) { #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype) \ case kExternal##Type##Array: \ - return DoExchange<ctype>(isolate, source, index, value); + return Op<ctype>::Do(isolate, source, index, value); INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) #undef TYPED_ARRAY_CASE @@ -275,81 +383,104 @@ RUNTIME_FUNCTION(Runtime_AtomicsExchange) { UNREACHABLE(); } -RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { +RUNTIME_FUNCTION(Runtime_AtomicsLoad64) { HandleScope scope(isolate); - DCHECK_EQ(4, args.length()); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); - CONVERT_NUMBER_ARG_HANDLE_CHECKED(oldobj, 2); - CONVERT_NUMBER_ARG_HANDLE_CHECKED(newobj, 3); CHECK(sta->GetBuffer()->is_shared()); - CHECK_LT(index, NumberToSize(sta->length())); uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) + - NumberToSize(sta->byte_offset()); + sta->byte_offset(); - switch (sta->type()) { -#define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype) \ - case kExternal##Type##Array: \ - return DoCompareExchange<ctype>(isolate, source, index, oldobj, newobj); - - INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) -#undef TYPED_ARRAY_CASE - - default: - break; + DCHECK(sta->type() == kExternalBigInt64Array || + sta->type() == kExternalBigUint64Array); + // SharedArrayBuffers are not neuterable. + CHECK_LT(index, NumberToSize(sta->length())); + if (sta->type() == kExternalBigInt64Array) { + return Load<int64_t>::Do(isolate, source, index); } - - UNREACHABLE(); + DCHECK(sta->type() == kExternalBigUint64Array); + return Load<uint64_t>::Do(isolate, source, index); } -// ES #sec-atomics.add -// Atomics.add( typedArray, index, value ) -RUNTIME_FUNCTION(Runtime_AtomicsAdd) { +RUNTIME_FUNCTION(Runtime_AtomicsStore64) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); - CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); + CONVERT_ARG_HANDLE_CHECKED(Object, value_obj, 2); CHECK(sta->GetBuffer()->is_shared()); - CHECK_LT(index, NumberToSize(sta->length())); uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) + - NumberToSize(sta->byte_offset()); + sta->byte_offset(); - switch (sta->type()) { -#define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype) \ - case kExternal##Type##Array: \ - return DoAdd<ctype>(isolate, source, index, value); + Handle<BigInt> bigint; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, bigint, + BigInt::FromObject(isolate, value_obj)); - INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) -#undef TYPED_ARRAY_CASE - - default: - break; + DCHECK(sta->type() == kExternalBigInt64Array || + sta->type() == kExternalBigUint64Array); + // SharedArrayBuffers are not neuterable. + CHECK_LT(index, NumberToSize(sta->length())); + if (sta->type() == kExternalBigInt64Array) { + Store<int64_t>::Do(isolate, source, index, bigint); + return *bigint; } + DCHECK(sta->type() == kExternalBigUint64Array); + Store<uint64_t>::Do(isolate, source, index, bigint); + return *bigint; +} - UNREACHABLE(); +RUNTIME_FUNCTION(Runtime_AtomicsExchange) { + return GetModifySetValueInBuffer<Exchange>(args, isolate); } -// ES #sec-atomics.sub -// Atomics.sub( typedArray, index, value ) -RUNTIME_FUNCTION(Runtime_AtomicsSub) { +RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); - CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); + CONVERT_ARG_HANDLE_CHECKED(Object, old_value_obj, 2); + CONVERT_ARG_HANDLE_CHECKED(Object, new_value_obj, 3); CHECK(sta->GetBuffer()->is_shared()); CHECK_LT(index, NumberToSize(sta->length())); uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) + - NumberToSize(sta->byte_offset()); + sta->byte_offset(); + + if (sta->type() >= kExternalBigInt64Array) { + Handle<BigInt> old_bigint; + Handle<BigInt> new_bigint; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, old_bigint, BigInt::FromObject(isolate, old_value_obj)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, new_bigint, BigInt::FromObject(isolate, new_value_obj)); + // SharedArrayBuffers are not neuterable. + CHECK_LT(index, NumberToSize(sta->length())); + if (sta->type() == kExternalBigInt64Array) { + return DoCompareExchange<int64_t>(isolate, source, index, old_bigint, + new_bigint); + } + DCHECK(sta->type() == kExternalBigUint64Array); + return DoCompareExchange<uint64_t>(isolate, source, index, old_bigint, + new_bigint); + } + + Handle<Object> old_value; + Handle<Object> new_value; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, old_value, + Object::ToInteger(isolate, old_value_obj)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, new_value, + Object::ToInteger(isolate, new_value_obj)); + // SharedArrayBuffers are not neuterable. + CHECK_LT(index, NumberToSize(sta->length())); switch (sta->type()) { -#define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype) \ - case kExternal##Type##Array: \ - return DoSub<ctype>(isolate, source, index, value); +#define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype) \ + case kExternal##Type##Array: \ + return DoCompareExchange<ctype>(isolate, source, index, old_value, \ + new_value); INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) #undef TYPED_ARRAY_CASE @@ -361,94 +492,60 @@ RUNTIME_FUNCTION(Runtime_AtomicsSub) { UNREACHABLE(); } +// ES #sec-atomics.add +// Atomics.add( typedArray, index, value ) +RUNTIME_FUNCTION(Runtime_AtomicsAdd) { + return GetModifySetValueInBuffer<Add>(args, isolate); +} + +// ES #sec-atomics.sub +// Atomics.sub( typedArray, index, value ) +RUNTIME_FUNCTION(Runtime_AtomicsSub) { + return GetModifySetValueInBuffer<Sub>(args, isolate); +} + // ES #sec-atomics.and // Atomics.and( typedArray, index, value ) RUNTIME_FUNCTION(Runtime_AtomicsAnd) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); - CONVERT_SIZE_ARG_CHECKED(index, 1); - CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); - CHECK(sta->GetBuffer()->is_shared()); - CHECK_LT(index, NumberToSize(sta->length())); - - uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) + - NumberToSize(sta->byte_offset()); - - switch (sta->type()) { -#define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype) \ - case kExternal##Type##Array: \ - return DoAnd<ctype>(isolate, source, index, value); - - INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) -#undef TYPED_ARRAY_CASE - - default: - break; - } - - UNREACHABLE(); + return GetModifySetValueInBuffer<And>(args, isolate); } // ES #sec-atomics.or // Atomics.or( typedArray, index, value ) RUNTIME_FUNCTION(Runtime_AtomicsOr) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); - CONVERT_SIZE_ARG_CHECKED(index, 1); - CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); - CHECK(sta->GetBuffer()->is_shared()); - CHECK_LT(index, NumberToSize(sta->length())); + return GetModifySetValueInBuffer<Or>(args, isolate); +} - uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) + - NumberToSize(sta->byte_offset()); +// ES #sec-atomics.xor +// Atomics.xor( typedArray, index, value ) +RUNTIME_FUNCTION(Runtime_AtomicsXor) { + return GetModifySetValueInBuffer<Xor>(args, isolate); +} - switch (sta->type()) { -#define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype) \ - case kExternal##Type##Array: \ - return DoOr<ctype>(isolate, source, index, value); +#undef INTEGER_TYPED_ARRAYS - INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) -#undef TYPED_ARRAY_CASE +#else - default: - break; - } +RUNTIME_FUNCTION(Runtime_AtomicsLoad64) { UNREACHABLE(); } - UNREACHABLE(); -} +RUNTIME_FUNCTION(Runtime_AtomicsStore64) { UNREACHABLE(); } -// ES #sec-atomics.xor -// Atomics.xor( typedArray, index, value ) -RUNTIME_FUNCTION(Runtime_AtomicsXor) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); - CONVERT_SIZE_ARG_CHECKED(index, 1); - CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); - CHECK(sta->GetBuffer()->is_shared()); - CHECK_LT(index, NumberToSize(sta->length())); +RUNTIME_FUNCTION(Runtime_AtomicsExchange) { UNREACHABLE(); } - uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) + - NumberToSize(sta->byte_offset()); +RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { UNREACHABLE(); } - switch (sta->type()) { -#define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype) \ - case kExternal##Type##Array: \ - return DoXor<ctype>(isolate, source, index, value); +RUNTIME_FUNCTION(Runtime_AtomicsAdd) { UNREACHABLE(); } - INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) -#undef TYPED_ARRAY_CASE +RUNTIME_FUNCTION(Runtime_AtomicsSub) { UNREACHABLE(); } - default: - break; - } +RUNTIME_FUNCTION(Runtime_AtomicsAnd) { UNREACHABLE(); } - UNREACHABLE(); -} +RUNTIME_FUNCTION(Runtime_AtomicsOr) { UNREACHABLE(); } -#undef INTEGER_TYPED_ARRAYS +RUNTIME_FUNCTION(Runtime_AtomicsXor) { UNREACHABLE(); } + +#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 + // || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-classes.cc b/deps/v8/src/runtime/runtime-classes.cc index d4fb0df3c3..0aea983f41 100644 --- a/deps/v8/src/runtime/runtime-classes.cc +++ b/deps/v8/src/runtime/runtime-classes.cc @@ -731,9 +731,9 @@ MaybeHandle<Object> StoreToSuper(Isolate* isolate, Handle<JSObject> home_object, SuperMode::kStore, name, 0), Object); LookupIterator it(receiver, name, holder); - MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, - Object::CERTAINLY_NOT_STORE_FROM_KEYED), - MaybeHandle<Object>()); + MAYBE_RETURN( + Object::SetSuperProperty(&it, value, language_mode, StoreOrigin::kNamed), + MaybeHandle<Object>()); return value; } @@ -750,7 +750,7 @@ MaybeHandle<Object> StoreElementToSuper(Isolate* isolate, Object); LookupIterator it(isolate, receiver, index, holder); MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, - Object::MAY_BE_STORE_FROM_KEYED), + StoreOrigin::kMaybeKeyed), MaybeHandle<Object>()); return value; } diff --git a/deps/v8/src/runtime/runtime-collections.cc b/deps/v8/src/runtime/runtime-collections.cc index 6c64802963..03a24139f3 100644 --- a/deps/v8/src/runtime/runtime-collections.cc +++ b/deps/v8/src/runtime/runtime-collections.cc @@ -39,16 +39,6 @@ RUNTIME_FUNCTION(Runtime_SetShrink) { return ReadOnlyRoots(isolate).undefined_value(); } -RUNTIME_FUNCTION(Runtime_SetIteratorClone) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); - return *isolate->factory()->NewJSSetIterator( - handle(holder->map(), isolate), - handle(OrderedHashSet::cast(holder->table()), isolate), - Smi::ToInt(holder->index())); -} - RUNTIME_FUNCTION(Runtime_MapShrink) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -69,25 +59,6 @@ RUNTIME_FUNCTION(Runtime_MapGrow) { return ReadOnlyRoots(isolate).undefined_value(); } -RUNTIME_FUNCTION(Runtime_MapIteratorClone) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); - return *isolate->factory()->NewJSMapIterator( - handle(holder->map(), isolate), - handle(OrderedHashMap::cast(holder->table()), isolate), - Smi::ToInt(holder->index())); -} - -RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); - CONVERT_NUMBER_CHECKED(int, max_entries, Int32, args[1]); - CHECK_GE(max_entries, 0); - return *JSWeakCollection::GetEntries(holder, max_entries); -} - RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); @@ -110,15 +81,6 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { return isolate->heap()->ToBoolean(was_present); } -RUNTIME_FUNCTION(Runtime_GetWeakSetValues) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); - CONVERT_NUMBER_CHECKED(int, max_values, Int32, args[1]); - CHECK_GE(max_values, 0); - return *JSWeakCollection::GetEntries(holder, max_values); -} - RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { HandleScope scope(isolate); DCHECK_EQ(4, args.length()); diff --git a/deps/v8/src/runtime/runtime-date.cc b/deps/v8/src/runtime/runtime-date.cc index e459da4da3..102f89ac14 100644 --- a/deps/v8/src/runtime/runtime-date.cc +++ b/deps/v8/src/runtime/runtime-date.cc @@ -14,13 +14,6 @@ namespace v8 { namespace internal { -RUNTIME_FUNCTION(Runtime_IsDate) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, obj, 0); - return isolate->heap()->ToBoolean(obj->IsJSDate()); -} - RUNTIME_FUNCTION(Runtime_DateCurrentTime) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc index c1dc4ec9df..4381fa6dcf 100644 --- a/deps/v8/src/runtime/runtime-debug.cc +++ b/deps/v8/src/runtime/runtime-debug.cc @@ -450,8 +450,8 @@ RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) { RUNTIME_FUNCTION(Runtime_CollectGarbage) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); - isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask, - GarbageCollectionReason::kRuntime); + isolate->heap()->PreciseCollectAllGarbage(Heap::kNoGCFlags, + GarbageCollectionReason::kRuntime); return ReadOnlyRoots(isolate).undefined_value(); } @@ -641,11 +641,6 @@ RUNTIME_FUNCTION(Runtime_DebugPopPromise) { return ReadOnlyRoots(isolate).undefined_value(); } -RUNTIME_FUNCTION(Runtime_DebugIsActive) { - SealHandleScope shs(isolate); - return Smi::FromInt(isolate->debug()->is_active()); -} - namespace { Handle<JSObject> MakeRangeObject(Isolate* isolate, const CoverageBlock& range) { Factory* factory = isolate->factory(); @@ -810,5 +805,19 @@ RUNTIME_FUNCTION(Runtime_LiveEditPatchScript) { } return ReadOnlyRoots(isolate).undefined_value(); } + +RUNTIME_FUNCTION(Runtime_PerformSideEffectCheckForObject) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); + + DCHECK_EQ(isolate->debug_execution_mode(), DebugInfo::kSideEffects); + if (!isolate->debug()->PerformSideEffectCheckForObject(object)) { + DCHECK(isolate->has_pending_exception()); + return ReadOnlyRoots(isolate).exception(); + } + return ReadOnlyRoots(isolate).undefined_value(); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-function.cc b/deps/v8/src/runtime/runtime-function.cc index 22f4a4fb48..769ccc528b 100644 --- a/deps/v8/src/runtime/runtime-function.cc +++ b/deps/v8/src/runtime/runtime-function.cc @@ -12,20 +12,6 @@ namespace v8 { namespace internal { -RUNTIME_FUNCTION(Runtime_FunctionGetName) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0); - if (function->IsJSBoundFunction()) { - RETURN_RESULT_OR_FAILURE( - isolate, JSBoundFunction::GetName( - isolate, Handle<JSBoundFunction>::cast(function))); - } else { - return *JSFunction::GetName(isolate, Handle<JSFunction>::cast(function)); - } -} - // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_FunctionGetScriptSource) { HandleScope scope(isolate); @@ -87,64 +73,6 @@ RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) { } -RUNTIME_FUNCTION(Runtime_SetCode) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1); - - Handle<SharedFunctionInfo> target_shared(target->shared(), isolate); - Handle<SharedFunctionInfo> source_shared(source->shared(), isolate); - - if (!source->is_compiled() && - !Compiler::Compile(source, Compiler::KEEP_EXCEPTION)) { - return ReadOnlyRoots(isolate).exception(); - } - - // Set the function data, scope info, formal parameter count, and the length - // of the target shared function info. - target_shared->set_function_data(source_shared->function_data()); - target_shared->set_length(source_shared->GetLength()); - target_shared->set_raw_outer_scope_info_or_feedback_metadata( - source_shared->raw_outer_scope_info_or_feedback_metadata()); - target_shared->set_internal_formal_parameter_count( - source_shared->internal_formal_parameter_count()); - bool was_native = target_shared->native(); - target_shared->set_flags(source_shared->flags()); - target_shared->set_native(was_native); - target_shared->set_scope_info(source_shared->scope_info()); - - Handle<Object> source_script(source_shared->script(), isolate); - int function_literal_id = source_shared->FunctionLiteralId(isolate); - if (source_script->IsScript()) { - SharedFunctionInfo::SetScript(source_shared, - isolate->factory()->undefined_value(), - function_literal_id); - } - SharedFunctionInfo::SetScript(target_shared, source_script, - function_literal_id); - - // Set the code of the target function. - target->set_code(source_shared->GetCode()); - Handle<Context> context(source->context(), isolate); - target->set_context(*context); - - // Make sure we get a fresh copy of the feedback vector to avoid cross - // context contamination, and that the feedback vector makes it's way into - // the target_shared optimized code map. - JSFunction::EnsureFeedbackVector(target); - - if (isolate->logger()->is_listening_to_code_events() || - isolate->is_profiling()) { - isolate->logger()->LogExistingFunction( - source_shared, handle(source_shared->abstract_code(), isolate)); - } - - return *target; -} - - // Set the native flag on the function. // This is used to decide if we should transform null and undefined // into the global object when doing call and apply. @@ -162,14 +90,6 @@ RUNTIME_FUNCTION(Runtime_SetNativeFlag) { } -RUNTIME_FUNCTION(Runtime_IsConstructor) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, object, 0); - return isolate->heap()->ToBoolean(object->IsConstructor()); -} - - RUNTIME_FUNCTION(Runtime_Call) { HandleScope scope(isolate); DCHECK_LE(2, args.length()); diff --git a/deps/v8/src/runtime/runtime-futex.cc b/deps/v8/src/runtime/runtime-futex.cc index 3c9a90fbbd..c891b6582c 100644 --- a/deps/v8/src/runtime/runtime-futex.cc +++ b/deps/v8/src/runtime/runtime-futex.cc @@ -23,12 +23,13 @@ RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); + CHECK(!sta->WasNeutered()); CHECK(sta->GetBuffer()->is_shared()); CHECK_LT(index, NumberToSize(sta->length())); CHECK_EQ(sta->type(), kExternalInt32Array); Handle<JSArrayBuffer> array_buffer = sta->GetBuffer(); - size_t addr = (index << 2) + NumberToSize(sta->byte_offset()); + size_t addr = (index << 2) + sta->byte_offset(); return FutexEmulation::NumWaitersForTesting(array_buffer, addr); } diff --git a/deps/v8/src/runtime/runtime-generator.cc b/deps/v8/src/runtime/runtime-generator.cc index 636aa63879..9d652599c1 100644 --- a/deps/v8/src/runtime/runtime-generator.cc +++ b/deps/v8/src/runtime/runtime-generator.cc @@ -53,12 +53,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) { return generator->function(); } -RUNTIME_FUNCTION(Runtime_GeneratorGetInputOrDebugPos) { - // Runtime call is implemented in InterpreterIntrinsics and lowered in - // JSIntrinsicLowering - UNREACHABLE(); -} - RUNTIME_FUNCTION(Runtime_AsyncGeneratorResolve) { // Runtime call is implemented in InterpreterIntrinsics and lowered in // JSIntrinsicLowering diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc index c98b27da27..8c227a1703 100644 --- a/deps/v8/src/runtime/runtime-internal.cc +++ b/deps/v8/src/runtime/runtime-internal.cc @@ -19,6 +19,7 @@ #include "src/parsing/parsing.h" #include "src/runtime/runtime-utils.h" #include "src/snapshot/snapshot.h" +#include "src/string-builder-inl.h" namespace v8 { namespace internal { @@ -343,6 +344,31 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) { return false; } +Handle<String> BuildDefaultCallSite(Isolate* isolate, Handle<Object> object) { + IncrementalStringBuilder builder(isolate); + + builder.AppendString(Object::TypeOf(isolate, object)); + if (object->IsString()) { + builder.AppendCString(" \""); + builder.AppendString(Handle<String>::cast(object)); + builder.AppendCString("\""); + } else if (object->IsNull(isolate)) { + builder.AppendCString(" "); + builder.AppendString(isolate->factory()->null_string()); + } else if (object->IsTrue(isolate)) { + builder.AppendCString(" "); + builder.AppendString(isolate->factory()->true_string()); + } else if (object->IsFalse(isolate)) { + builder.AppendCString(" "); + builder.AppendString(isolate->factory()->false_string()); + } else if (object->IsNumber()) { + builder.AppendCString(" "); + builder.AppendString(isolate->factory()->NumberToString(object)); + } + + return builder.Finish().ToHandleChecked(); +} + Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object, CallPrinter::ErrorHint* hint) { MessageLocation location; @@ -358,7 +384,7 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object, isolate->clear_pending_exception(); } } - return Object::TypeOf(isolate, object); + return BuildDefaultCallSite(isolate, object); } MessageTemplate::Template UpdateErrorTemplate( @@ -388,11 +414,11 @@ MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate, Handle<Object> object) { CallPrinter::ErrorHint hint = CallPrinter::kNone; Handle<String> callsite = RenderCallSite(isolate, object, &hint); - MessageTemplate::Template id = MessageTemplate::kNonObjectPropertyLoad; + MessageTemplate::Template id = MessageTemplate::kNotIterableNoSymbolLoad; if (hint == CallPrinter::kNone) { Handle<Symbol> iterator_symbol = isolate->factory()->iterator_symbol(); - THROW_NEW_ERROR(isolate, NewTypeError(id, iterator_symbol, callsite), + THROW_NEW_ERROR(isolate, NewTypeError(id, callsite, iterator_symbol), Object); } @@ -400,6 +426,14 @@ MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate, THROW_NEW_ERROR(isolate, NewTypeError(id, callsite), Object); } +RUNTIME_FUNCTION(Runtime_ThrowIteratorError) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); + RETURN_RESULT_OR_FAILURE(isolate, + Runtime::ThrowIteratorError(isolate, object)); +} + RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -476,6 +510,12 @@ RUNTIME_FUNCTION(Runtime_IncrementUseCounter) { RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) { HandleScope scope(isolate); + + // Append any worker thread runtime call stats to the main table before + // printing. + isolate->counters()->worker_thread_runtime_call_stats()->AddToMainTable( + isolate->counters()->runtime_call_stats()); + if (args.length() == 0) { // Without arguments, the result is returned as a string. DCHECK_EQ(0, args.length()); @@ -591,5 +631,14 @@ RUNTIME_FUNCTION(Runtime_ReportMessage) { return ReadOnlyRoots(isolate).undefined_value(); } +RUNTIME_FUNCTION(Runtime_GetInitializerFunction) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, constructor, 0); + Handle<Symbol> key = isolate->factory()->class_fields_symbol(); + Handle<Object> initializer = JSReceiver::GetDataProperty(constructor, key); + return *initializer; +} } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-interpreter.cc b/deps/v8/src/runtime/runtime-interpreter.cc index 7f07d084a1..e87feac361 100644 --- a/deps/v8/src/runtime/runtime-interpreter.cc +++ b/deps/v8/src/runtime/runtime-interpreter.cc @@ -23,7 +23,6 @@ namespace internal { RUNTIME_FUNCTION(Runtime_InterpreterDeserializeLazy) { HandleScope scope(isolate); - DCHECK(FLAG_lazy_handler_deserialization); DCHECK(FLAG_lazy_deserialization); DCHECK_EQ(2, args.length()); CONVERT_SMI_ARG_CHECKED(bytecode_int, 0); diff --git a/deps/v8/src/runtime/runtime-intl.cc b/deps/v8/src/runtime/runtime-intl.cc index ad75952824..32e7a46b6e 100644 --- a/deps/v8/src/runtime/runtime-intl.cc +++ b/deps/v8/src/runtime/runtime-intl.cc @@ -22,8 +22,10 @@ #include "src/objects/intl-objects.h" #include "src/objects/js-array-inl.h" #include "src/objects/js-collator-inl.h" +#include "src/objects/js-date-time-format-inl.h" #include "src/objects/js-list-format-inl.h" #include "src/objects/js-list-format.h" +#include "src/objects/js-number-format-inl.h" #include "src/objects/js-plural-rules-inl.h" #include "src/objects/managed.h" #include "src/runtime/runtime-utils.h" @@ -42,7 +44,6 @@ #include "unicode/numfmt.h" #include "unicode/numsys.h" #include "unicode/plurrule.h" -#include "unicode/rbbi.h" #include "unicode/smpdtfmt.h" #include "unicode/timezone.h" #include "unicode/uchar.h" @@ -77,40 +78,6 @@ RUNTIME_FUNCTION(Runtime_FormatListToParts) { isolate, JSListFormat::FormatListToParts(isolate, list_format, list)); } -RUNTIME_FUNCTION(Runtime_GetNumberOption) { - HandleScope scope(isolate); - DCHECK_EQ(5, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, options, 0); - CONVERT_ARG_HANDLE_CHECKED(String, property, 1); - CONVERT_SMI_ARG_CHECKED(min, 2); - CONVERT_SMI_ARG_CHECKED(max, 3); - CONVERT_SMI_ARG_CHECKED(fallback, 4); - - Maybe<int> num = - Intl::GetNumberOption(isolate, options, property, min, max, fallback); - if (num.IsNothing()) { - return ReadOnlyRoots(isolate).exception(); - } - return Smi::FromInt(num.FromJust()); -} - -RUNTIME_FUNCTION(Runtime_DefaultNumberOption) { - HandleScope scope(isolate); - DCHECK_EQ(5, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); - CONVERT_SMI_ARG_CHECKED(min, 1); - CONVERT_SMI_ARG_CHECKED(max, 2); - CONVERT_SMI_ARG_CHECKED(fallback, 3); - CONVERT_ARG_HANDLE_CHECKED(String, property, 4); - - Maybe<int> num = - Intl::DefaultNumberOption(isolate, value, min, max, fallback, property); - if (num.IsNothing()) { - return ReadOnlyRoots(isolate).exception(); - } - return Smi::FromInt(num.FromJust()); -} - // ECMA 402 6.2.3 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) { HandleScope scope(isolate); @@ -143,340 +110,6 @@ RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) { Intl::DefaultLocale(isolate).c_str()); } -RUNTIME_FUNCTION(Runtime_IsWellFormedCurrencyCode) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(String, currency, 0); - return *(isolate->factory()->ToBoolean( - Intl::IsWellFormedCurrencyCode(isolate, currency))); -} - -RUNTIME_FUNCTION(Runtime_DefineWEProperty) { - HandleScope scope(isolate); - - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); - CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); - Intl::DefineWEProperty(isolate, target, key, value); - return ReadOnlyRoots(isolate).undefined_value(); -} - -RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) { - HandleScope scope(isolate); - - DCHECK_EQ(2, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); - CONVERT_SMI_ARG_CHECKED(expected_type_int, 1); - - Intl::Type expected_type = Intl::TypeFromInt(expected_type_int); - - return isolate->heap()->ToBoolean( - Intl::IsObjectOfType(isolate, input, expected_type)); -} - -RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) { - HandleScope scope(isolate); - - DCHECK_EQ(2, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0); - CONVERT_ARG_HANDLE_CHECKED(Smi, type, 1); - -#ifdef DEBUG - // TypeFromSmi does correctness checks. - Intl::Type type_intl = Intl::TypeFromSmi(*type); - USE(type_intl); -#endif - - Handle<Symbol> marker = isolate->factory()->intl_initialized_marker_symbol(); - JSObject::SetProperty(isolate, input, marker, type, LanguageMode::kStrict) - .Assert(); - - return ReadOnlyRoots(isolate).undefined_value(); -} - -RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) { - HandleScope scope(isolate); - - DCHECK_EQ(3, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); - CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); - CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); - - Handle<JSFunction> constructor( - isolate->native_context()->intl_date_time_format_function(), isolate); - - Handle<JSObject> local_object; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object, - JSObject::New(constructor, constructor)); - - // Set date time formatter as embedder field of the resulting JS object. - icu::SimpleDateFormat* date_format = - DateFormat::InitializeDateTimeFormat(isolate, locale, options, resolved); - CHECK_NOT_NULL(date_format); - - local_object->SetEmbedderField(DateFormat::kSimpleDateFormatIndex, - reinterpret_cast<Smi*>(date_format)); - - // Make object handle weak so we can delete the data format once GC kicks in. - Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); - GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(), - DateFormat::DeleteDateFormat, - WeakCallbackType::kInternalFields); - return *local_object; -} - -RUNTIME_FUNCTION(Runtime_CreateNumberFormat) { - HandleScope scope(isolate); - - DCHECK_EQ(3, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); - CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); - CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); - RETURN_RESULT_OR_FAILURE( - isolate, Intl::CreateNumberFormat(isolate, locale, options, resolved)); -} - -RUNTIME_FUNCTION(Runtime_CurrencyDigits) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(String, currency, 0); - return *Intl::CurrencyDigits(isolate, currency); -} - -RUNTIME_FUNCTION(Runtime_CollatorResolvedOptions) { - HandleScope scope(isolate); - - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, collator_obj, 0); - - // 3. If pr does not have an [[InitializedCollator]] internal - // slot, throw a TypeError exception. - if (!collator_obj->IsJSCollator()) { - Handle<String> method_str = isolate->factory()->NewStringFromStaticChars( - "Intl.Collator.prototype.resolvedOptions"); - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, - method_str, collator_obj)); - } - - Handle<JSCollator> collator = Handle<JSCollator>::cast(collator_obj); - - return *JSCollator::ResolvedOptions(isolate, collator); -} - -RUNTIME_FUNCTION(Runtime_PluralRulesResolvedOptions) { - HandleScope scope(isolate); - - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, plural_rules_obj, 0); - - // 3. If pr does not have an [[InitializedPluralRules]] internal - // slot, throw a TypeError exception. - if (!plural_rules_obj->IsJSPluralRules()) { - Handle<String> method_str = isolate->factory()->NewStringFromStaticChars( - "Intl.PluralRules.prototype.resolvedOptions"); - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, - method_str, plural_rules_obj)); - } - - Handle<JSPluralRules> plural_rules = - Handle<JSPluralRules>::cast(plural_rules_obj); - - return *JSPluralRules::ResolvedOptions(isolate, plural_rules); -} - -RUNTIME_FUNCTION(Runtime_ParseExtension) { - Factory* factory = isolate->factory(); - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(String, extension, 0); - std::map<std::string, std::string> map; - Intl::ParseExtension(isolate, std::string(extension->ToCString().get()), map); - Handle<JSObject> extension_map = - isolate->factory()->NewJSObjectWithNullProto(); - for (std::map<std::string, std::string>::iterator it = map.begin(); - it != map.end(); it++) { - JSObject::AddProperty( - isolate, extension_map, - factory->NewStringFromAsciiChecked(it->first.c_str()), - factory->NewStringFromAsciiChecked(it->second.c_str()), NONE); - } - return *extension_map; -} - -RUNTIME_FUNCTION(Runtime_PluralRulesSelect) { - HandleScope scope(isolate); - - DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, plural_rules_obj, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, number, 1); - - // 3. If pr does not have an [[InitializedPluralRules]] internal - // slot, throw a TypeError exception. - if (!plural_rules_obj->IsJSPluralRules()) { - Handle<String> method_str = isolate->factory()->NewStringFromStaticChars( - "Intl.PluralRules.prototype.select"); - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, - method_str, plural_rules_obj)); - } - - Handle<JSPluralRules> plural_rules = - Handle<JSPluralRules>::cast(plural_rules_obj); - - // 4. Return ? ResolvePlural(pr, n). - - RETURN_RESULT_OR_FAILURE( - isolate, JSPluralRules::ResolvePlural(isolate, plural_rules, number)); -} - -RUNTIME_FUNCTION(Runtime_CreateBreakIterator) { - HandleScope scope(isolate); - - DCHECK_EQ(3, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); - CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); - CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); - - Handle<JSFunction> constructor( - isolate->native_context()->intl_v8_break_iterator_function(), isolate); - - Handle<JSObject> local_object; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object, - JSObject::New(constructor, constructor)); - - // Set break iterator as embedder field of the resulting JS object. - icu::BreakIterator* break_iterator = V8BreakIterator::InitializeBreakIterator( - isolate, locale, options, resolved); - CHECK_NOT_NULL(break_iterator); - - if (!break_iterator) return isolate->ThrowIllegalOperation(); - - local_object->SetEmbedderField(V8BreakIterator::kBreakIteratorIndex, - reinterpret_cast<Smi*>(break_iterator)); - // Make sure that the pointer to adopted text is nullptr. - local_object->SetEmbedderField(V8BreakIterator::kUnicodeStringIndex, - static_cast<Smi*>(nullptr)); - - // Make object handle weak so we can delete the break iterator once GC kicks - // in. - Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); - GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(), - V8BreakIterator::DeleteBreakIterator, - WeakCallbackType::kInternalFields); - return *local_object; -} - -RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) { - HandleScope scope(isolate); - - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); - - icu::BreakIterator* break_iterator = - V8BreakIterator::UnpackBreakIterator(break_iterator_holder); - CHECK_NOT_NULL(break_iterator); - - return *isolate->factory()->NewNumberFromInt(break_iterator->first()); -} - -RUNTIME_FUNCTION(Runtime_BreakIteratorNext) { - HandleScope scope(isolate); - - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); - - icu::BreakIterator* break_iterator = - V8BreakIterator::UnpackBreakIterator(break_iterator_holder); - CHECK_NOT_NULL(break_iterator); - - return *isolate->factory()->NewNumberFromInt(break_iterator->next()); -} - -RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) { - HandleScope scope(isolate); - - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); - - icu::BreakIterator* break_iterator = - V8BreakIterator::UnpackBreakIterator(break_iterator_holder); - CHECK_NOT_NULL(break_iterator); - - return *isolate->factory()->NewNumberFromInt(break_iterator->current()); -} - -RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) { - HandleScope scope(isolate); - - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); - - icu::BreakIterator* break_iterator = - V8BreakIterator::UnpackBreakIterator(break_iterator_holder); - CHECK_NOT_NULL(break_iterator); - - // TODO(cira): Remove cast once ICU fixes base BreakIterator class. - icu::RuleBasedBreakIterator* rule_based_iterator = - static_cast<icu::RuleBasedBreakIterator*>(break_iterator); - int32_t status = rule_based_iterator->getRuleStatus(); - // Keep return values in sync with JavaScript BreakType enum. - if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) { - return *isolate->factory()->NewStringFromStaticChars("none"); - } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) { - return ReadOnlyRoots(isolate).number_string(); - } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) { - return *isolate->factory()->NewStringFromStaticChars("letter"); - } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) { - return *isolate->factory()->NewStringFromStaticChars("kana"); - } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) { - return *isolate->factory()->NewStringFromStaticChars("ideo"); - } else { - return *isolate->factory()->NewStringFromStaticChars("unknown"); - } -} - -RUNTIME_FUNCTION(Runtime_ToLocaleDateTime) { - HandleScope scope(isolate); - - DCHECK_EQ(6, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(Object, date, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, locales, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, options, 2); - CONVERT_ARG_HANDLE_CHECKED(String, required, 3); - CONVERT_ARG_HANDLE_CHECKED(String, defaults, 4); - CONVERT_ARG_HANDLE_CHECKED(String, service, 5); - - RETURN_RESULT_OR_FAILURE( - isolate, DateFormat::ToLocaleDateTime( - isolate, date, locales, options, required->ToCString().get(), - defaults->ToCString().get(), service->ToCString().get())); -} - -RUNTIME_FUNCTION(Runtime_ToDateTimeOptions) { - HandleScope scope(isolate); - DCHECK_EQ(args.length(), 3); - CONVERT_ARG_HANDLE_CHECKED(Object, options, 0); - CONVERT_ARG_HANDLE_CHECKED(String, required, 1); - CONVERT_ARG_HANDLE_CHECKED(String, defaults, 2); - RETURN_RESULT_OR_FAILURE( - isolate, DateFormat::ToDateTimeOptions(isolate, options, - required->ToCString().get(), - defaults->ToCString().get())); -} - RUNTIME_FUNCTION(Runtime_StringToLowerCaseIntl) { HandleScope scope(isolate); DCHECK_EQ(args.length(), 1); @@ -511,33 +144,5 @@ RUNTIME_FUNCTION(Runtime_DateCacheVersion) { return date_cache_version->get(0); } -RUNTIME_FUNCTION(Runtime_IntlUnwrapReceiver) { - HandleScope scope(isolate); - DCHECK_EQ(5, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - CONVERT_SMI_ARG_CHECKED(type_int, 1); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 2); - CONVERT_ARG_HANDLE_CHECKED(String, method, 3); - CONVERT_BOOLEAN_ARG_CHECKED(check_legacy_constructor, 4); - - RETURN_RESULT_OR_FAILURE( - isolate, Intl::UnwrapReceiver(isolate, receiver, constructor, - Intl::TypeFromInt(type_int), method, - check_legacy_constructor)); -} - -RUNTIME_FUNCTION(Runtime_SupportedLocalesOf) { - HandleScope scope(isolate); - - DCHECK_EQ(args.length(), 3); - - CONVERT_ARG_HANDLE_CHECKED(String, service, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, locales, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, options, 2); - - RETURN_RESULT_OR_FAILURE( - isolate, Intl::SupportedLocalesOf(isolate, service, locales, options)); -} - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc index d5111f7efa..8632388388 100644 --- a/deps/v8/src/runtime/runtime-literals.cc +++ b/deps/v8/src/runtime/runtime-literals.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/allocation-site-scopes.h" +#include "src/allocation-site-scopes-inl.h" #include "src/arguments-inl.h" #include "src/ast/ast.h" #include "src/isolate-inl.h" @@ -497,7 +497,8 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, Handle<HeapObject> description, int flags) { FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); CHECK(literals_slot.ToInt() < vector->length()); - Handle<Object> literal_site(vector->Get(literals_slot)->ToObject(), isolate); + Handle<Object> literal_site(vector->Get(literals_slot)->cast<Object>(), + isolate); DeepCopyHints copy_hints = DecodeCopyHints(flags); Handle<AllocationSite> site; @@ -597,7 +598,8 @@ RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); // Check if boilerplate exists. If not, create it first. - Handle<Object> literal_site(vector->Get(literal_slot)->ToObject(), isolate); + Handle<Object> literal_site(vector->Get(literal_slot)->cast<Object>(), + isolate); Handle<Object> boilerplate; if (!HasBoilerplate(literal_site)) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION( diff --git a/deps/v8/src/runtime/runtime-maths.cc b/deps/v8/src/runtime/runtime-maths.cc deleted file mode 100644 index 7695c14657..0000000000 --- a/deps/v8/src/runtime/runtime-maths.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/runtime/runtime-utils.h" - -#include "src/arguments.h" -#include "src/base/utils/random-number-generator.h" -#include "src/bootstrapper.h" -#include "src/counters.h" -#include "src/double.h" -#include "src/objects-inl.h" - -namespace v8 { -namespace internal { - -RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) { - HandleScope scope(isolate); - DCHECK_EQ(0, args.length()); - - Handle<Context> native_context = isolate->native_context(); - DCHECK_EQ(0, native_context->math_random_index()->value()); - - static const int kCacheSize = 64; - static const int kState0Offset = kCacheSize - 1; - static const int kState1Offset = kState0Offset - 1; - // The index is decremented before used to access the cache. - static const int kInitialIndex = kState1Offset; - - Handle<FixedDoubleArray> cache; - uint64_t state0 = 0; - uint64_t state1 = 0; - if (native_context->math_random_cache()->IsFixedDoubleArray()) { - cache = Handle<FixedDoubleArray>( - FixedDoubleArray::cast(native_context->math_random_cache()), isolate); - state0 = double_to_uint64(cache->get_scalar(kState0Offset)); - state1 = double_to_uint64(cache->get_scalar(kState1Offset)); - } else { - cache = Handle<FixedDoubleArray>::cast( - isolate->factory()->NewFixedDoubleArray(kCacheSize, TENURED)); - native_context->set_math_random_cache(*cache); - // Initialize state if not yet initialized. If a fixed random seed was - // requested, use it to reset our state the first time a script asks for - // random numbers in this context. This ensures the script sees a consistent - // sequence. - if (FLAG_random_seed != 0) { - state0 = FLAG_random_seed; - state1 = FLAG_random_seed; - } else { - while (state0 == 0 || state1 == 0) { - isolate->random_number_generator()->NextBytes(&state0, sizeof(state0)); - isolate->random_number_generator()->NextBytes(&state1, sizeof(state1)); - } - } - } - - DisallowHeapAllocation no_gc; - FixedDoubleArray* raw_cache = *cache; - // Create random numbers. - for (int i = 0; i < kInitialIndex; i++) { - // Generate random numbers using xorshift128+. - base::RandomNumberGenerator::XorShift128(&state0, &state1); - raw_cache->set(i, base::RandomNumberGenerator::ToDouble(state0, state1)); - } - - // Persist current state. - raw_cache->set(kState0Offset, uint64_to_double(state0)); - raw_cache->set(kState1Offset, uint64_to_double(state1)); - return Smi::FromInt(kInitialIndex); -} -} // namespace internal -} // namespace v8 diff --git a/deps/v8/src/runtime/runtime-numbers.cc b/deps/v8/src/runtime/runtime-numbers.cc index 14b91c8f1b..a8f62099a4 100644 --- a/deps/v8/src/runtime/runtime-numbers.cc +++ b/deps/v8/src/runtime/runtime-numbers.cc @@ -82,80 +82,16 @@ RUNTIME_FUNCTION(Runtime_NumberToString) { // -1 if x < y // 0 if x == y // 1 if x > y +// TODO(szuend): Remove once the call-site in src/js/array.js is gone. RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); - CONVERT_SMI_ARG_CHECKED(x_value, 0); - CONVERT_SMI_ARG_CHECKED(y_value, 1); - - // If the integers are equal so are the string representations. - if (x_value == y_value) return Smi::FromInt(0); - - // If one of the integers is zero the normal integer order is the - // same as the lexicographic order of the string representations. - if (x_value == 0 || y_value == 0) - return Smi::FromInt(x_value < y_value ? -1 : 1); - - // If only one of the integers is negative the negative number is - // smallest because the char code of '-' is less than the char code - // of any digit. Otherwise, we make both values positive. - - // Use unsigned values otherwise the logic is incorrect for -MIN_INT on - // architectures using 32-bit Smis. - uint32_t x_scaled = x_value; - uint32_t y_scaled = y_value; - if (x_value < 0 || y_value < 0) { - if (y_value >= 0) return Smi::FromInt(-1); - if (x_value >= 0) return Smi::FromInt(1); - x_scaled = -x_value; - y_scaled = -y_value; - } - - static const uint32_t kPowersOf10[] = { - 1, 10, 100, 1000, - 10 * 1000, 100 * 1000, 1000 * 1000, 10 * 1000 * 1000, - 100 * 1000 * 1000, 1000 * 1000 * 1000}; - - // If the integers have the same number of decimal digits they can be - // compared directly as the numeric order is the same as the - // lexicographic order. If one integer has fewer digits, it is scaled - // by some power of 10 to have the same number of digits as the longer - // integer. If the scaled integers are equal it means the shorter - // integer comes first in the lexicographic order. - - // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - int x_log2 = 31 - base::bits::CountLeadingZeros(x_scaled); - int x_log10 = ((x_log2 + 1) * 1233) >> 12; - x_log10 -= x_scaled < kPowersOf10[x_log10]; - - int y_log2 = 31 - base::bits::CountLeadingZeros(y_scaled); - int y_log10 = ((y_log2 + 1) * 1233) >> 12; - y_log10 -= y_scaled < kPowersOf10[y_log10]; - - int tie = 0; - - if (x_log10 < y_log10) { - // X has fewer digits. We would like to simply scale up X but that - // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would - // be scaled up to 9_000_000_000. So we scale up by the next - // smallest power and scale down Y to drop one digit. It is OK to - // drop one digit from the longer integer since the final digit is - // past the length of the shorter integer. - x_scaled *= kPowersOf10[y_log10 - x_log10 - 1]; - y_scaled /= 10; - tie = -1; - } else if (y_log10 < x_log10) { - y_scaled *= kPowersOf10[x_log10 - y_log10 - 1]; - x_scaled /= 10; - tie = 1; - } + CONVERT_ARG_CHECKED(Smi, x_value, 0); + CONVERT_ARG_CHECKED(Smi, y_value, 1); - if (x_scaled < y_scaled) return Smi::FromInt(-1); - if (x_scaled > y_scaled) return Smi::FromInt(1); - return Smi::FromInt(tie); + return Smi::LexicographicCompare(isolate, x_value, y_value); } - RUNTIME_FUNCTION(Runtime_MaxSmi) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); @@ -184,6 +120,5 @@ RUNTIME_FUNCTION(Runtime_GetHoleNaNLower) { return *isolate->factory()->NewNumberFromUint(kHoleNanLower32); } - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc index 81478b0e1b..3778e0576c 100644 --- a/deps/v8/src/runtime/runtime-object.cc +++ b/deps/v8/src/runtime/runtime-object.cc @@ -49,95 +49,6 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, return result; } -static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate, - Handle<Object> receiver_obj, - Handle<Object> key_obj) { - // Fast cases for getting named properties of the receiver JSObject - // itself. - // - // The global proxy objects has to be excluded since LookupOwn on - // the global proxy object can return a valid result even though the - // global proxy object never has properties. This is the case - // because the global proxy object forwards everything to its hidden - // prototype including own lookups. - // - // Additionally, we need to make sure that we do not cache results - // for objects that require access checks. - - // Convert string-index keys to their number variant to avoid internalization - // below; and speed up subsequent conversion to index. - uint32_t index; - if (key_obj->IsString() && String::cast(*key_obj)->AsArrayIndex(&index)) { - key_obj = isolate->factory()->NewNumberFromUint(index); - } - if (receiver_obj->IsJSObject()) { - if (!receiver_obj->IsJSGlobalProxy() && - !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) { - Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); - Handle<Name> key = Handle<Name>::cast(key_obj); - key_obj = key = isolate->factory()->InternalizeName(key); - - DisallowHeapAllocation no_allocation; - if (receiver->IsJSGlobalObject()) { - // Attempt dictionary lookup. - GlobalDictionary* dictionary = - JSGlobalObject::cast(*receiver)->global_dictionary(); - int entry = dictionary->FindEntry(isolate, key); - if (entry != GlobalDictionary::kNotFound) { - PropertyCell* cell = dictionary->CellAt(entry); - if (cell->property_details().kind() == kData) { - Object* value = cell->value(); - if (!value->IsTheHole(isolate)) { - return Handle<Object>(value, isolate); - } - // If value is the hole (meaning, absent) do the general lookup. - } - } - } else if (!receiver->HasFastProperties()) { - // Attempt dictionary lookup. - NameDictionary* dictionary = receiver->property_dictionary(); - int entry = dictionary->FindEntry(isolate, key); - if ((entry != NameDictionary::kNotFound) && - (dictionary->DetailsAt(entry).kind() == kData)) { - Object* value = dictionary->ValueAt(entry); - return Handle<Object>(value, isolate); - } - } - } else if (key_obj->IsSmi()) { - // JSObject without a name key. If the key is a Smi, check for a - // definite out-of-bounds access to elements, which is a strong indicator - // that subsequent accesses will also call the runtime. Proactively - // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of - // doubles for those future calls in the case that the elements would - // become PACKED_DOUBLE_ELEMENTS. - Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj); - ElementsKind elements_kind = js_object->GetElementsKind(); - if (IsDoubleElementsKind(elements_kind)) { - if (Smi::ToInt(*key_obj) >= js_object->elements()->length()) { - elements_kind = IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS - : PACKED_ELEMENTS; - JSObject::TransitionElementsKind(js_object, elements_kind); - } - } else { - DCHECK(IsSmiOrObjectElementsKind(elements_kind) || - !IsFastElementsKind(elements_kind)); - } - } - } else if (receiver_obj->IsString() && key_obj->IsSmi()) { - // Fast case for string indexing using [] with a smi index. - Handle<String> str = Handle<String>::cast(receiver_obj); - int index = Handle<Smi>::cast(key_obj)->value(); - if (index >= 0 && index < str->length()) { - Factory* factory = isolate->factory(); - return factory->LookupSingleCharacterStringFromCode( - String::Flatten(isolate, str)->Get(index)); - } - } - - // Fall back to GetObjectProperty. - return Runtime::GetObjectProperty(isolate, receiver_obj, key_obj); -} - namespace { bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver, @@ -431,7 +342,8 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate, Handle<Object> object, Handle<Object> key, Handle<Object> value, - LanguageMode language_mode) { + LanguageMode language_mode, + StoreOrigin store_origin) { if (object->IsNullOrUndefined(isolate)) { THROW_NEW_ERROR( isolate, @@ -453,17 +365,10 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate, Object); } - MAYBE_RETURN_NULL(Object::SetProperty(&it, value, language_mode, - Object::MAY_BE_STORE_FROM_KEYED)); - return value; -} - + MAYBE_RETURN_NULL( + Object::SetProperty(&it, value, language_mode, store_origin)); -RUNTIME_FUNCTION(Runtime_GetPrototype) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); - RETURN_RESULT_OR_FAILURE(isolate, JSReceiver::GetPrototype(isolate, obj)); + return value; } @@ -561,24 +466,91 @@ RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath) { RUNTIME_FUNCTION(Runtime_GetProperty) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); - - RETURN_RESULT_OR_FAILURE(isolate, - Runtime::GetObjectProperty(isolate, object, key)); -} + // Fast cases for getting named properties of the receiver JSObject + // itself. + // + // The global proxy objects has to be excluded since LookupOwn on + // the global proxy object can return a valid result even though the + // global proxy object never has properties. This is the case + // because the global proxy object forwards everything to its hidden + // prototype including own lookups. + // + // Additionally, we need to make sure that we do not cache results + // for objects that require access checks. -// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric. -RUNTIME_FUNCTION(Runtime_KeyedGetProperty) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); + // Convert string-index keys to their number variant to avoid internalization + // below; and speed up subsequent conversion to index. + uint32_t index; + if (key_obj->IsString() && String::cast(*key_obj)->AsArrayIndex(&index)) { + key_obj = isolate->factory()->NewNumberFromUint(index); + } + if (receiver_obj->IsJSObject()) { + if (!receiver_obj->IsJSGlobalProxy() && + !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) { + Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); + Handle<Name> key = Handle<Name>::cast(key_obj); + key_obj = key = isolate->factory()->InternalizeName(key); - CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1); + DisallowHeapAllocation no_allocation; + if (receiver->IsJSGlobalObject()) { + // Attempt dictionary lookup. + GlobalDictionary* dictionary = + JSGlobalObject::cast(*receiver)->global_dictionary(); + int entry = dictionary->FindEntry(isolate, key); + if (entry != GlobalDictionary::kNotFound) { + PropertyCell* cell = dictionary->CellAt(entry); + if (cell->property_details().kind() == kData) { + Object* value = cell->value(); + if (!value->IsTheHole(isolate)) return value; + // If value is the hole (meaning, absent) do the general lookup. + } + } + } else if (!receiver->HasFastProperties()) { + // Attempt dictionary lookup. + NameDictionary* dictionary = receiver->property_dictionary(); + int entry = dictionary->FindEntry(isolate, key); + if ((entry != NameDictionary::kNotFound) && + (dictionary->DetailsAt(entry).kind() == kData)) { + return dictionary->ValueAt(entry); + } + } + } else if (key_obj->IsSmi()) { + // JSObject without a name key. If the key is a Smi, check for a + // definite out-of-bounds access to elements, which is a strong indicator + // that subsequent accesses will also call the runtime. Proactively + // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of + // doubles for those future calls in the case that the elements would + // become PACKED_DOUBLE_ELEMENTS. + Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj); + ElementsKind elements_kind = js_object->GetElementsKind(); + if (IsDoubleElementsKind(elements_kind)) { + if (Smi::ToInt(*key_obj) >= js_object->elements()->length()) { + elements_kind = IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS + : PACKED_ELEMENTS; + JSObject::TransitionElementsKind(js_object, elements_kind); + } + } else { + DCHECK(IsSmiOrObjectElementsKind(elements_kind) || + !IsFastElementsKind(elements_kind)); + } + } + } else if (receiver_obj->IsString() && key_obj->IsSmi()) { + // Fast case for string indexing using [] with a smi index. + Handle<String> str = Handle<String>::cast(receiver_obj); + int index = Handle<Smi>::cast(key_obj)->value(); + if (index >= 0 && index < str->length()) { + Factory* factory = isolate->factory(); + return *factory->LookupSingleCharacterStringFromCode( + String::Flatten(isolate, str)->Get(index)); + } + } + // Fall back to GetObjectProperty. RETURN_RESULT_OR_FAILURE( - isolate, KeyedGetObjectProperty(isolate, receiver_obj, key_obj)); + isolate, Runtime::GetObjectProperty(isolate, receiver_obj, key_obj)); } RUNTIME_FUNCTION(Runtime_AddNamedProperty) { @@ -634,8 +606,7 @@ RUNTIME_FUNCTION(Runtime_AddElement) { object, index, value, NONE)); } - -RUNTIME_FUNCTION(Runtime_SetProperty) { +RUNTIME_FUNCTION(Runtime_SetKeyedProperty) { HandleScope scope(isolate); DCHECK_EQ(4, args.length()); @@ -646,9 +617,48 @@ RUNTIME_FUNCTION(Runtime_SetProperty) { RETURN_RESULT_OR_FAILURE( isolate, - Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); + Runtime::SetObjectProperty(isolate, object, key, value, language_mode, + StoreOrigin::kMaybeKeyed)); +} + +RUNTIME_FUNCTION(Runtime_SetNamedProperty) { + HandleScope scope(isolate); + DCHECK_EQ(4, args.length()); + + CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); + CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3); + + RETURN_RESULT_OR_FAILURE( + isolate, Runtime::SetObjectProperty(isolate, object, key, value, + language_mode, StoreOrigin::kNamed)); } +// Similar to DefineDataPropertyInLiteral, but does not update feedback, and +// and does not have a flags parameter for performing SetFunctionName(). +// +// Currently, this is used for ObjectLiteral spread properties. +RUNTIME_FUNCTION(Runtime_StoreDataPropertyInLiteral) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); + + bool success; + LookupIterator it = LookupIterator::PropertyOrElement( + isolate, object, key, &success, LookupIterator::OWN); + + Maybe<bool> result = + JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE, kDontThrow); + RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); + DCHECK(result.IsJust()); + USE(result); + + return *value; +} namespace { @@ -755,7 +765,9 @@ RUNTIME_FUNCTION(Runtime_NewObject) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1); - RETURN_RESULT_OR_FAILURE(isolate, JSObject::New(target, new_target)); + RETURN_RESULT_OR_FAILURE( + isolate, + JSObject::New(target, new_target, Handle<AllocationSite>::null())); } RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) { @@ -905,15 +917,6 @@ RUNTIME_FUNCTION(Runtime_HasFastPackedElements) { } -RUNTIME_FUNCTION(Runtime_ValueOf) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, obj, 0); - if (!obj->IsJSValue()) return obj; - return JSValue::cast(obj)->value(); -} - - RUNTIME_FUNCTION(Runtime_IsJSReceiver) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); @@ -1114,22 +1117,6 @@ RUNTIME_FUNCTION(Runtime_ToObject) { UNREACHABLE(); } -RUNTIME_FUNCTION(Runtime_ToPrimitive) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); - RETURN_RESULT_OR_FAILURE(isolate, Object::ToPrimitive(input)); -} - - -RUNTIME_FUNCTION(Runtime_ToPrimitive_Number) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); - RETURN_RESULT_OR_FAILURE( - isolate, Object::ToPrimitive(input, ToPrimitiveHint::kNumber)); -} - RUNTIME_FUNCTION(Runtime_ToNumber) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -1144,13 +1131,6 @@ RUNTIME_FUNCTION(Runtime_ToNumeric) { RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumeric(isolate, input)); } -RUNTIME_FUNCTION(Runtime_ToInteger) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); - RETURN_RESULT_OR_FAILURE(isolate, Object::ToInteger(isolate, input)); -} - RUNTIME_FUNCTION(Runtime_ToLength) { HandleScope scope(isolate); @@ -1175,24 +1155,6 @@ RUNTIME_FUNCTION(Runtime_ToName) { RETURN_RESULT_OR_FAILURE(isolate, Object::ToName(isolate, input)); } - -RUNTIME_FUNCTION(Runtime_SameValue) { - SealHandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_CHECKED(Object, x, 0); - CONVERT_ARG_CHECKED(Object, y, 1); - return isolate->heap()->ToBoolean(x->SameValue(y)); -} - - -RUNTIME_FUNCTION(Runtime_SameValueZero) { - SealHandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_CHECKED(Object, x, 0); - CONVERT_ARG_CHECKED(Object, y, 1); - return isolate->heap()->ToBoolean(x->SameValueZero(y)); -} - RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -1264,7 +1226,7 @@ RUNTIME_FUNCTION(Runtime_AddPrivateField) { } CHECK(Object::AddDataProperty(&it, value, NONE, kDontThrow, - Object::MAY_BE_STORE_FROM_KEYED) + StoreOrigin::kMaybeKeyed) .FromJust()); return ReadOnlyRoots(isolate).undefined_value(); } diff --git a/deps/v8/src/runtime/runtime-proxy.cc b/deps/v8/src/runtime/runtime-proxy.cc index 7eeee631be..69b7c9795c 100644 --- a/deps/v8/src/runtime/runtime-proxy.cc +++ b/deps/v8/src/runtime/runtime-proxy.cc @@ -77,8 +77,8 @@ RUNTIME_FUNCTION(Runtime_SetPropertyWithReceiver) { DCHECK(isolate->has_pending_exception()); return ReadOnlyRoots(isolate).exception(); } - Maybe<bool> result = Object::SetSuperProperty( - &it, value, language_mode, Object::MAY_BE_STORE_FROM_KEYED); + Maybe<bool> result = Object::SetSuperProperty(&it, value, language_mode, + StoreOrigin::kMaybeKeyed); MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception()); return *isolate->factory()->ToBoolean(result.FromJust()); } diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc index 3e77bf1f3b..e66319bfb5 100644 --- a/deps/v8/src/runtime/runtime-regexp.cc +++ b/deps/v8/src/runtime/runtime-regexp.cc @@ -38,7 +38,7 @@ uint32_t GetArgcForReplaceCallable(uint32_t num_captures, // Looks up the capture of the given name. Returns the (1-based) numbered // capture index or -1 on failure. -int LookupNamedCapture(std::function<bool(String*)> name_matches, +int LookupNamedCapture(const std::function<bool(String*)>& name_matches, FixedArray* capture_name_map) { // TODO(jgruber): Sort capture_name_map and do binary search via // internalized strings. @@ -1097,7 +1097,7 @@ class VectorBackedMatch : public String::Match { // RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo). Handle<JSObject> ConstructNamedCaptureGroupsObject( Isolate* isolate, Handle<FixedArray> capture_map, - std::function<Object*(int)> f_get_capture) { + const std::function<Object*(int)>& f_get_capture) { Handle<JSObject> groups = isolate->factory()->NewJSObjectWithNullProto(); const int capture_count = capture_map->length() >> 1; diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc index 4772f400b3..7a24b066c1 100644 --- a/deps/v8/src/runtime/runtime-scopes.cc +++ b/deps/v8/src/runtime/runtime-scopes.cc @@ -158,8 +158,8 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, FeedbackSlot feedback_cells_slot( Smi::ToInt(*possibly_feedback_cell_slot)); Handle<FeedbackCell> feedback_cell( - FeedbackCell::cast( - feedback_vector->Get(feedback_cells_slot)->ToStrongHeapObject()), + FeedbackCell::cast(feedback_vector->Get(feedback_cells_slot) + ->GetHeapObjectAssumeStrong()), isolate); Handle<JSFunction> function = isolate->factory()->NewFunctionFromSharedFunctionInfo( @@ -461,8 +461,7 @@ Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, return result; } - -class HandleArguments BASE_EMBEDDED { +class HandleArguments { public: explicit HandleArguments(Handle<Object>* array) : array_(array) {} Object* operator[](int index) { return *array_[index]; } @@ -471,8 +470,7 @@ class HandleArguments BASE_EMBEDDED { Handle<Object>* array_; }; - -class ParameterArguments BASE_EMBEDDED { +class ParameterArguments { public: explicit ParameterArguments(Object** parameters) : parameters_(parameters) {} Object*& operator[](int index) { return *(parameters_ - index - 1); } @@ -803,6 +801,8 @@ MaybeHandle<Object> LoadLookupSlot(Isolate* isolate, Handle<String> name, if (isolate->has_pending_exception()) return MaybeHandle<Object>(); if (!holder.is_null() && holder->IsModule()) { + Handle<Object> receiver = isolate->factory()->undefined_value(); + if (receiver_return) *receiver_return = receiver; return Module::LoadVariable(isolate, Handle<Module>::cast(holder), index); } if (index != Context::kNotFound) { diff --git a/deps/v8/src/runtime/runtime-strings.cc b/deps/v8/src/runtime/runtime-strings.cc index f6537fd073..d57959687c 100644 --- a/deps/v8/src/runtime/runtime-strings.cc +++ b/deps/v8/src/runtime/runtime-strings.cc @@ -581,7 +581,8 @@ static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars, elements->set(i, value, mode); } if (i < length) { - static_assert(Smi::kZero == 0, "Can use memset since Smi::kZero is 0"); + static_assert(Smi::kZero == nullptr, + "Can use memset since Smi::kZero is 0"); memset(elements->data_start() + i, 0, kPointerSize * (length - i)); } #ifdef DEBUG @@ -693,14 +694,6 @@ RUNTIME_FUNCTION(Runtime_StringEqual) { return isolate->heap()->ToBoolean(String::Equals(isolate, x, y)); } -RUNTIME_FUNCTION(Runtime_StringNotEqual) { - HandleScope handle_scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(String, x, 0); - CONVERT_ARG_HANDLE_CHECKED(String, y, 1); - return isolate->heap()->ToBoolean(!String::Equals(isolate, x, y)); -} - RUNTIME_FUNCTION(Runtime_FlattenString) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -708,17 +701,6 @@ RUNTIME_FUNCTION(Runtime_FlattenString) { return *String::Flatten(isolate, str); } -RUNTIME_FUNCTION(Runtime_StringCharFromCode) { - HandleScope handlescope(isolate); - DCHECK_EQ(1, args.length()); - if (args[0]->IsNumber()) { - CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]); - code &= 0xFFFF; - return *isolate->factory()->LookupSingleCharacterStringFromCode(code); - } - return ReadOnlyRoots(isolate).empty_string(); -} - RUNTIME_FUNCTION(Runtime_StringMaxLength) { SealHandleScope shs(isolate); return Smi::FromInt(String::kMaxLength); diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc index 94376e1364..bcc36e9d87 100644 --- a/deps/v8/src/runtime/runtime-test.cc +++ b/deps/v8/src/runtime/runtime-test.cc @@ -10,6 +10,7 @@ #include "src/api-inl.h" #include "src/arguments-inl.h" #include "src/assembler-inl.h" +#include "src/base/platform/mutex.h" #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" #include "src/compiler.h" #include "src/deoptimizer.h" @@ -25,6 +26,9 @@ #include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-serialization.h" +namespace v8 { +namespace internal { + namespace { struct WasmCompileControls { uint32_t MaxWasmBufferSize = std::numeric_limits<uint32_t>::max(); @@ -32,14 +36,16 @@ struct WasmCompileControls { }; // We need per-isolate controls, because we sometimes run tests in multiple -// isolates -// concurrently. +// isolates concurrently. Methods need to hold the accompanying mutex on access. // To avoid upsetting the static initializer count, we lazy initialize this. -v8::base::LazyInstance<std::map<v8::Isolate*, WasmCompileControls>>::type +base::LazyInstance<std::map<v8::Isolate*, WasmCompileControls>>::type g_PerIsolateWasmControls = LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<base::Mutex>::type g_PerIsolateWasmControlsMutex = + LAZY_INSTANCE_INITIALIZER; bool IsWasmCompileAllowed(v8::Isolate* isolate, v8::Local<v8::Value> value, bool is_async) { + base::LockGuard<base::Mutex> guard(g_PerIsolateWasmControlsMutex.Pointer()); DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0); const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate); return (is_async && ctrls.AllowAnySizeForAsync) || @@ -52,6 +58,7 @@ bool IsWasmCompileAllowed(v8::Isolate* isolate, v8::Local<v8::Value> value, bool IsWasmInstantiateAllowed(v8::Isolate* isolate, v8::Local<v8::Value> module_or_bytes, bool is_async) { + base::LockGuard<base::Mutex> guard(g_PerIsolateWasmControlsMutex.Pointer()); DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0); const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate); if (is_async && ctrls.AllowAnySizeForAsync) return true; @@ -91,9 +98,6 @@ bool WasmInstanceOverride(const v8::FunctionCallbackInfo<v8::Value>& args) { } // namespace -namespace v8 { -namespace internal { - RUNTIME_FUNCTION(Runtime_ConstructDouble) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -477,6 +481,7 @@ RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) { CHECK_EQ(args.length(), 2); CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0); CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1); + base::LockGuard<base::Mutex> guard(g_PerIsolateWasmControlsMutex.Pointer()); WasmCompileControls& ctrl = (*g_PerIsolateWasmControls.Pointer())[v8_isolate]; ctrl.AllowAnySizeForAsync = allow_async; ctrl.MaxWasmBufferSize = static_cast<uint32_t>(block_size->value()); @@ -533,17 +538,18 @@ RUNTIME_FUNCTION(Runtime_DebugPrint) { MaybeObject* maybe_object = reinterpret_cast<MaybeObject*>(args[0]); StdoutStream os; - if (maybe_object->IsClearedWeakHeapObject()) { + if (maybe_object->IsCleared()) { os << "[weak cleared]"; } else { Object* object; + HeapObject* heap_object; bool weak = false; - if (maybe_object->IsWeakHeapObject()) { + if (maybe_object->GetHeapObjectIfWeak(&heap_object)) { weak = true; - object = maybe_object->ToWeakHeapObject(); + object = heap_object; } else { // Strong reference or SMI. - object = maybe_object->ToObject(); + object = maybe_object->cast<Object>(); } #ifdef DEBUG @@ -830,12 +836,39 @@ RUNTIME_FUNCTION(Runtime_IsWasmTrapHandlerEnabled) { } RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) { - HandleScope shs(isolate); + HandleScope scope(isolate); DCHECK_EQ(0, args.length()); size_t trap_count = trap_handler::GetRecoveredTrapCount(); return *isolate->factory()->NewNumberFromSize(trap_count); } +RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 1); + Handle<Object> tag; + if (JSReceiver::GetProperty(isolate, exception, + isolate->factory()->wasm_exception_tag_symbol()) + .ToHandle(&tag)) { + Handle<FixedArray> exceptions_table(instance->exceptions_table(), isolate); + for (int index = 0; index < exceptions_table->length(); ++index) { + if (exceptions_table->get(index) == *tag) return Smi::FromInt(index); + } + } + return ReadOnlyRoots(isolate).undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0); + RETURN_RESULT_OR_FAILURE( + isolate, JSReceiver::GetProperty( + isolate, exception, + isolate->factory()->wasm_exception_values_symbol())); +} + namespace { bool EnableWasmThreads(v8::Local<v8::Context> context) { return true; } @@ -902,6 +935,13 @@ RUNTIME_FUNCTION(Runtime_PromiseSpeciesProtector) { isolate->IsPromiseSpeciesLookupChainIntact()); } +RUNTIME_FUNCTION(Runtime_StringIteratorProtector) { + SealHandleScope shs(isolate); + DCHECK_EQ(0, args.length()); + return isolate->heap()->ToBoolean( + isolate->IsStringIteratorLookupChainIntact()); +} + // Take a compiled wasm module and serialize it into an array buffer, which is // then returned. RUNTIME_FUNCTION(Runtime_SerializeWasmModule) { @@ -937,9 +977,9 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) { wasm::DeserializeNativeModule( isolate, {reinterpret_cast<uint8_t*>(buffer->backing_store()), - static_cast<size_t>(buffer->byte_length()->Number())}, + buffer->byte_length()}, {reinterpret_cast<uint8_t*>(wire_bytes->backing_store()), - static_cast<size_t>(wire_bytes->byte_length()->Number())}); + wire_bytes->byte_length()}); Handle<WasmModuleObject> module_object; if (!maybe_module_object.ToHandle(&module_object)) { return ReadOnlyRoots(isolate).undefined_value(); @@ -971,7 +1011,7 @@ RUNTIME_FUNCTION(Runtime_WasmGetNumberOfInstances) { int instance_count = 0; WeakArrayList* weak_instance_list = module_obj->weak_instance_list(); for (int i = 0; i < weak_instance_list->length(); ++i) { - if (weak_instance_list->Get(i)->IsWeakHeapObject()) instance_count++; + if (weak_instance_list->Get(i)->IsWeak()) instance_count++; } return Smi::FromInt(instance_count); } @@ -980,7 +1020,7 @@ RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) { DCHECK_EQ(1, args.length()); HandleScope scope(isolate); CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0); - if (!instance->has_debug_info()) return 0; + if (!instance->has_debug_info()) return nullptr; uint64_t num = instance->debug_info()->NumInterpretedCalls(); return *isolate->factory()->NewNumberFromSize(static_cast<size_t>(num)); } diff --git a/deps/v8/src/runtime/runtime-typedarray.cc b/deps/v8/src/runtime/runtime-typedarray.cc index c101219d2c..8a9d6fe366 100644 --- a/deps/v8/src/runtime/runtime-typedarray.cc +++ b/deps/v8/src/runtime/runtime-typedarray.cc @@ -30,14 +30,14 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) { return ReadOnlyRoots(isolate).undefined_value(); } if (array_buffer->backing_store() == nullptr) { - CHECK_EQ(Smi::kZero, array_buffer->byte_length()); + CHECK_EQ(0, array_buffer->byte_length()); return ReadOnlyRoots(isolate).undefined_value(); } // Shared array buffers should never be neutered. CHECK(!array_buffer->is_shared()); DCHECK(!array_buffer->is_external()); void* backing_store = array_buffer->backing_store(); - size_t byte_length = NumberToSize(array_buffer->byte_length()); + size_t byte_length = array_buffer->byte_length(); array_buffer->set_is_external(true); isolate->heap()->UnregisterArrayBuffer(*array_buffer); array_buffer->Neuter(); diff --git a/deps/v8/src/runtime/runtime-wasm.cc b/deps/v8/src/runtime/runtime-wasm.cc index 5a6c782292..f852df0d85 100644 --- a/deps/v8/src/runtime/runtime-wasm.cc +++ b/deps/v8/src/runtime/runtime-wasm.cc @@ -24,41 +24,28 @@ namespace internal { namespace { -WasmInstanceObject* GetWasmInstanceOnStackTop(Isolate* isolate) { +Context* GetNativeContextFromWasmInstanceOnStackTop(Isolate* isolate) { StackFrameIterator it(isolate, isolate->thread_local_top()); // On top: C entry stub. DCHECK_EQ(StackFrame::EXIT, it.frame()->type()); it.Advance(); - // Next: the wasm (compiled or interpreted) frame. - WasmInstanceObject* result = nullptr; - if (it.frame()->is_wasm_compiled()) { - result = WasmCompiledFrame::cast(it.frame())->wasm_instance(); - } else { - DCHECK(it.frame()->is_wasm_interpreter_entry()); - result = WasmInterpreterEntryFrame::cast(it.frame())->wasm_instance(); - } - return result; -} - -Context* GetNativeContextFromWasmInstanceOnStackTop(Isolate* isolate) { - return GetWasmInstanceOnStackTop(isolate)->native_context(); + // Next: the wasm compiled frame. + DCHECK(it.frame()->is_wasm_compiled()); + WasmCompiledFrame* frame = WasmCompiledFrame::cast(it.frame()); + return frame->wasm_instance()->native_context(); } class ClearThreadInWasmScope { public: - explicit ClearThreadInWasmScope(bool coming_from_wasm) - : coming_from_wasm_(coming_from_wasm) { - DCHECK_EQ(trap_handler::IsTrapHandlerEnabled() && coming_from_wasm, + ClearThreadInWasmScope() { + DCHECK_EQ(trap_handler::IsTrapHandlerEnabled(), trap_handler::IsThreadInWasm()); - if (coming_from_wasm) trap_handler::ClearThreadInWasm(); + trap_handler::ClearThreadInWasm(); } ~ClearThreadInWasmScope() { DCHECK(!trap_handler::IsThreadInWasm()); - if (coming_from_wasm_) trap_handler::SetThreadInWasm(); + trap_handler::SetThreadInWasm(); } - - private: - const bool coming_from_wasm_; }; } // namespace @@ -72,11 +59,7 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { CONVERT_UINT32_ARG_CHECKED(delta_pages, 1); // This runtime function is always being called from wasm code. - ClearThreadInWasmScope flag_scope(true); - - // Set the current isolate's context. - DCHECK_NULL(isolate->context()); - isolate->set_context(instance->native_context()); + ClearThreadInWasmScope flag_scope; int ret = WasmMemoryObject::Grow( isolate, handle(instance->memory_object(), isolate), delta_pages); @@ -88,11 +71,9 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { RUNTIME_FUNCTION(Runtime_ThrowWasmError) { DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(message_id, 0); - ClearThreadInWasmScope clear_wasm_flag(isolate->context() == nullptr); + ClearThreadInWasmScope clear_wasm_flag; HandleScope scope(isolate); - DCHECK_NULL(isolate->context()); - isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate)); Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError( static_cast<MessageTemplate::Template>(message_id)); return isolate->Throw(*error_obj); @@ -116,81 +97,73 @@ RUNTIME_FUNCTION(Runtime_WasmThrowTypeError) { RUNTIME_FUNCTION(Runtime_WasmThrowCreate) { // TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls. HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); DCHECK_NULL(isolate->context()); isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate)); - DCHECK_EQ(2, args.length()); + CONVERT_ARG_CHECKED(HeapObject, tag_raw, 0); + CONVERT_SMI_ARG_CHECKED(size, 1); + // TODO(mstarzinger): Manually box because parameters are not visited yet. + Handle<Object> tag(tag_raw, isolate); Handle<Object> exception = isolate->factory()->NewWasmRuntimeError( static_cast<MessageTemplate::Template>( MessageTemplate::kWasmExceptionError)); - isolate->set_wasm_caught_exception(*exception); - CONVERT_ARG_HANDLE_CHECKED(Smi, id, 0); - CHECK(!JSReceiver::SetProperty(isolate, exception, - isolate->factory()->InternalizeUtf8String( - wasm::WasmException::kRuntimeIdStr), - id, LanguageMode::kStrict) - .is_null()); - CONVERT_SMI_ARG_CHECKED(size, 1); + CHECK( + !JSReceiver::SetProperty(isolate, exception, + isolate->factory()->wasm_exception_tag_symbol(), + tag, LanguageMode::kStrict) + .is_null()); Handle<JSTypedArray> values = isolate->factory()->NewJSTypedArray(ElementsKind::UINT16_ELEMENTS, size); - CHECK(!JSReceiver::SetProperty(isolate, exception, - isolate->factory()->InternalizeUtf8String( - wasm::WasmException::kRuntimeValuesStr), - values, LanguageMode::kStrict) + CHECK(!JSReceiver::SetProperty( + isolate, exception, + isolate->factory()->wasm_exception_values_symbol(), values, + LanguageMode::kStrict) .is_null()); - return ReadOnlyRoots(isolate).undefined_value(); + return *exception; } -RUNTIME_FUNCTION(Runtime_WasmThrow) { - // TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls. - HandleScope scope(isolate); - DCHECK_NULL(isolate->context()); - isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate)); - DCHECK_EQ(0, args.length()); - Handle<Object> exception(isolate->get_wasm_caught_exception(), isolate); - CHECK(!exception.is_null()); - isolate->clear_wasm_caught_exception(); - return isolate->Throw(*exception); -} - -RUNTIME_FUNCTION(Runtime_WasmGetExceptionRuntimeId) { +RUNTIME_FUNCTION(Runtime_WasmExceptionGetTag) { // TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls. HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); DCHECK_NULL(isolate->context()); isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate)); - Handle<Object> except_obj(isolate->get_wasm_caught_exception(), isolate); + CONVERT_ARG_CHECKED(Object, except_obj_raw, 0); + // TODO(mstarzinger): Manually box because parameters are not visited yet. + Handle<Object> except_obj(except_obj_raw, isolate); if (!except_obj.is_null() && except_obj->IsJSReceiver()) { Handle<JSReceiver> exception(JSReceiver::cast(*except_obj), isolate); Handle<Object> tag; if (JSReceiver::GetProperty(isolate, exception, - isolate->factory()->InternalizeUtf8String( - wasm::WasmException::kRuntimeIdStr)) + isolate->factory()->wasm_exception_tag_symbol()) .ToHandle(&tag)) { - if (tag->IsSmi()) { - return *tag; - } + return *tag; } } - return Smi::FromInt(wasm::kInvalidExceptionTag); + return ReadOnlyRoots(isolate).undefined_value(); } RUNTIME_FUNCTION(Runtime_WasmExceptionGetElement) { // TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls. HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); DCHECK_NULL(isolate->context()); isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate)); - DCHECK_EQ(1, args.length()); - Handle<Object> except_obj(isolate->get_wasm_caught_exception(), isolate); + CONVERT_ARG_CHECKED(Object, except_obj_raw, 0); + // TODO(mstarzinger): Manually box because parameters are not visited yet. + Handle<Object> except_obj(except_obj_raw, isolate); if (!except_obj.is_null() && except_obj->IsJSReceiver()) { Handle<JSReceiver> exception(JSReceiver::cast(*except_obj), isolate); Handle<Object> values_obj; - if (JSReceiver::GetProperty(isolate, exception, - isolate->factory()->InternalizeUtf8String( - wasm::WasmException::kRuntimeValuesStr)) + if (JSReceiver::GetProperty( + isolate, exception, + isolate->factory()->wasm_exception_values_symbol()) .ToHandle(&values_obj)) { if (values_obj->IsJSTypedArray()) { Handle<JSTypedArray> values = Handle<JSTypedArray>::cast(values_obj); CHECK_EQ(values->type(), kExternalUint16Array); - CONVERT_SMI_ARG_CHECKED(index, 0); + CONVERT_SMI_ARG_CHECKED(index, 1); + CHECK(!values->WasNeutered()); CHECK_LT(index, Smi::ToInt(values->length())); auto* vals = reinterpret_cast<uint16_t*>(values->GetBuffer()->backing_store()); @@ -204,23 +177,26 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetElement) { RUNTIME_FUNCTION(Runtime_WasmExceptionSetElement) { // TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls. HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); + DCHECK_EQ(3, args.length()); DCHECK_NULL(isolate->context()); isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate)); - Handle<Object> except_obj(isolate->get_wasm_caught_exception(), isolate); + CONVERT_ARG_CHECKED(Object, except_obj_raw, 0); + // TODO(mstarzinger): Manually box because parameters are not visited yet. + Handle<Object> except_obj(except_obj_raw, isolate); if (!except_obj.is_null() && except_obj->IsJSReceiver()) { Handle<JSReceiver> exception(JSReceiver::cast(*except_obj), isolate); Handle<Object> values_obj; - if (JSReceiver::GetProperty(isolate, exception, - isolate->factory()->InternalizeUtf8String( - wasm::WasmException::kRuntimeValuesStr)) + if (JSReceiver::GetProperty( + isolate, exception, + isolate->factory()->wasm_exception_values_symbol()) .ToHandle(&values_obj)) { if (values_obj->IsJSTypedArray()) { Handle<JSTypedArray> values = Handle<JSTypedArray>::cast(values_obj); CHECK_EQ(values->type(), kExternalUint16Array); - CONVERT_SMI_ARG_CHECKED(index, 0); + CONVERT_SMI_ARG_CHECKED(index, 1); + CHECK(!values->WasNeutered()); CHECK_LT(index, Smi::ToInt(values->length())); - CONVERT_SMI_ARG_CHECKED(value, 1); + CONVERT_SMI_ARG_CHECKED(value, 2); auto* vals = reinterpret_cast<uint16_t*>(values->GetBuffer()->backing_store()); vals[index] = static_cast<uint16_t>(value); @@ -235,8 +211,6 @@ RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { HandleScope scope(isolate); CONVERT_NUMBER_CHECKED(int32_t, func_index, Int32, args[0]); CONVERT_ARG_HANDLE_CHECKED(Object, arg_buffer_obj, 1); - Handle<WasmInstanceObject> instance(GetWasmInstanceOnStackTop(isolate), - isolate); // The arg buffer is the raw pointer to the caller's stack. It looks like a // Smi (lowest bit not set, as checked by IsSmi), but is no valid Smi. We just @@ -245,13 +219,10 @@ RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { CHECK(arg_buffer_obj->IsSmi()); Address arg_buffer = reinterpret_cast<Address>(*arg_buffer_obj); - ClearThreadInWasmScope wasm_flag(true); - - // Set the current isolate's context. - DCHECK_NULL(isolate->context()); - isolate->set_context(instance->native_context()); + ClearThreadInWasmScope wasm_flag; - // Find the frame pointer of the interpreter entry. + // Find the frame pointer and instance of the interpreter frame on the stack. + Handle<WasmInstanceObject> instance; Address frame_pointer = 0; { StackFrameIterator it(isolate, isolate->thread_local_top()); @@ -260,9 +231,15 @@ RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { it.Advance(); // Next: the wasm interpreter entry. DCHECK_EQ(StackFrame::WASM_INTERPRETER_ENTRY, it.frame()->type()); + instance = handle( + WasmInterpreterEntryFrame::cast(it.frame())->wasm_instance(), isolate); frame_pointer = it.frame()->fp(); } + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(instance->native_context()); + // Run the function in the interpreter. Note that neither the {WasmDebugInfo} // nor the {InterpreterHandle} have to exist, because interpretation might // have been triggered by another Isolate sharing the same WasmEngine. @@ -284,11 +261,7 @@ RUNTIME_FUNCTION(Runtime_WasmStackGuard) { DCHECK(!trap_handler::IsTrapHandlerEnabled() || trap_handler::IsThreadInWasm()); - ClearThreadInWasmScope wasm_flag(true); - - // Set the current isolate's context. - DCHECK_NULL(isolate->context()); - isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate)); + ClearThreadInWasmScope wasm_flag; // Check if this is a real stack overflow. StackLimitCheck check(isolate); @@ -303,7 +276,7 @@ RUNTIME_FUNCTION(Runtime_WasmCompileLazy) { CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0); CONVERT_SMI_ARG_CHECKED(func_index, 1); - ClearThreadInWasmScope wasm_flag(true); + ClearThreadInWasmScope wasm_flag; #ifdef DEBUG StackFrameIterator it(isolate, isolate->thread_local_top()); diff --git a/deps/v8/src/runtime/runtime.cc b/deps/v8/src/runtime/runtime.cc index ec35131c90..d9d7d85664 100644 --- a/deps/v8/src/runtime/runtime.cc +++ b/deps/v8/src/runtime/runtime.cc @@ -45,9 +45,7 @@ FOR_EACH_INTRINSIC_RETURN_PAIR(P) , static const Runtime::Function kIntrinsicFunctions[] = { - FOR_EACH_INTRINSIC(F) - FOR_EACH_INTRINSIC(I) -}; + FOR_EACH_INTRINSIC(F) FOR_EACH_INLINE_INTRINSIC(I)}; #undef I #undef F @@ -98,6 +96,44 @@ void InitializeIntrinsicFunctionNames() { } // namespace +bool Runtime::NeedsExactContext(FunctionId id) { + switch (id) { + case Runtime::kAddPrivateField: + case Runtime::kCopyDataProperties: + case Runtime::kCreateDataProperty: + case Runtime::kCreatePrivateFieldSymbol: + case Runtime::kReThrow: + case Runtime::kThrow: + case Runtime::kThrowApplyNonFunction: + case Runtime::kThrowCalledNonCallable: + case Runtime::kThrowConstAssignError: + case Runtime::kThrowConstructorNonCallableError: + case Runtime::kThrowConstructedNonConstructable: + case Runtime::kThrowConstructorReturnedNonObject: + case Runtime::kThrowInvalidStringLength: + case Runtime::kThrowInvalidTypedArrayAlignment: + case Runtime::kThrowIteratorError: + case Runtime::kThrowIteratorResultNotAnObject: + case Runtime::kThrowNotConstructor: + case Runtime::kThrowRangeError: + case Runtime::kThrowReferenceError: + case Runtime::kThrowStackOverflow: + case Runtime::kThrowStaticPrototypeError: + case Runtime::kThrowSuperAlreadyCalledError: + case Runtime::kThrowSuperNotCalled: + case Runtime::kThrowSymbolAsyncIteratorInvalid: + case Runtime::kThrowSymbolIteratorInvalid: + case Runtime::kThrowThrowMethodMissing: + case Runtime::kThrowTypeError: + case Runtime::kThrowUnsupportedSuperError: + case Runtime::kThrowWasmError: + case Runtime::kThrowWasmStackOverflow: + return false; + default: + return true; + } +} + bool Runtime::IsNonReturning(FunctionId id) { switch (id) { case Runtime::kThrowUnsupportedSuperError: @@ -113,6 +149,7 @@ bool Runtime::IsNonReturning(FunctionId id) { case Runtime::kThrowConstructorReturnedNonObject: case Runtime::kThrowInvalidStringLength: case Runtime::kThrowInvalidTypedArrayAlignment: + case Runtime::kThrowIteratorError: case Runtime::kThrowIteratorResultNotAnObject: case Runtime::kThrowThrowMethodMissing: case Runtime::kThrowSymbolIteratorInvalid: diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h index 5a6364f644..f091d99092 100644 --- a/deps/v8/src/runtime/runtime.h +++ b/deps/v8/src/runtime/runtime.h @@ -17,10 +17,10 @@ namespace v8 { namespace internal { -// * Each intrinsic is consistently exposed in JavaScript via 2 names: +// * Each intrinsic is exposed in JavaScript via: // * %#name, which is always a runtime call. -// * %_#name, which can be inlined or just a runtime call, the compiler in -// question decides. +// * (optionally) %_#name, which can be inlined or just a runtime call, the +// compiler in question decides. // // * IntrinsicTypes are Runtime::RUNTIME and Runtime::INLINE, respectively. // @@ -31,53 +31,57 @@ namespace internal { // * Each compiler has an explicit list of intrisics it supports, falling back // to a simple runtime call if necessary. - // Entries have the form F(name, number of arguments, number of values): // A variable number of arguments is specified by a -1, additional restrictions -// are specified by inline comments - -#define FOR_EACH_INTRINSIC_ARRAY(F) \ - F(ArrayIncludes_Slow, 3, 1) \ - F(ArrayIndexOf, 3, 1) \ - F(ArrayIsArray, 1, 1) \ - F(ArraySpeciesConstructor, 1, 1) \ - F(EstimateNumberOfElements, 1, 1) \ - F(GetArrayKeys, 2, 1) \ - F(GrowArrayElements, 2, 1) \ - F(HasComplexElements, 1, 1) \ - F(IsArray, 1, 1) \ - F(MoveArrayContents, 2, 1) \ - F(NewArray, -1 /* >= 3 */, 1) \ - F(NormalizeElements, 1, 1) \ - F(PrepareElementsForSort, 2, 1) \ - F(TransitionElementsKind, 2, 1) \ +// are specified by inline comments. To declare only the runtime version (no +// inline), use the F macro below. To declare the runtime version and the inline +// version simultaneously, use the I macro below. + +#define FOR_EACH_INTRINSIC_ARRAY(F, I) \ + F(ArrayIncludes_Slow, 3, 1) \ + F(ArrayIndexOf, 3, 1) \ + F(ArrayIsArray, 1, 1) \ + F(ArraySpeciesConstructor, 1, 1) \ + F(EstimateNumberOfElements, 1, 1) \ + F(GetArrayKeys, 2, 1) \ + F(GrowArrayElements, 2, 1) \ + F(HasComplexElements, 1, 1) \ + I(IsArray, 1, 1) \ + F(MoveArrayContents, 2, 1) \ + F(NewArray, -1 /* >= 3 */, 1) \ + F(NormalizeElements, 1, 1) \ + F(PrepareElementsForSort, 2, 1) \ + F(TransitionElementsKind, 2, 1) \ + F(TransitionElementsKindWithKind, 2, 1) \ F(TrySliceSimpleNonFastElements, 3, 1) -#define FOR_EACH_INTRINSIC_ATOMICS(F) \ - F(AtomicsAdd, 3, 1) \ - F(AtomicsAnd, 3, 1) \ - F(AtomicsCompareExchange, 4, 1) \ - F(AtomicsExchange, 3, 1) \ - F(AtomicsNumWaitersForTesting, 2, 1) \ - F(AtomicsOr, 3, 1) \ - F(AtomicsSub, 3, 1) \ - F(AtomicsXor, 3, 1) \ +#define FOR_EACH_INTRINSIC_ATOMICS(F, I) \ + F(AtomicsLoad64, 2, 1) \ + F(AtomicsStore64, 3, 1) \ + F(AtomicsAdd, 3, 1) \ + F(AtomicsAnd, 3, 1) \ + F(AtomicsCompareExchange, 4, 1) \ + F(AtomicsExchange, 3, 1) \ + F(AtomicsNumWaitersForTesting, 2, 1) \ + F(AtomicsOr, 3, 1) \ + F(AtomicsSub, 3, 1) \ + F(AtomicsXor, 3, 1) \ F(SetAllowAtomicsWait, 1, 1) -#define FOR_EACH_INTRINSIC_BIGINT(F) \ - F(BigIntBinaryOp, 3, 1) \ - F(BigIntCompareToBigInt, 3, 1) \ - F(BigIntCompareToNumber, 3, 1) \ - F(BigIntCompareToString, 3, 1) \ - F(BigIntEqualToBigInt, 2, 1) \ - F(BigIntEqualToNumber, 2, 1) \ - F(BigIntEqualToString, 2, 1) \ - F(BigIntToBoolean, 1, 1) \ - F(BigIntToNumber, 1, 1) \ - F(BigIntUnaryOp, 2, 1) \ +#define FOR_EACH_INTRINSIC_BIGINT(F, I) \ + F(BigIntBinaryOp, 3, 1) \ + F(BigIntCompareToBigInt, 3, 1) \ + F(BigIntCompareToNumber, 3, 1) \ + F(BigIntCompareToString, 3, 1) \ + F(BigIntEqualToBigInt, 2, 1) \ + F(BigIntEqualToNumber, 2, 1) \ + F(BigIntEqualToString, 2, 1) \ + F(BigIntToBoolean, 1, 1) \ + F(BigIntToNumber, 1, 1) \ + F(BigIntUnaryOp, 2, 1) \ F(ToBigInt, 1, 1) -#define FOR_EACH_INTRINSIC_CLASSES(F) \ +#define FOR_EACH_INTRINSIC_CLASSES(F, I) \ F(DefineClass, -1 /* >= 3 */, 1) \ F(HomeObjectSymbol, 0, 1) \ F(LoadFromSuper, 3, 1) \ @@ -93,20 +97,16 @@ namespace internal { F(ThrowSuperNotCalled, 0, 1) \ F(ThrowUnsupportedSuperError, 0, 1) -#define FOR_EACH_INTRINSIC_COLLECTIONS(F) \ - F(GetWeakMapEntries, 2, 1) \ - F(GetWeakSetValues, 2, 1) \ - F(MapGrow, 1, 1) \ - F(MapIteratorClone, 1, 1) \ - F(MapShrink, 1, 1) \ - F(SetGrow, 1, 1) \ - F(SetIteratorClone, 1, 1) \ - F(SetShrink, 1, 1) \ - F(TheHole, 0, 1) \ - F(WeakCollectionDelete, 3, 1) \ +#define FOR_EACH_INTRINSIC_COLLECTIONS(F, I) \ + F(MapGrow, 1, 1) \ + F(MapShrink, 1, 1) \ + F(SetGrow, 1, 1) \ + F(SetShrink, 1, 1) \ + F(TheHole, 0, 1) \ + F(WeakCollectionDelete, 3, 1) \ F(WeakCollectionSet, 4, 1) -#define FOR_EACH_INTRINSIC_COMPILER(F) \ +#define FOR_EACH_INTRINSIC_COMPILER(F, I) \ F(CompileForOnStackReplacement, 1, 1) \ F(CompileLazy, 1, 1) \ F(CompileOptimized_Concurrent, 1, 1) \ @@ -117,17 +117,14 @@ namespace internal { F(NotifyDeoptimized, 0, 1) \ F(ResolvePossiblyDirectEval, 6, 1) -#define FOR_EACH_INTRINSIC_DATE(F) \ - F(DateCurrentTime, 0, 1) \ - F(IsDate, 1, 1) +#define FOR_EACH_INTRINSIC_DATE(F, I) F(DateCurrentTime, 0, 1) -#define FOR_EACH_INTRINSIC_DEBUG(F) \ +#define FOR_EACH_INTRINSIC_DEBUG(F, I) \ F(ClearStepping, 0, 1) \ F(CollectGarbage, 1, 1) \ F(DebugBreakAtEntry, 1, 1) \ F(DebugCollectCoverage, 0, 1) \ F(DebugGetLoadedScriptIds, 0, 1) \ - F(DebugIsActive, 0, 1) \ F(DebugOnFunctionCall, 2, 1) \ F(DebugPopPromise, 0, 1) \ F(DebugPrepareStepInSuspendedGenerator, 0, 1) \ @@ -149,164 +146,136 @@ namespace internal { F(SetGeneratorScopeVariableValue, 4, 1) \ F(LiveEditPatchScript, 2, 1) -#define FOR_EACH_INTRINSIC_FORIN(F) \ - F(ForInEnumerate, 1, 1) \ +#define FOR_EACH_INTRINSIC_FORIN(F, I) \ + F(ForInEnumerate, 1, 1) \ F(ForInHasProperty, 2, 1) #ifdef V8_TRACE_IGNITION -#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) \ - F(InterpreterTraceBytecodeEntry, 3, 1) \ +#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F, I) \ + F(InterpreterTraceBytecodeEntry, 3, 1) \ F(InterpreterTraceBytecodeExit, 3, 1) #else -#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) +#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F, I) #endif #ifdef V8_TRACE_FEEDBACK_UPDATES -#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F) \ +#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F, I) \ F(InterpreterTraceUpdateFeedback, 3, 1) #else -#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F) +#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F, I) #endif -#define FOR_EACH_INTRINSIC_INTERPRETER(F) \ - FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) \ - FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F) \ +#define FOR_EACH_INTRINSIC_INTERPRETER(F, I) \ + FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F, I) \ + FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F, I) \ F(InterpreterDeserializeLazy, 2, 1) -#define FOR_EACH_INTRINSIC_FUNCTION(F) \ - F(Call, -1 /* >= 2 */, 1) \ - F(FunctionGetName, 1, 1) \ +#define FOR_EACH_INTRINSIC_FUNCTION(F, I) \ + I(Call, -1 /* >= 2 */, 1) \ F(FunctionGetScriptSource, 1, 1) \ F(FunctionGetScriptId, 1, 1) \ F(FunctionGetScriptSourcePosition, 1, 1) \ F(FunctionGetSourceCode, 1, 1) \ F(FunctionIsAPIFunction, 1, 1) \ - F(IsConstructor, 1, 1) \ F(IsFunction, 1, 1) \ - F(SetCode, 2, 1) \ F(SetNativeFlag, 1, 1) -#define FOR_EACH_INTRINSIC_GENERATOR(F) \ +#define FOR_EACH_INTRINSIC_GENERATOR(F, I) \ F(AsyncGeneratorHasCatchHandlerForPC, 1, 1) \ - F(AsyncGeneratorReject, 2, 1) \ - F(AsyncGeneratorResolve, 3, 1) \ - F(AsyncGeneratorYield, 3, 1) \ - F(CreateJSGeneratorObject, 2, 1) \ - F(GeneratorClose, 1, 1) \ + I(AsyncGeneratorReject, 2, 1) \ + I(AsyncGeneratorResolve, 3, 1) \ + I(AsyncGeneratorYield, 3, 1) \ + I(CreateJSGeneratorObject, 2, 1) \ + I(GeneratorClose, 1, 1) \ F(GeneratorGetFunction, 1, 1) \ - F(GeneratorGetInputOrDebugPos, 1, 1) \ - F(GeneratorGetResumeMode, 1, 1) + I(GeneratorGetResumeMode, 1, 1) #ifdef V8_INTL_SUPPORT -#define FOR_EACH_INTRINSIC_INTL(F) \ - F(AvailableLocalesOf, 1, 1) \ - F(BreakIteratorBreakType, 1, 1) \ - F(BreakIteratorCurrent, 1, 1) \ - F(BreakIteratorFirst, 1, 1) \ - F(BreakIteratorNext, 1, 1) \ - F(CanonicalizeLanguageTag, 1, 1) \ - F(CollatorResolvedOptions, 1, 1) \ - F(CreateBreakIterator, 3, 1) \ - F(CreateDateTimeFormat, 3, 1) \ - F(CreateNumberFormat, 3, 1) \ - F(CurrencyDigits, 1, 1) \ - F(DateCacheVersion, 0, 1) \ - F(DefaultNumberOption, 5, 1) \ - F(DefineWEProperty, 3, 1) \ - F(FormatList, 2, 1) \ - F(FormatListToParts, 2, 1) \ - F(GetDefaultICULocale, 0, 1) \ - F(GetNumberOption, 5, 1) \ - F(IntlUnwrapReceiver, 5, 1) \ - F(IsInitializedIntlObjectOfType, 2, 1) \ - F(IsWellFormedCurrencyCode, 1, 1) \ - F(MarkAsInitializedIntlObjectOfType, 2, 1) \ - F(ParseExtension, 1, 1) \ - F(PluralRulesResolvedOptions, 1, 1) \ - F(PluralRulesSelect, 2, 1) \ - F(ToDateTimeOptions, 3, 1) \ - F(ToLocaleDateTime, 6, 1) \ - F(StringToLowerCaseIntl, 1, 1) \ - F(StringToUpperCaseIntl, 1, 1) \ - F(SupportedLocalesOf, 3, 1) \ -// End of macro. +#define FOR_EACH_INTRINSIC_INTL(F, I) \ + F(AvailableLocalesOf, 1, 1) \ + F(CanonicalizeLanguageTag, 1, 1) \ + F(DateCacheVersion, 0, 1) \ + F(FormatList, 2, 1) \ + F(FormatListToParts, 2, 1) \ + F(GetDefaultICULocale, 0, 1) \ + F(StringToLowerCaseIntl, 1, 1) \ + F(StringToUpperCaseIntl, 1, 1) // End of macro. #else -#define FOR_EACH_INTRINSIC_INTL(F) +#define FOR_EACH_INTRINSIC_INTL(F, I) #endif // V8_INTL_SUPPORT -#define FOR_EACH_INTRINSIC_INTERNAL(F) \ - F(AllocateInNewSpace, 1, 1) \ - F(AllocateInTargetSpace, 2, 1) \ - F(AllocateSeqOneByteString, 1, 1) \ - F(AllocateSeqTwoByteString, 1, 1) \ - F(AllowDynamicFunction, 1, 1) \ - F(CheckIsBootstrapping, 0, 1) \ - F(CreateAsyncFromSyncIterator, 1, 1) \ - F(CreateListFromArrayLike, 1, 1) \ - F(CreateTemplateObject, 1, 1) \ - F(DeserializeLazy, 1, 1) \ - F(ExportFromRuntime, 1, 1) \ - F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \ - F(IncrementUseCounter, 1, 1) \ - F(InstallToContext, 1, 1) \ - F(Interrupt, 0, 1) \ - F(IS_VAR, 1, 1) \ - F(NewReferenceError, 2, 1) \ - F(NewSyntaxError, 2, 1) \ - F(NewTypeError, 2, 1) \ - F(OrdinaryHasInstance, 2, 1) \ - F(PromoteScheduledException, 0, 1) \ - F(ReportMessage, 1, 1) \ - F(ReThrow, 1, 1) \ - F(RunMicrotaskCallback, 2, 1) \ - F(RunMicrotasks, 0, 1) \ - F(StackGuard, 0, 1) \ - F(Throw, 1, 1) \ - F(ThrowApplyNonFunction, 1, 1) \ - F(ThrowCalledNonCallable, 1, 1) \ - F(ThrowConstructedNonConstructable, 1, 1) \ - F(ThrowConstructorReturnedNonObject, 0, 1) \ - F(ThrowInvalidStringLength, 0, 1) \ - F(ThrowInvalidTypedArrayAlignment, 2, 1) \ - F(ThrowIteratorResultNotAnObject, 1, 1) \ - F(ThrowNotConstructor, 1, 1) \ - F(ThrowRangeError, -1 /* >= 1 */, 1) \ - F(ThrowReferenceError, 1, 1) \ - F(ThrowStackOverflow, 0, 1) \ - F(ThrowSymbolAsyncIteratorInvalid, 0, 1) \ - F(ThrowSymbolIteratorInvalid, 0, 1) \ - F(ThrowThrowMethodMissing, 0, 1) \ - F(ThrowTypeError, -1 /* >= 1 */, 1) \ - F(Typeof, 1, 1) \ +#define FOR_EACH_INTRINSIC_INTERNAL(F, I) \ + F(AllocateInNewSpace, 1, 1) \ + F(AllocateInTargetSpace, 2, 1) \ + F(AllocateSeqOneByteString, 1, 1) \ + F(AllocateSeqTwoByteString, 1, 1) \ + F(AllowDynamicFunction, 1, 1) \ + F(CheckIsBootstrapping, 0, 1) \ + I(CreateAsyncFromSyncIterator, 1, 1) \ + F(CreateListFromArrayLike, 1, 1) \ + F(CreateTemplateObject, 1, 1) \ + F(DeserializeLazy, 1, 1) \ + F(ExportFromRuntime, 1, 1) \ + F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \ + F(IncrementUseCounter, 1, 1) \ + F(InstallToContext, 1, 1) \ + F(Interrupt, 0, 1) \ + F(IS_VAR, 1, 1) \ + F(NewReferenceError, 2, 1) \ + F(NewSyntaxError, 2, 1) \ + F(NewTypeError, 2, 1) \ + F(OrdinaryHasInstance, 2, 1) \ + F(PromoteScheduledException, 0, 1) \ + F(ReportMessage, 1, 1) \ + F(ReThrow, 1, 1) \ + F(RunMicrotaskCallback, 2, 1) \ + F(RunMicrotasks, 0, 1) \ + F(StackGuard, 0, 1) \ + F(Throw, 1, 1) \ + F(ThrowApplyNonFunction, 1, 1) \ + F(ThrowCalledNonCallable, 1, 1) \ + F(ThrowConstructedNonConstructable, 1, 1) \ + F(ThrowConstructorReturnedNonObject, 0, 1) \ + F(ThrowInvalidStringLength, 0, 1) \ + F(ThrowInvalidTypedArrayAlignment, 2, 1) \ + F(ThrowIteratorError, 1, 1) \ + F(ThrowIteratorResultNotAnObject, 1, 1) \ + F(ThrowNotConstructor, 1, 1) \ + F(ThrowRangeError, -1 /* >= 1 */, 1) \ + F(ThrowReferenceError, 1, 1) \ + F(ThrowStackOverflow, 0, 1) \ + F(ThrowSymbolAsyncIteratorInvalid, 0, 1) \ + F(ThrowSymbolIteratorInvalid, 0, 1) \ + F(ThrowThrowMethodMissing, 0, 1) \ + F(ThrowTypeError, -1 /* >= 1 */, 1) \ + F(Typeof, 1, 1) \ F(UnwindAndFindExceptionHandler, 0, 1) -#define FOR_EACH_INTRINSIC_LITERALS(F) \ +#define FOR_EACH_INTRINSIC_LITERALS(F, I) \ F(CreateArrayLiteral, 4, 1) \ F(CreateArrayLiteralWithoutAllocationSite, 2, 1) \ F(CreateObjectLiteral, 4, 1) \ F(CreateObjectLiteralWithoutAllocationSite, 2, 1) \ F(CreateRegExpLiteral, 4, 1) -#define FOR_EACH_INTRINSIC_MATHS(F) F(GenerateRandomNumbers, 0, 1) - -#define FOR_EACH_INTRINSIC_MODULE(F) \ - F(DynamicImportCall, 2, 1) \ - F(GetImportMetaObject, 0, 1) \ +#define FOR_EACH_INTRINSIC_MODULE(F, I) \ + F(DynamicImportCall, 2, 1) \ + I(GetImportMetaObject, 0, 1) \ F(GetModuleNamespace, 1, 1) -#define FOR_EACH_INTRINSIC_NUMBERS(F) \ - F(GetHoleNaNLower, 0, 1) \ - F(GetHoleNaNUpper, 0, 1) \ - F(IsSmi, 1, 1) \ - F(IsValidSmi, 1, 1) \ - F(MaxSmi, 0, 1) \ - F(NumberToString, 1, 1) \ - F(SmiLexicographicCompare, 2, 1) \ - F(StringParseFloat, 1, 1) \ - F(StringParseInt, 2, 1) \ +#define FOR_EACH_INTRINSIC_NUMBERS(F, I) \ + F(GetHoleNaNLower, 0, 1) \ + F(GetHoleNaNUpper, 0, 1) \ + I(IsSmi, 1, 1) \ + F(IsValidSmi, 1, 1) \ + F(MaxSmi, 0, 1) \ + F(NumberToString, 1, 1) \ + F(SmiLexicographicCompare, 2, 1) \ + F(StringParseFloat, 1, 1) \ + F(StringParseInt, 2, 1) \ F(StringToNumber, 1, 1) -#define FOR_EACH_INTRINSIC_OBJECT(F) \ +#define FOR_EACH_INTRINSIC_OBJECT(F, I) \ F(AddDictionaryProperty, 3, 1) \ F(AddElement, 3, 1) \ F(AddNamedProperty, 4, 1) \ @@ -317,8 +286,8 @@ namespace internal { F(CompleteInobjectSlackTrackingForMap, 1, 1) \ F(CopyDataProperties, 2, 1) \ F(CopyDataPropertiesWithExcludedProperties, -1 /* >= 1 */, 1) \ - F(CreateDataProperty, 3, 1) \ - F(CreateIterResultObject, 2, 1) \ + I(CreateDataProperty, 3, 1) \ + I(CreateIterResultObject, 2, 1) \ F(DefineAccessorPropertyUnchecked, 5, 1) \ F(DefineDataPropertyInLiteral, 6, 1) \ F(DefineGetterPropertyUnchecked, 4, 1) \ @@ -329,13 +298,11 @@ namespace internal { F(GetOwnPropertyDescriptor, 2, 1) \ F(GetOwnPropertyKeys, 2, 1) \ F(GetProperty, 2, 1) \ - F(GetPrototype, 1, 1) \ F(HasFastPackedElements, 1, 1) \ F(HasInPrototypeChain, 2, 1) \ - F(HasProperty, 2, 1) \ + I(HasProperty, 2, 1) \ F(InternalSetPrototype, 2, 1) \ - F(IsJSReceiver, 1, 1) \ - F(KeyedGetProperty, 2, 1) \ + I(IsJSReceiver, 1, 1) \ F(NewObject, 2, 1) \ F(ObjectCreate, 2, 1) \ F(ObjectEntries, 1, 1) \ @@ -347,62 +314,59 @@ namespace internal { F(ObjectValues, 1, 1) \ F(ObjectValuesSkipFastPath, 1, 1) \ F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ - F(SameValue, 2, 1) \ - F(SameValueZero, 2, 1) \ + F(PerformSideEffectCheckForObject, 1, 1) \ F(SetDataProperties, 2, 1) \ - F(SetProperty, 4, 1) \ + F(SetKeyedProperty, 4, 1) \ + F(SetNamedProperty, 4, 1) \ + F(StoreDataPropertyInLiteral, 3, 1) \ F(ShrinkPropertyDictionary, 1, 1) \ F(ToFastProperties, 1, 1) \ - F(ToInteger, 1, 1) \ - F(ToLength, 1, 1) \ + I(ToLength, 1, 1) \ F(ToName, 1, 1) \ - F(ToNumber, 1, 1) \ + I(ToNumber, 1, 1) \ F(ToNumeric, 1, 1) \ - F(ToObject, 1, 1) \ - F(ToPrimitive, 1, 1) \ - F(ToPrimitive_Number, 1, 1) \ - F(ToString, 1, 1) \ - F(TryMigrateInstance, 1, 1) \ - F(ValueOf, 1, 1) - -#define FOR_EACH_INTRINSIC_OPERATORS(F) \ - F(Add, 2, 1) \ - F(Equal, 2, 1) \ - F(GreaterThan, 2, 1) \ - F(GreaterThanOrEqual, 2, 1) \ - F(LessThan, 2, 1) \ - F(LessThanOrEqual, 2, 1) \ - F(NotEqual, 2, 1) \ - F(StrictEqual, 2, 1) \ + I(ToObject, 1, 1) \ + I(ToString, 1, 1) \ + F(TryMigrateInstance, 1, 1) + +#define FOR_EACH_INTRINSIC_OPERATORS(F, I) \ + F(Add, 2, 1) \ + F(Equal, 2, 1) \ + F(GreaterThan, 2, 1) \ + F(GreaterThanOrEqual, 2, 1) \ + F(LessThan, 2, 1) \ + F(LessThanOrEqual, 2, 1) \ + F(NotEqual, 2, 1) \ + F(StrictEqual, 2, 1) \ F(StrictNotEqual, 2, 1) -#define FOR_EACH_INTRINSIC_PROMISE(F) \ - F(EnqueueMicrotask, 1, 1) \ - F(PromiseHookAfter, 1, 1) \ - F(PromiseHookBefore, 1, 1) \ - F(PromiseHookInit, 2, 1) \ - F(AwaitPromisesInit, 3, 1) \ - F(PromiseMarkAsHandled, 1, 1) \ - F(PromiseRejectEventFromStack, 2, 1) \ - F(PromiseResult, 1, 1) \ - F(PromiseRevokeReject, 1, 1) \ - F(PromiseStatus, 1, 1) \ - F(RejectPromise, 3, 1) \ - F(ResolvePromise, 2, 1) \ - F(PromiseRejectAfterResolved, 2, 1) \ +#define FOR_EACH_INTRINSIC_PROMISE(F, I) \ + F(EnqueueMicrotask, 1, 1) \ + F(PromiseHookAfter, 1, 1) \ + F(PromiseHookBefore, 1, 1) \ + F(PromiseHookInit, 2, 1) \ + F(AwaitPromisesInit, 3, 1) \ + F(PromiseMarkAsHandled, 1, 1) \ + F(PromiseRejectEventFromStack, 2, 1) \ + F(PromiseResult, 1, 1) \ + F(PromiseRevokeReject, 1, 1) \ + F(PromiseStatus, 1, 1) \ + I(RejectPromise, 3, 1) \ + I(ResolvePromise, 2, 1) \ + F(PromiseRejectAfterResolved, 2, 1) \ F(PromiseResolveAfterResolved, 2, 1) -#define FOR_EACH_INTRINSIC_PROXY(F) \ - F(CheckProxyGetSetTrapResult, 2, 1) \ - F(CheckProxyHasTrap, 2, 1) \ - F(GetPropertyWithReceiver, 3, 1) \ - F(IsJSProxy, 1, 1) \ - F(JSProxyGetHandler, 1, 1) \ - F(JSProxyGetTarget, 1, 1) \ +#define FOR_EACH_INTRINSIC_PROXY(F, I) \ + F(CheckProxyGetSetTrapResult, 2, 1) \ + F(CheckProxyHasTrap, 2, 1) \ + F(GetPropertyWithReceiver, 3, 1) \ + F(IsJSProxy, 1, 1) \ + F(JSProxyGetHandler, 1, 1) \ + F(JSProxyGetTarget, 1, 1) \ F(SetPropertyWithReceiver, 5, 1) -#define FOR_EACH_INTRINSIC_REGEXP(F) \ - F(IsRegExp, 1, 1) \ +#define FOR_EACH_INTRINSIC_REGEXP(F, I) \ + I(IsRegExp, 1, 1) \ F(RegExpExec, 4, 1) \ F(RegExpExecMultiple, 4, 1) \ F(RegExpInitializeAndCompile, 3, 1) \ @@ -412,7 +376,7 @@ namespace internal { F(StringReplaceNonGlobalRegExpWithFunction, 3, 1) \ F(StringSplit, 3, 1) -#define FOR_EACH_INTRINSIC_SCOPES(F) \ +#define FOR_EACH_INTRINSIC_SCOPES(F, I) \ F(DeclareEvalFunction, 2, 1) \ F(DeclareEvalVar, 1, 1) \ F(DeclareGlobals, 3, 1) \ @@ -438,7 +402,7 @@ namespace internal { F(StoreLookupSlot_Strict, 2, 1) \ F(ThrowConstAssignError, 0, 1) -#define FOR_EACH_INTRINSIC_STRINGS(F) \ +#define FOR_EACH_INTRINSIC_STRINGS(F, I) \ F(FlattenString, 1, 1) \ F(GetSubstitution, 5, 1) \ F(InternalizeString, 1, 1) \ @@ -447,7 +411,6 @@ namespace internal { F(StringBuilderConcat, 3, 1) \ F(StringBuilderJoin, 3, 1) \ F(StringCharCodeAt, 2, 1) \ - F(StringCharFromCode, 1, 1) \ F(StringEqual, 2, 1) \ F(StringGreaterThan, 2, 1) \ F(StringGreaterThanOrEqual, 2, 1) \ @@ -458,19 +421,18 @@ namespace internal { F(StringLessThan, 2, 1) \ F(StringLessThanOrEqual, 2, 1) \ F(StringMaxLength, 0, 1) \ - F(StringNotEqual, 2, 1) \ F(StringReplaceOneCharWithString, 3, 1) \ F(StringSubstring, 3, 1) \ F(StringToArray, 2, 1) \ F(StringTrim, 2, 1) -#define FOR_EACH_INTRINSIC_SYMBOL(F) \ +#define FOR_EACH_INTRINSIC_SYMBOL(F, I) \ F(CreatePrivateFieldSymbol, 0, 1) \ F(CreatePrivateSymbol, -1 /* <= 1 */, 1) \ F(SymbolDescriptiveString, 1, 1) \ F(SymbolIsPrivate, 1, 1) -#define FOR_EACH_INTRINSIC_TEST(F) \ +#define FOR_EACH_INTRINSIC_TEST(F, I) \ F(Abort, 1, 1) \ F(AbortJS, 1, 1) \ F(ClearFunctionFeedback, 1, 1) \ @@ -482,7 +444,7 @@ namespace internal { F(DebugTrace, 0, 1) \ F(DebugTrackRetainingPath, -1, 1) \ F(DeoptimizeFunction, 1, 1) \ - F(DeoptimizeNow, 0, 1) \ + I(DeoptimizeNow, 0, 1) \ F(DeserializeWasmModule, 2, 1) \ F(DisallowCodegenFromStrings, 1, 1) \ F(DisallowWasmCodegen, 1, 1) \ @@ -490,8 +452,11 @@ namespace internal { F(FreezeWasmLazyCompilation, 1, 1) \ F(GetCallable, 0, 1) \ F(GetDeoptCount, 1, 1) \ + F(GetInitializerFunction, 1, 1) \ F(GetOptimizationStatus, -1, 1) \ F(GetUndetectable, 0, 1) \ + F(GetWasmExceptionId, 2, 1) \ + F(GetWasmExceptionValues, 1, 1) \ F(GetWasmRecoveredTrapCount, 0, 1) \ F(GlobalPrint, 1, 1) \ F(HasDictionaryElements, 1, 1) \ @@ -538,6 +503,7 @@ namespace internal { F(ArraySpeciesProtector, 0, 1) \ F(TypedArraySpeciesProtector, 0, 1) \ F(PromiseSpeciesProtector, 0, 1) \ + F(StringIteratorProtector, 0, 1) \ F(SystemBreak, 0, 1) \ F(TraceEnter, 0, 1) \ F(TraceExit, 1, 1) \ @@ -548,37 +514,36 @@ namespace internal { F(WasmMemoryHasFullGuardRegion, 1, 1) \ F(SetWasmThreadsEnabled, 1, 1) -#define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \ - F(ArrayBufferNeuter, 1, 1) \ - F(ArrayBufferViewWasNeutered, 1, 1) \ - F(IsTypedArray, 1, 1) \ - F(TypedArrayCopyElements, 3, 1) \ - F(TypedArrayGetBuffer, 1, 1) \ - F(TypedArrayGetLength, 1, 1) \ - F(TypedArraySet, 2, 1) \ +#define FOR_EACH_INTRINSIC_TYPEDARRAY(F, I) \ + F(ArrayBufferNeuter, 1, 1) \ + F(ArrayBufferViewWasNeutered, 1, 1) \ + I(IsTypedArray, 1, 1) \ + F(TypedArrayCopyElements, 3, 1) \ + F(TypedArrayGetBuffer, 1, 1) \ + F(TypedArrayGetLength, 1, 1) \ + F(TypedArraySet, 2, 1) \ F(TypedArraySortFast, 1, 1) -#define FOR_EACH_INTRINSIC_WASM(F) \ - F(ThrowWasmError, 1, 1) \ - F(ThrowWasmStackOverflow, 0, 1) \ - F(WasmExceptionGetElement, 1, 1) \ - F(WasmExceptionSetElement, 2, 1) \ - F(WasmGetExceptionRuntimeId, 0, 1) \ - F(WasmGrowMemory, 2, 1) \ - F(WasmRunInterpreter, 2, 1) \ - F(WasmStackGuard, 0, 1) \ - F(WasmThrow, 0, 1) \ - F(WasmThrowCreate, 2, 1) \ - F(WasmThrowTypeError, 0, 1) \ +#define FOR_EACH_INTRINSIC_WASM(F, I) \ + F(ThrowWasmError, 1, 1) \ + F(ThrowWasmStackOverflow, 0, 1) \ + F(WasmExceptionGetElement, 2, 1) \ + F(WasmExceptionSetElement, 3, 1) \ + F(WasmExceptionGetTag, 1, 1) \ + F(WasmGrowMemory, 2, 1) \ + F(WasmRunInterpreter, 2, 1) \ + F(WasmStackGuard, 0, 1) \ + F(WasmThrowCreate, 2, 1) \ + F(WasmThrowTypeError, 0, 1) \ F(WasmCompileLazy, 2, 1) -#define FOR_EACH_INTRINSIC_RETURN_PAIR(F) \ - F(DebugBreakOnBytecode, 1, 2) \ +#define FOR_EACH_INTRINSIC_RETURN_PAIR_IMPL(F, I) \ + F(DebugBreakOnBytecode, 1, 2) \ F(LoadLookupSlotForCall, 1, 2) // Most intrinsics are implemented in the runtime/ directory, but ICs are // implemented in ic.cc for now. -#define FOR_EACH_INTRINSIC_IC(F) \ +#define FOR_EACH_INTRINSIC_IC(F, I) \ F(ElementsTransitionAndStoreIC_Miss, 6, 1) \ F(KeyedLoadIC_Miss, 4, 1) \ F(KeyedStoreIC_Miss, 5, 1) \ @@ -599,44 +564,55 @@ namespace internal { F(CloneObjectIC_Miss, 4, 1) \ F(CloneObjectIC_Slow, 2, 1) +#define FOR_EACH_INTRINSIC_RETURN_OBJECT_IMPL(F, I) \ + FOR_EACH_INTRINSIC_ARRAY(F, I) \ + FOR_EACH_INTRINSIC_ATOMICS(F, I) \ + FOR_EACH_INTRINSIC_BIGINT(F, I) \ + FOR_EACH_INTRINSIC_CLASSES(F, I) \ + FOR_EACH_INTRINSIC_COLLECTIONS(F, I) \ + FOR_EACH_INTRINSIC_COMPILER(F, I) \ + FOR_EACH_INTRINSIC_DATE(F, I) \ + FOR_EACH_INTRINSIC_DEBUG(F, I) \ + FOR_EACH_INTRINSIC_FORIN(F, I) \ + FOR_EACH_INTRINSIC_FUNCTION(F, I) \ + FOR_EACH_INTRINSIC_GENERATOR(F, I) \ + FOR_EACH_INTRINSIC_IC(F, I) \ + FOR_EACH_INTRINSIC_INTERNAL(F, I) \ + FOR_EACH_INTRINSIC_INTERPRETER(F, I) \ + FOR_EACH_INTRINSIC_INTL(F, I) \ + FOR_EACH_INTRINSIC_LITERALS(F, I) \ + FOR_EACH_INTRINSIC_MODULE(F, I) \ + FOR_EACH_INTRINSIC_NUMBERS(F, I) \ + FOR_EACH_INTRINSIC_OBJECT(F, I) \ + FOR_EACH_INTRINSIC_OPERATORS(F, I) \ + FOR_EACH_INTRINSIC_PROMISE(F, I) \ + FOR_EACH_INTRINSIC_PROXY(F, I) \ + FOR_EACH_INTRINSIC_REGEXP(F, I) \ + FOR_EACH_INTRINSIC_SCOPES(F, I) \ + FOR_EACH_INTRINSIC_STRINGS(F, I) \ + FOR_EACH_INTRINSIC_SYMBOL(F, I) \ + FOR_EACH_INTRINSIC_TEST(F, I) \ + FOR_EACH_INTRINSIC_TYPEDARRAY(F, I) \ + FOR_EACH_INTRINSIC_WASM(F, I) + +// Defines the list of all intrinsics, coming in 2 flavors, either returning an +// object or a pair. +#define FOR_EACH_INTRINSIC_IMPL(F, I) \ + FOR_EACH_INTRINSIC_RETURN_PAIR_IMPL(F, I) \ + FOR_EACH_INTRINSIC_RETURN_OBJECT_IMPL(F, I) + #define FOR_EACH_INTRINSIC_RETURN_OBJECT(F) \ - FOR_EACH_INTRINSIC_ARRAY(F) \ - FOR_EACH_INTRINSIC_ATOMICS(F) \ - FOR_EACH_INTRINSIC_BIGINT(F) \ - FOR_EACH_INTRINSIC_CLASSES(F) \ - FOR_EACH_INTRINSIC_COLLECTIONS(F) \ - FOR_EACH_INTRINSIC_COMPILER(F) \ - FOR_EACH_INTRINSIC_DATE(F) \ - FOR_EACH_INTRINSIC_DEBUG(F) \ - FOR_EACH_INTRINSIC_FORIN(F) \ - FOR_EACH_INTRINSIC_FUNCTION(F) \ - FOR_EACH_INTRINSIC_GENERATOR(F) \ - FOR_EACH_INTRINSIC_IC(F) \ - FOR_EACH_INTRINSIC_INTERNAL(F) \ - FOR_EACH_INTRINSIC_INTERPRETER(F) \ - FOR_EACH_INTRINSIC_INTL(F) \ - FOR_EACH_INTRINSIC_LITERALS(F) \ - FOR_EACH_INTRINSIC_MATHS(F) \ - FOR_EACH_INTRINSIC_MODULE(F) \ - FOR_EACH_INTRINSIC_NUMBERS(F) \ - FOR_EACH_INTRINSIC_OBJECT(F) \ - FOR_EACH_INTRINSIC_OPERATORS(F) \ - FOR_EACH_INTRINSIC_PROMISE(F) \ - FOR_EACH_INTRINSIC_PROXY(F) \ - FOR_EACH_INTRINSIC_REGEXP(F) \ - FOR_EACH_INTRINSIC_SCOPES(F) \ - FOR_EACH_INTRINSIC_STRINGS(F) \ - FOR_EACH_INTRINSIC_SYMBOL(F) \ - FOR_EACH_INTRINSIC_TEST(F) \ - FOR_EACH_INTRINSIC_TYPEDARRAY(F) \ - FOR_EACH_INTRINSIC_WASM(F) - -// FOR_EACH_INTRINSIC defines the list of all intrinsics, coming in 2 flavors, -// either returning an object or a pair. -#define FOR_EACH_INTRINSIC(F) \ - FOR_EACH_INTRINSIC_RETURN_PAIR(F) \ - FOR_EACH_INTRINSIC_RETURN_OBJECT(F) + FOR_EACH_INTRINSIC_RETURN_OBJECT_IMPL(F, F) + +#define FOR_EACH_INTRINSIC_RETURN_PAIR(F) \ + FOR_EACH_INTRINSIC_RETURN_PAIR_IMPL(F, F) + +// The list of all intrinsics, including those that have inline versions, but +// not the inline versions themselves. +#define FOR_EACH_INTRINSIC(F) FOR_EACH_INTRINSIC_IMPL(F, F) +// The list of all inline intrinsics only. +#define FOR_EACH_INLINE_INTRINSIC(I) FOR_EACH_INTRINSIC_IMPL(NOTHING, I) #define F(name, nargs, ressize) \ Object* Runtime_##name(int args_length, Object** args_object, \ @@ -652,12 +628,17 @@ class Runtime : public AllStatic { enum FunctionId : int32_t { #define F(name, nargs, ressize) k##name, #define I(name, nargs, ressize) kInline##name, - FOR_EACH_INTRINSIC(F) FOR_EACH_INTRINSIC(I) + FOR_EACH_INTRINSIC(F) FOR_EACH_INLINE_INTRINSIC(I) #undef I #undef F kNumFunctions, }; + static constexpr int kNumInlineFunctions = +#define COUNT(...) +1 + FOR_EACH_INLINE_INTRINSIC(COUNT); +#undef COUNT + enum IntrinsicType { RUNTIME, INLINE }; // Intrinsic function descriptor. @@ -680,6 +661,11 @@ class Runtime : public AllStatic { static const int kNotFound = -1; + // Checks whether the runtime function with the given {id} depends on the + // "current context", i.e. because it does scoped lookups, or whether it's + // fine to just pass any context within the same "native context". + static bool NeedsExactContext(FunctionId id); + // Checks whether the runtime function with the given {id} never returns // to it's caller normally, i.e. whether it'll always raise an exception. // More specifically: The C++ implementation returns the Heap::exception @@ -704,7 +690,8 @@ class Runtime : public AllStatic { V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetObjectProperty( Isolate* isolate, Handle<Object> object, Handle<Object> key, - Handle<Object> value, LanguageMode language_mode); + Handle<Object> value, LanguageMode language_mode, + StoreOrigin store_origin); V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetObjectProperty( Isolate* isolate, Handle<Object> object, Handle<Object> key, @@ -739,7 +726,7 @@ class RuntimeState { } private: - RuntimeState() {} + RuntimeState() = default; #ifndef V8_INTL_SUPPORT unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_; unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_; @@ -781,6 +768,8 @@ enum class OptimizationStatus { kTopmostFrameIsTurboFanned = 1 << 11, }; +Smi* SmiLexicographicCompare(Smi* x_value, Smi* y_value); + } // namespace internal } // namespace v8 |