1// Copyright 2018 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be: 3// Context found in the LICENSE file. 4 5#include 'src/builtins/builtins-regexp-gen.h' 6#include 'src/builtins/builtins-utils-gen.h' 7#include 'src/builtins/builtins.h' 8#include 'src/codegen/code-factory.h' 9#include 'src/heap/factory-inl.h' 10#include 'src/objects/arguments.h' 11#include 'src/objects/bigint.h' 12#include 'src/objects/call-site-info.h' 13#include 'src/objects/elements-kind.h' 14#include 'src/objects/free-space.h' 15#include 'src/objects/js-function.h' 16#include 'src/objects/js-generator.h' 17#include 'src/objects/js-promise.h' 18#include 'src/objects/js-regexp-string-iterator.h' 19#include 'src/objects/js-shadow-realms.h' 20#include 'src/objects/js-struct.h' 21#include 'src/objects/js-weak-refs.h' 22#include 'src/objects/objects.h' 23#include 'src/objects/source-text-module.h' 24#include 'src/objects/synthetic-module.h' 25#include 'src/objects/template-objects.h' 26#include 'src/torque/runtime-support.h' 27 28type void; 29type never; 30 31type IntegerLiteral constexpr 'IntegerLiteral'; 32 33type Tagged generates 'TNode<MaybeObject>' constexpr 'MaybeObject'; 34type StrongTagged extends Tagged 35 generates 'TNode<Object>' constexpr 'Object'; 36type Smi extends StrongTagged generates 'TNode<Smi>' constexpr 'Smi'; 37type TaggedIndex extends StrongTagged 38 generates 'TNode<TaggedIndex>' constexpr 'TaggedIndex'; 39// A possibly cleared weak pointer with a bit pattern that distinguishes it from 40// strong HeapObject pointers and Smi values. 41type WeakHeapObject extends Tagged; 42type Weak<T : type extends HeapObject> extends WeakHeapObject; 43 44type Object = Smi|HeapObject; 45type MaybeObject = Smi|HeapObject|WeakHeapObject; 46 47// A Smi that is greater than or equal to 0. See TaggedIsPositiveSmi. 48type PositiveSmi extends Smi; 49 50// The Smi value zero, which is often used as null for HeapObject types. 51type Zero extends PositiveSmi; 52// A tagged value represented by an all-zero bitpattern. 53type TaggedZeroPattern extends TaggedIndex; 54 55// A value with the size of Tagged which may contain arbitrary data. 56type Uninitialized extends Tagged; 57 58extern macro MakeWeak(HeapObject): WeakHeapObject; 59extern macro GetHeapObjectAssumeWeak(MaybeObject): HeapObject labels IfCleared; 60extern macro GetHeapObjectIfStrong(MaybeObject): HeapObject labels IfNotStrong; 61extern macro IsWeakOrCleared(MaybeObject): bool; 62extern macro IsWeakReferenceToObject(MaybeObject, Object): bool; 63extern macro IsStrong(MaybeObject): bool; 64 65macro StrongToWeak<T: type>(x: T): Weak<T> { 66 return %RawDownCast<Weak<T>>(MakeWeak(x)); 67} 68macro WeakToStrong<T: type>(x: Weak<T>): T labels ClearedWeakPointer { 69 const x = GetHeapObjectAssumeWeak(x) otherwise ClearedWeakPointer; 70 return %RawDownCast<T>(x); 71} 72 73// Defined to coincide with https://tc39.es/ecma262/#sec-ispropertykey 74// Doesn't include PrivateSymbol. 75type PropertyKey = String|PublicSymbol; 76 77// TODO(turbofan): PrivateSymbol is only exposed to JavaScript through the 78// debugger API. We should reconsider this and try not to expose it at all. Then 79// JSAny would not need to contain it. 80 81// A JavaScript primitive value as defined in 82// https://tc39.es/ecma262/#sec-primitive-value. 83type JSPrimitive = Numeric|String|Symbol|Boolean|Null|Undefined; 84 85// A user-exposed JavaScript value, as opposed to V8-internal values like 86// TheHole or FixedArray. 87type JSAny = JSReceiver|JSPrimitive; 88 89type JSAnyNotNumeric = String|Symbol|Boolean|Null|Undefined|JSReceiver; 90type JSAnyNotNumber = BigInt|JSAnyNotNumeric; 91 92// This is the intersection of JSAny and HeapObject. 93type JSAnyNotSmi = JSAnyNotNumber|HeapNumber; 94 95type int32 generates 'TNode<Int32T>' constexpr 'int32_t'; 96type uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t'; 97type int31 extends int32 98 generates 'TNode<Int32T>' constexpr 'int31_t'; 99type uint31 extends uint32 100 generates 'TNode<Uint32T>' constexpr 'uint32_t'; 101type int16 extends int31 102 generates 'TNode<Int16T>' constexpr 'int16_t'; 103type uint16 extends uint31 104 generates 'TNode<Uint16T>' constexpr 'uint16_t'; 105type int8 extends int16 generates 'TNode<Int8T>' constexpr 'int8_t'; 106type uint8 extends uint16 107 generates 'TNode<Uint8T>' constexpr 'uint8_t'; 108type char8 extends uint8 constexpr 'char'; 109type char16 extends uint16 constexpr 'char16_t'; 110type int64 generates 'TNode<Int64T>' constexpr 'int64_t'; 111type uint64 generates 'TNode<Uint64T>' constexpr 'uint64_t'; 112type intptr generates 'TNode<IntPtrT>' constexpr 'intptr_t'; 113type uintptr generates 'TNode<UintPtrT>' constexpr 'uintptr_t'; 114type float32 generates 'TNode<Float32T>' constexpr 'float'; 115type float64 generates 'TNode<Float64T>' constexpr 'double'; 116type bool generates 'TNode<BoolT>' constexpr 'bool'; 117type bint generates 'TNode<BInt>' constexpr 'BInt'; 118type string constexpr 'const char*'; 119 120type Simd128 generates 'TNode<Simd128T>'; 121type I8X16 extends Simd128 generates 'TNode<I8x16T>'; 122 123// Represents a std::function which produces the generated TNode type of T. 124// Useful for passing values to and from CSA code that uses LazyNode<T>, which 125// is a typedef for std::function<TNode<T>()>. Can be created with %MakeLazy and 126// accessed with RunLazy. 127type Lazy<T: type>; 128 129// Makes a Lazy. The first parameter is the name of a macro, which is looked up 130// in the context where %MakeLazy is called, as a workaround for the fact that 131// macros can't be used as values directly. The other parameters are saved and 132// passed to the macro when somebody runs the resulting Lazy object. Torque 133// syntax doesn't allow for arbitrary-length generic macros, but the internals 134// support any number of parameters, so if you need more parameters, feel free 135// to add additional declarations here. 136intrinsic %MakeLazy<T: type>(getter: constexpr string): Lazy<T>; 137intrinsic %MakeLazy<T: type, A1: type>( 138 getter: constexpr string, arg1: A1): Lazy<T>; 139intrinsic %MakeLazy<T: type, A1: type, A2: type>( 140 getter: constexpr string, arg1: A1, arg2: A2): Lazy<T>; 141intrinsic %MakeLazy<T: type, A1: type, A2: type, A3: type>( 142 getter: constexpr string, arg1: A1, arg2: A2, arg3: A3): Lazy<T>; 143 144// Executes a Lazy and returns the result. The CSA-side definition is a 145// template, but Torque doesn't understand how to use templates for extern 146// macros, so just add whatever overload definitions you need here. 147extern macro RunLazy(Lazy<Smi>): Smi; 148extern macro RunLazy(Lazy<JSAny>): JSAny; 149 150// A Smi value containing a bitfield struct as its integer data. 151@useParentTypeChecker type SmiTagged<T : type extends uint31> extends Smi; 152 153// WARNING: The memory representation (i.e., in class fields and arrays) of 154// float64_or_hole is just a float64 that may be the hole-representing 155// signalling NaN bit-pattern. So it's memory size is that of float64 and 156// loading and storing float64_or_hole emits special code. 157struct float64_or_hole { 158 macro Value(): float64 labels IfHole { 159 if (this.is_hole) { 160 goto IfHole; 161 } 162 return this.value; 163 } 164 macro ValueUnsafeAssumeNotHole(): float64 { 165 dcheck(!this.is_hole); 166 return this.value; 167 } 168 169 is_hole: bool; 170 value: float64; 171} 172const kDoubleHole: float64_or_hole = float64_or_hole{is_hole: true, value: 0}; 173 174@doNotGenerateCast 175@abstract 176extern class JSPrototype extends JSObject generates 'TNode<JSObject>'; 177@doNotGenerateCast 178extern class JSObjectPrototype extends JSPrototype 179 generates 'TNode<JSObject>'; 180@doNotGenerateCast 181extern class JSRegExpPrototype extends JSPrototype 182 generates 'TNode<JSObject>'; 183@doNotGenerateCast 184extern class JSPromisePrototype extends JSPrototype 185 generates 'TNode<JSObject>'; 186@doNotGenerateCast 187extern class JSTypedArrayPrototype extends JSPrototype 188 generates 'TNode<JSObject>'; 189@doNotGenerateCast 190extern class JSSetPrototype extends JSPrototype 191 generates 'TNode<JSObject>'; 192@doNotGenerateCast 193extern class JSIteratorPrototype extends JSPrototype 194 generates 'TNode<JSObject>'; 195@doNotGenerateCast 196extern class JSArrayIteratorPrototype extends JSPrototype 197 generates 'TNode<JSObject>'; 198@doNotGenerateCast 199extern class JSMapIteratorPrototype extends JSPrototype 200 generates 'TNode<JSObject>'; 201@doNotGenerateCast 202extern class JSSetIteratorPrototype extends JSPrototype 203 generates 'TNode<JSObject>'; 204@doNotGenerateCast 205extern class JSStringIteratorPrototype extends JSPrototype 206 generates 'TNode<JSObject>'; 207 208// The HashTable inheritance hierarchy doesn't actually look like this in C++ 209// because it uses some class templates that we can't yet (and may never) 210// express in Torque, but this is the expected organization of instance types. 211@doNotGenerateCast 212extern class HashTable extends FixedArray generates 'TNode<FixedArray>'; 213extern class OrderedHashMap extends HashTable; 214extern class OrderedHashSet extends HashTable; 215extern class OrderedNameDictionary extends HashTable; 216extern class NameToIndexHashTable extends HashTable; 217extern class RegisteredSymbolTable extends HashTable; 218extern class NameDictionary extends HashTable; 219extern class GlobalDictionary extends HashTable; 220extern class SimpleNumberDictionary extends HashTable; 221extern class EphemeronHashTable extends HashTable; 222type ObjectHashTable extends HashTable 223 generates 'TNode<ObjectHashTable>' constexpr 'ObjectHashTable'; 224extern class NumberDictionary extends HashTable; 225 226type RawPtr generates 'TNode<RawPtrT>' constexpr 'Address'; 227type RawPtr<To: type> extends RawPtr; 228type ExternalPointer 229 generates 'TNode<ExternalPointerT>' constexpr 'ExternalPointer_t'; 230extern class Code extends HeapObject; 231type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>'; 232 233type Number = Smi|HeapNumber; 234type Numeric = Number|BigInt; 235 236extern class ObjectBoilerplateDescription extends FixedArray; 237extern class ClosureFeedbackCellArray extends FixedArray; 238extern class ScriptContextTable extends FixedArray; 239 240extern class TransitionArray extends WeakFixedArray; 241 242extern operator '.length_intptr' macro LoadAndUntagWeakFixedArrayLength( 243 WeakFixedArray): intptr; 244 245type InstanceType extends uint16 constexpr 'InstanceType'; 246 247type NoSharedNameSentinel extends Smi; 248 249// Specialized types. The following three type definitions don't correspond to 250// actual C++ classes, but have Is... methods that check additional constraints. 251 252// A Foreign object whose raw pointer is not allowed to be null. 253type NonNullForeign extends Foreign; 254 255// A function built with InstantiateFunction for the public API. 256type CallableApiObject extends JSObject; 257 258// A JSProxy with the callable bit set. 259type CallableJSProxy extends JSProxy; 260 261type Callable = JSFunction|JSBoundFunction|JSWrappedFunction|CallableJSProxy| 262 CallableApiObject; 263 264type WriteBarrierMode 265 generates 'TNode<Int32T>' constexpr 'WriteBarrierMode'; 266 267extern enum UpdateFeedbackMode { kOptionalFeedback, kGuaranteedFeedback } 268extern operator '==' macro UpdateFeedbackModeEqual( 269 constexpr UpdateFeedbackMode, constexpr UpdateFeedbackMode): constexpr bool; 270 271extern enum CallFeedbackContent extends int32 { kTarget, kReceiver } 272 273extern enum UnicodeEncoding { UTF16, UTF32 } 274 275// Promise constants 276extern enum PromiseState extends int31 constexpr 'Promise::PromiseState' { 277 kPending, 278 kFulfilled, 279 kRejected 280} 281 282const kTaggedSize: constexpr int31 generates 'kTaggedSize'; 283const kDoubleSize: constexpr int31 generates 'kDoubleSize'; 284const kVariableSizeSentinel: 285 constexpr int31 generates 'kVariableSizeSentinel'; 286 287const kSmiTagSize: constexpr int31 generates 'kSmiTagSize'; 288const kHeapObjectTag: constexpr int31 generates 'kHeapObjectTag'; 289const V8_INFINITY: constexpr float64 generates 'V8_INFINITY'; 290const MINUS_V8_INFINITY: constexpr float64 generates '-V8_INFINITY'; 291 292extern enum ElementsKind extends int32 { 293 NO_ELEMENTS, 294 295 PACKED_SMI_ELEMENTS, 296 HOLEY_SMI_ELEMENTS, 297 PACKED_ELEMENTS, 298 HOLEY_ELEMENTS, 299 PACKED_DOUBLE_ELEMENTS, 300 HOLEY_DOUBLE_ELEMENTS, 301 LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND, 302 DICTIONARY_ELEMENTS, 303 304 UINT8_ELEMENTS, 305 INT8_ELEMENTS, 306 UINT16_ELEMENTS, 307 INT16_ELEMENTS, 308 UINT32_ELEMENTS, 309 INT32_ELEMENTS, 310 FLOAT32_ELEMENTS, 311 FLOAT64_ELEMENTS, 312 UINT8_CLAMPED_ELEMENTS, 313 BIGUINT64_ELEMENTS, 314 BIGINT64_ELEMENTS, 315 RAB_GSAB_UINT8_ELEMENTS, 316 RAB_GSAB_INT8_ELEMENTS, 317 RAB_GSAB_UINT16_ELEMENTS, 318 RAB_GSAB_INT16_ELEMENTS, 319 RAB_GSAB_UINT32_ELEMENTS, 320 RAB_GSAB_INT32_ELEMENTS, 321 RAB_GSAB_FLOAT32_ELEMENTS, 322 RAB_GSAB_FLOAT64_ELEMENTS, 323 RAB_GSAB_UINT8_CLAMPED_ELEMENTS, 324 RAB_GSAB_BIGUINT64_ELEMENTS, 325 RAB_GSAB_BIGINT64_ELEMENTS, 326 // TODO(torque): Allow duplicate enum values. 327 // FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND, 328 // FIRST_RAB_GSAB_FIXED_TYPED_ARRAY_ELEMENTS_KIND, 329 ... 330} 331 332const kFirstFixedTypedArrayElementsKind: constexpr ElementsKind = 333 ElementsKind::UINT8_ELEMENTS; 334const kFirstRabGsabFixedTypedArrayElementsKind: constexpr ElementsKind = 335 ElementsKind::RAB_GSAB_UINT8_ELEMENTS; 336 337extern enum AllocationFlag extends int32 338constexpr 'CodeStubAssembler::AllocationFlag' { 339 kNone, 340 kDoubleAlignment, 341 kPretenured, 342 kAllowLargeObjectAllocation 343} 344 345extern enum SlackTrackingMode 346constexpr 'CodeStubAssembler::SlackTrackingMode' { 347 kWithSlackTracking, 348 kNoSlackTracking 349} 350 351extern enum ExtractFixedArrayFlag 352constexpr 'CodeStubAssembler::ExtractFixedArrayFlag' { 353 kFixedDoubleArrays, 354 kAllFixedArrays, 355 kFixedArrays, 356 ... 357} 358 359extern enum InitializationMode 360constexpr 'CodeStubAssembler::InitializationMode' { 361 kUninitialized, 362 kInitializeToZero, 363 kInitializeToNull 364} 365 366const kBigIntMaxLength: constexpr intptr generates 'BigInt::kMaxLength'; 367 368extern enum MessageTemplate { 369 kAllPromisesRejected, 370 kInvalidArrayBufferLength, 371 kInvalidArrayLength, 372 kInvalidIndex, 373 kNotConstructor, 374 kNotGeneric, 375 kCalledNonCallable, 376 kCalledOnNullOrUndefined, 377 kCannotConvertToPrimitive, 378 kProtoObjectOrNull, 379 kInvalidOffset, 380 kInvalidTypedArrayLength, 381 kIteratorSymbolNonCallable, 382 kIteratorValueNotAnObject, 383 kNotIterable, 384 kReduceNoInitial, 385 kFirstArgumentNotRegExp, 386 kBigIntMixedTypes, 387 kTypedArrayTooShort, 388 kTypedArrayTooLargeToSort, 389 kInvalidCountValue, 390 kConstructorNotFunction, 391 kSymbolToString, 392 kPropertyNotFunction, 393 kBigIntTooBig, 394 kNotTypedArray, 395 kDetachedOperation, 396 kBadSortComparisonFunction, 397 kIncompatibleMethodReceiver, 398 kInvalidDataViewAccessorOffset, 399 kTypedArraySetOffsetOutOfBounds, 400 kInvalidArgument, 401 kInvalidRegExpExecResult, 402 kRegExpNonRegExp, 403 kRegExpNonObject, 404 kPromiseNonCallable, 405 kPromiseNewTargetUndefined, 406 kResolverNotAFunction, 407 kTooManyElementsInPromiseCombinator, 408 kToRadixFormatRange, 409 kCalledOnNonObject, 410 kRegExpGlobalInvokedOnNonGlobal, 411 kProxyNonObject, 412 kProxyRevoked, 413 kProxyTrapReturnedFalsishFor, 414 kProxyPrivate, 415 kProxyIsExtensibleInconsistent, 416 kProxyPreventExtensionsExtensible, 417 kProxyTrapReturnedFalsish, 418 kProxyGetPrototypeOfInvalid, 419 kProxyGetPrototypeOfNonExtensible, 420 kProxySetPrototypeOfNonExtensible, 421 kProxyDeletePropertyNonExtensible, 422 kUndefinedOrNullToObject, 423 kWeakRefsCleanupMustBeCallable, 424 kWasmTrapUnreachable, 425 kWasmTrapMemOutOfBounds, 426 kWasmTrapUnalignedAccess, 427 kWasmTrapDivByZero, 428 kWasmTrapDivUnrepresentable, 429 kWasmTrapRemByZero, 430 kWasmTrapFloatUnrepresentable, 431 kWasmTrapFuncSigMismatch, 432 kWasmTrapDataSegmentOutOfBounds, 433 kWasmTrapElemSegmentDropped, 434 kWasmTrapTableOutOfBounds, 435 kWasmTrapRethrowNull, 436 kWasmTrapNullDereference, 437 kWasmTrapIllegalCast, 438 kWasmTrapArrayOutOfBounds, 439 kWasmTrapArrayTooLarge, 440 kWeakRefsRegisterTargetAndHoldingsMustNotBeSame, 441 kInvalidWeakRefsRegisterTarget, 442 kInvalidWeakRefsUnregisterToken, 443 kInvalidWeakRefsWeakRefConstructorTarget, 444 ... 445} 446 447extern enum PropertyAttributes extends int31 { 448 NONE, 449 READ_ONLY, 450 DONT_ENUM, 451 DONT_DELETE, 452 ALL_ATTRIBUTES_MASK, 453 FROZEN, 454 ... 455} 456 457const kArrayBufferMaxByteLength: 458 constexpr uintptr generates 'JSArrayBuffer::kMaxByteLength'; 459const kTypedArrayMaxLength: 460 constexpr uintptr generates 'JSTypedArray::kMaxLength'; 461const kMaxTypedArrayInHeap: 462 constexpr int31 generates 'JSTypedArray::kMaxSizeInHeap'; 463// CSA does not support 64-bit types on 32-bit platforms so as a workaround the 464// kMaxSafeIntegerUint64 is defined as uintptr and allowed to be used only 465// inside if constexpr (Is64()) i.e. on 64-bit architectures. 466const kMaxSafeIntegerUint64: constexpr uintptr 467 generates 'CodeStubAssembler::MaxSafeIntegerUintPtr()'; 468const kMaxSafeInteger: constexpr float64 generates 'kMaxSafeInteger'; 469const kMaxUInt32Double: constexpr float64 generates 'kMaxUInt32Double'; 470const kSmiMaxValue: constexpr uintptr generates 'kSmiMaxValue'; 471const kSmiMax: uintptr = kSmiMaxValue; 472// TODO(v8:8996): Use uintptr version instead and drop this one. 473const kStringMaxLength: constexpr int31 generates 'String::kMaxLength'; 474const kStringMaxLengthUintptr: 475 constexpr uintptr generates 'String::kMaxLength'; 476const kFixedArrayMaxLength: 477 constexpr int31 generates 'FixedArray::kMaxLength'; 478const kFixedDoubleArrayMaxLength: 479 constexpr int31 generates 'FixedDoubleArray::kMaxLength'; 480const kObjectAlignmentMask: constexpr intptr 481 generates 'kObjectAlignmentMask'; 482const kMinAddedElementsCapacity: 483 constexpr int31 generates 'JSObject::kMinAddedElementsCapacity'; 484const kMaxCopyElements: 485 constexpr int31 generates 'JSArray::kMaxCopyElements'; 486const kMaxRegularHeapObjectSize: constexpr int31 487 generates 'kMaxRegularHeapObjectSize'; 488 489const kMaxNewSpaceFixedArrayElements: constexpr int31 490 generates 'FixedArray::kMaxRegularLength'; 491 492extern enum PrimitiveType { kString, kBoolean, kSymbol, kNumber } 493 494const kNameDictionaryInitialCapacity: 495 constexpr int32 generates 'NameDictionary::kInitialCapacity'; 496const kSwissNameDictionaryInitialCapacity: 497 constexpr int32 generates 'SwissNameDictionary::kInitialCapacity'; 498 499const kWasmArrayHeaderSize: 500 constexpr int32 generates 'WasmArray::kHeaderSize'; 501 502const kHeapObjectHeaderSize: 503 constexpr int32 generates 'HeapObject::kHeaderSize'; 504 505type TheHole extends Oddball; 506type Null extends Oddball; 507type Undefined extends Oddball; 508type True extends Oddball; 509type False extends Oddball; 510type Exception extends Oddball; 511type EmptyString extends String; 512type Boolean = True|False; 513 514type NumberOrUndefined = Number|Undefined; 515 516extern macro DefaultStringConstant(): String; 517extern macro EmptyStringConstant(): EmptyString; 518extern macro ErrorsStringConstant(): String; 519extern macro FalseConstant(): False; 520extern macro Int32FalseConstant(): bool; 521extern macro Int32TrueConstant(): bool; 522extern macro IteratorSymbolConstant(): PublicSymbol; 523extern macro LengthStringConstant(): String; 524extern macro MatchSymbolConstant(): Symbol; 525extern macro MessageStringConstant(): String; 526extern macro NanConstant(): NaN; 527extern macro NameStringConstant(): String; 528extern macro NullConstant(): Null; 529extern macro NumberStringConstant(): String; 530extern macro ReturnStringConstant(): String; 531extern macro SearchSymbolConstant(): Symbol; 532extern macro StringStringConstant(): String; 533extern macro TheHoleConstant(): TheHole; 534extern macro ToPrimitiveSymbolConstant(): PublicSymbol; 535extern macro ToStringStringConstant(): String; 536extern macro TrueConstant(): True; 537extern macro UndefinedConstant(): Undefined; 538extern macro ValueOfStringConstant(): String; 539extern macro WasmWrappedObjectSymbolConstant(): Symbol; 540 541const TheHole: TheHole = TheHoleConstant(); 542const Null: Null = NullConstant(); 543const Undefined: Undefined = UndefinedConstant(); 544const True: True = TrueConstant(); 545const False: False = FalseConstant(); 546const kEmptyString: EmptyString = EmptyStringConstant(); 547const kLengthString: String = LengthStringConstant(); 548const kMessageString: String = MessageStringConstant(); 549const kReturnString: String = ReturnStringConstant(); 550 551const kNaN: NaN = NanConstant(); 552const kZero: Zero = %RawDownCast<Zero>(SmiConstant(0)); 553const kZeroBitPattern: TaggedZeroPattern = %RawDownCast<TaggedZeroPattern>( 554 Convert<Tagged>(BitcastWordToTaggedSigned(Convert<intptr>(0)))); 555 556const true: constexpr bool generates 'true'; 557const false: constexpr bool generates 'false'; 558 559extern enum LanguageMode extends bool { kStrict, kSloppy } 560type LanguageModeSmi extends Smi; 561 562const SKIP_WRITE_BARRIER: 563 constexpr WriteBarrierMode generates 'SKIP_WRITE_BARRIER'; 564const UNSAFE_SKIP_WRITE_BARRIER: 565 constexpr WriteBarrierMode generates 'UNSAFE_SKIP_WRITE_BARRIER'; 566 567extern transitioning macro AllocateJSIteratorResult(implicit context: Context)( 568 JSAny, Boolean): JSObject; 569 570extern class Filler extends HeapObject generates 'TNode<HeapObject>'; 571 572// Various logical subclasses of JSObject, which have their own instance types 573// but not their own class definitions: 574 575// Like JSObject, but created from API function. 576@apiExposedInstanceTypeValue(0x422) 577@doNotGenerateCast 578extern class JSApiObject extends JSObjectWithEmbedderSlots 579 generates 'TNode<JSObject>'; 580 581// TODO(gsathya): This only exists to make JSApiObject instance type into a 582// range. 583@apiExposedInstanceTypeValue(0x80A) 584@doNotGenerateCast 585@highestInstanceTypeWithinParentClassRange 586extern class JSLastDummyApiObject extends JSApiObject 587 generates 'TNode<JSObject>'; 588 589// Like JSApiObject, but requires access checks and/or has interceptors. 590@apiExposedInstanceTypeValue(0x410) 591extern class JSSpecialApiObject extends JSSpecialObject 592 generates 'TNode<JSSpecialObject>'; 593extern class JSContextExtensionObject extends JSObject 594 generates 'TNode<JSObject>'; 595extern class JSError extends JSObject generates 'TNode<JSObject>'; 596 597extern macro Is64(): constexpr bool; 598 599extern macro SelectBooleanConstant(bool): Boolean; 600 601extern macro Print(constexpr string): void; 602extern macro Print(constexpr string, Object): void; 603extern macro Comment(constexpr string): void; 604extern macro Print(Object): void; 605extern macro DebugBreak(): void; 606 607// ES6 7.1.4 ToInteger ( argument ) 608transitioning macro ToIntegerImpl(implicit context: Context)(input: JSAny): 609 Number { 610 let input = input; 611 612 while (true) { 613 typeswitch (input) { 614 case (s: Smi): { 615 return s; 616 } 617 case (hn: HeapNumber): { 618 let value = Convert<float64>(hn); 619 if (Float64IsNaN(value)) return SmiConstant(0); 620 value = math::Float64Trunc(value); 621 // ToInteger normalizes -0 to +0. 622 if (value == 0) return SmiConstant(0); 623 const result = ChangeFloat64ToTagged(value); 624 dcheck(IsNumberNormalized(result)); 625 return result; 626 } 627 case (a: JSAnyNotNumber): { 628 input = conversion::NonNumberToNumber(a); 629 } 630 } 631 } 632 unreachable; 633} 634 635transitioning builtin ToInteger(implicit context: Context)(input: JSAny): 636 Number { 637 return ToIntegerImpl(input); 638} 639 640@export 641transitioning macro ToInteger_Inline(implicit context: Context)(input: JSAny): 642 Number { 643 typeswitch (input) { 644 case (s: Smi): { 645 return s; 646 } 647 case (JSAny): { 648 return ToInteger(input); 649 } 650 } 651} 652 653extern enum BigIntHandling extends int32 654constexpr 'CodeStubAssembler::BigIntHandling' { kConvertToNumber, kThrow } 655 656extern transitioning macro ToNumber(implicit context: Context)( 657 JSAny, constexpr BigIntHandling): Number; 658 659extern transitioning macro ToLength_Inline(implicit context: Context)(JSAny): 660 Number; 661extern transitioning macro ToNumber_Inline(implicit context: Context)(JSAny): 662 Number; 663extern transitioning macro ToString_Inline(implicit context: Context)(JSAny): 664 String; 665extern transitioning macro ToThisString(implicit context: Context)( 666 JSAny, String): String; 667extern transitioning macro ToThisValue(implicit context: Context)( 668 JSAny, constexpr PrimitiveType, constexpr string): JSAny; 669extern transitioning macro GetProperty(implicit context: Context)( 670 JSAny, JSAny): JSAny; 671extern transitioning builtin SetProperty(implicit context: Context)( 672 JSAny, JSAny, JSAny): JSAny; 673extern transitioning builtin SetPropertyIgnoreAttributes( 674 implicit context: Context)(JSObject, String, JSAny, Smi): JSAny; 675extern transitioning builtin CreateDataProperty(implicit context: Context)( 676 JSAny, JSAny, JSAny): JSAny; 677extern transitioning builtin DeleteProperty(implicit context: Context)( 678 JSAny, JSAny | PrivateSymbol, LanguageModeSmi): Boolean; 679extern transitioning builtin HasProperty(implicit context: Context)( 680 JSAny, JSAny): Boolean; 681extern transitioning macro HasProperty_Inline(implicit context: Context)( 682 JSReceiver, JSAny): Boolean; 683extern builtin LoadIC( 684 Context, JSAny, JSAny, TaggedIndex, FeedbackVector): JSAny; 685 686extern macro SetPropertyStrict(Context, Object, Object, Object): Object; 687 688extern macro ThrowRangeError(implicit context: Context)( 689 constexpr MessageTemplate): never; 690extern macro ThrowRangeError(implicit context: Context)( 691 constexpr MessageTemplate, Object): never; 692extern macro ThrowTypeError(implicit context: Context)( 693 constexpr MessageTemplate): never; 694extern macro ThrowTypeError(implicit context: Context)( 695 constexpr MessageTemplate, constexpr string): never; 696extern macro ThrowTypeError(implicit context: Context)( 697 constexpr MessageTemplate, Object): never; 698extern macro ThrowTypeError(implicit context: Context)( 699 constexpr MessageTemplate, Object, Object): never; 700extern macro ThrowTypeError(implicit context: Context)( 701 constexpr MessageTemplate, Object, Object, Object): never; 702extern transitioning runtime ThrowTypeErrorIfStrict(implicit context: Context)( 703 Smi, Object, Object): void; 704extern transitioning runtime ThrowIteratorError(implicit context: Context)( 705 JSAny): never; 706extern transitioning runtime ThrowCalledNonCallable(implicit context: Context)( 707 JSAny): never; 708 709extern transitioning macro ThrowIfNotJSReceiver(implicit context: Context)( 710 JSAny, constexpr MessageTemplate, constexpr string): void; 711 712extern macro ArraySpeciesCreate(Context, JSAny, Number): JSReceiver; 713extern macro ArrayCreate(implicit context: Context)(Number): JSArray; 714extern macro BuildAppendJSArray( 715 constexpr ElementsKind, FastJSArray, JSAny): void labels Bailout; 716 717extern macro EnsureArrayPushable(implicit context: Context)(Map): ElementsKind 718 labels Bailout; 719// TODO: Reduce duplication once varargs are supported in macros. 720extern macro Construct(implicit context: Context)(Constructor): JSReceiver; 721extern macro Construct(implicit context: Context)( 722 Constructor, JSAny): JSReceiver; 723extern macro Construct(implicit context: Context)( 724 Constructor, JSAny, JSAny): JSReceiver; 725extern macro Construct(implicit context: Context)( 726 Constructor, JSAny, JSAny, JSAny): JSReceiver; 727extern macro ConstructWithTarget(implicit context: Context)( 728 Constructor, JSReceiver): JSReceiver; 729extern macro ConstructWithTarget(implicit context: Context)( 730 Constructor, JSReceiver, JSAny): JSReceiver; 731extern macro SpeciesConstructor(implicit context: Context)( 732 JSAny, JSReceiver): JSReceiver; 733 734extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool; 735extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32): 736 NameDictionary; 737extern macro CodeStubAssembler::AllocateOrderedNameDictionary(constexpr int32): 738 OrderedNameDictionary; 739extern macro CodeStubAssembler::AllocateSwissNameDictionary(constexpr int32): 740 SwissNameDictionary; 741 742extern builtin ToObject(Context, JSAny): JSReceiver; 743extern macro ToObject_Inline(Context, JSAny): JSReceiver; 744extern macro IsUndefined(Object): bool; 745extern macro IsNullOrUndefined(Object): bool; 746extern macro IsString(HeapObject): bool; 747extern transitioning builtin NonPrimitiveToPrimitive_String( 748 Context, JSAny): JSPrimitive; 749extern transitioning builtin NonPrimitiveToPrimitive_Default( 750 Context, JSAny): JSPrimitive; 751 752transitioning macro ToPrimitiveDefault(implicit context: Context)(v: JSAny): 753 JSPrimitive { 754 typeswitch (v) { 755 case (v: JSReceiver): { 756 return NonPrimitiveToPrimitive_Default(context, v); 757 } 758 case (v: JSPrimitive): { 759 return v; 760 } 761 } 762} 763 764extern transitioning runtime NormalizeElements(Context, JSObject): void; 765extern transitioning runtime TransitionElementsKindWithKind( 766 Context, JSObject, Smi): void; 767 768extern macro LoadBufferObject(RawPtr, constexpr int32): Object; 769extern macro LoadBufferPointer(RawPtr, constexpr int32): RawPtr; 770extern macro LoadBufferSmi(RawPtr, constexpr int32): Smi; 771extern macro LoadBufferIntptr(RawPtr, constexpr int32): intptr; 772 773extern runtime StringEqual(Context, String, String): Oddball; 774extern builtin StringLessThan(Context, String, String): Boolean; 775extern macro StringCharCodeAt(String, uintptr): char16; 776extern macro StringFromSingleCharCode(char8): String; 777extern macro StringFromSingleCharCode(char16): String; 778 779extern macro NumberToString(Number): String; 780extern macro StringToNumber(String): Number; 781extern transitioning macro NonNumberToNumber(implicit context: Context)( 782 JSAnyNotNumber): Number; 783extern transitioning macro NonNumberToNumeric(implicit context: Context)( 784 JSAnyNotNumber): Numeric; 785 786extern macro Equal(JSAny, JSAny, Context): Boolean; 787macro Equal(implicit context: Context)(left: JSAny, right: JSAny): Boolean { 788 return Equal(left, right); 789} 790 791extern macro StrictEqual(JSAny, JSAny): Boolean; 792extern macro SmiLexicographicCompare(Smi, Smi): Smi; 793 794extern runtime ReThrowWithMessage( 795 Context, JSAny, TheHole | JSMessageObject): never; 796extern runtime Throw(implicit context: Context)(JSAny): never; 797extern runtime ThrowInvalidStringLength(Context): never; 798 799extern operator '==' macro WordEqual(RawPtr, RawPtr): bool; 800extern operator '!=' macro WordNotEqual(RawPtr, RawPtr): bool; 801extern operator '+' macro RawPtrAdd(RawPtr, intptr): RawPtr; 802extern operator '+' macro RawPtrAdd(intptr, RawPtr): RawPtr; 803 804extern operator '<' macro Int32LessThan(int32, int32): bool; 805extern operator '<' macro Uint32LessThan(uint32, uint32): bool; 806extern operator '>' macro Int32GreaterThan(int32, int32): bool; 807extern operator '>' macro Uint32GreaterThan(uint32, uint32): bool; 808extern operator '<=' macro Int32LessThanOrEqual(int32, int32): bool; 809extern operator '<=' macro Uint32LessThanOrEqual(uint32, uint32): bool; 810extern operator '>=' macro Int32GreaterThanOrEqual(int32, int32): bool; 811extern operator '>=' macro Uint32GreaterThanOrEqual(uint32, uint32): bool; 812 813extern operator '==' macro SmiEqual(Smi, Smi): bool; 814extern operator '!=' macro SmiNotEqual(Smi, Smi): bool; 815extern operator '<' macro SmiLessThan(Smi, Smi): bool; 816extern operator '<=' macro SmiLessThanOrEqual(Smi, Smi): bool; 817extern operator '>' macro SmiGreaterThan(Smi, Smi): bool; 818extern operator '>=' macro SmiGreaterThanOrEqual(Smi, Smi): bool; 819 820extern operator '==' macro ElementsKindEqual( 821 constexpr ElementsKind, constexpr ElementsKind): constexpr bool; 822extern operator '==' macro ElementsKindEqual(ElementsKind, ElementsKind): bool; 823operator '!=' macro ElementsKindNotEqual( 824 k1: ElementsKind, k2: ElementsKind): bool { 825 return !ElementsKindEqual(k1, k2); 826} 827extern macro IsElementsKindLessThanOrEqual( 828 ElementsKind, constexpr ElementsKind): bool; 829extern macro IsElementsKindGreaterThan( 830 ElementsKind, constexpr ElementsKind): bool; 831extern macro IsElementsKindGreaterThanOrEqual( 832 ElementsKind, constexpr ElementsKind): bool; 833extern macro IsElementsKindInRange( 834 ElementsKind, constexpr ElementsKind, constexpr ElementsKind): bool; 835 836extern macro IsFastElementsKind(constexpr ElementsKind): constexpr bool; 837extern macro IsDoubleElementsKind(constexpr ElementsKind): constexpr bool; 838 839extern macro IsFastAliasedArgumentsMap(implicit context: Context)(Map): bool; 840extern macro IsSlowAliasedArgumentsMap(implicit context: Context)(Map): bool; 841extern macro IsSloppyArgumentsMap(implicit context: Context)(Map): bool; 842extern macro IsStrictArgumentsMap(implicit context: Context)(Map): bool; 843extern macro IsTuple2Map(Map): bool; 844 845extern macro SmiAbove(Smi, Smi): bool; 846 847extern operator '==' macro WordEqual(intptr, intptr): bool; 848extern operator '==' macro WordEqual(uintptr, uintptr): bool; 849extern operator '!=' macro WordNotEqual(intptr, intptr): bool; 850extern operator '!=' macro WordNotEqual(uintptr, uintptr): bool; 851extern operator '<' macro IntPtrLessThan(intptr, intptr): bool; 852extern operator '<' macro UintPtrLessThan(uintptr, uintptr): bool; 853extern operator '>' macro IntPtrGreaterThan(intptr, intptr): bool; 854extern operator '>' macro UintPtrGreaterThan(uintptr, uintptr): bool; 855extern operator '<=' macro IntPtrLessThanOrEqual(intptr, intptr): bool; 856extern operator '<=' macro UintPtrLessThanOrEqual(uintptr, uintptr): bool; 857extern operator '>=' macro IntPtrGreaterThanOrEqual(intptr, intptr): bool; 858extern operator '>=' macro UintPtrGreaterThanOrEqual(uintptr, uintptr): bool; 859extern operator '~' macro WordNot(intptr): intptr; 860extern operator '~' macro WordNot(uintptr): uintptr; 861extern operator '~' macro Word64Not(uint64): uint64; 862extern operator '~' macro Word64Not(int64): int64; 863extern operator '~' macro ConstexprWordNot(constexpr intptr): constexpr intptr; 864extern operator '~' macro ConstexprWordNot(constexpr uintptr): 865 constexpr uintptr; 866 867extern operator '==' macro Float64Equal(float64, float64): bool; 868extern operator '!=' macro Float64NotEqual(float64, float64): bool; 869extern operator '>' macro Float64GreaterThan(float64, float64): bool; 870extern operator '>=' macro Float64GreaterThanOrEqual(float64, float64): bool; 871extern operator '<' macro Float64LessThan(float64, float64): bool; 872extern operator '<=' macro Float64LessThanOrEqual(float64, float64): bool; 873 874extern macro BranchIfNumberEqual(Number, Number): never 875 labels Taken, NotTaken; 876operator '==' macro IsNumberEqual(a: Number, b: Number): bool { 877 BranchIfNumberEqual(a, b) otherwise return true, return false; 878} 879operator '!=' macro IsNumberNotEqual(a: Number, b: Number): bool { 880 return !(a == b); 881} 882extern macro BranchIfNumberLessThan(Number, Number): never 883 labels Taken, NotTaken; 884operator '<' macro NumberIsLessThan(a: Number, b: Number): bool { 885 BranchIfNumberLessThan(a, b) otherwise return true, return false; 886} 887extern macro BranchIfNumberLessThanOrEqual(Number, Number): never 888 labels Taken, NotTaken; 889operator '<=' macro NumberIsLessThanOrEqual(a: Number, b: Number): bool { 890 BranchIfNumberLessThanOrEqual(a, b) otherwise return true, return false; 891} 892 893operator '>' macro NumberIsGreaterThan(a: Number, b: Number): bool { 894 return b < a; 895} 896operator '>=' macro NumberIsGreaterThanOrEqual(a: Number, b: Number): bool { 897 return b <= a; 898} 899 900extern macro BranchIfFloat64IsNaN(float64): never 901 labels Taken, NotTaken; 902macro Float64IsNaN(n: float64): bool { 903 BranchIfFloat64IsNaN(n) otherwise return true, return false; 904} 905 906// The type of all tagged values that can safely be compared with TaggedEqual. 907@if(V8_ENABLE_WEBASSEMBLY) 908type TaggedWithIdentity = JSReceiver | FixedArrayBase | Oddball | Map | 909 WeakCell | Context | EmptyString | Symbol | WasmInternalFunction; 910@ifnot(V8_ENABLE_WEBASSEMBLY) 911type TaggedWithIdentity = JSReceiver | FixedArrayBase | Oddball | Map | 912 WeakCell | Context | EmptyString | Symbol; 913 914extern operator '==' macro TaggedEqual(TaggedWithIdentity, Object): bool; 915extern operator '==' macro TaggedEqual(Object, TaggedWithIdentity): bool; 916extern operator '==' macro TaggedEqual( 917 TaggedWithIdentity, TaggedWithIdentity): bool; 918extern operator '==' macro TaggedEqual(WeakHeapObject, WeakHeapObject): bool; 919extern operator '!=' macro TaggedNotEqual(TaggedWithIdentity, Object): bool; 920extern operator '!=' macro TaggedNotEqual(Object, TaggedWithIdentity): bool; 921extern operator '!=' macro TaggedNotEqual( 922 TaggedWithIdentity, TaggedWithIdentity): bool; 923extern operator '!=' macro TaggedNotEqual(WeakHeapObject, WeakHeapObject): bool; 924// Do not overload == and != if it is unclear if object identity is the right 925// equality. 926extern macro TaggedEqual(MaybeObject, MaybeObject): bool; 927extern macro TaggedNotEqual(MaybeObject, MaybeObject): bool; 928 929extern operator '+' macro SmiAdd(Smi, Smi): Smi; 930extern operator '-' macro SmiSub(Smi, Smi): Smi; 931extern operator '&' macro SmiAnd(Smi, Smi): Smi; 932extern operator '|' macro SmiOr(Smi, Smi): Smi; 933extern operator '<<' macro SmiShl(Smi, constexpr int31): Smi; 934extern operator '>>' macro SmiSar(Smi, constexpr int31): Smi; 935 936extern operator '+' macro IntPtrAdd(intptr, intptr): intptr; 937extern operator '+' macro ConstexprIntPtrAdd( 938 constexpr intptr, constexpr intptr): constexpr intptr; 939extern operator '+' macro ConstexprUintPtrAdd( 940 constexpr uintptr, constexpr uintptr): constexpr intptr; 941extern operator '+' macro Int64Add(int64, int64): int64; 942extern operator '-' macro IntPtrSub(intptr, intptr): intptr; 943extern operator '-' macro Int64Sub(int64, int64): int64; 944extern operator '*' macro IntPtrMul(intptr, intptr): intptr; 945extern operator '*' macro Int64Mul(int64, int64): int64; 946extern operator '/' macro IntPtrDiv(intptr, intptr): intptr; 947extern operator '/' macro Int64Div(int64, int64): int64; 948extern operator '<<' macro WordShl(intptr, intptr): intptr; 949extern operator '>>' macro WordSar(intptr, intptr): intptr; 950extern operator '&' macro WordAnd(intptr, intptr): intptr; 951extern operator '|' macro WordOr(intptr, intptr): intptr; 952 953extern operator '+' macro UintPtrAdd(uintptr, uintptr): uintptr; 954extern operator '+' macro Uint64Add(uint64, uint64): uint64; 955extern operator '-' macro UintPtrSub(uintptr, uintptr): uintptr; 956extern operator '-' macro Uint64Sub(uint64, uint64): uint64; 957extern operator '*' macro Uint64Mul(uint64, uint64): uint64; 958extern operator '<<' macro WordShl(uintptr, uintptr): uintptr; 959extern operator '>>>' macro WordShr(uintptr, uintptr): uintptr; 960extern operator '&' macro WordAnd(uintptr, uintptr): uintptr; 961extern operator '|' macro WordOr(uintptr, uintptr): uintptr; 962 963extern operator '+' macro Int32Add(int32, int32): int32; 964extern operator '+' macro Uint32Add(uint32, uint32): uint32; 965extern operator '+' macro ConstexprUint32Add( 966 constexpr uint32, constexpr int32): constexpr uint32; 967extern operator '+' macro ConstexprInt31Add( 968 constexpr int31, constexpr int31): constexpr int31; 969extern operator '+' macro ConstexprInt32Add( 970 constexpr int32, constexpr int32): constexpr int32; 971extern operator '*' macro ConstexprInt31Mul( 972 constexpr int31, constexpr int31): constexpr int31; 973extern operator '-' macro Int32Sub(int16, int16): int32; 974extern operator '-' macro Int32Sub(int32, int32): int32; 975extern operator '-' macro Uint32Sub(uint32, uint32): uint32; 976extern operator '*' macro Int32Mul(int32, int32): int32; 977extern operator '*' macro Uint32Mul(uint32, uint32): uint32; 978extern operator '/' macro Int32Div(int32, int32): int32; 979extern operator '%' macro Int32Mod(int32, int32): int32; 980extern operator '&' macro Word32And(int32, int32): int32; 981extern operator '&' macro Word32And(uint32, uint32): uint32; 982extern operator '==' macro 983ConstexprInt31Equal(constexpr int31, constexpr int31): constexpr bool; 984extern operator '!=' macro 985ConstexprInt31NotEqual(constexpr int31, constexpr int31): constexpr bool; 986extern operator '==' macro 987ConstexprUint32Equal(constexpr uint32, constexpr uint32): constexpr bool; 988extern operator '!=' macro 989ConstexprUint32NotEqual(constexpr uint32, constexpr uint32): constexpr bool; 990extern operator '>=' macro 991ConstexprInt31GreaterThanEqual( 992 constexpr int31, constexpr int31): constexpr bool; 993extern operator '==' macro ConstexprInt32Equal( 994 constexpr int32, constexpr int32): constexpr bool; 995extern operator '!=' macro ConstexprInt32NotEqual( 996 constexpr int32, constexpr int32): constexpr bool; 997 998// IntegerLiteral overloads 999extern macro ConstexprIntegerLiteralToInt31(constexpr IntegerLiteral): 1000 constexpr int31; 1001extern macro ConstexprIntegerLiteralToInt32(constexpr IntegerLiteral): 1002 constexpr int32; 1003extern macro ConstexprIntegerLiteralToUint32(constexpr IntegerLiteral): 1004 constexpr uint32; 1005extern macro ConstexprIntegerLiteralToUint64(constexpr IntegerLiteral): 1006 constexpr uint64; 1007extern macro ConstexprIntegerLiteralToIntptr(constexpr IntegerLiteral): 1008 constexpr intptr; 1009extern macro ConstexprIntegerLiteralToUintptr(constexpr IntegerLiteral): 1010 constexpr uintptr; 1011extern macro ConstexprIntegerLiteralToInt8(constexpr IntegerLiteral): 1012 constexpr int8; 1013extern macro ConstexprIntegerLiteralToUint8(constexpr IntegerLiteral): 1014 constexpr uint8; 1015extern macro ConstexprIntegerLiteralToFloat64(constexpr IntegerLiteral): 1016 constexpr float64; 1017 1018extern operator '==' macro ConstexprIntegerLiteralEqual( 1019 constexpr IntegerLiteral, constexpr IntegerLiteral): constexpr bool; 1020extern operator '+' macro ConstexprIntegerLiteralAdd( 1021 constexpr IntegerLiteral, 1022 constexpr IntegerLiteral): constexpr IntegerLiteral; 1023extern operator '<<' macro ConstexprIntegerLiteralLeftShift( 1024 constexpr IntegerLiteral, 1025 constexpr IntegerLiteral): constexpr IntegerLiteral; 1026extern operator '|' macro ConstexprIntegerLiteralBitwiseOr( 1027 constexpr IntegerLiteral, 1028 constexpr IntegerLiteral): constexpr IntegerLiteral; 1029 1030extern operator '==' macro Word32Equal(int32, int32): bool; 1031extern operator '==' macro Word32Equal(uint32, uint32): bool; 1032extern operator '!=' macro Word32NotEqual(int32, int32): bool; 1033extern operator '!=' macro Word32NotEqual(uint32, uint32): bool; 1034extern operator '>>>' macro Word32Shr(uint32, uint32): uint32; 1035extern operator '>>' macro Word32Sar(int32, int32): int32; 1036extern operator '<<' macro Word32Shl(int32, int32): int32; 1037extern operator '<<' macro Word32Shl(uint32, uint32): uint32; 1038extern operator '|' macro Word32Or(int32, int32): int32; 1039extern operator '|' macro Word32Or(uint32, uint32): uint32; 1040extern operator '&' macro Word32And(bool, bool): bool; 1041extern operator '|' macro Word32Or(bool, bool): bool; 1042extern operator '==' macro Word32Equal(bool, bool): bool; 1043extern operator '!=' macro Word32NotEqual(bool, bool): bool; 1044extern operator '|' macro ConstexprWord32Or( 1045 constexpr int32, constexpr int32): constexpr int32; 1046extern operator '^' macro Word32Xor(int32, int32): int32; 1047extern operator '^' macro Word32Xor(uint32, uint32): uint32; 1048extern operator '<<' macro ConstexprWord32Shl( 1049 constexpr uint32, constexpr int32): uint32; 1050 1051extern operator '==' macro Word64Equal(int64, int64): bool; 1052extern operator '==' macro Word64Equal(uint64, uint64): bool; 1053extern operator '!=' macro Word64NotEqual(int64, int64): bool; 1054extern operator '!=' macro Word64NotEqual(uint64, uint64): bool; 1055extern operator '>>>' macro Word64Shr(uint64, uint64): uint64; 1056extern operator '>>' macro Word64Sar(int64, int64): int64; 1057extern operator '<<' macro Word64Shl(int64, int64): int64; 1058extern operator '<<' macro Word64Shl(uint64, uint64): uint64; 1059extern operator '|' macro Word64Or(int64, int64): int64; 1060extern operator '|' macro Word64Or(uint64, uint64): uint64; 1061extern operator '&' macro Word64And(uint64, uint64): uint64; 1062extern operator '^' macro Word64Xor(int64, int64): int64; 1063extern operator '^' macro Word64Xor(uint64, uint64): uint64; 1064 1065extern operator '+' macro Float64Add(float64, float64): float64; 1066extern operator '-' macro Float64Sub(float64, float64): float64; 1067extern operator '*' macro Float64Mul(float64, float64): float64; 1068extern operator '/' macro Float64Div(float64, float64): float64; 1069extern operator '%' macro Float64Mod(float64, float64): float64; 1070 1071extern operator '+' macro NumberAdd(Number, Number): Number; 1072extern operator '-' macro NumberSub(Number, Number): Number; 1073extern macro NumberMin(Number, Number): Number; 1074extern macro NumberMax(Number, Number): Number; 1075macro Min(x: Number, y: Number): Number { 1076 return NumberMin(x, y); 1077} 1078macro Max(x: Number, y: Number): Number { 1079 return NumberMax(x, y); 1080} 1081 1082extern macro TryIntPtrAdd(intptr, intptr): intptr labels Overflow; 1083extern macro TryIntPtrSub(intptr, intptr): intptr labels Overflow; 1084extern macro TryInt32Mul(int32, int32): int32 labels Overflow; 1085 1086extern operator '<' macro ConstexprUintPtrLessThan( 1087 constexpr uintptr, constexpr uintptr): constexpr bool; 1088extern operator '<<' macro ConstexprUintPtrShl( 1089 constexpr uintptr, constexpr int31): constexpr uintptr; 1090extern operator '>>>' macro ConstexprUintPtrShr( 1091 constexpr uintptr, constexpr int31): constexpr uintptr; 1092 1093extern macro SmiMax(Smi, Smi): Smi; 1094extern macro SmiMin(Smi, Smi): Smi; 1095extern macro SmiMul(Smi, Smi): Number; 1096extern macro SmiMod(Smi, Smi): Number; 1097 1098extern macro IntPtrMax(intptr, intptr): intptr; 1099extern macro IntPtrMin(intptr, intptr): intptr; 1100extern macro UintPtrMin(uintptr, uintptr): uintptr; 1101 1102extern operator '!' macro ConstexprBoolNot(constexpr bool): constexpr bool; 1103extern operator '!' macro Word32BinaryNot(bool): bool; 1104extern operator '!' macro IsFalse(Boolean): bool; 1105 1106extern operator '==' macro 1107ConstexprInt31Equal( 1108 constexpr InstanceType, constexpr InstanceType): constexpr bool; 1109extern operator '-' macro ConstexprUint32Sub( 1110 constexpr InstanceType, constexpr InstanceType): constexpr int32; 1111extern operator '-' macro ConstexprInt32Sub( 1112 constexpr int32, constexpr int32): constexpr int32; 1113 1114extern operator '.instanceType' macro LoadInstanceType(HeapObject): 1115 InstanceType; 1116 1117operator '.length_uintptr' macro LoadJSArrayLengthAsUintPtr(array: JSArray): 1118 uintptr { 1119 return Convert<uintptr>(array.length); 1120} 1121 1122extern operator '.length_intptr' macro LoadStringLengthAsWord(String): intptr; 1123operator '.length_uintptr' macro LoadStringLengthAsUintPtr(s: String): uintptr { 1124 return Unsigned(s.length_intptr); 1125} 1126extern operator '.length_uint32' macro LoadStringLengthAsWord32(String): uint32; 1127extern operator '.length_smi' macro LoadStringLengthAsSmi(String): Smi; 1128 1129extern builtin StringAdd_CheckNone(implicit context: Context)( 1130 String, String): String; 1131operator '+' macro StringAdd(implicit context: Context)( 1132 a: String, b: String): String { 1133 return StringAdd_CheckNone(a, b); 1134} 1135 1136operator '==' macro PromiseStateEquals( 1137 s1: PromiseState, s2: PromiseState): bool { 1138 return Word32Equal(s1, s2); 1139} 1140 1141extern macro CountLeadingZeros64(uint64): int64; 1142extern macro CountTrailingZeros32(uint32): int32; 1143extern macro CountTrailingZeros64(uint64): int64; 1144 1145extern macro TaggedIsSmi(Object): bool; 1146extern macro TaggedIsNotSmi(Object): bool; 1147extern macro TaggedIsPositiveSmi(Object): bool; 1148extern macro IsValidPositiveSmi(intptr): bool; 1149 1150extern macro IsInteger(JSAny): bool; 1151extern macro IsInteger(HeapNumber): bool; 1152 1153extern macro AllocateHeapNumberWithValue(float64): HeapNumber; 1154extern macro ChangeInt32ToTagged(int32): Number; 1155extern macro ChangeUint32ToTagged(uint32): Number; 1156extern macro ChangeUintPtrToFloat64(uintptr): float64; 1157extern macro ChangeUintPtrToTagged(uintptr): Number; 1158extern macro Unsigned(int64): uint64; 1159extern macro Unsigned(int32): uint32; 1160extern macro Unsigned(int16): uint16; 1161extern macro Unsigned(int8): uint8; 1162extern macro Unsigned(intptr): uintptr; 1163extern macro Unsigned(RawPtr): uintptr; 1164extern macro Signed(uint64): int64; 1165extern macro Signed(uint32): int32; 1166extern macro Signed(uint16): int16; 1167extern macro Signed(uint8): int8; 1168extern macro Signed(uintptr): intptr; 1169extern macro Signed(RawPtr): intptr; 1170extern macro TruncateIntPtrToInt32(intptr): int32; 1171extern macro TruncateInt64ToInt32(int64): int32; 1172extern macro SmiTag(intptr): Smi; 1173extern macro SmiFromInt32(int32): Smi; 1174extern macro SmiFromUint32(uint32): Smi; 1175extern macro SmiFromIntPtr(intptr): Smi; 1176extern macro SmiUntag(Smi): intptr; 1177macro SmiUntag<T: type>(value: SmiTagged<T>): T { 1178 return %RawDownCast<T>(Unsigned(SmiToInt32(Convert<Smi>(value)))); 1179} 1180macro SmiTag<T : type extends uint31>(value: T): SmiTagged<T> { 1181 return %RawDownCast<SmiTagged<T>>(SmiFromUint32(value)); 1182} 1183extern macro SmiToInt32(Smi): int32; 1184extern macro SmiToFloat64(Smi): float64; 1185extern macro TaggedIndexToIntPtr(TaggedIndex): intptr; 1186extern macro IntPtrToTaggedIndex(intptr): TaggedIndex; 1187extern macro TaggedIndexToSmi(TaggedIndex): Smi; 1188extern macro SmiToTaggedIndex(Smi): TaggedIndex; 1189extern macro RoundIntPtrToFloat64(intptr): float64; 1190extern macro IntPtrRoundUpToPowerOfTwo32(intptr): intptr; 1191extern macro ChangeFloat32ToFloat64(float32): float64; 1192extern macro ChangeNumberToFloat64(Number): float64; 1193extern macro ChangeNumberToUint32(Number): uint32; 1194extern macro ChangeTaggedNonSmiToInt32(implicit context: Context)(JSAnyNotSmi): 1195 int32; 1196extern macro ChangeTaggedToFloat64(implicit context: Context)(JSAny): float64; 1197extern macro ChangeFloat64ToTagged(float64): Number; 1198extern macro ChangeFloat64ToUintPtr(float64): uintptr; 1199extern macro ChangeFloat64ToIntPtr(float64): intptr; 1200extern macro ChangeBoolToInt32(bool): int32; 1201extern macro ChangeInt32ToFloat64(int32): float64; 1202extern macro ChangeInt32ToIntPtr(int32): intptr; // Sign-extends. 1203extern macro ChangeUint32ToWord(uint32): uintptr; // Doesn't sign-extend. 1204extern macro ChangeInt32ToInt64(int32): intptr; // Sign-extends. 1205extern macro ChangeUint32ToUint64(uint32): uint64; // Doesn't sign-extend. 1206extern macro LoadNativeContext(Context): NativeContext; 1207extern macro TruncateFloat64ToFloat32(float64): float32; 1208extern macro TruncateHeapNumberValueToWord32(HeapNumber): int32; 1209extern macro LoadJSArrayElementsMap(constexpr ElementsKind, NativeContext): Map; 1210extern macro LoadJSArrayElementsMap(ElementsKind, NativeContext): Map; 1211extern macro NumberConstant(constexpr float64): Number; 1212extern macro NumberConstant(constexpr int32): Number; 1213extern macro NumberConstant(constexpr uint32): Number; 1214extern macro IntPtrConstant(constexpr int31): intptr; 1215extern macro IntPtrConstant(constexpr int32): intptr; 1216extern macro Uint16Constant(constexpr uint16): uint16; 1217extern macro Int32Constant(constexpr int31): int31; 1218extern macro Int32Constant(constexpr int32): int32; 1219macro Int32Constant(i: constexpr IntegerLiteral): int32 { 1220 return Int32Constant(ConstexprIntegerLiteralToInt32(i)); 1221} 1222extern macro Int64Constant(constexpr int64): int64; 1223extern macro Uint64Constant(constexpr uint64): uint64; 1224extern macro Float64Constant(constexpr int32): float64; 1225extern macro Float64Constant(constexpr float64): float64; 1226extern macro Float64Constant(constexpr IntegerLiteral): float64; 1227extern macro SmiConstant(constexpr int31): Smi; 1228extern macro SmiConstant(constexpr Smi): Smi; 1229extern macro SmiConstant(constexpr MessageTemplate): Smi; 1230extern macro SmiConstant(constexpr bool): Smi; 1231extern macro SmiConstant(constexpr uint32): Smi; 1232macro SmiConstant(il: constexpr IntegerLiteral): Smi { 1233 return SmiConstant(ConstexprIntegerLiteralToInt31(il)); 1234} 1235extern macro BoolConstant(constexpr bool): bool; 1236extern macro StringConstant(constexpr string): String; 1237extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot; 1238extern macro IntPtrConstant(constexpr intptr): intptr; 1239macro IntPtrConstant(il: constexpr IntegerLiteral): intptr { 1240 return IntPtrConstant(ConstexprIntegerLiteralToIntptr(il)); 1241} 1242extern macro PointerConstant(constexpr RawPtr): RawPtr; 1243extern macro SingleCharacterStringConstant(constexpr string): String; 1244extern macro Float64SilenceNaN(float64): float64; 1245 1246extern macro BitcastWordToTaggedSigned(intptr): Smi; 1247extern macro BitcastWordToTaggedSigned(uintptr): Smi; 1248extern macro BitcastWordToTagged(intptr): Object; 1249extern macro BitcastWordToTagged(uintptr): Object; 1250extern macro BitcastTaggedToWord(Object): intptr; 1251extern macro BitcastTaggedToWordForTagAndSmiBits(Tagged): intptr; 1252 1253extern macro FixedArrayMapConstant(): Map; 1254extern macro FixedDoubleArrayMapConstant(): Map; 1255extern macro FixedCOWArrayMapConstant(): Map; 1256extern macro EmptyByteArrayConstant(): ByteArray; 1257extern macro EmptyFixedArrayConstant(): EmptyFixedArray; 1258extern macro PromiseCapabilityMapConstant(): Map; 1259extern macro OneByteStringMapConstant(): Map; 1260extern macro StringMapConstant(): Map; 1261 1262const kFixedArrayMap: Map = FixedArrayMapConstant(); 1263const kFixedDoubleArrayMap: Map = FixedDoubleArrayMapConstant(); 1264const kCOWMap: Map = FixedCOWArrayMapConstant(); 1265const kEmptyByteArray: ByteArray = EmptyByteArrayConstant(); 1266const kEmptyFixedArray: EmptyFixedArray = EmptyFixedArrayConstant(); 1267const kPromiseCapabilityMap: Map = PromiseCapabilityMapConstant(); 1268// The map of a non-internalized internal SeqOneByteString. 1269const kOneByteStringMap: Map = OneByteStringMapConstant(); 1270// The map of a non-internalized internal SeqTwoByteString. 1271const kStringMap: Map = StringMapConstant(); 1272 1273macro OutOfBounds<T: type, X: type>(index: T, length: X): bool { 1274 return UintPtrGreaterThanOrEqual( 1275 Convert<uintptr>(Convert<intptr>(index)), 1276 Convert<uintptr>(Convert<intptr>(length))); 1277} 1278 1279extern macro IsPrototypeInitialArrayPrototype(implicit context: Context)(Map): 1280 bool; 1281extern macro IsNoElementsProtectorCellInvalid(): bool; 1282extern macro IsArrayIteratorProtectorCellInvalid(): bool; 1283extern macro IsArraySpeciesProtectorCellInvalid(): bool; 1284extern macro IsIsConcatSpreadableProtectorCellInvalid(): bool; 1285extern macro IsTypedArraySpeciesProtectorCellInvalid(): bool; 1286extern macro IsPromiseSpeciesProtectorCellInvalid(): bool; 1287extern macro IsMockArrayBufferAllocatorFlag(): bool; 1288extern macro HasBuiltinSubclassingFlag(): bool; 1289extern macro IsPrototypeTypedArrayPrototype(implicit context: Context)(Map): 1290 bool; 1291 1292extern operator '.data_ptr' macro LoadJSTypedArrayDataPtr(JSTypedArray): RawPtr; 1293 1294extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind; 1295extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray): 1296 ElementsKind; 1297 1298extern operator '.length' macro LoadFastJSArrayLength(FastJSArray): Smi; 1299operator '.length=' macro StoreFastJSArrayLength( 1300 array: FastJSArray, length: Smi): void { 1301 const array: JSArray = array; 1302 array.length = length; 1303} 1304 1305extern macro GetNumberDictionaryNumberOfElements(NumberDictionary): Smi; 1306 1307extern macro LoadConstructorOrBackPointer(Map): Object; 1308 1309extern macro BasicLoadNumberDictionaryElement(NumberDictionary, intptr): JSAny 1310 labels NotData, IfHole; 1311 1312extern macro IsFastElementsKind(ElementsKind): bool; 1313extern macro IsDoubleElementsKind(ElementsKind): bool; 1314extern macro IsFastSmiOrTaggedElementsKind(ElementsKind): bool; 1315extern macro IsFastSmiElementsKind(ElementsKind): bool; 1316extern macro IsHoleyFastElementsKind(ElementsKind): bool; 1317 1318macro FastHoleyElementsKind(kind: ElementsKind): ElementsKind { 1319 if (kind == ElementsKind::PACKED_SMI_ELEMENTS) { 1320 return ElementsKind::HOLEY_SMI_ELEMENTS; 1321 } else if (kind == ElementsKind::PACKED_DOUBLE_ELEMENTS) { 1322 return ElementsKind::HOLEY_DOUBLE_ELEMENTS; 1323 } 1324 dcheck(kind == ElementsKind::PACKED_ELEMENTS); 1325 return ElementsKind::HOLEY_ELEMENTS; 1326} 1327 1328macro AllowDoubleElements(kind: ElementsKind): ElementsKind { 1329 if (kind == ElementsKind::PACKED_SMI_ELEMENTS) { 1330 return ElementsKind::PACKED_DOUBLE_ELEMENTS; 1331 } else if (kind == ElementsKind::HOLEY_SMI_ELEMENTS) { 1332 return ElementsKind::HOLEY_DOUBLE_ELEMENTS; 1333 } 1334 return kind; 1335} 1336 1337macro AllowNonNumberElements(kind: ElementsKind): ElementsKind { 1338 if (kind == ElementsKind::PACKED_SMI_ELEMENTS) { 1339 return ElementsKind::PACKED_ELEMENTS; 1340 } else if (kind == ElementsKind::HOLEY_SMI_ELEMENTS) { 1341 return ElementsKind::HOLEY_ELEMENTS; 1342 } else if (kind == ElementsKind::PACKED_DOUBLE_ELEMENTS) { 1343 return ElementsKind::PACKED_ELEMENTS; 1344 } else if (kind == ElementsKind::HOLEY_DOUBLE_ELEMENTS) { 1345 return ElementsKind::HOLEY_ELEMENTS; 1346 } 1347 return kind; 1348} 1349 1350macro GetObjectFunction(implicit context: Context)(): JSFunction { 1351 return *NativeContextSlot(ContextSlot::OBJECT_FUNCTION_INDEX); 1352} 1353macro GetArrayFunction(implicit context: Context)(): JSFunction { 1354 return *NativeContextSlot(ContextSlot::ARRAY_FUNCTION_INDEX); 1355} 1356macro GetArrayBufferFunction(implicit context: Context)(): Constructor { 1357 return *NativeContextSlot(ContextSlot::ARRAY_BUFFER_FUN_INDEX); 1358} 1359macro GetArrayBufferNoInitFunction(implicit context: Context)(): JSFunction { 1360 return *NativeContextSlot(ContextSlot::ARRAY_BUFFER_NOINIT_FUN_INDEX); 1361} 1362macro GetFastPackedElementsJSArrayMap(implicit context: Context)(): Map { 1363 return *NativeContextSlot(ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX); 1364} 1365macro GetFastPackedSmiElementsJSArrayMap(implicit context: Context)(): Map { 1366 return *NativeContextSlot( 1367 ContextSlot::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX); 1368} 1369macro GetProxyRevocableResultMap(implicit context: Context)(): Map { 1370 return *NativeContextSlot(ContextSlot::PROXY_REVOCABLE_RESULT_MAP_INDEX); 1371} 1372macro GetIteratorResultMap(implicit context: Context)(): Map { 1373 return *NativeContextSlot(ContextSlot::ITERATOR_RESULT_MAP_INDEX); 1374} 1375macro GetInitialStringIteratorMap(implicit context: Context)(): Map { 1376 return *NativeContextSlot(ContextSlot::INITIAL_STRING_ITERATOR_MAP_INDEX); 1377} 1378macro GetReflectApply(implicit context: Context)(): Callable { 1379 return *NativeContextSlot(ContextSlot::REFLECT_APPLY_INDEX); 1380} 1381macro GetRegExpLastMatchInfo(implicit context: Context)(): RegExpMatchInfo { 1382 return *NativeContextSlot(ContextSlot::REGEXP_LAST_MATCH_INFO_INDEX); 1383} 1384macro GetStrictArgumentsMap(implicit context: Context)(): Map { 1385 return *NativeContextSlot(ContextSlot::STRICT_ARGUMENTS_MAP_INDEX); 1386} 1387macro GetSloppyArgumentsMap(implicit context: Context)(): Map { 1388 return *NativeContextSlot(ContextSlot::SLOPPY_ARGUMENTS_MAP_INDEX); 1389} 1390macro GetFastAliasedArgumentsMap(implicit context: Context)(): Map { 1391 return *NativeContextSlot(ContextSlot::FAST_ALIASED_ARGUMENTS_MAP_INDEX); 1392} 1393macro GetWeakCellMap(implicit context: Context)(): Map { 1394 return %GetClassMapConstant<WeakCell>(); 1395} 1396macro GetPrototypeApplyFunction(implicit context: Context)(): JSFunction { 1397 return *NativeContextSlot(ContextSlot::FUNCTION_PROTOTYPE_APPLY_INDEX); 1398} 1399 1400// Call(Context, Target, Receiver, ...Args) 1401// TODO(joshualitt): Assuming the context parameter is for throwing when Target 1402// is non-callable, then we should make it an implicit 1403// parameter. 1404extern transitioning macro Call(Context, JSAny, JSAny): JSAny; 1405extern transitioning macro Call(Context, JSAny, JSAny, JSAny): JSAny; 1406extern transitioning macro Call(Context, JSAny, JSAny, JSAny, JSAny): JSAny; 1407extern transitioning macro Call( 1408 Context, JSAny, JSAny, JSAny, JSAny, JSAny): JSAny; 1409extern transitioning macro Call( 1410 Context, JSAny, JSAny, JSAny, JSAny, JSAny, JSAny): JSAny; 1411extern transitioning macro Call( 1412 Context, JSAny, JSAny, JSAny, JSAny, JSAny, JSAny, JSAny): JSAny; 1413 1414extern macro TransitionElementsKind( 1415 JSObject, Map, constexpr ElementsKind, 1416 constexpr ElementsKind): void labels Bailout; 1417extern macro PerformStackCheck(implicit context: Context)(): void; 1418 1419extern macro Typeof(JSAny): String; 1420 1421// Return true iff number is NaN. 1422macro NumberIsNaN(number: Number): bool { 1423 typeswitch (number) { 1424 case (Smi): { 1425 return false; 1426 } 1427 case (hn: HeapNumber): { 1428 const value: float64 = Convert<float64>(hn); 1429 return value != value; 1430 } 1431 } 1432} 1433 1434extern macro GotoIfForceSlowPath(): void labels Taken; 1435macro IsForceSlowPath(): bool { 1436 GotoIfForceSlowPath() otherwise return true; 1437 return false; 1438} 1439 1440extern macro BranchIfToBooleanIsTrue(JSAny): never 1441 labels Taken, NotTaken; 1442extern macro BranchIfToBooleanIsFalse(JSAny): never 1443 labels Taken, NotTaken; 1444 1445macro ToBoolean(obj: JSAny): bool { 1446 BranchIfToBooleanIsTrue(obj) otherwise return true, return false; 1447} 1448 1449@export 1450macro RequireObjectCoercible(implicit context: Context)( 1451 value: JSAny, name: constexpr string): JSAny { 1452 if (IsNullOrUndefined(value)) { 1453 ThrowTypeError(MessageTemplate::kCalledOnNullOrUndefined, name); 1454 } 1455 return value; 1456} 1457 1458extern macro BranchIfSameValue(JSAny, JSAny): never labels Taken, NotTaken; 1459macro SameValue(a: JSAny, b: JSAny): bool { 1460 BranchIfSameValue(a, b) otherwise return true, return false; 1461} 1462 1463// Does "if (index1 + index2 > limit) goto IfOverflow" in an uintptr overflow 1464// friendly way where index1 and index2 are in [0, kMaxSafeInteger] range. 1465macro CheckIntegerIndexAdditionOverflow( 1466 index1: uintptr, index2: uintptr, limit: uintptr): void labels IfOverflow { 1467 if constexpr (Is64()) { 1468 dcheck(index1 <= kMaxSafeIntegerUint64); 1469 dcheck(index2 <= kMaxSafeIntegerUint64); 1470 // Given that both index1 and index2 are in a safe integer range the 1471 // addition can't overflow. 1472 if (index1 + index2 > limit) goto IfOverflow; 1473 } else { 1474 // Uintptr range is "smaller" than [0, kMaxSafeInteger] range, so 1475 // "index1 + index2" may overflow, so we check the condition in the 1476 // following way "if (index1 > limit - index2) goto IfOverflow" and check 1477 // that "limit - index2" does not underflow. 1478 const index1Limit = limit - index2; 1479 if (index1 > index1Limit) goto IfOverflow; 1480 // Handle potential index1Limit underflow. 1481 if (index1Limit > limit) goto IfOverflow; 1482 } 1483} 1484 1485// TODO(turbofan): Define enum here once they appear in Torque. 1486// 1487// The value is a SafeInteger that fits into uintptr range, so no bounds checks 1488// are necessary. 1489const kModeValueIsSafeIntegerUintPtr: constexpr int31 = 0; 1490// The value is a SafeInteger that may not fit into uintptr range, so only 1491// uintptr bounds check is necessary. 1492const kModeValueIsSafeInteger: constexpr int31 = 1; 1493// The value is can be whatever non-NaN number, all checks are necessary. 1494const kModeValueIsAnyNumber: constexpr int31 = 2; 1495 1496macro TryNumberToUintPtr(valueNumber: Number, kMode: constexpr int31): 1497 uintptr labels IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow { 1498 typeswitch (valueNumber) { 1499 case (valueSmi: Smi): { 1500 if (kMode == kModeValueIsAnyNumber) { 1501 if (valueSmi < 0) goto IfLessThanZero; 1502 } else { 1503 dcheck(valueSmi >= 0); 1504 } 1505 const value: uintptr = Unsigned(Convert<intptr>(valueSmi)); 1506 // Positive Smi values definitely fit into both [0, kMaxSafeInteger] and 1507 // [0, kMaxUintPtr] ranges. 1508 return value; 1509 } 1510 case (valueHeapNumber: HeapNumber): { 1511 dcheck(IsNumberNormalized(valueHeapNumber)); 1512 const valueDouble: float64 = Convert<float64>(valueHeapNumber); 1513 // NaNs must be handled outside. 1514 dcheck(!Float64IsNaN(valueDouble)); 1515 if (kMode == kModeValueIsAnyNumber) { 1516 if (valueDouble < 0) goto IfLessThanZero; 1517 } else { 1518 dcheck(valueDouble >= 0); 1519 } 1520 1521 if constexpr (Is64()) { 1522 // On 64-bit architectures uintptr range is bigger than safe integer 1523 // range. 1524 if (kMode == kModeValueIsAnyNumber) { 1525 if (valueDouble > kMaxSafeInteger) goto IfSafeIntegerOverflow; 1526 } else { 1527 dcheck(valueDouble <= kMaxSafeInteger); 1528 } 1529 } else { 1530 // On 32-bit architectures uintptr range is smaller than safe integer 1531 // range. 1532 if (kMode == kModeValueIsAnyNumber || 1533 kMode == kModeValueIsSafeInteger) { 1534 if (valueDouble > kMaxUInt32Double) goto IfUIntPtrOverflow; 1535 } else { 1536 dcheck(valueDouble <= kMaxUInt32Double); 1537 } 1538 } 1539 return ChangeFloat64ToUintPtr(valueDouble); 1540 } 1541 } 1542} 1543 1544@export 1545macro ChangeUintPtrNumberToUintPtr(value: Number): uintptr { 1546 try { 1547 return TryNumberToUintPtr(value, kModeValueIsSafeIntegerUintPtr) 1548 otherwise InvalidValue, InvalidValue, InvalidValue; 1549 } label InvalidValue { 1550 unreachable; 1551 } 1552} 1553 1554@export 1555macro ChangeSafeIntegerNumberToUintPtr(value: Number): 1556 uintptr labels IfUIntPtrOverflow { 1557 try { 1558 return TryNumberToUintPtr(value, kModeValueIsSafeInteger) 1559 otherwise InvalidValue, IfUIntPtrOverflow, InvalidValue; 1560 } label InvalidValue { 1561 unreachable; 1562 } 1563} 1564 1565transitioning macro ToUintPtr(implicit context: Context)(value: JSAny): 1566 uintptr labels IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow { 1567 if (value == Undefined) return 0; 1568 const indexNumber = ToInteger_Inline(value); 1569 return TryNumberToUintPtr(indexNumber, kModeValueIsAnyNumber) 1570 otherwise IfLessThanZero, IfUIntPtrOverflow, IfSafeIntegerOverflow; 1571} 1572 1573// https://tc39.github.io/ecma262/#sec-toindex 1574// Unlike ToIndex from the spec this implementation triggers IfRangeError if 1575// the result is bigger than min(kMaxUIntPtr, kMaxSafeInteger). 1576// We can do this because all callers do a range checks against uintptr length 1577// anyway and throw a RangeError in case of out-of-bounds index. 1578@export 1579transitioning macro ToIndex(implicit context: Context)(value: JSAny): 1580 uintptr labels IfRangeError { 1581 if (value == Undefined) return 0; 1582 const indexNumber = ToInteger_Inline(value); 1583 // Less than 0 case, uintptr range overflow and safe integer range overflow 1584 // imply IfRangeError. 1585 return TryNumberToUintPtr(indexNumber, kModeValueIsAnyNumber) 1586 otherwise IfRangeError, IfRangeError, IfRangeError; 1587} 1588 1589transitioning macro GetLengthProperty(implicit context: Context)(o: JSAny): 1590 Number { 1591 try { 1592 typeswitch (o) { 1593 case (a: JSArray): { 1594 return a.length; 1595 } 1596 case (a: JSStrictArgumentsObject): { 1597 goto ToLength(a.length); 1598 } 1599 case (a: JSSloppyArgumentsObject): { 1600 goto ToLength(a.length); 1601 } 1602 case (JSAny): deferred { 1603 goto ToLength(GetProperty(o, kLengthString)); 1604 } 1605 } 1606 } label ToLength(length: JSAny) deferred { 1607 return ToLength_Inline(length); 1608 } 1609} 1610 1611transitioning macro GetMethod(implicit context: Context)( 1612 o: JSAny, name: AnyName): Callable labels IfNullOrUndefined, 1613 IfMethodNotCallable(JSAny) { 1614 const value = GetProperty(o, name); 1615 // TODO(v8:9933): Consider checking for null/undefined after checking for 1616 // callable because the latter seems to be more common. 1617 if (value == Undefined || value == Null) goto IfNullOrUndefined; 1618 return Cast<Callable>(value) 1619 otherwise goto IfMethodNotCallable(value); 1620} 1621 1622transitioning macro GetMethod(implicit context: Context)( 1623 o: JSAny, name: String): Callable labels IfNullOrUndefined { 1624 try { 1625 return GetMethod(o, name) otherwise IfNullOrUndefined, IfMethodNotCallable; 1626 } label IfMethodNotCallable(value: JSAny) deferred { 1627 ThrowTypeError(MessageTemplate::kPropertyNotFunction, value, name, o); 1628 } 1629} 1630 1631transitioning macro GetMethod(implicit context: Context)( 1632 o: JSAny, name: constexpr string): Callable labels IfNullOrUndefined { 1633 return GetMethod(o, StringConstant(name)) otherwise IfNullOrUndefined; 1634} 1635 1636transitioning macro GetMethod(implicit context: Context)( 1637 o: JSAny, symbol: Symbol): Callable labels IfNullOrUndefined { 1638 const value = GetProperty(o, symbol); 1639 if (value == Undefined || value == Null) goto IfNullOrUndefined; 1640 return Cast<Callable>(value) 1641 otherwise ThrowTypeError( 1642 MessageTemplate::kPropertyNotFunction, value, symbol, o); 1643} 1644 1645extern macro IsOneByteStringInstanceType(InstanceType): bool; 1646 1647// After converting an index to an integer, calculate a relative index: 1648// return index < 0 ? max(length + index, 0) : min(index, length) 1649@export 1650transitioning macro ConvertToRelativeIndex(implicit context: Context)( 1651 index: JSAny, length: uintptr): uintptr { 1652 const indexNumber: Number = ToInteger_Inline(index); 1653 return ConvertToRelativeIndex(indexNumber, length); 1654} 1655 1656// Calculate a relative index: 1657// return index < 0 ? max(length + index, 0) : min(index, length) 1658@export 1659macro ConvertToRelativeIndex(indexNumber: Number, length: uintptr): uintptr { 1660 typeswitch (indexNumber) { 1661 case (indexSmi: Smi): { 1662 const indexIntPtr: intptr = Convert<intptr>(indexSmi); 1663 // The logic is implemented using unsigned types. 1664 if (indexIntPtr < 0) { 1665 const relativeIndex: uintptr = Unsigned(indexIntPtr) + length; 1666 return relativeIndex < length ? relativeIndex : 0; 1667 1668 } else { 1669 const relativeIndex: uintptr = Unsigned(indexIntPtr); 1670 return relativeIndex < length ? relativeIndex : length; 1671 } 1672 } 1673 case (indexHeapNumber: HeapNumber): { 1674 dcheck(IsNumberNormalized(indexHeapNumber)); 1675 const indexDouble: float64 = Convert<float64>(indexHeapNumber); 1676 // NaNs must already be handled by ConvertToRelativeIndex() version 1677 // above accepting JSAny indices. 1678 dcheck(!Float64IsNaN(indexDouble)); 1679 const lengthDouble: float64 = Convert<float64>(length); 1680 dcheck(lengthDouble <= kMaxSafeInteger); 1681 if (indexDouble < 0) { 1682 const relativeIndex: float64 = lengthDouble + indexDouble; 1683 return relativeIndex > 0 ? ChangeFloat64ToUintPtr(relativeIndex) : 0; 1684 1685 } else { 1686 return ChangeFloat64ToUintPtr( 1687 indexDouble < lengthDouble ? indexDouble : lengthDouble); 1688 } 1689 } 1690 } 1691} 1692 1693// After converting an index to a signed integer, clamps it to the provided 1694// range [0, limit]: 1695// return min(max(index, 0), limit) 1696@export 1697transitioning macro ClampToIndexRange(implicit context: Context)( 1698 index: JSAny, limit: uintptr): uintptr { 1699 const indexNumber: Number = ToInteger_Inline(index); 1700 return ClampToIndexRange(indexNumber, limit); 1701} 1702 1703// Clamps given signed indexNumber to the provided range [0, limit]: 1704// return min(max(index, 0), limit) 1705@export 1706macro ClampToIndexRange(indexNumber: Number, limit: uintptr): uintptr { 1707 typeswitch (indexNumber) { 1708 case (indexSmi: Smi): { 1709 if (indexSmi < 0) return 0; 1710 const index: uintptr = Unsigned(Convert<intptr>(indexSmi)); 1711 if (index >= limit) return limit; 1712 return index; 1713 } 1714 case (indexHeapNumber: HeapNumber): { 1715 dcheck(IsNumberNormalized(indexHeapNumber)); 1716 const indexDouble: float64 = Convert<float64>(indexHeapNumber); 1717 // NaNs must already be handled by ClampToIndexRange() version 1718 // above accepting JSAny indices. 1719 dcheck(!Float64IsNaN(indexDouble)); 1720 if (indexDouble <= 0) return 0; 1721 1722 const maxIndexDouble: float64 = Convert<float64>(limit); 1723 dcheck(maxIndexDouble <= kMaxSafeInteger); 1724 if (indexDouble >= maxIndexDouble) return limit; 1725 1726 return ChangeFloat64ToUintPtr(indexDouble); 1727 } 1728 } 1729} 1730 1731extern builtin ObjectToString(Context, JSAny): String; 1732extern builtin StringRepeat(Context, String, Number): String; 1733 1734@export 1735struct KeyValuePair { 1736 key: JSAny; 1737 value: JSAny; 1738} 1739 1740// Macro definitions for compatibility that expose functionality to the CSA 1741// using "legacy" APIs. In Torque code, these should not be used. 1742@export 1743macro IsFastJSArray(o: Object, context: Context): bool { 1744 // Long-term, it's likely not a good idea to have this slow-path test here, 1745 // since it fundamentally breaks the type system. 1746 if (IsForceSlowPath()) return false; 1747 return Is<FastJSArray>(o); 1748} 1749 1750@export 1751macro BranchIfFastJSArray(o: Object, context: Context): never labels True, 1752 False { 1753 if (IsFastJSArray(o, context)) { 1754 goto True; 1755 } else { 1756 goto False; 1757 } 1758} 1759 1760@export 1761macro BranchIfFastJSArrayForRead(o: Object, context: Context): 1762 never labels True, False { 1763 // Long-term, it's likely not a good idea to have this slow-path test here, 1764 // since it fundamentally breaks the type system. 1765 if (IsForceSlowPath()) goto False; 1766 if (Is<FastJSArrayForRead>(o)) { 1767 goto True; 1768 } else { 1769 goto False; 1770 } 1771} 1772 1773@export 1774macro IsFastJSArrayWithNoCustomIteration(context: Context, o: Object): bool { 1775 return Is<FastJSArrayWithNoCustomIteration>(o); 1776} 1777 1778@export 1779macro IsFastJSArrayForReadWithNoCustomIteration(context: Context, o: Object): 1780 bool { 1781 return Is<FastJSArrayForReadWithNoCustomIteration>(o); 1782} 1783 1784extern transitioning runtime 1785CreateDataProperty(implicit context: Context)(JSReceiver, JSAny, JSAny): void; 1786 1787extern transitioning runtime SetOwnPropertyIgnoreAttributes( 1788 implicit context: Context)(JSObject, String, JSAny, Smi): void; 1789 1790namespace runtime { 1791extern runtime 1792GetDerivedMap(Context, JSFunction, JSReceiver, JSAny): Map; 1793} 1794extern macro IsDeprecatedMap(Map): bool; 1795 1796transitioning builtin FastCreateDataProperty(implicit context: Context)( 1797 receiver: JSReceiver, key: JSAny, value: JSAny): Object { 1798 try { 1799 const array = Cast<FastJSArray>(receiver) otherwise Slow; 1800 const index: Smi = Cast<Smi>(key) otherwise goto Slow; 1801 if (index < 0 || index > array.length) goto Slow; 1802 const isAppend = index == array.length; 1803 1804 if (isAppend) { 1805 // Fast append only works on fast elements kind and with writable length. 1806 const kind = EnsureArrayPushable(array.map) otherwise Slow; 1807 array::EnsureWriteableFastElements(array); 1808 1809 // We may have to transition a. 1810 // For now, if transition is required, jump away to slow. 1811 if (IsFastSmiElementsKind(kind)) { 1812 BuildAppendJSArray(ElementsKind::HOLEY_SMI_ELEMENTS, array, value) 1813 otherwise Slow; 1814 } else if (IsDoubleElementsKind(kind)) { 1815 BuildAppendJSArray(ElementsKind::HOLEY_DOUBLE_ELEMENTS, array, value) 1816 otherwise Slow; 1817 } else { 1818 dcheck(IsFastSmiOrTaggedElementsKind(kind)); 1819 BuildAppendJSArray(ElementsKind::HOLEY_ELEMENTS, array, value) 1820 otherwise Slow; 1821 } 1822 } else { 1823 // Non-appending element store. 1824 const kind = array.map.elements_kind; 1825 array::EnsureWriteableFastElements(array); 1826 1827 // We may have to transition a. 1828 // For now, if transition is required, jump away to slow. 1829 if (IsFastSmiElementsKind(kind)) { 1830 const smiValue = Cast<Smi>(value) otherwise Slow; 1831 const elements = Cast<FixedArray>(array.elements) otherwise unreachable; 1832 elements[index] = smiValue; 1833 } else if (IsDoubleElementsKind(kind)) { 1834 const numberValue = Cast<Number>(value) otherwise Slow; 1835 const doubleElements = Cast<FixedDoubleArray>(array.elements) 1836 otherwise unreachable; 1837 doubleElements[index] = numberValue; 1838 } else { 1839 dcheck(IsFastSmiOrTaggedElementsKind(kind)); 1840 const elements = Cast<FixedArray>(array.elements) otherwise unreachable; 1841 elements[index] = value; 1842 } 1843 } 1844 } label Slow { 1845 CreateDataProperty(receiver, key, value); 1846 } 1847 return Undefined; 1848} 1849 1850macro VerifiedUnreachable(): never { 1851 static_assert(false); 1852 unreachable; 1853} 1854 1855macro Float64IsSomeInfinity(value: float64): bool { 1856 if (value == V8_INFINITY) { 1857 return true; 1858 } 1859 return value == (Convert<float64>(0) - V8_INFINITY); 1860} 1861 1862macro IsIntegerOrSomeInfinity(o: Object): bool { 1863 typeswitch (o) { 1864 case (Smi): { 1865 return true; 1866 } 1867 case (hn: HeapNumber): { 1868 if (Float64IsSomeInfinity(Convert<float64>(hn))) { 1869 return true; 1870 } 1871 return IsInteger(hn); 1872 } 1873 case (Object): { 1874 return false; 1875 } 1876 } 1877} 1878 1879// Assert that the objects satisfy SameValue or are both the hole. 1880builtin CheckSameObject(implicit context: Context)( 1881 lhs: Object, rhs: Object): Undefined { 1882 typeswitch (lhs) { 1883 case (TheHole): { 1884 if (rhs == TheHole) return Undefined; 1885 } 1886 case (a: JSAny): { 1887 typeswitch (rhs) { 1888 case (b: JSAny): { 1889 if (SameValue(a, b)) return Undefined; 1890 } 1891 case (Object): { 1892 } 1893 } 1894 } 1895 case (Object): { 1896 } 1897 } 1898 Print('Distinct or unexpected values in CheckSameObject'); 1899 unreachable; 1900} 1901 1902macro ReplaceTheHoleWithUndefined(o: JSAny|TheHole): JSAny { 1903 typeswitch (o) { 1904 case (TheHole): { 1905 return Undefined; 1906 } 1907 case (a: JSAny): { 1908 return a; 1909 } 1910 } 1911} 1912 1913extern macro DecodeScopeInfoHasContextExtension(intptr): intptr; 1914 1915struct ConstantIterator<T: type> { 1916 macro Empty(): bool { 1917 return false; 1918 } 1919 macro Next(): T labels _NoMore { 1920 return this.value; 1921 } 1922 1923 value: T; 1924} 1925macro ConstantIterator<T: type>(value: T): ConstantIterator<T> { 1926 return ConstantIterator{value}; 1927} 1928 1929extern macro FeedbackIteratorEntrySize(): intptr; 1930extern macro FeedbackIteratorHandlerOffset(): intptr; 1931extern operator '[]' macro LoadWeakFixedArrayElement( 1932 WeakFixedArray, intptr): MaybeObject; 1933 1934extern operator '[]' macro LoadUint8Ptr(RawPtr<uint8>, intptr): uint8; 1935 1936extern enum HashFieldType extends uint32 constexpr 'Name::HashFieldType' { 1937 kHash, 1938 kIntegerIndex, 1939 kForwardingIndex, 1940 kEmpty 1941} 1942 1943operator '==' macro HashFieldTypeEquals( 1944 s1: HashFieldType, s2: HashFieldType): bool { 1945 return Word32Equal(s1, s2); 1946} 1947 1948const kNoHashSentinel: 1949 constexpr int32 generates 'PropertyArray::kNoHashSentinel'; 1950extern macro LoadNameHash(Name): uint32; 1951 1952extern macro LoadSimd128(intptr): Simd128; 1953extern macro I8x16BitMask(I8X16): int32; 1954extern macro I8x16Eq(I8X16, I8X16): I8X16; 1955extern macro I8x16Splat(int32): I8X16; 1956