%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/builtins/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/builtins/base.tq |
// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be: // Context found in the LICENSE file. #include 'src/builtins/builtins-regexp-gen.h' #include 'src/builtins/builtins-utils-gen.h' #include 'src/builtins/builtins.h' #include 'src/codegen/code-factory.h' #include 'src/heap/factory-inl.h' #include 'src/objects/arguments.h' #include 'src/objects/bigint.h' #include 'src/objects/call-site-info.h' #include 'src/objects/elements-kind.h' #include 'src/objects/free-space.h' #include 'src/objects/js-atomics-synchronization.h' #include 'src/objects/js-function.h' #include 'src/objects/js-generator.h' #include 'src/objects/js-iterator-helpers.h' #include 'src/objects/js-promise.h' #include 'src/objects/js-regexp-string-iterator.h' #include 'src/objects/js-shadow-realm.h' #include 'src/objects/js-shared-array.h' #include 'src/objects/js-struct.h' #include 'src/objects/js-weak-refs.h' #include 'src/objects/objects.h' #include 'src/objects/source-text-module.h' #include 'src/objects/synthetic-module.h' #include 'src/objects/template-objects.h' #include 'src/torque/runtime-support.h' type void; type never; type IntegerLiteral constexpr 'IntegerLiteral'; type Tagged generates 'TNode<MaybeObject>' constexpr 'MaybeObject'; type StrongTagged extends Tagged generates 'TNode<Object>' constexpr 'Object'; type Smi extends StrongTagged generates 'TNode<Smi>' constexpr 'Smi'; type TaggedIndex extends StrongTagged generates 'TNode<TaggedIndex>' constexpr 'TaggedIndex'; // A possibly cleared weak pointer with a bit pattern that distinguishes it from // strong HeapObject pointers and Smi values. type WeakHeapObject extends Tagged; type Weak<T : type extends HeapObject> extends WeakHeapObject; type Object = Smi|HeapObject; type MaybeObject = Smi|HeapObject|WeakHeapObject; // A Smi that is greater than or equal to 0. See TaggedIsPositiveSmi. type PositiveSmi extends Smi; // The Smi value zero, which is often used as null for HeapObject types. type Zero extends PositiveSmi; // A tagged value represented by an all-zero bitpattern. type TaggedZeroPattern extends TaggedIndex; // A value with the size of Tagged which may contain arbitrary data. type Uninitialized extends Tagged; type BuiltinsName extends int31 constexpr 'Builtin'; extern macro MakeWeak(HeapObject): WeakHeapObject; extern macro GetHeapObjectAssumeWeak(MaybeObject): HeapObject labels IfCleared; extern macro GetHeapObjectIfStrong(MaybeObject): HeapObject labels IfNotStrong; extern macro IsWeakOrCleared(MaybeObject): bool; extern macro IsWeakReferenceToObject(MaybeObject, Object): bool; extern macro IsStrong(MaybeObject): bool; macro StrongToWeak<T: type>(x: T): Weak<T> { return %RawDownCast<Weak<T>>(MakeWeak(x)); } macro WeakToStrong<T: type>(x: Weak<T>): T labels ClearedWeakPointer { const x = GetHeapObjectAssumeWeak(x) otherwise ClearedWeakPointer; return %RawDownCast<T>(x); } // Defined to coincide with https://tc39.es/ecma262/#sec-ispropertykey // Doesn't include PrivateSymbol. type PropertyKey = String|PublicSymbol; // TODO(turbofan): PrivateSymbol is only exposed to JavaScript through the // debugger API. We should reconsider this and try not to expose it at all. Then // JSAny would not need to contain it. // A JavaScript primitive value as defined in // https://tc39.es/ecma262/#sec-primitive-value. type JSPrimitive = Numeric|String|Symbol|Boolean|Null|Undefined; // A user-exposed JavaScript value, as opposed to V8-internal values like Holes // or a FixedArray. type JSAny = JSReceiver|JSPrimitive; type JSAnyNotNumeric = String|Symbol|Boolean|Null|Undefined|JSReceiver; type JSAnyNotNumber = BigInt|JSAnyNotNumeric; // This is the intersection of JSAny and HeapObject. type JSAnyNotSmi = JSAnyNotNumber|HeapNumber; type int32 generates 'TNode<Int32T>' constexpr 'int32_t'; type uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t'; type int31 extends int32 generates 'TNode<Int32T>' constexpr 'int31_t'; type uint31 extends uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t'; type int16 extends int31 generates 'TNode<Int16T>' constexpr 'int16_t'; type uint16 extends uint31 generates 'TNode<Uint16T>' constexpr 'uint16_t'; type int8 extends int16 generates 'TNode<Int8T>' constexpr 'int8_t'; type uint8 extends uint16 generates 'TNode<Uint8T>' constexpr 'uint8_t'; type char8 extends uint8 constexpr 'char'; type char16 extends uint16 constexpr 'char16_t'; type int64 generates 'TNode<Int64T>' constexpr 'int64_t'; type uint64 generates 'TNode<Uint64T>' constexpr 'uint64_t'; type intptr generates 'TNode<IntPtrT>' constexpr 'intptr_t'; type uintptr generates 'TNode<UintPtrT>' constexpr 'uintptr_t'; type float32 generates 'TNode<Float32T>' constexpr 'float'; type float64 generates 'TNode<Float64T>' constexpr 'double'; type bool generates 'TNode<BoolT>' constexpr 'bool'; type bint generates 'TNode<BInt>' constexpr 'BInt'; type string constexpr 'const char*'; type Simd128 generates 'TNode<Simd128T>'; type I8X16 extends Simd128 generates 'TNode<I8x16T>'; // Represents a std::function which produces the generated TNode type of T. // Useful for passing values to and from CSA code that uses LazyNode<T>, which // is a typedef for std::function<TNode<T>()>. Can be created with %MakeLazy and // accessed with RunLazy. type Lazy<T: type>; // Makes a Lazy. The first parameter is the name of a macro, which is looked up // in the context where %MakeLazy is called, as a workaround for the fact that // macros can't be used as values directly. The other parameters are saved and // passed to the macro when somebody runs the resulting Lazy object. Torque // syntax doesn't allow for arbitrary-length generic macros, but the internals // support any number of parameters, so if you need more parameters, feel free // to add additional declarations here. intrinsic %MakeLazy<T: type>(getter: constexpr string): Lazy<T>; intrinsic %MakeLazy<T: type, A1: type>( getter: constexpr string, arg1: A1): Lazy<T>; intrinsic %MakeLazy<T: type, A1: type, A2: type>( getter: constexpr string, arg1: A1, arg2: A2): Lazy<T>; intrinsic %MakeLazy<T: type, A1: type, A2: type, A3: type>( getter: constexpr string, arg1: A1, arg2: A2, arg3: A3): Lazy<T>; // Executes a Lazy and returns the result. The CSA-side definition is a // template, but Torque doesn't understand how to use templates for extern // macros, so just add whatever overload definitions you need here. extern macro RunLazy(Lazy<Smi>): Smi; extern macro RunLazy(Lazy<JSAny>): JSAny; // A Smi value containing a bitfield struct as its integer data. @useParentTypeChecker type SmiTagged<T : type extends uint31> extends Smi; // WARNING: The memory representation (i.e., in class fields and arrays) of // float64_or_hole is just a float64 that may be the hole-representing // signalling NaN bit-pattern. So it's memory size is that of float64 and // loading and storing float64_or_hole emits special code. struct float64_or_hole { macro Value(): float64 labels IfHole { if (this.is_hole) { goto IfHole; } return this.value; } macro ValueUnsafeAssumeNotHole(): float64 { dcheck(!this.is_hole); return this.value; } is_hole: bool; value: float64; } const kDoubleHole: float64_or_hole = float64_or_hole{is_hole: true, value: 0}; @doNotGenerateCast @abstract extern class JSPrototype extends JSObject generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSObjectPrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSRegExpPrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSPromisePrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSTypedArrayPrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSSetPrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSIteratorPrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSArrayIteratorPrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSMapIteratorPrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSSetIteratorPrototype extends JSPrototype generates 'TNode<JSObject>'; @doNotGenerateCast extern class JSStringIteratorPrototype extends JSPrototype generates 'TNode<JSObject>'; // The HashTable inheritance hierarchy doesn't actually look like this in C++ // because it uses some class templates that we can't yet (and may never) // express in Torque, but this is the expected organization of instance types. @doNotGenerateCast extern class HashTable extends FixedArray generates 'TNode<FixedArray>'; extern class OrderedHashMap extends HashTable; extern class OrderedHashSet extends HashTable; extern class OrderedNameDictionary extends HashTable; extern class NameToIndexHashTable extends HashTable; extern class RegisteredSymbolTable extends HashTable; extern class NameDictionary extends HashTable; extern class GlobalDictionary extends HashTable; extern class SimpleNumberDictionary extends HashTable; extern class EphemeronHashTable extends HashTable; type ObjectHashTable extends HashTable generates 'TNode<ObjectHashTable>' constexpr 'ObjectHashTable'; extern class NumberDictionary extends HashTable; type RawPtr generates 'TNode<RawPtrT>' constexpr 'Address'; type RawPtr<To: type> extends RawPtr; type ExternalPointer generates 'TNode<ExternalPointerT>' constexpr 'ExternalPointer_t'; type IndirectPointer generates 'TNode<IndirectPointerHandleT>' constexpr 'IndirectPointerHandle'; // TODO(saelo): implement accessors and type checkers for these fields. type IndirectPointer<To: type> extends IndirectPointer; extern class InstructionStream extends HeapObject; type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>'; type Number = Smi|HeapNumber; type Numeric = Number|BigInt; extern class ObjectBoilerplateDescription extends FixedArray; extern class ClosureFeedbackCellArray extends FixedArray; extern class ScriptContextTable extends FixedArray; extern class TransitionArray extends WeakFixedArray; extern operator '.length_intptr' macro LoadAndUntagWeakFixedArrayLength( WeakFixedArray): intptr; type InstanceType extends uint16 constexpr 'InstanceType'; type NoSharedNameSentinel extends Smi; // Specialized types. The following three type definitions don't correspond to // actual C++ classes, but have Is... methods that check additional constraints. // A Foreign object whose raw pointer is not allowed to be null. type NonNullForeign extends Foreign; // A function built with InstantiateFunction for the public API. type CallableApiObject extends JSObject; // A JSProxy with the callable bit set. type CallableJSProxy extends JSProxy; type Callable = JSFunction|JSBoundFunction|JSWrappedFunction|CallableJSProxy| CallableApiObject; type WriteBarrierMode generates 'TNode<Int32T>' constexpr 'WriteBarrierMode'; extern enum UpdateFeedbackMode { kOptionalFeedback, kGuaranteedFeedback, kNoFeedback } extern operator '==' macro UpdateFeedbackModeEqual( constexpr UpdateFeedbackMode, constexpr UpdateFeedbackMode): constexpr bool; extern enum CallFeedbackContent extends int32 { kTarget, kReceiver } extern enum UnicodeEncoding { UTF16, UTF32 } // Promise constants extern enum PromiseState extends int31 constexpr 'Promise::PromiseState' { kPending, kFulfilled, kRejected } const kTaggedSize: constexpr int31 generates 'kTaggedSize'; const kDoubleSize: constexpr int31 generates 'kDoubleSize'; const kVariableSizeSentinel: constexpr int31 generates 'kVariableSizeSentinel'; const kSmiTagSize: constexpr int31 generates 'kSmiTagSize'; const kHeapObjectTag: constexpr int31 generates 'kHeapObjectTag'; const V8_INFINITY: constexpr float64 generates 'V8_INFINITY'; const MINUS_V8_INFINITY: constexpr float64 generates '-V8_INFINITY'; extern enum ElementsKind extends int32 { NO_ELEMENTS, PACKED_SMI_ELEMENTS, HOLEY_SMI_ELEMENTS, PACKED_ELEMENTS, HOLEY_ELEMENTS, PACKED_DOUBLE_ELEMENTS, HOLEY_DOUBLE_ELEMENTS, LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND, DICTIONARY_ELEMENTS, UINT8_ELEMENTS, INT8_ELEMENTS, UINT16_ELEMENTS, INT16_ELEMENTS, UINT32_ELEMENTS, INT32_ELEMENTS, FLOAT32_ELEMENTS, FLOAT64_ELEMENTS, UINT8_CLAMPED_ELEMENTS, BIGUINT64_ELEMENTS, BIGINT64_ELEMENTS, RAB_GSAB_UINT8_ELEMENTS, RAB_GSAB_INT8_ELEMENTS, RAB_GSAB_UINT16_ELEMENTS, RAB_GSAB_INT16_ELEMENTS, RAB_GSAB_UINT32_ELEMENTS, RAB_GSAB_INT32_ELEMENTS, RAB_GSAB_FLOAT32_ELEMENTS, RAB_GSAB_FLOAT64_ELEMENTS, RAB_GSAB_UINT8_CLAMPED_ELEMENTS, RAB_GSAB_BIGUINT64_ELEMENTS, RAB_GSAB_BIGINT64_ELEMENTS, // TODO(torque): Allow duplicate enum values. // FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND, // FIRST_RAB_GSAB_FIXED_TYPED_ARRAY_ELEMENTS_KIND, ... } const kFirstFixedTypedArrayElementsKind: constexpr ElementsKind = ElementsKind::UINT8_ELEMENTS; const kFirstRabGsabFixedTypedArrayElementsKind: constexpr ElementsKind = ElementsKind::RAB_GSAB_UINT8_ELEMENTS; extern enum AllocationFlag extends int32 constexpr 'CodeStubAssembler::AllocationFlag' { kNone, kDoubleAlignment, kPretenured } extern enum SlackTrackingMode constexpr 'CodeStubAssembler::SlackTrackingMode' { kWithSlackTracking, kNoSlackTracking, kDontInitializeInObjectProperties } extern enum ExtractFixedArrayFlag constexpr 'CodeStubAssembler::ExtractFixedArrayFlag' { kFixedDoubleArrays, kAllFixedArrays, kFixedArrays, ... } const kBigIntMaxLengthBits: constexpr uintptr generates 'BigInt::kMaxLengthBits'; const kBigIntMaxLength: constexpr intptr generates 'BigInt::kMaxLength'; const kBigIntDigitSize: constexpr intptr generates 'kSystemPointerSize'; const kBitsPerByte: constexpr intptr generates 'kBitsPerByte'; const kBigIntDigitBits: intptr = kBigIntDigitSize * kBitsPerByte; extern enum MessageTemplate { kAllPromisesRejected, kInvalid, kInvalidArrayBufferLength, kInvalidArrayLength, kInvalidIndex, kInvalidTypedArrayIndex, kNotConstructor, kNotGeneric, kCalledNonCallable, kCalledOnNullOrUndefined, kCannotConvertToPrimitive, kProtoObjectOrNull, kInvalidOffset, kInvalidTypedArrayLength, kFirstArgumentIteratorSymbolNonCallable, kIteratorValueNotAnObject, kNotIterable, kReduceNoInitial, kFirstArgumentNotRegExp, kBigIntMixedTypes, kTypedArrayTooShort, kTypedArrayTooLargeToSort, kInvalidCountValue, kConstructAbstractClass, kConstructorNotFunction, kSymbolToString, kSymbolIteratorInvalid, kPropertyNotFunction, kBigIntTooBig, kBigIntDivZero, kNotTypedArray, kDetachedOperation, kBadSortComparisonFunction, kIncompatibleMethodReceiver, kInvalidDataViewAccessorOffset, kTypedArraySetOffsetOutOfBounds, kInvalidArgument, kInvalidRegExpExecResult, kRegExpNonRegExp, kRegExpNonObject, kPromiseNonCallable, kPromiseNewTargetUndefined, kResolverNotAFunction, kTooManyElementsInPromiseCombinator, kToRadixFormatRange, kCalledOnNonObject, kRegExpGlobalInvokedOnNonGlobal, kProxyNonObject, kProxyRevoked, kProxyTrapReturnedFalsishFor, kProxyPrivate, kProxyIsExtensibleInconsistent, kProxyPreventExtensionsExtensible, kProxyTrapReturnedFalsish, kProxyGetPrototypeOfInvalid, kProxyGetPrototypeOfNonExtensible, kProxySetPrototypeOfNonExtensible, kProxyDeletePropertyNonExtensible, kUndefinedOrNullToObject, kWeakRefsCleanupMustBeCallable, kWasmTrapUnreachable, kWasmTrapMemOutOfBounds, kWasmTrapUnalignedAccess, kWasmTrapDivByZero, kWasmTrapDivUnrepresentable, kWasmTrapRemByZero, kWasmTrapFloatUnrepresentable, kWasmTrapFuncSigMismatch, kWasmTrapDataSegmentOutOfBounds, kWasmTrapElementSegmentOutOfBounds, kWasmTrapJSTypeError, kWasmTrapTableOutOfBounds, kWasmTrapRethrowNull, kWasmTrapNullDereference, kWasmTrapIllegalCast, kWasmTrapArrayOutOfBounds, kWasmTrapArrayTooLarge, kWasmTrapStringOffsetOutOfBounds, kWasmObjectsAreOpaque, kWeakRefsRegisterTargetAndHoldingsMustNotBeSame, kInvalidWeakRefsRegisterTarget, kInvalidWeakRefsUnregisterToken, kInvalidWeakRefsWeakRefConstructorTarget, kObjectGetterCallable, kObjectSetterCallable, kPropertyDescObject, kMustBePositive, kIteratorReduceNoInitial, kSizeIsNaN, kArgumentIsNonObject, kKeysMethodInvalid, kGeneratorRunning, kFirstArgumentAsyncIteratorSymbolNonCallable, kIteratorResultNotAnObject, ... } extern enum PropertyAttributes extends int31 { NONE, READ_ONLY, DONT_ENUM, DONT_DELETE, ALL_ATTRIBUTES_MASK, FROZEN, ... } const kArrayBufferMaxByteLength: constexpr uintptr generates 'JSArrayBuffer::kMaxByteLength'; const kMaxTypedArrayInHeap: constexpr int31 generates 'JSTypedArray::kMaxSizeInHeap'; // CSA does not support 64-bit types on 32-bit platforms so as a workaround the // kMaxSafeIntegerUint64 is defined as uintptr and allowed to be used only // inside if constexpr (Is64()) i.e. on 64-bit architectures. const kMaxSafeIntegerUint64: constexpr uintptr generates 'CodeStubAssembler::MaxSafeIntegerUintPtr()'; const kMaxSafeInteger: constexpr float64 generates 'kMaxSafeInteger'; const kMaxUInt32Double: constexpr float64 generates 'kMaxUInt32Double'; const kSmiMaxValue: constexpr uintptr generates 'kSmiMaxValue'; const kSmiMax: uintptr = kSmiMaxValue; // TODO(v8:8996): Use uintptr version instead and drop this one. const kStringMaxLength: constexpr int31 generates 'String::kMaxLength'; const kStringMaxLengthUintptr: constexpr uintptr generates 'String::kMaxLength'; const kFixedArrayMaxLength: constexpr int31 generates 'FixedArray::kMaxLength'; const kFixedDoubleArrayMaxLength: constexpr int31 generates 'FixedDoubleArray::kMaxLength'; const kObjectAlignmentMask: constexpr intptr generates 'kObjectAlignmentMask'; const kObjectAlignment: constexpr intptr generates 'kObjectAlignment'; const kMinAddedElementsCapacity: constexpr int31 generates 'JSObject::kMinAddedElementsCapacity'; const kMaxFastArrayLength: constexpr int31 generates 'JSArray::kMaxFastArrayLength'; const kMaxCopyElements: constexpr int31 generates 'JSArray::kMaxCopyElements'; const kMaxRegularHeapObjectSize: constexpr int31 generates 'kMaxRegularHeapObjectSize'; const kMaxNewSpaceFixedArrayElements: constexpr int31 generates 'FixedArray::kMaxRegularLength'; extern enum PrimitiveType { kString, kBoolean, kSymbol, kNumber } const kNameDictionaryInitialCapacity: constexpr int32 generates 'NameDictionary::kInitialCapacity'; const kSwissNameDictionaryInitialCapacity: constexpr int32 generates 'SwissNameDictionary::kInitialCapacity'; const kWasmArrayHeaderSize: constexpr int32 generates 'WasmArray::kHeaderSize'; const kHeapObjectHeaderSize: constexpr int32 generates 'HeapObject::kHeaderSize'; type TheHole extends Hole; type Exception extends Oddball; type EmptyString extends String; type NumberOrUndefined = Number|Undefined; extern macro DefaultStringConstant(): String; extern macro EmptyStringConstant(): EmptyString; extern macro ErrorsStringConstant(): String; extern macro FalseConstant(): False; extern macro GetStringConstant(): String; extern macro HasStringConstant(): String; extern macro Int32FalseConstant(): bool; extern macro Int32TrueConstant(): bool; extern macro IteratorSymbolConstant(): PublicSymbol; extern macro KeysStringConstant(): String; extern macro AsyncIteratorSymbolConstant(): PublicSymbol; extern macro LengthStringConstant(): String; extern macro MatchSymbolConstant(): Symbol; extern macro MessageStringConstant(): String; extern macro NanConstant(): NaN; extern macro NameStringConstant(): String; extern macro NextStringConstant(): String; extern macro NullConstant(): Null; extern macro NumberStringConstant(): String; extern macro ReturnStringConstant(): String; extern macro SearchSymbolConstant(): Symbol; extern macro SizeStringConstant(): String; extern macro StringStringConstant(): String; extern macro TheHoleConstant(): TheHole; extern macro ToPrimitiveSymbolConstant(): PublicSymbol; extern macro ToStringStringConstant(): String; extern macro TrueConstant(): True; extern macro UndefinedConstant(): Undefined; extern macro ValueOfStringConstant(): String; extern macro WasmWrappedObjectSymbolConstant(): Symbol; const TheHole: TheHole = TheHoleConstant(); const Null: Null = NullConstant(); const Undefined: Undefined = UndefinedConstant(); const True: True = TrueConstant(); const False: False = FalseConstant(); const kEmptyString: EmptyString = EmptyStringConstant(); const kLengthString: String = LengthStringConstant(); const kMessageString: String = MessageStringConstant(); const kNextString: String = NextStringConstant(); const kReturnString: String = ReturnStringConstant(); const kSizeString: String = SizeStringConstant(); const kHasString: String = HasStringConstant(); const kKeysString: String = KeysStringConstant(); const kNaN: NaN = NanConstant(); const kZero: Zero = %RawDownCast<Zero>(SmiConstant(0)); const kZeroBitPattern: TaggedZeroPattern = %RawDownCast<TaggedZeroPattern>( Convert<Tagged>(BitcastWordToTaggedSigned(Convert<intptr>(0)))); const true: constexpr bool generates 'true'; const false: constexpr bool generates 'false'; extern enum LanguageMode extends bool { kStrict, kSloppy } type LanguageModeSmi extends Smi; const SKIP_WRITE_BARRIER: constexpr WriteBarrierMode generates 'SKIP_WRITE_BARRIER'; const UNSAFE_SKIP_WRITE_BARRIER: constexpr WriteBarrierMode generates 'UNSAFE_SKIP_WRITE_BARRIER'; extern transitioning macro AllocateJSIteratorResult( implicit context: Context)(JSAny, Boolean): JSObject; extern class Filler extends HeapObject generates 'TNode<HeapObject>'; // Various logical subclasses of JSObject, which have their own instance types // but not their own class definitions: // Like JSObject, but created from API function. @apiExposedInstanceTypeValue(0x422) @doNotGenerateCast extern class JSApiObject extends JSObjectWithEmbedderSlots generates 'TNode<JSObject>'; // TODO(gsathya): This only exists to make JSApiObject instance type into a // range. @apiExposedInstanceTypeValue(0x80A) @doNotGenerateCast @highestInstanceTypeWithinParentClassRange extern class JSLastDummyApiObject extends JSApiObject generates 'TNode<JSObject>'; // Like JSApiObject, but requires access checks and/or has interceptors. @apiExposedInstanceTypeValue(0x410) extern class JSSpecialApiObject extends JSSpecialObject generates 'TNode<JSSpecialObject>'; extern class JSContextExtensionObject extends JSObject generates 'TNode<JSObject>'; extern class JSError extends JSObject generates 'TNode<JSObject>'; extern macro Is64(): constexpr bool; extern macro SelectBooleanConstant(bool): Boolean; extern macro Print(constexpr string): void; extern macro Print(constexpr string, Object): void; extern macro Print(Object): void; extern macro Print(constexpr string, uintptr): void; extern macro Print(constexpr string, float64): void; extern macro PrintErr(constexpr string): void; extern macro PrintErr(constexpr string, Object): void; extern macro PrintErr(Object): void; extern macro Comment(constexpr string): void; extern macro DebugBreak(): void; // ES6 7.1.4 ToInteger ( argument ) transitioning macro ToIntegerImpl( implicit context: Context)(input: JSAny): Number { let input = input; while (true) { typeswitch (input) { case (s: Smi): { return s; } case (hn: HeapNumber): { let value = Convert<float64>(hn); if (Float64IsNaN(value)) return SmiConstant(0); value = math::Float64Trunc(value); // ToInteger normalizes -0 to +0. if (value == 0) return SmiConstant(0); const result = ChangeFloat64ToTagged(value); dcheck(IsNumberNormalized(result)); return result; } case (a: JSAnyNotNumber): { input = conversion::NonNumberToNumber(a); } } } unreachable; } transitioning builtin ToInteger( implicit context: Context)(input: JSAny): Number { return ToIntegerImpl(input); } @export transitioning macro ToInteger_Inline( implicit context: Context)(input: JSAny): Number { typeswitch (input) { case (s: Smi): { return s; } case (JSAny): { return ToInteger(input); } } } extern macro ToBigInt(Context, JSAny): BigInt; extern enum BigIntHandling extends int32 constexpr 'CodeStubAssembler::BigIntHandling' { kConvertToNumber, kThrow } extern transitioning macro ToNumber( implicit context: Context)(JSAny, constexpr BigIntHandling): Number; extern transitioning macro ToLength_Inline( implicit context: Context)(JSAny): Number; extern transitioning macro ToNumber_Inline( implicit context: Context)(JSAny): Number; extern transitioning macro ToString_Inline( implicit context: Context)(JSAny): String; extern transitioning macro ToThisString( implicit context: Context)(JSAny, String): String; extern transitioning macro ToThisValue( implicit context: Context)(JSAny, constexpr PrimitiveType, constexpr string): JSAny; extern transitioning macro GetProperty( implicit context: Context)(JSAny, JSAny): JSAny; extern macro IsInterestingProperty(Name): bool; extern macro GetInterestingProperty(Context, JSReceiver, Name): JSAny labels NotFound; extern transitioning builtin SetProperty( implicit context: Context)(JSAny, JSAny, JSAny): JSAny; extern transitioning builtin SetPropertyIgnoreAttributes( implicit context: Context)(JSObject, String, JSAny, Smi): JSAny; extern transitioning builtin CreateDataProperty( implicit context: Context)(JSAny, JSAny, JSAny): JSAny; extern transitioning builtin DeleteProperty( implicit context: Context)(JSAny, JSAny|PrivateSymbol, LanguageModeSmi): Boolean; extern transitioning builtin HasProperty( implicit context: Context)(JSAny, JSAny): Boolean; extern transitioning macro HasProperty_Inline( implicit context: Context)(JSReceiver, JSAny): Boolean; extern builtin LoadIC( Context, JSAny, JSAny, TaggedIndex, FeedbackVector): JSAny; extern macro SetPropertyStrict(Context, Object, Object, Object): Object; extern macro ThrowRangeError( implicit context: Context)(constexpr MessageTemplate): never; extern macro ThrowRangeError( implicit context: Context)(constexpr MessageTemplate, Object): never; extern macro ThrowRangeError( implicit context: Context)(constexpr MessageTemplate, Object, Object): never; extern macro ThrowTypeError( implicit context: Context)(constexpr MessageTemplate): never; extern macro ThrowTypeError( implicit context: Context)(constexpr MessageTemplate, constexpr string): never; extern macro ThrowTypeError( implicit context: Context)(constexpr MessageTemplate, Object): never; extern macro ThrowTypeError( implicit context: Context)(constexpr MessageTemplate, Object, Object): never; extern macro ThrowTypeError( implicit context: Context)(constexpr MessageTemplate, Object, Object, Object): never; extern transitioning runtime ThrowTypeErrorIfStrict( implicit context: Context)(Smi, Object, Object): void; extern transitioning runtime ThrowIteratorError( implicit context: Context)(JSAny): never; extern transitioning runtime ThrowCalledNonCallable( implicit context: Context)(JSAny): never; extern transitioning macro ThrowIfNotJSReceiver( implicit context: Context)(JSAny, constexpr MessageTemplate, constexpr string): void; extern macro TerminateExecution(implicit context: Context)(): never; extern macro ArraySpeciesCreate(Context, JSAny, Number): JSReceiver; extern macro ArrayCreate(implicit context: Context)(Number): JSArray; extern macro BuildAppendJSArray( constexpr ElementsKind, FastJSArray, JSAny): void labels Bailout; extern macro EnsureArrayPushable(implicit context: Context)(Map): ElementsKind labels Bailout; // TODO: Reduce duplication once varargs are supported in macros. extern macro Construct(implicit context: Context)(Constructor): JSReceiver; extern macro Construct( implicit context: Context)(Constructor, JSAny): JSReceiver; extern macro Construct( implicit context: Context)(Constructor, JSAny, JSAny): JSReceiver; extern macro Construct( implicit context: Context)(Constructor, JSAny, JSAny, JSAny): JSReceiver; extern macro ConstructWithTarget( implicit context: Context)(Constructor, JSReceiver): JSReceiver; extern macro ConstructWithTarget( implicit context: Context)(Constructor, JSReceiver, JSAny): JSReceiver; extern macro SpeciesConstructor( implicit context: Context)(JSAny, JSReceiver): JSReceiver; extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool; extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32): NameDictionary; extern macro CodeStubAssembler::AllocateNameDictionary(intptr): NameDictionary; extern macro CodeStubAssembler::AllocateNameDictionary( intptr, constexpr AllocationFlag): NameDictionary; extern macro CodeStubAssembler::AllocateOrderedNameDictionary(constexpr int32): OrderedNameDictionary; extern macro CodeStubAssembler::AllocateSwissNameDictionary(constexpr int32): SwissNameDictionary; extern macro CodeStubAssembler::AddToDictionary( NameDictionary, Name, Object): void labels Bailout; extern macro CodeStubAssembler::AddToDictionary( SwissNameDictionary, Name, Object): void labels Bailout; extern macro AllocateOrderedHashSet(): OrderedHashSet; extern macro AllocateOrderedHashMap(): OrderedHashMap; extern builtin ToObject(Context, JSAny): JSReceiver; extern macro ToObject_Inline(Context, JSAny): JSReceiver; extern macro IsUndefined(Object): bool; extern macro IsNullOrUndefined(Object): bool; extern macro IsString(HeapObject): bool; extern transitioning builtin NonPrimitiveToPrimitive_String( Context, JSAny): JSPrimitive; extern transitioning builtin NonPrimitiveToPrimitive_Default( Context, JSAny): JSPrimitive; transitioning macro ToPrimitiveDefault( implicit context: Context)(v: JSAny): JSPrimitive { typeswitch (v) { case (v: JSReceiver): { return NonPrimitiveToPrimitive_Default(context, v); } case (v: JSPrimitive): { return v; } } } extern transitioning runtime NormalizeElements(Context, JSObject): void; extern transitioning runtime TransitionElementsKindWithKind( Context, JSObject, Smi): void; extern macro ArrayListElements(ArrayList): FixedArray; extern macro LoadObjectField(HeapObject, constexpr int32): Object; extern macro LoadBufferObject(RawPtr, constexpr int32): Object; extern macro LoadBufferPointer(RawPtr, constexpr int32): RawPtr; extern macro LoadBufferSmi(RawPtr, constexpr int32): Smi; extern macro LoadBufferIntptr(RawPtr, constexpr int32): intptr; extern runtime StringEqual(Context, String, String): Oddball; extern builtin StringLessThan(String, String): Boolean; extern builtin StringCompare(String, String): Smi; extern macro StringCharCodeAt(String, uintptr): char16; extern macro StringFromSingleCharCode(char8): String; extern macro StringFromSingleCharCode(char16): String; extern macro NumberToString(Number): String; extern macro StringToNumber(String): Number; extern transitioning macro NonNumberToNumber( implicit context: Context)(JSAnyNotNumber): Number; extern transitioning macro NonNumberToNumeric( implicit context: Context)(JSAnyNotNumber): Numeric; extern macro Equal(JSAny, JSAny, Context): Boolean; macro Equal(implicit context: Context)(left: JSAny, right: JSAny): Boolean { return Equal(left, right); } extern macro StrictEqual(JSAny, JSAny): Boolean; extern macro SmiLexicographicCompare(Smi, Smi): Smi; extern runtime ReThrowWithMessage( Context, JSAny, TheHole|JSMessageObject): never; extern runtime Throw(implicit context: Context)(JSAny): never; extern runtime ThrowInvalidStringLength(Context): never; extern operator '==' macro WordEqual(RawPtr, RawPtr): bool; extern operator '!=' macro WordNotEqual(RawPtr, RawPtr): bool; extern operator '+' macro RawPtrAdd(RawPtr, intptr): RawPtr; extern operator '+' macro RawPtrAdd(intptr, RawPtr): RawPtr; extern operator '<' macro Int32LessThan(int32, int32): bool; extern operator '<' macro Uint32LessThan(uint32, uint32): bool; extern operator '>' macro Int32GreaterThan(int32, int32): bool; extern operator '>' macro Uint32GreaterThan(uint32, uint32): bool; extern operator '<=' macro Int32LessThanOrEqual(int32, int32): bool; extern operator '<=' macro Uint32LessThanOrEqual(uint32, uint32): bool; extern operator '>=' macro Int32GreaterThanOrEqual(int32, int32): bool; extern operator '>=' macro Uint32GreaterThanOrEqual(uint32, uint32): bool; extern operator '==' macro SmiEqual(Smi, Smi): bool; extern operator '!=' macro SmiNotEqual(Smi, Smi): bool; extern operator '<' macro SmiLessThan(Smi, Smi): bool; extern operator '<=' macro SmiLessThanOrEqual(Smi, Smi): bool; extern operator '>' macro SmiGreaterThan(Smi, Smi): bool; extern operator '>=' macro SmiGreaterThanOrEqual(Smi, Smi): bool; extern operator '==' macro ElementsKindEqual( constexpr ElementsKind, constexpr ElementsKind): constexpr bool; extern operator '==' macro ElementsKindEqual(ElementsKind, ElementsKind): bool; operator '!=' macro ElementsKindNotEqual( k1: ElementsKind, k2: ElementsKind): bool { return !ElementsKindEqual(k1, k2); } extern macro IsElementsKindLessThanOrEqual( ElementsKind, constexpr ElementsKind): bool; extern macro IsElementsKindGreaterThan( ElementsKind, constexpr ElementsKind): bool; extern macro IsElementsKindGreaterThanOrEqual( ElementsKind, constexpr ElementsKind): bool; extern macro IsElementsKindInRange( ElementsKind, constexpr ElementsKind, constexpr ElementsKind): bool; extern macro IsFastElementsKind(constexpr ElementsKind): constexpr bool; extern macro IsFastPackedElementsKind(constexpr ElementsKind): constexpr bool; extern macro IsDoubleElementsKind(constexpr ElementsKind): constexpr bool; extern macro GetNonRabGsabElementsKind(ElementsKind): ElementsKind; extern macro IsFastAliasedArgumentsMap(implicit context: Context)(Map): bool; extern macro IsSlowAliasedArgumentsMap(implicit context: Context)(Map): bool; extern macro IsSloppyArgumentsMap(implicit context: Context)(Map): bool; extern macro IsStrictArgumentsMap(implicit context: Context)(Map): bool; extern macro IsTuple2Map(Map): bool; extern macro SmiAbove(Smi, Smi): bool; extern operator '==' macro WordEqual(intptr, intptr): bool; extern operator '==' macro WordEqual(uintptr, uintptr): bool; extern operator '!=' macro WordNotEqual(intptr, intptr): bool; extern operator '!=' macro WordNotEqual(uintptr, uintptr): bool; extern operator '<' macro IntPtrLessThan(intptr, intptr): bool; extern operator '<' macro UintPtrLessThan(uintptr, uintptr): bool; extern operator '>' macro IntPtrGreaterThan(intptr, intptr): bool; extern operator '>' macro UintPtrGreaterThan(uintptr, uintptr): bool; extern operator '<=' macro IntPtrLessThanOrEqual(intptr, intptr): bool; extern operator '<=' macro UintPtrLessThanOrEqual(uintptr, uintptr): bool; extern operator '>=' macro IntPtrGreaterThanOrEqual(intptr, intptr): bool; extern operator '>=' macro UintPtrGreaterThanOrEqual(uintptr, uintptr): bool; extern operator '~' macro WordNot(intptr): intptr; extern operator '~' macro WordNot(uintptr): uintptr; extern operator '~' macro Word32BitwiseNot(int32): int32; extern operator '~' macro Word64Not(uint64): uint64; extern operator '~' macro Word64Not(int64): int64; extern operator '~' macro ConstexprWordNot(constexpr intptr): constexpr intptr; extern operator '~' macro ConstexprWordNot(constexpr uintptr): constexpr uintptr; extern operator '==' macro Float64Equal(float64, float64): bool; extern operator '!=' macro Float64NotEqual(float64, float64): bool; extern operator '>' macro Float64GreaterThan(float64, float64): bool; extern operator '>=' macro Float64GreaterThanOrEqual(float64, float64): bool; extern operator '<' macro Float64LessThan(float64, float64): bool; extern operator '<=' macro Float64LessThanOrEqual(float64, float64): bool; extern macro Float64AlmostEqual(float64, float64, constexpr float64): bool; extern macro BranchIfNumberEqual(Number, Number): never labels Taken, NotTaken; operator '==' macro IsNumberEqual(a: Number, b: Number): bool { BranchIfNumberEqual(a, b) otherwise return true, return false; } operator '!=' macro IsNumberNotEqual(a: Number, b: Number): bool { return !(a == b); } extern macro BranchIfNumberLessThan(Number, Number): never labels Taken, NotTaken; operator '<' macro NumberIsLessThan(a: Number, b: Number): bool { BranchIfNumberLessThan(a, b) otherwise return true, return false; } extern macro BranchIfNumberLessThanOrEqual(Number, Number): never labels Taken, NotTaken; operator '<=' macro NumberIsLessThanOrEqual(a: Number, b: Number): bool { BranchIfNumberLessThanOrEqual(a, b) otherwise return true, return false; } operator '>' macro NumberIsGreaterThan(a: Number, b: Number): bool { return b < a; } operator '>=' macro NumberIsGreaterThanOrEqual(a: Number, b: Number): bool { return b <= a; } extern macro BranchIfFloat64IsNaN(float64): never labels Taken, NotTaken; macro Float64IsNaN(n: float64): bool { BranchIfFloat64IsNaN(n) otherwise return true, return false; } // The type of all tagged values that can safely be compared with TaggedEqual. @if(V8_ENABLE_WEBASSEMBLY) type TaggedWithIdentity = JSReceiver|FixedArrayBase|Oddball|Hole|Map|WeakCell| Context|EmptyString|Symbol|WasmInternalFunction|WasmNull; @ifnot(V8_ENABLE_WEBASSEMBLY) type TaggedWithIdentity = JSReceiver|FixedArrayBase|Oddball|Hole|Map|WeakCell| Context|EmptyString|Symbol; extern operator '==' macro TaggedEqual(TaggedWithIdentity, Object): bool; extern operator '==' macro TaggedEqual(Object, TaggedWithIdentity): bool; extern operator '==' macro TaggedEqual( TaggedWithIdentity, TaggedWithIdentity): bool; extern operator '==' macro TaggedEqual(WeakHeapObject, WeakHeapObject): bool; extern operator '!=' macro TaggedNotEqual(TaggedWithIdentity, Object): bool; extern operator '!=' macro TaggedNotEqual(Object, TaggedWithIdentity): bool; extern operator '!=' macro TaggedNotEqual( TaggedWithIdentity, TaggedWithIdentity): bool; extern operator '!=' macro TaggedNotEqual(WeakHeapObject, WeakHeapObject): bool; // Do not overload == and != if it is unclear if object identity is the right // equality. extern macro TaggedEqual(MaybeObject, MaybeObject): bool; extern macro TaggedNotEqual(MaybeObject, MaybeObject): bool; extern operator '+' macro SmiAdd(Smi, Smi): Smi; extern operator '-' macro SmiSub(Smi, Smi): Smi; extern operator '&' macro SmiAnd(Smi, Smi): Smi; extern operator '|' macro SmiOr(Smi, Smi): Smi; extern operator '<<' macro SmiShl(Smi, constexpr int31): Smi; extern operator '>>' macro SmiSar(Smi, constexpr int31): Smi; extern operator '+' macro IntPtrAdd(intptr, intptr): intptr; extern operator '+' macro ConstexprIntPtrAdd( constexpr intptr, constexpr intptr): constexpr intptr; extern operator '+' macro ConstexprUintPtrAdd( constexpr uintptr, constexpr uintptr): constexpr intptr; extern operator '+' macro Int64Add(int64, int64): int64; extern operator '-' macro IntPtrSub(intptr, intptr): intptr; extern operator '-' macro Int64Sub(int64, int64): int64; extern operator '*' macro IntPtrMul(intptr, intptr): intptr; extern operator '*' macro Int64Mul(int64, int64): int64; extern operator '/' macro IntPtrDiv(intptr, intptr): intptr; extern operator '/' macro Int64Div(int64, int64): int64; extern operator '%' macro IntPtrMod(intptr, intptr): intptr; extern operator '%' macro Int64Mod(int64, int64): int64; extern operator '<<' macro WordShl(intptr, intptr): intptr; extern operator '>>' macro WordSar(intptr, intptr): intptr; extern operator '&' macro WordAnd(intptr, intptr): intptr; extern operator '|' macro WordOr(intptr, intptr): intptr; extern operator '+' macro UintPtrAdd(uintptr, uintptr): uintptr; extern operator '+' macro Uint64Add(uint64, uint64): uint64; extern operator '-' macro UintPtrSub(uintptr, uintptr): uintptr; extern operator '-' macro Uint64Sub(uint64, uint64): uint64; extern operator '*' macro Uint64Mul(uint64, uint64): uint64; extern operator '<<' macro WordShl(uintptr, uintptr): uintptr; extern operator '>>>' macro WordShr(uintptr, uintptr): uintptr; extern operator '&' macro WordAnd(uintptr, uintptr): uintptr; extern operator '|' macro WordOr(uintptr, uintptr): uintptr; extern operator '+' macro Int32Add(int32, int32): int32; extern operator '+' macro Uint32Add(uint32, uint32): uint32; extern operator '+' macro ConstexprUint32Add( constexpr uint32, constexpr int32): constexpr uint32; extern operator '+' macro ConstexprInt31Add( constexpr int31, constexpr int31): constexpr int31; extern operator '+' macro ConstexprInt32Add( constexpr int32, constexpr int32): constexpr int32; extern operator '*' macro ConstexprInt31Mul( constexpr int31, constexpr int31): constexpr int31; extern operator '-' macro Int32Sub(int16, int16): int32; extern operator '-' macro Int32Sub(int32, int32): int32; extern operator '-' macro Uint32Sub(uint32, uint32): uint32; extern operator '*' macro Int32Mul(int32, int32): int32; extern operator '*' macro Uint32Mul(uint32, uint32): uint32; extern operator '/' macro Int32Div(int32, int32): int32; extern operator '/' macro Uint32Div(uint32, uint32): uint32; extern operator '%' macro Int32Mod(int32, int32): int32; extern operator '%' macro Uint32Mod(uint32, uint32): uint32; extern operator '&' macro Word32And(int32, int32): int32; extern operator '&' macro Word32And(uint32, uint32): uint32; extern operator '==' macro ConstexprInt31Equal( constexpr int31, constexpr int31): constexpr bool; extern operator '!=' macro ConstexprInt31NotEqual( constexpr int31, constexpr int31): constexpr bool; extern operator '==' macro ConstexprUint32Equal( constexpr uint32, constexpr uint32): constexpr bool; extern operator '!=' macro ConstexprUint32NotEqual( constexpr uint32, constexpr uint32): constexpr bool; extern operator '>=' macro ConstexprInt31GreaterThanEqual( constexpr int31, constexpr int31): constexpr bool; extern operator '==' macro ConstexprInt32Equal( constexpr int32, constexpr int32): constexpr bool; extern operator '!=' macro ConstexprInt32NotEqual( constexpr int32, constexpr int32): constexpr bool; // IntegerLiteral overloads extern macro ConstexprIntegerLiteralToInt31(constexpr IntegerLiteral): constexpr int31; extern macro ConstexprIntegerLiteralToInt32(constexpr IntegerLiteral): constexpr int32; extern macro ConstexprIntegerLiteralToUint32(constexpr IntegerLiteral): constexpr uint32; extern macro ConstexprIntegerLiteralToInt64(constexpr IntegerLiteral): constexpr int64; extern macro ConstexprIntegerLiteralToUint64(constexpr IntegerLiteral): constexpr uint64; extern macro ConstexprIntegerLiteralToIntptr(constexpr IntegerLiteral): constexpr intptr; extern macro ConstexprIntegerLiteralToUintptr(constexpr IntegerLiteral): constexpr uintptr; extern macro ConstexprIntegerLiteralToInt8(constexpr IntegerLiteral): constexpr int8; extern macro ConstexprIntegerLiteralToUint8(constexpr IntegerLiteral): constexpr uint8; extern macro ConstexprIntegerLiteralToFloat64(constexpr IntegerLiteral): constexpr float64; extern operator '==' macro ConstexprIntegerLiteralEqual( constexpr IntegerLiteral, constexpr IntegerLiteral): constexpr bool; extern operator '+' macro ConstexprIntegerLiteralAdd( constexpr IntegerLiteral, constexpr IntegerLiteral): constexpr IntegerLiteral; extern operator '<<' macro ConstexprIntegerLiteralLeftShift( constexpr IntegerLiteral, constexpr IntegerLiteral): constexpr IntegerLiteral; extern operator '|' macro ConstexprIntegerLiteralBitwiseOr( constexpr IntegerLiteral, constexpr IntegerLiteral): constexpr IntegerLiteral; extern operator '==' macro Word32Equal(int32, int32): bool; extern operator '==' macro Word32Equal(uint32, uint32): bool; extern operator '!=' macro Word32NotEqual(int32, int32): bool; extern operator '!=' macro Word32NotEqual(uint32, uint32): bool; extern operator '>>>' macro Word32Shr(uint32, uint32): uint32; extern operator '>>' macro Word32Sar(int32, int32): int32; extern operator '<<' macro Word32Shl(int32, int32): int32; extern operator '<<' macro Word32Shl(uint32, uint32): uint32; extern operator '|' macro Word32Or(int32, int32): int32; extern operator '|' macro Word32Or(uint32, uint32): uint32; extern operator '&' macro Word32And(bool, bool): bool; extern operator '|' macro Word32Or(bool, bool): bool; extern operator '==' macro Word32Equal(bool, bool): bool; extern operator '!=' macro Word32NotEqual(bool, bool): bool; extern operator '|' macro ConstexprWord32Or( constexpr int32, constexpr int32): constexpr int32; extern operator '^' macro Word32Xor(int32, int32): int32; extern operator '^' macro Word32Xor(uint32, uint32): uint32; extern operator '<<' macro ConstexprWord32Shl( constexpr uint32, constexpr int32): uint32; extern operator '==' macro Word64Equal(int64, int64): bool; extern operator '==' macro Word64Equal(uint64, uint64): bool; extern operator '!=' macro Word64NotEqual(int64, int64): bool; extern operator '!=' macro Word64NotEqual(uint64, uint64): bool; extern operator '>>>' macro Word64Shr(uint64, uint64): uint64; extern operator '>>' macro Word64Sar(int64, int64): int64; extern operator '<<' macro Word64Shl(int64, int64): int64; extern operator '<<' macro Word64Shl(uint64, uint64): uint64; extern operator '|' macro Word64Or(int64, int64): int64; extern operator '|' macro Word64Or(uint64, uint64): uint64; extern operator '&' macro Word64And(uint64, uint64): uint64; extern operator '^' macro Word64Xor(int64, int64): int64; extern operator '^' macro Word64Xor(uint64, uint64): uint64; extern operator '+' macro Float64Add(float64, float64): float64; extern operator '-' macro Float64Sub(float64, float64): float64; extern operator '*' macro Float64Mul(float64, float64): float64; extern operator '/' macro Float64Div(float64, float64): float64; extern operator '%' macro Float64Mod(float64, float64): float64; extern operator '+' macro NumberAdd(Number, Number): Number; extern operator '-' macro NumberSub(Number, Number): Number; extern macro NumberMin(Number, Number): Number; extern macro NumberMax(Number, Number): Number; macro Min(x: Number, y: Number): Number { return NumberMin(x, y); } macro Max(x: Number, y: Number): Number { return NumberMax(x, y); } extern macro TryIntPtrAdd(intptr, intptr): intptr labels Overflow; extern macro TryIntPtrSub(intptr, intptr): intptr labels Overflow; extern macro TryInt32Mul(int32, int32): int32 labels Overflow; extern operator '<' macro ConstexprUintPtrLessThan( constexpr uintptr, constexpr uintptr): constexpr bool; extern operator '<<' macro ConstexprUintPtrShl( constexpr uintptr, constexpr int31): constexpr uintptr; extern operator '>>>' macro ConstexprUintPtrShr( constexpr uintptr, constexpr int31): constexpr uintptr; extern macro SmiMax(Smi, Smi): Smi; extern macro SmiMin(Smi, Smi): Smi; extern macro SmiMul(Smi, Smi): Number; extern macro SmiMod(Smi, Smi): Number; extern macro IntPtrMax(intptr, intptr): intptr; extern macro IntPtrMin(intptr, intptr): intptr; extern macro UintPtrMin(uintptr, uintptr): uintptr; extern operator '!' macro ConstexprBoolNot(constexpr bool): constexpr bool; extern operator '!' macro Word32BinaryNot(bool): bool; extern operator '!' macro IsFalse(Boolean): bool; extern operator '==' macro ConstexprInt31Equal( constexpr InstanceType, constexpr InstanceType): constexpr bool; extern operator '-' macro ConstexprUint32Sub( constexpr InstanceType, constexpr InstanceType): constexpr int32; extern operator '-' macro ConstexprInt32Sub( constexpr int32, constexpr int32): constexpr int32; extern operator '.instanceType' macro LoadInstanceType(HeapObject): InstanceType; operator '.length_uintptr' macro LoadJSArrayLengthAsUintPtr(array: JSArray): uintptr { return Convert<uintptr>(array.length); } extern operator '.length_intptr' macro LoadStringLengthAsWord(String): intptr; operator '.length_uintptr' macro LoadStringLengthAsUintPtr(s: String): uintptr { return Unsigned(s.length_intptr); } extern operator '.length_uint32' macro LoadStringLengthAsWord32(String): uint32; extern operator '.length_smi' macro LoadStringLengthAsSmi(String): Smi; extern builtin StringAdd_CheckNone( implicit context: Context)(String, String): String; operator '+' macro StringAdd( implicit context: Context)(a: String, b: String): String { return StringAdd_CheckNone(a, b); } operator '==' macro PromiseStateEquals( s1: PromiseState, s2: PromiseState): bool { return Word32Equal(s1, s2); } extern macro CountLeadingZeros64(uint64): int64; extern macro CountTrailingZeros32(uint32): int32; extern macro CountTrailingZeros64(uint64): int64; extern macro TaggedIsSmi(Object): bool; extern macro TaggedIsNotSmi(Object): bool; extern macro TaggedIsPositiveSmi(Object): bool; extern macro IsValidPositiveSmi(intptr): bool; extern macro IsInteger(JSAny): bool; extern macro IsInteger(HeapNumber): bool; extern macro AllocateHeapNumberWithValue(float64): HeapNumber; extern macro ChangeInt32ToTagged(int32): Number; extern macro ChangeUint32ToTagged(uint32): Number; extern macro ChangeUintPtrToFloat64(uintptr): float64; extern macro ChangeUintPtrToTagged(uintptr): Number; extern macro Unsigned(int64): uint64; extern macro Unsigned(int32): uint32; extern macro Unsigned(int16): uint16; extern macro Unsigned(int8): uint8; extern macro Unsigned(intptr): uintptr; extern macro Unsigned(RawPtr): uintptr; extern macro Signed(uint64): int64; extern macro Signed(uint32): int32; extern macro Signed(uint16): int16; extern macro Signed(uint8): int8; extern macro Signed(uintptr): intptr; extern macro Signed(RawPtr): intptr; extern macro TruncateIntPtrToInt32(intptr): int32; extern macro TruncateInt64ToInt32(int64): int32; extern macro SmiTag(intptr): Smi; extern macro SmiFromInt32(int32): Smi; extern macro SmiFromUint32(uint32): Smi; extern macro SmiFromIntPtr(intptr): Smi; extern macro SmiUntag(Smi): intptr; macro SmiUntag<T: type>(value: SmiTagged<T>): T { return %RawDownCast<T>(Unsigned(SmiToInt32(Convert<Smi>(value)))); } macro SmiTag<T : type extends uint31>(value: T): SmiTagged<T> { return %RawDownCast<SmiTagged<T>>(SmiFromUint32(value)); } extern macro SmiToInt32(Smi): int32; extern macro SmiToFloat64(Smi): float64; extern macro TaggedIndexToIntPtr(TaggedIndex): intptr; extern macro IntPtrToTaggedIndex(intptr): TaggedIndex; extern macro TaggedIndexToSmi(TaggedIndex): Smi; extern macro SmiToTaggedIndex(Smi): TaggedIndex; extern macro RoundIntPtrToFloat64(intptr): float64; extern macro IntPtrRoundUpToPowerOfTwo32(intptr): intptr; extern macro ChangeFloat32ToFloat64(float32): float64; extern macro RoundInt32ToFloat32(int32): float32; extern macro ChangeNumberToFloat64(Number): float64; extern macro ChangeNumberToUint32(Number): uint32; extern macro ChangeTaggedNonSmiToInt32( implicit context: Context)(HeapObject): int32; extern macro ChangeFloat32ToTagged(float32): Number; extern macro ChangeTaggedToFloat64(implicit context: Context)(JSAny): float64; extern macro ChangeFloat64ToTagged(float64): Number; extern macro ChangeFloat64ToUintPtr(float64): uintptr; extern macro ChangeFloat64ToIntPtr(float64): intptr; extern macro ChangeBoolToInt32(bool): int32; extern macro ChangeInt32ToFloat64(int32): float64; extern macro ChangeInt32ToIntPtr(int32): intptr; // Sign-extends. extern macro ChangeUint32ToWord(uint32): uintptr; // Doesn't sign-extend. extern macro ChangeInt32ToInt64(int32): int64; // Sign-extends. extern macro ChangeUint32ToUint64(uint32): uint64; // Doesn't sign-extend. extern macro LoadNativeContext(Context): NativeContext; extern macro TruncateFloat64ToFloat32(float64): float32; extern macro TruncateHeapNumberValueToWord32(HeapNumber): int32; extern macro LoadJSArrayElementsMap( constexpr ElementsKind, NativeContext): Map; extern macro LoadJSArrayElementsMap(ElementsKind, NativeContext): Map; extern macro NumberConstant(constexpr float64): Number; extern macro NumberConstant(constexpr int32): Number; extern macro NumberConstant(constexpr uint32): Number; extern macro IntPtrConstant(constexpr int31): intptr; extern macro IntPtrConstant(constexpr int32): intptr; extern macro Uint16Constant(constexpr uint16): uint16; extern macro Int32Constant(constexpr int31): int31; extern macro Int32Constant(constexpr int32): int32; macro Int32Constant(i: constexpr IntegerLiteral): int32 { return Int32Constant(ConstexprIntegerLiteralToInt32(i)); } extern macro Int64Constant(constexpr int64): int64; extern macro Uint64Constant(constexpr uint64): uint64; extern macro Float64Constant(constexpr int32): float64; extern macro Float64Constant(constexpr float64): float64; extern macro Float64Constant(constexpr IntegerLiteral): float64; extern macro SmiConstant(constexpr int31): Smi; extern macro SmiConstant(constexpr Smi): Smi; extern macro SmiConstant(constexpr MessageTemplate): Smi; extern macro SmiConstant(constexpr bool): Smi; extern macro SmiConstant(constexpr uint32): Smi; macro SmiConstant(il: constexpr IntegerLiteral): Smi { return SmiConstant(ConstexprIntegerLiteralToInt31(il)); } extern macro BoolConstant(constexpr bool): bool; extern macro StringConstant(constexpr string): String; extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot; extern macro IntPtrConstant(constexpr intptr): intptr; macro IntPtrConstant(il: constexpr IntegerLiteral): intptr { return IntPtrConstant(ConstexprIntegerLiteralToIntptr(il)); } extern macro PointerConstant(constexpr RawPtr): RawPtr; extern macro SingleCharacterStringConstant(constexpr string): String; extern macro Float64SilenceNaN(float64): float64; extern macro BitcastWordToTaggedSigned(intptr): Smi; extern macro BitcastWordToTaggedSigned(uintptr): Smi; extern macro BitcastWordToTagged(intptr): Object; extern macro BitcastWordToTagged(uintptr): Object; extern macro BitcastWordToTagged(RawPtr): Object; extern macro BitcastTaggedToWord(Object): intptr; extern macro BitcastTaggedToWordForTagAndSmiBits(Tagged): intptr; extern macro FixedArrayMapConstant(): Map; extern macro FixedDoubleArrayMapConstant(): Map; extern macro FixedCOWArrayMapConstant(): Map; extern macro EmptyByteArrayConstant(): ByteArray; extern macro EmptyFixedArrayConstant(): EmptyFixedArray; extern macro PromiseCapabilityMapConstant(): Map; extern macro SeqOneByteStringMapConstant(): Map; extern macro SeqTwoByteStringMapConstant(): Map; const kFixedArrayMap: Map = FixedArrayMapConstant(); const kFixedDoubleArrayMap: Map = FixedDoubleArrayMapConstant(); const kCOWMap: Map = FixedCOWArrayMapConstant(); const kEmptyByteArray: ByteArray = EmptyByteArrayConstant(); const kEmptyFixedArray: EmptyFixedArray = EmptyFixedArrayConstant(); const kPromiseCapabilityMap: Map = PromiseCapabilityMapConstant(); // The map of a non-internalized internal SeqOneByteString. const kSeqOneByteStringMap: Map = SeqOneByteStringMapConstant(); // The map of a non-internalized internal SeqTwoByteString. const kSeqTwoByteStringMap: Map = SeqTwoByteStringMapConstant(); macro OutOfBounds<T: type, X: type>(index: T, length: X): bool { return UintPtrGreaterThanOrEqual( Convert<uintptr>(Convert<intptr>(index)), Convert<uintptr>(Convert<intptr>(length))); } extern macro IsPrototypeInitialArrayPrototype( implicit context: Context)(Map): bool; extern macro IsNoElementsProtectorCellInvalid(): bool; extern macro IsArrayIteratorProtectorCellInvalid(): bool; extern macro IsArraySpeciesProtectorCellInvalid(): bool; extern macro IsIsConcatSpreadableProtectorCellInvalid(): bool; extern macro IsTypedArraySpeciesProtectorCellInvalid(): bool; extern macro IsPromiseSpeciesProtectorCellInvalid(): bool; extern macro IsMockArrayBufferAllocatorFlag(): bool; extern macro HasBuiltinSubclassingFlag(): bool; extern macro IsPrototypeTypedArrayPrototype( implicit context: Context)(Map): bool; extern macro IsSetIteratorProtectorCellInvalid(): bool; extern macro IsMapIteratorProtectorCellInvalid(): bool; extern operator '.data_ptr' macro LoadJSTypedArrayDataPtr(JSTypedArray): RawPtr; extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind; extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray): ElementsKind; extern operator '.length' macro LoadFastJSArrayLength(FastJSArray): Smi; operator '.length=' macro StoreFastJSArrayLength( array: FastJSArray, length: Smi): void { const array: JSArray = array; array.length = length; } extern macro GetNumberDictionaryNumberOfElements(NumberDictionary): Smi; extern macro LoadConstructorOrBackPointer(Map): Object; extern macro BasicLoadNumberDictionaryElement(NumberDictionary, intptr): JSAny labels NotData, IfHole; extern macro IsFastElementsKind(ElementsKind): bool; extern macro IsFastPackedElementsKind(ElementsKind): bool; extern macro IsDoubleElementsKind(ElementsKind): bool; extern macro IsFastSmiOrTaggedElementsKind(ElementsKind): bool; extern macro IsFastSmiElementsKind(ElementsKind): bool; extern macro IsHoleyFastElementsKind(ElementsKind): bool; macro FastHoleyElementsKind(kind: ElementsKind): ElementsKind { if (kind == ElementsKind::PACKED_SMI_ELEMENTS) { return ElementsKind::HOLEY_SMI_ELEMENTS; } else if (kind == ElementsKind::PACKED_DOUBLE_ELEMENTS) { return ElementsKind::HOLEY_DOUBLE_ELEMENTS; } dcheck(kind == ElementsKind::PACKED_ELEMENTS); return ElementsKind::HOLEY_ELEMENTS; } macro AllowDoubleElements(kind: ElementsKind): ElementsKind { if (kind == ElementsKind::PACKED_SMI_ELEMENTS) { return ElementsKind::PACKED_DOUBLE_ELEMENTS; } else if (kind == ElementsKind::HOLEY_SMI_ELEMENTS) { return ElementsKind::HOLEY_DOUBLE_ELEMENTS; } return kind; } macro AllowNonNumberElements(kind: ElementsKind): ElementsKind { if (kind == ElementsKind::PACKED_SMI_ELEMENTS) { return ElementsKind::PACKED_ELEMENTS; } else if (kind == ElementsKind::HOLEY_SMI_ELEMENTS) { return ElementsKind::HOLEY_ELEMENTS; } else if (kind == ElementsKind::PACKED_DOUBLE_ELEMENTS) { return ElementsKind::PACKED_ELEMENTS; } else if (kind == ElementsKind::HOLEY_DOUBLE_ELEMENTS) { return ElementsKind::HOLEY_ELEMENTS; } return kind; } macro GetObjectFunction(implicit context: Context)(): JSFunction { return *NativeContextSlot(ContextSlot::OBJECT_FUNCTION_INDEX); } macro GetArrayFunction(implicit context: Context)(): JSFunction { return *NativeContextSlot(ContextSlot::ARRAY_FUNCTION_INDEX); } macro GetArrayBufferFunction(implicit context: Context)(): Constructor { return *NativeContextSlot(ContextSlot::ARRAY_BUFFER_FUN_INDEX); } macro GetArrayBufferNoInitFunction(implicit context: Context)(): JSFunction { return *NativeContextSlot(ContextSlot::ARRAY_BUFFER_NOINIT_FUN_INDEX); } macro GetIteratorFunction(implicit context: Context)(): JSFunction { return *NativeContextSlot(ContextSlot::ITERATOR_FUNCTION_INDEX); } macro GetFastPackedElementsJSArrayMap(implicit context: Context)(): Map { return *NativeContextSlot(ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX); } macro GetFastPackedSmiElementsJSArrayMap(implicit context: Context)(): Map { return *NativeContextSlot( ContextSlot::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX); } macro GetProxyRevocableResultMap(implicit context: Context)(): Map { return *NativeContextSlot(ContextSlot::PROXY_REVOCABLE_RESULT_MAP_INDEX); } macro GetIteratorResultMap(implicit context: Context)(): Map { return *NativeContextSlot(ContextSlot::ITERATOR_RESULT_MAP_INDEX); } macro GetInitialStringIteratorMap(implicit context: Context)(): Map { return *NativeContextSlot(ContextSlot::INITIAL_STRING_ITERATOR_MAP_INDEX); } macro GetReflectApply(implicit context: Context)(): Callable { return *NativeContextSlot(ContextSlot::REFLECT_APPLY_INDEX); } macro GetRegExpLastMatchInfo(implicit context: Context)(): RegExpMatchInfo { return *NativeContextSlot(ContextSlot::REGEXP_LAST_MATCH_INFO_INDEX); } macro GetStrictArgumentsMap(implicit context: Context)(): Map { return *NativeContextSlot(ContextSlot::STRICT_ARGUMENTS_MAP_INDEX); } macro GetSloppyArgumentsMap(implicit context: Context)(): Map { return *NativeContextSlot(ContextSlot::SLOPPY_ARGUMENTS_MAP_INDEX); } macro GetFastAliasedArgumentsMap(implicit context: Context)(): Map { return *NativeContextSlot(ContextSlot::FAST_ALIASED_ARGUMENTS_MAP_INDEX); } macro GetWeakCellMap(implicit context: Context)(): Map { return %GetClassMapConstant<WeakCell>(); } macro GetPrototypeApplyFunction(implicit context: Context)(): JSFunction { return *NativeContextSlot(ContextSlot::FUNCTION_PROTOTYPE_APPLY_INDEX); } // Call(Context, Target, Receiver, ...Args) // TODO(joshualitt): Assuming the context parameter is for throwing when Target // is non-callable, then we should make it an implicit // parameter. extern transitioning macro Call(Context, JSAny, JSAny): JSAny; extern transitioning macro Call(Context, JSAny, JSAny, JSAny): JSAny; extern transitioning macro Call(Context, JSAny, JSAny, JSAny, JSAny): JSAny; extern transitioning macro Call( Context, JSAny, JSAny, JSAny, JSAny, JSAny): JSAny; extern transitioning macro Call( Context, JSAny, JSAny, JSAny, JSAny, JSAny, JSAny): JSAny; extern transitioning macro Call( Context, JSAny, JSAny, JSAny, JSAny, JSAny, JSAny, JSAny): JSAny; extern macro TransitionElementsKind( JSObject, Map, constexpr ElementsKind, constexpr ElementsKind): void labels Bailout; extern macro PerformStackCheck(implicit context: Context)(): void; extern macro Typeof(JSAny): String; // Return true iff number is NaN. macro NumberIsNaN(number: Number): bool { typeswitch (number) { case (Smi): { return false; } case (hn: HeapNumber): { const value: float64 = Convert<float64>(hn); return value != value; } } } extern macro GotoIfForceSlowPath(): void labels Taken; macro IsForceSlowPath(): bool { GotoIfForceSlowPath() otherwise return true; return false; } extern macro BranchIfToBooleanIsTrue(JSAny): never labels Taken, NotTaken; extern macro BranchIfToBooleanIsFalse(JSAny): never labels Taken, NotTaken; macro ToBoolean(obj: JSAny): bool { BranchIfToBooleanIsTrue(obj) otherwise return true, return false; } @export macro RequireObjectCoercible( implicit context: Context)(value: JSAny, name: constexpr string): JSAny { if (IsNullOrUndefined(value)) { ThrowTypeError(MessageTemplate::kCalledOnNullOrUndefined, name); } return value; } extern macro BranchIfSameValue(JSAny, JSAny): never labels Taken, NotTaken; macro SameValue(a: JSAny, b: JSAny): bool { BranchIfSameValue(a, b) otherwise return true, return false; } macro SameValue(a: (JSAny|TheHole), b: (JSAny|TheHole)): bool { typeswitch (a) { case (a: TheHole): { return UnsafeCast<TheHole>(b) == a; } case (a: JSAny): { typeswitch (b) { case (TheHole): { return false; } case (b: JSAny): { return SameValue(a, b); } } } } } // Does "if (index1 + index2 > limit) goto IfOverflow" in an uintptr overflow // friendly way where index1 and index2 are in [0, kMaxSafeInteger] range. macro CheckIntegerIndexAdditionOverflow( index1: uintptr, index2: uintptr, limit: uintptr): void labels IfOverflow { if constexpr (Is64()) { dcheck(index1 <= kMaxSafeIntegerUint64); dcheck(index2 <= kMaxSafeIntegerUint64); // Given that both index1 and index2 are in a safe integer range the // addition can't overflow. if (index1 + index2 > limit) goto IfOverflow; } else { // Uintptr range is "smaller" than [0, kMaxSafeInteger] range, so // "index1 + index2" may overflow, so we check the condition in the // following way "if (index1 > limit - index2) goto IfOverflow" and check // that "limit - index2" does not underflow. const index1Limit = limit - index2; if (index1 > index1Limit) goto IfOverflow; // Handle potential index1Limit underflow. if (index1Limit > limit) goto IfOverflow; } } // TODO(turbofan): Define enum here once they appear in Torque. // // The value is a SafeInteger that fits into uintptr range, so no bounds checks // are necessary. const kModeValueIsSafeIntegerUintPtr: constexpr int31 = 0; // The value is a SafeInteger that may not fit into uintptr range, so only // uintptr bounds check is necessary. const kModeValueIsSafeInteger: constexpr int31 = 1; // The value is can be whatever non-NaN number, all checks are necessary. const kModeValueIsAnyNumber: constexpr int31 = 2; macro TryNumberToUintPtr(valueNumber: Number, kMode: constexpr int31): uintptr labels IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow { typeswitch (valueNumber) { case (valueSmi: Smi): { if (kMode == kModeValueIsAnyNumber) { if (valueSmi < 0) goto IfLessThanZero; } else { dcheck(valueSmi >= 0); } const value: uintptr = Unsigned(Convert<intptr>(valueSmi)); // Positive Smi values definitely fit into both [0, kMaxSafeInteger] and // [0, kMaxUintPtr] ranges. return value; } case (valueHeapNumber: HeapNumber): { dcheck(IsNumberNormalized(valueHeapNumber)); const valueDouble: float64 = Convert<float64>(valueHeapNumber); // NaNs must be handled outside. dcheck(!Float64IsNaN(valueDouble)); if (kMode == kModeValueIsAnyNumber) { if (valueDouble < 0) goto IfLessThanZero; } else { dcheck(valueDouble >= 0); } if constexpr (Is64()) { // On 64-bit architectures uintptr range is bigger than safe integer // range. if (kMode == kModeValueIsAnyNumber) { if (valueDouble > kMaxSafeInteger) goto IfSafeIntegerOverflow; } else { dcheck(valueDouble <= kMaxSafeInteger); } } else { // On 32-bit architectures uintptr range is smaller than safe integer // range. if (kMode == kModeValueIsAnyNumber || kMode == kModeValueIsSafeInteger) { if (valueDouble > kMaxUInt32Double) goto IfUIntPtrOverflow; } else { dcheck(valueDouble <= kMaxUInt32Double); } } return ChangeFloat64ToUintPtr(valueDouble); } } } @export macro ChangeUintPtrNumberToUintPtr(value: Number): uintptr { try { return TryNumberToUintPtr(value, kModeValueIsSafeIntegerUintPtr) otherwise InvalidValue, InvalidValue, InvalidValue; } label InvalidValue { unreachable; } } @export macro ChangeSafeIntegerNumberToUintPtr(value: Number): uintptr labels IfUIntPtrOverflow { try { return TryNumberToUintPtr(value, kModeValueIsSafeInteger) otherwise InvalidValue, IfUIntPtrOverflow, InvalidValue; } label InvalidValue { unreachable; } } transitioning macro ToUintPtr(implicit context: Context)(value: JSAny): uintptr labels IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow { if (value == Undefined) return 0; const indexNumber = ToInteger_Inline(value); return TryNumberToUintPtr(indexNumber, kModeValueIsAnyNumber) otherwise IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow; } // https://tc39.github.io/ecma262/#sec-toindex // Unlike ToIndex from the spec this implementation triggers IfRangeError if // the result is bigger than min(kMaxUIntPtr, kMaxSafeInteger). // We can do this because all callers do a range checks against uintptr length // anyway and throw a RangeError in case of out-of-bounds index. @export transitioning macro ToIndex( implicit context: Context)(value: JSAny): uintptr labels IfRangeError { if (value == Undefined) return 0; const indexNumber = ToInteger_Inline(value); // Less than 0 case, uintptr range overflow and safe integer range overflow // imply IfRangeError. return TryNumberToUintPtr(indexNumber, kModeValueIsAnyNumber) otherwise IfRangeError, IfRangeError, IfRangeError; } transitioning macro GetLengthProperty( implicit context: Context)(o: JSAny): Number { try { typeswitch (o) { case (a: JSArray): { return a.length; } case (a: JSStrictArgumentsObject): { goto ToLength(a.length); } case (a: JSSloppyArgumentsObject): { goto ToLength(a.length); } case (JSAny): deferred { goto ToLength(GetProperty(o, kLengthString)); } } } label ToLength(length: JSAny) deferred { return ToLength_Inline(length); } } transitioning macro GetMethod( implicit context: Context)(o: JSAny, name: AnyName): Callable labels IfNullOrUndefined, IfMethodNotCallable(JSAny) { // Use GetInterestingMethod - a version of GetMethod optimized for interesting // properties. dcheck(!IsInterestingProperty(name)); const value = GetProperty(o, name); // TODO(v8:9933): Consider checking for null/undefined after checking for // callable because the latter seems to be more common. if (value == Undefined || value == Null) goto IfNullOrUndefined; return Cast<Callable>(value) otherwise goto IfMethodNotCallable(value); } transitioning macro GetMethod( implicit context: Context)(o: JSAny, name: String): Callable labels IfNullOrUndefined { // Use GetInterestingMethod - a version of GetMethod optimized for interesting // properties. dcheck(!IsInterestingProperty(name)); try { return GetMethod(o, name) otherwise IfNullOrUndefined, IfMethodNotCallable; } label IfMethodNotCallable(value: JSAny) deferred { ThrowTypeError(MessageTemplate::kPropertyNotFunction, value, name, o); } } transitioning macro GetMethod( implicit context: Context)(o: JSAny, name: constexpr string): Callable labels IfNullOrUndefined { return GetMethod(o, StringConstant(name)) otherwise IfNullOrUndefined; } transitioning macro GetMethod( implicit context: Context)(o: JSAny, symbol: Symbol): Callable labels IfNullOrUndefined { // Use GetInterestingMethod - a version of GetMethod optimized for interesting // properties. dcheck(!IsInterestingProperty(symbol)); const value = GetProperty(o, symbol); if (value == Undefined || value == Null) goto IfNullOrUndefined; return Cast<Callable>(value) otherwise ThrowTypeError( MessageTemplate::kPropertyNotFunction, value, symbol, o); } transitioning macro GetInterestingMethod( implicit context: Context)(o: JSReceiver, name: String): Callable labels IfNullOrUndefined { dcheck(IsInterestingProperty(name)); try { const value = GetInterestingProperty(context, o, name) otherwise goto IfNullOrUndefined; if (value == Undefined || value == Null) goto IfNullOrUndefined; return Cast<Callable>(value) otherwise goto IfMethodNotCallable(value); } label IfMethodNotCallable(value: JSAny) deferred { ThrowTypeError(MessageTemplate::kPropertyNotFunction, value, name, o); } } extern macro IsOneByteStringInstanceType(InstanceType): bool; // After converting an index to an integer, calculate a relative index: // return index < 0 ? max(length + index, 0) : min(index, length) @export transitioning macro ConvertAndClampRelativeIndex( implicit context: Context)(index: JSAny, length: uintptr): uintptr { const indexNumber: Number = ToInteger_Inline(index); return ConvertAndClampRelativeIndex(indexNumber, length); } // Calculate a relative index: // return index < 0 ? max(length + index, 0) : min(index, length) @export macro ConvertAndClampRelativeIndex( indexNumber: Number, length: uintptr): uintptr { try { return ConvertRelativeIndex(indexNumber, length) otherwise OutOfBoundsLow, OutOfBoundsHigh; } label OutOfBoundsLow { return 0; } label OutOfBoundsHigh { return length; } } // Calculate a relative index with explicit out-of-bounds labels. macro ConvertRelativeIndex(indexNumber: Number, length: uintptr): uintptr labels OutOfBoundsLow, OutOfBoundsHigh { typeswitch (indexNumber) { case (indexSmi: Smi): { const indexIntPtr: intptr = Convert<intptr>(indexSmi); // The logic is implemented using unsigned types. if (indexIntPtr < 0) { const relativeIndex: uintptr = Unsigned(indexIntPtr) + length; if (relativeIndex < length) return relativeIndex; goto OutOfBoundsLow; } else { const relativeIndex: uintptr = Unsigned(indexIntPtr); if (relativeIndex < length) return relativeIndex; goto OutOfBoundsHigh; } } case (indexHeapNumber: HeapNumber): { dcheck(IsNumberNormalized(indexHeapNumber)); const indexDouble: float64 = Convert<float64>(indexHeapNumber); // NaNs must already be handled by ConvertAndClampRelativeIndex() version // above accepting JSAny indices. dcheck(!Float64IsNaN(indexDouble)); const lengthDouble: float64 = Convert<float64>(length); dcheck(lengthDouble <= kMaxSafeInteger); if (indexDouble < 0) { const relativeIndex: float64 = lengthDouble + indexDouble; if (relativeIndex > 0) { return ChangeFloat64ToUintPtr(relativeIndex); } goto OutOfBoundsLow; } else { if (indexDouble < lengthDouble) { return ChangeFloat64ToUintPtr(indexDouble); } goto OutOfBoundsHigh; } } } } // After converting an index to a signed integer, clamps it to the provided // range [0, limit]: // return min(max(index, 0), limit) @export transitioning macro ClampToIndexRange( implicit context: Context)(index: JSAny, limit: uintptr): uintptr { const indexNumber: Number = ToInteger_Inline(index); return ClampToIndexRange(indexNumber, limit); } // Clamps given signed indexNumber to the provided range [0, limit]: // return min(max(index, 0), limit) @export macro ClampToIndexRange(indexNumber: Number, limit: uintptr): uintptr { typeswitch (indexNumber) { case (indexSmi: Smi): { if (indexSmi < 0) return 0; const index: uintptr = Unsigned(Convert<intptr>(indexSmi)); if (index >= limit) return limit; return index; } case (indexHeapNumber: HeapNumber): { dcheck(IsNumberNormalized(indexHeapNumber)); const indexDouble: float64 = Convert<float64>(indexHeapNumber); // NaNs must already be handled by ClampToIndexRange() version // above accepting JSAny indices. dcheck(!Float64IsNaN(indexDouble)); if (indexDouble <= 0) return 0; const maxIndexDouble: float64 = Convert<float64>(limit); dcheck(maxIndexDouble <= kMaxSafeInteger); if (indexDouble >= maxIndexDouble) return limit; return ChangeFloat64ToUintPtr(indexDouble); } } } extern builtin ObjectToString(Context, JSAny): String; extern builtin StringRepeat(Context, String, Number): String; @export struct KeyValuePair { key: JSAny; value: JSAny; } // Macro definitions for compatibility that expose functionality to the CSA // using "legacy" APIs. In Torque code, these should not be used. @export macro IsFastJSArray(o: Object, context: Context): bool { // Long-term, it's likely not a good idea to have this slow-path test here, // since it fundamentally breaks the type system. if (IsForceSlowPath()) return false; return Is<FastJSArray>(o); } @export macro BranchIfFastJSArray(o: Object, context: Context): never labels True, False { if (IsFastJSArray(o, context)) { goto True; } else { goto False; } } @export macro BranchIfFastJSArrayForRead(o: Object, context: Context): never labels True, False { // Long-term, it's likely not a good idea to have this slow-path test here, // since it fundamentally breaks the type system. if (IsForceSlowPath()) goto False; if (Is<FastJSArrayForRead>(o)) { goto True; } else { goto False; } } @export macro IsFastJSArrayWithNoCustomIteration(context: Context, o: Object): bool { return Is<FastJSArrayWithNoCustomIteration>(o); } @export macro IsFastJSArrayForReadWithNoCustomIteration( context: Context, o: Object): bool { return Is<FastJSArrayForReadWithNoCustomIteration>(o); } extern transitioning runtime CreateDataProperty( implicit context: Context)(JSReceiver, JSAny, JSAny): void; extern transitioning runtime SetOwnPropertyIgnoreAttributes( implicit context: Context)(JSObject, String, JSAny, Smi): void; namespace runtime { extern runtime GetDerivedMap(Context, JSFunction, JSReceiver, JSAny): Map; } extern macro IsDeprecatedMap(Map): bool; extern macro LoadSlowObjectWithNullPrototypeMap(NativeContext): Map; transitioning builtin FastCreateDataProperty( implicit context: Context)(receiver: JSReceiver, key: JSAny, value: JSAny): Object { try { const array = Cast<FastJSArray>(receiver) otherwise Slow; const index: Smi = Cast<Smi>(key) otherwise goto Slow; if (index < 0 || index > array.length) goto Slow; const isAppend = index == array.length; if (isAppend) { // Fast append only works on fast elements kind and with writable length. const kind = EnsureArrayPushable(array.map) otherwise Slow; array::EnsureWriteableFastElements(array); // We may have to transition a. // For now, if transition is required, jump away to slow. if (IsFastSmiElementsKind(kind)) { BuildAppendJSArray(ElementsKind::HOLEY_SMI_ELEMENTS, array, value) otherwise Slow; } else if (IsDoubleElementsKind(kind)) { BuildAppendJSArray(ElementsKind::HOLEY_DOUBLE_ELEMENTS, array, value) otherwise Slow; } else { dcheck(IsFastSmiOrTaggedElementsKind(kind)); BuildAppendJSArray(ElementsKind::HOLEY_ELEMENTS, array, value) otherwise Slow; } } else { // Non-appending element store. const kind = array.map.elements_kind; array::EnsureWriteableFastElements(array); // We may have to transition a. // For now, if transition is required, jump away to slow. if (IsFastSmiElementsKind(kind)) { const smiValue = Cast<Smi>(value) otherwise Slow; const elements = Cast<FixedArray>(array.elements) otherwise unreachable; elements[index] = smiValue; } else if (IsDoubleElementsKind(kind)) { const numberValue = Cast<Number>(value) otherwise Slow; const doubleElements = Cast<FixedDoubleArray>(array.elements) otherwise unreachable; doubleElements[index] = numberValue; } else { dcheck(IsFastSmiOrTaggedElementsKind(kind)); const elements = Cast<FixedArray>(array.elements) otherwise unreachable; elements[index] = value; } } } label Slow { CreateDataProperty(receiver, key, value); } return Undefined; } macro VerifiedUnreachable(): never { static_assert(false); unreachable; } macro Float64IsSomeInfinity(value: float64): bool { if (value == V8_INFINITY) { return true; } return value == (Convert<float64>(0) - V8_INFINITY); } macro IsIntegerOrSomeInfinity(o: Object): bool { typeswitch (o) { case (Smi): { return true; } case (hn: HeapNumber): { if (Float64IsSomeInfinity(Convert<float64>(hn))) { return true; } return IsInteger(hn); } case (Object): { return false; } } } macro NumberIsSomeInfinity(n: Number): bool { typeswitch (n) { case (Smi): { return false; } case (hn: HeapNumber): { return Float64IsSomeInfinity(Convert<float64>(hn)); } } } macro ReplaceTheHoleWithUndefined(o: JSAny|TheHole): JSAny { typeswitch (o) { case (TheHole): { return Undefined; } case (a: JSAny): { return a; } } } extern macro DecodeScopeInfoHasContextExtension(intptr): intptr; struct ConstantIterator<T: type> { macro Empty(): bool { return false; } macro Next(): T labels _NoMore { return this.value; } value: T; } macro ConstantIterator<T: type>(value: T): ConstantIterator<T> { return ConstantIterator{value}; } extern macro FeedbackIteratorEntrySize(): intptr; extern macro FeedbackIteratorHandlerOffset(): intptr; extern operator '[]' macro LoadWeakFixedArrayElement( WeakFixedArray, intptr): MaybeObject; extern operator '[]' macro LoadUint8Ptr(RawPtr<uint8>, intptr): uint8; extern operator '[]' macro LoadUint64Ptr(RawPtr<uint64>, intptr): uint64; extern enum HashFieldType extends uint32 constexpr 'Name::HashFieldType' { kHash, kIntegerIndex, kForwardingIndex, kEmpty } operator '==' macro HashFieldTypeEquals( s1: HashFieldType, s2: HashFieldType): bool { return Word32Equal(s1, s2); } const kNoHashSentinel: constexpr int32 generates 'PropertyArray::kNoHashSentinel'; extern macro LoadNameHash(Name): uint32; extern transitioning builtin ToName(implicit context: Context)(JSAny): AnyName; extern macro LoadSimd128(intptr): Simd128; extern macro I8x16BitMask(I8X16): int32; extern macro I8x16Eq(I8X16, I8X16): I8X16; extern macro I8x16Splat(int32): I8X16;