| // 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/elements-kind.h' |
| #include 'src/objects/free-space.h' |
| #include 'src/objects/js-function.h' |
| #include 'src/objects/js-generator.h' |
| #include 'src/objects/js-promise.h' |
| #include 'src/objects/js-regexp-string-iterator.h' |
| #include 'src/objects/js-weak-refs.h' |
| #include 'src/objects/objects.h' |
| #include 'src/objects/source-text-module.h' |
| #include 'src/objects/stack-frame-info.h' |
| #include 'src/objects/synthetic-module.h' |
| #include 'src/objects/template-objects.h' |
| #include 'src/torque/runtime-support.h' |
| |
| type void; |
| type never; |
| |
| 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 value with the size of Tagged which may contain arbitrary data. |
| type Uninitialized extends Tagged; |
| |
| 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(tebbi): 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 |
| // TheHole or 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 int8 constexpr 'char'; |
| type char16 extends uint16 constexpr 'char16_t'; |
| type int64 generates 'TNode<Int64T>' constexpr 'int64_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*'; |
| |
| // 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 { |
| assert(!this.is_hole); |
| return this.value; |
| } |
| |
| is_hole: bool; |
| value: float64; |
| } |
| const kDoubleHole: float64_or_hole = float64_or_hole{is_hole: true, value: 0}; |
| |
| // 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 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>'; |
| extern class NumberDictionary extends HashTable; |
| |
| type RawPtr generates 'TNode<RawPtrT>' constexpr 'Address'; |
| type ExternalPointer |
| generates 'TNode<ExternalPointerT>' constexpr 'ExternalPointer_t'; |
| extern class Code 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; |
| |
| type LayoutDescriptor extends ByteArray |
| generates 'TNode<LayoutDescriptor>'; |
| 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|CallableJSProxy|CallableApiObject; |
| |
| type WriteBarrierMode |
| generates 'TNode<Int32T>' constexpr 'WriteBarrierMode'; |
| |
| extern enum UnicodeEncoding { UTF16, UTF32 } |
| |
| // Promise constants |
| extern enum PromiseState extends int31 constexpr 'Promise::PromiseState' { |
| kPending, |
| kFulfilled, |
| kRejected |
| } |
| |
| type FrameArray extends FixedArray; |
| |
| 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, |
| ... |
| } |
| |
| extern enum AllocationFlag extends int32 |
| constexpr 'CodeStubAssembler::AllocationFlag' { |
| kNone, |
| kDoubleAlignment, |
| kPretenured, |
| kAllowLargeObjectAllocation |
| } |
| |
| extern enum SlackTrackingMode |
| constexpr 'CodeStubAssembler::SlackTrackingMode' { |
| kWithSlackTracking, |
| kNoSlackTracking |
| } |
| |
| extern enum ExtractFixedArrayFlag |
| constexpr 'CodeStubAssembler::ExtractFixedArrayFlag' { |
| kFixedDoubleArrays, |
| kAllFixedArrays, |
| kFixedArrays, |
| ... |
| } |
| |
| const kBigIntMaxLength: constexpr intptr generates 'BigInt::kMaxLength'; |
| |
| extern enum MessageTemplate { |
| kAllPromisesRejected, |
| kInvalidArrayBufferLength, |
| kInvalidArrayLength, |
| kInvalidIndex, |
| kNotConstructor, |
| kNotGeneric, |
| kCalledNonCallable, |
| kCalledOnNullOrUndefined, |
| kCannotConvertToPrimitive, |
| kProtoObjectOrNull, |
| kInvalidOffset, |
| kInvalidTypedArrayLength, |
| kIteratorSymbolNonCallable, |
| kIteratorValueNotAnObject, |
| kNotIterable, |
| kReduceNoInitial, |
| kFirstArgumentNotRegExp, |
| kBigIntMixedTypes, |
| kTypedArrayTooShort, |
| kTypedArrayTooLargeToSort, |
| kInvalidCountValue, |
| kConstructorNotFunction, |
| kSymbolToString, |
| kPropertyNotFunction, |
| kBigIntTooBig, |
| kNotTypedArray, |
| kDetachedOperation, |
| kBadSortComparisonFunction, |
| kIncompatibleMethodReceiver, |
| kInvalidDataViewAccessorOffset, |
| kTypedArraySetOffsetOutOfBounds, |
| kInvalidArgument, |
| kInvalidRegExpExecResult, |
| kRegExpNonRegExp, |
| kRegExpNonObject, |
| kPromiseNonCallable, |
| kNotAPromise, |
| 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, |
| kWasmTrapDataSegmentDropped, |
| kWasmTrapElemSegmentDropped, |
| kWasmTrapTableOutOfBounds, |
| kWasmTrapBrOnExnNull, |
| kWasmTrapRethrowNull, |
| kWasmTrapNullDereference, |
| kWasmTrapIllegalCast, |
| kWasmTrapArrayOutOfBounds, |
| kWeakRefsRegisterTargetAndHoldingsMustNotBeSame, |
| kWeakRefsRegisterTargetMustBeObject, |
| kWeakRefsUnregisterTokenMustBeObject, |
| kWeakRefsWeakRefConstructorTargetMustBeObject, |
| ... |
| } |
| |
| extern enum PropertyAttributes extends int31 { |
| NONE, |
| READ_ONLY, |
| DONT_ENUM, |
| DONT_DELETE, |
| ALL_ATTRIBUTES_MASK, |
| FROZEN, |
| ... |
| } |
| |
| const kMaxArrayIndex: |
| constexpr uint32 generates 'JSArray::kMaxArrayIndex'; |
| const kArrayBufferMaxByteLength: |
| constexpr uintptr generates 'JSArrayBuffer::kMaxByteLength'; |
| const kTypedArrayMaxLength: |
| constexpr uintptr generates 'JSTypedArray::kMaxLength'; |
| 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 kMinAddedElementsCapacity: |
| constexpr int31 generates 'JSObject::kMinAddedElementsCapacity'; |
| 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'; |
| |
| type TheHole extends Oddball; |
| type Null extends Oddball; |
| type Undefined extends Oddball; |
| type True extends Oddball; |
| type False extends Oddball; |
| type Exception extends Oddball; |
| type EmptyString extends String; |
| type Boolean = True|False; |
| |
| type NumberOrUndefined = Number|Undefined; |
| |
| extern macro DefaultStringConstant(): String; |
| extern macro EmptyStringConstant(): EmptyString; |
| extern macro ErrorsStringConstant(): String; |
| extern macro FalseConstant(): False; |
| extern macro Int32FalseConstant(): bool; |
| extern macro Int32TrueConstant(): bool; |
| extern macro IteratorSymbolConstant(): PublicSymbol; |
| extern macro LengthStringConstant(): String; |
| extern macro MatchSymbolConstant(): Symbol; |
| extern macro MessageStringConstant(): String; |
| extern macro NanConstant(): NaN; |
| extern macro NameStringConstant(): String; |
| extern macro NullConstant(): Null; |
| extern macro NumberStringConstant(): String; |
| extern macro ReturnStringConstant(): 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 kReturnString: String = ReturnStringConstant(); |
| |
| const kNaN: NaN = NanConstant(); |
| const kZero: Zero = %RawDownCast<Zero>(SmiConstant(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(0x420) |
| extern class JSApiObject extends JSObject 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); |
| extern macro Print(constexpr string, Object); |
| extern macro Comment(constexpr string); |
| extern macro Print(Object); |
| extern macro DebugBreak(); |
| |
| // 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.0) return SmiConstant(0); |
| const result = ChangeFloat64ToTagged(value); |
| assert(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 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 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 SetPropertyInLiteral(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 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 ThrowCalledNonCallable(implicit context: Context)( |
| JSAny): never; |
| |
| extern transitioning macro ThrowIfNotJSReceiver(implicit context: Context)( |
| JSAny, constexpr MessageTemplate, constexpr string): void; |
| |
| 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 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 macro IsSeqOneByteString(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); |
| extern transitioning runtime TransitionElementsKindWithKind( |
| Context, JSObject, Smi); |
| |
| 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(Context, String, String): Boolean; |
| extern macro StringCharCodeAt(String, uintptr): int32; |
| extern runtime StringCompareSequence(Context, String, String, Number): Boolean; |
| extern macro StringFromSingleCharCode(int32): 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 ReThrow(Context, JSAny): 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 IsElementsKindInRange( |
| ElementsKind, constexpr ElementsKind, constexpr ElementsKind): bool; |
| |
| extern macro IsFastElementsKind(constexpr ElementsKind): constexpr bool; |
| extern macro IsDoubleElementsKind(constexpr ElementsKind): constexpr bool; |
| |
| 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 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 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. |
| type TaggedWithIdentity = |
| JSReceiver|FixedArrayBase|Oddball|Map|WeakCell|Context|EmptyString; |
| |
| 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 IntPtrSub(intptr, intptr): intptr; |
| extern operator '*' macro IntPtrMul(intptr, intptr): intptr; |
| extern operator '/' macro IntPtrDiv(intptr, intptr): intptr; |
| 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 UintPtrSub(uintptr, uintptr): uintptr; |
| 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 ConstexprUint32Add( |
| constexpr uint32, constexpr int32): constexpr uint32; |
| extern operator '+' macro ConstexprInt31Add( |
| constexpr int31, constexpr int31): constexpr int31; |
| extern operator '*' macro ConstexprInt31Mul( |
| constexpr int31, constexpr int31): constexpr int31; |
| extern operator '-' macro Int32Sub(int16, int16): int32; |
| extern operator '-' macro Int32Sub(uint16, uint16): int32; |
| extern operator '-' macro Int32Sub(int32, int32): int32; |
| extern operator '*' macro Int32Mul(int32, int32): int32; |
| extern operator '/' macro Int32Div(int32, int32): int32; |
| extern operator '%' macro Int32Mod(int32, int32): int32; |
| 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; |
| |
| 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 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 '.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 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(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(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 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 ChangeFloat32ToFloat64(float32): float64; |
| extern macro ChangeNumberToFloat64(Number): float64; |
| extern macro ChangeNumberToUint32(Number): uint32; |
| extern macro ChangeTaggedNonSmiToInt32(implicit context: Context)(JSAnyNotSmi): |
| int32; |
| 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 ChangeInt32ToFloat64(int32): float64; |
| extern macro ChangeInt32ToIntPtr(int32): intptr; // Sign-extends. |
| extern macro ChangeUint32ToWord(uint32): uintptr; // 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; |
| extern macro Float64Constant(constexpr int31): float64; |
| extern macro Float64Constant(constexpr float64): 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; |
| extern macro BoolConstant(constexpr bool): bool; |
| extern macro StringConstant(constexpr string): String; |
| extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot; |
| extern macro IntPtrConstant(constexpr intptr): intptr; |
| 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 BitcastTaggedToWord(Tagged): 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 OneByteStringMapConstant(): Map; |
| extern macro StringMapConstant(): 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 kOneByteStringMap: Map = OneByteStringMapConstant(); |
| // The map of a non-internalized internal SeqTwoByteString. |
| const kStringMap: Map = StringMapConstant(); |
| |
| 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 IsTypedArraySpeciesProtectorCellInvalid(): bool; |
| extern macro IsPromiseSpeciesProtectorCellInvalid(): bool; |
| extern macro IsMockArrayBufferAllocatorFlag(): bool; |
| extern macro IsPrototypeTypedArrayPrototype(implicit context: Context)(Map): |
| 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) { |
| 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 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; |
| } |
| assert(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 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>(); |
| } |
| |
| // 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() 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; |
| } |
| |
| // 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) labels IfOverflow { |
| if constexpr (Is64()) { |
| assert(index1 <= kMaxSafeIntegerUint64); |
| assert(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(tebbi): 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 { |
| assert(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): { |
| assert(IsNumberNormalized(valueHeapNumber)); |
| const valueDouble: float64 = Convert<float64>(valueHeapNumber); |
| // NaNs must be handled outside. |
| assert(!Float64IsNaN(valueDouble)); |
| if (kMode == kModeValueIsAnyNumber) { |
| if (valueDouble < 0) goto IfLessThanZero; |
| } else { |
| assert(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 { |
| assert(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 { |
| assert(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) { |
| 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 { |
| 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 { |
| const value = GetProperty(o, symbol); |
| if (value == Undefined || value == Null) goto IfNullOrUndefined; |
| return Cast<Callable>(value) |
| otherwise ThrowTypeError( |
| MessageTemplate::kPropertyNotFunction, value, symbol, 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 ConvertToRelativeIndex(implicit context: Context)( |
| index: JSAny, length: uintptr): uintptr { |
| const indexNumber: Number = ToInteger_Inline(index); |
| return ConvertToRelativeIndex(indexNumber, length); |
| } |
| |
| // Calculate a relative index: |
| // return index < 0 ? max(length + index, 0) : min(index, length) |
| @export |
| macro ConvertToRelativeIndex(indexNumber: Number, length: uintptr): uintptr { |
| 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; |
| return relativeIndex < length ? relativeIndex : 0; |
| |
| } else { |
| const relativeIndex: uintptr = Unsigned(indexIntPtr); |
| return relativeIndex < length ? relativeIndex : length; |
| } |
| } |
| case (indexHeapNumber: HeapNumber): { |
| assert(IsNumberNormalized(indexHeapNumber)); |
| const indexDouble: float64 = Convert<float64>(indexHeapNumber); |
| // NaNs must already be handled by ConvertToRelativeIndex() version |
| // above accepting JSAny indices. |
| assert(!Float64IsNaN(indexDouble)); |
| const lengthDouble: float64 = Convert<float64>(length); |
| assert(lengthDouble <= kMaxSafeInteger); |
| if (indexDouble < 0) { |
| const relativeIndex: float64 = lengthDouble + indexDouble; |
| return relativeIndex > 0 ? ChangeFloat64ToUintPtr(relativeIndex) : 0; |
| |
| } else { |
| return ChangeFloat64ToUintPtr( |
| indexDouble < lengthDouble ? indexDouble : lengthDouble); |
| } |
| } |
| } |
| } |
| |
| // 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): { |
| assert(IsNumberNormalized(indexHeapNumber)); |
| const indexDouble: float64 = Convert<float64>(indexHeapNumber); |
| // NaNs must already be handled by ClampToIndexRange() version |
| // above accepting JSAny indices. |
| assert(!Float64IsNaN(indexDouble)); |
| if (indexDouble <= 0) return 0; |
| |
| const maxIndexDouble: float64 = Convert<float64>(limit); |
| assert(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); |
| |
| extern transitioning runtime SetOwnPropertyIgnoreAttributes( |
| implicit context: Context)(JSObject, String, JSAny, Smi); |
| |
| namespace runtime { |
| extern runtime |
| GetDerivedMap(Context, JSFunction, JSReceiver): Map; |
| } |
| extern macro IsDeprecatedMap(Map): bool; |
| |
| 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 { |
| assert(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 { |
| assert(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); |
| } |
| |
| @export |
| 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; |
| } |
| } |
| } |
| |
| builtin CheckNumberInRange(implicit context: Context)( |
| value: Number, min: Number, max: Number, nodeId: Smi): Undefined { |
| if (IsIntegerOrSomeInfinity(value) && min <= value && value <= max) { |
| return Undefined; |
| } else { |
| Print('Range type assertion failed! (value/min/max/nodeId)'); |
| Print(value); |
| Print(min); |
| Print(max); |
| Print(nodeId); |
| unreachable; |
| } |
| } |
| |
| // Assert that the objects satisfy SameValue or are both the hole. |
| builtin CheckSameObject(implicit context: Context)( |
| lhs: Object, rhs: Object): Undefined { |
| typeswitch (lhs) { |
| case (TheHole): { |
| if (rhs == TheHole) return Undefined; |
| } |
| case (a: JSAny): { |
| typeswitch (rhs) { |
| case (b: JSAny): { |
| if (SameValue(a, b)) return Undefined; |
| } |
| case (Object): { |
| } |
| } |
| } |
| case (Object): { |
| } |
| } |
| Print('Distinct or unexpected values in CheckSameObject'); |
| unreachable; |
| } |
| |
| 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 FeedbackIteratorSizeFor(constexpr int32): intptr; |
| extern macro FeedbackIteratorMapIndexForEntry(constexpr int32): intptr; |
| extern macro FeedbackIteratorHandlerIndexForEntry(constexpr int32): intptr; |
| extern operator '[]' macro LoadWeakFixedArrayElement( |
| WeakFixedArray, intptr): MaybeObject; |