SpeculatedType.h
1 /* 2 * Copyright (C) 2011-2020 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #pragma once 30 31 #include "CPU.h" 32 #include "JSCJSValue.h" 33 #include "TypedArrayType.h" 34 #include <wtf/PrintStream.h> 35 36 namespace JSC { 37 38 class Structure; 39 40 typedef uint64_t SpeculatedType; 41 static constexpr SpeculatedType SpecNone = 0; // We don't know anything yet. 42 static constexpr SpeculatedType SpecFinalObject = 1ull << 0; // It's definitely a JSFinalObject. 43 static constexpr SpeculatedType SpecArray = 1ull << 1; // It's definitely a JSArray. 44 static constexpr SpeculatedType SpecFunctionWithDefaultHasInstance = 1ull << 2; // It's definitely a JSFunction that has its ImplementsDefaultHasInstance type info flags bit set. 45 static constexpr SpeculatedType SpecFunctionWithNonDefaultHasInstance = 1ull << 3; // It's definitely a JSFunction that does not have its ImplementsDefaultHasInstance type info flags bit set. 46 static constexpr SpeculatedType SpecFunction = SpecFunctionWithDefaultHasInstance | SpecFunctionWithNonDefaultHasInstance; // It's definitely a JSFunction. 47 static constexpr SpeculatedType SpecInt8Array = 1ull << 4; // It's definitely an Int8Array or one of its subclasses. 48 static constexpr SpeculatedType SpecInt16Array = 1ull << 5; // It's definitely an Int16Array or one of its subclasses. 49 static constexpr SpeculatedType SpecInt32Array = 1ull << 6; // It's definitely an Int32Array or one of its subclasses. 50 static constexpr SpeculatedType SpecUint8Array = 1ull << 7; // It's definitely an Uint8Array or one of its subclasses. 51 static constexpr SpeculatedType SpecUint8ClampedArray = 1ull << 8; // It's definitely an Uint8ClampedArray or one of its subclasses. 52 static constexpr SpeculatedType SpecUint16Array = 1ull << 9; // It's definitely an Uint16Array or one of its subclasses. 53 static constexpr SpeculatedType SpecUint32Array = 1ull << 10; // It's definitely an Uint32Array or one of its subclasses. 54 static constexpr SpeculatedType SpecFloat32Array = 1ull << 11; // It's definitely an Uint16Array or one of its subclasses. 55 static constexpr SpeculatedType SpecFloat64Array = 1ull << 12; // It's definitely an Uint16Array or one of its subclasses. 56 static constexpr SpeculatedType SpecTypedArrayView = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array; 57 static constexpr SpeculatedType SpecDirectArguments = 1ull << 13; // It's definitely a DirectArguments object. 58 static constexpr SpeculatedType SpecScopedArguments = 1ull << 14; // It's definitely a ScopedArguments object. 59 static constexpr SpeculatedType SpecStringObject = 1ull << 15; // It's definitely a StringObject. 60 static constexpr SpeculatedType SpecRegExpObject = 1ull << 16; // It's definitely a RegExpObject (and not any subclass of RegExpObject). 61 static constexpr SpeculatedType SpecDateObject = 1ull << 17; // It's definitely a Date object or one of its subclasses. 62 static constexpr SpeculatedType SpecPromiseObject = 1ull << 18; // It's definitely a Promise object or one of its subclasses. 63 static constexpr SpeculatedType SpecMapObject = 1ull << 19; // It's definitely a Map object or one of its subclasses. 64 static constexpr SpeculatedType SpecSetObject = 1ull << 20; // It's definitely a Set object or one of its subclasses. 65 static constexpr SpeculatedType SpecWeakMapObject = 1ull << 21; // It's definitely a WeakMap object or one of its subclasses. 66 static constexpr SpeculatedType SpecWeakSetObject = 1ull << 22; // It's definitely a WeakSet object or one of its subclasses. 67 static constexpr SpeculatedType SpecProxyObject = 1ull << 23; // It's definitely a Proxy object or one of its subclasses. 68 static constexpr SpeculatedType SpecDerivedArray = 1ull << 24; // It's definitely a DerivedArray object. 69 static constexpr SpeculatedType SpecObjectOther = 1ull << 25; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction. 70 static constexpr SpeculatedType SpecStringIdent = 1ull << 26; // It's definitely a JSString, and it's an identifier. 71 static constexpr SpeculatedType SpecStringVar = 1ull << 27; // It's definitely a JSString, and it's not an identifier. 72 static constexpr SpeculatedType SpecString = SpecStringIdent | SpecStringVar; // It's definitely a JSString. 73 static constexpr SpeculatedType SpecSymbol = 1ull << 28; // It's definitely a Symbol. 74 static constexpr SpeculatedType SpecCellOther = 1ull << 29; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString, BigInt, or Symbol. 75 static constexpr SpeculatedType SpecBoolInt32 = 1ull << 30; // It's definitely an Int32 with value 0 or 1. 76 static constexpr SpeculatedType SpecNonBoolInt32 = 1ull << 31; // It's definitely an Int32 with value other than 0 or 1. 77 static constexpr SpeculatedType SpecInt32Only = SpecBoolInt32 | SpecNonBoolInt32; // It's definitely an Int32. 78 79 static constexpr SpeculatedType SpecInt32AsInt52 = 1ull << 32; // It's an Int52 and it can fit in an int32. 80 static constexpr SpeculatedType SpecNonInt32AsInt52 = 1ull << 33; // It's an Int52 and it can't fit in an int32. 81 static constexpr SpeculatedType SpecInt52Any = SpecInt32AsInt52 | SpecNonInt32AsInt52; // It's any kind of Int52. 82 83 static constexpr SpeculatedType SpecAnyIntAsDouble = 1ull << 34; // It's definitely an Int52 and it's inside a double. 84 static constexpr SpeculatedType SpecNonIntAsDouble = 1ull << 35; // It's definitely not an Int52 but it's a real number and it's a double. 85 static constexpr SpeculatedType SpecDoubleReal = SpecNonIntAsDouble | SpecAnyIntAsDouble; // It's definitely a non-NaN double. 86 static constexpr SpeculatedType SpecDoublePureNaN = 1ull << 36; // It's definitely a NaN that is safe to tag (i.e. pure). 87 static constexpr SpeculatedType SpecDoubleImpureNaN = 1ull << 37; // It's definitely a NaN that is unsafe to tag (i.e. impure). 88 static constexpr SpeculatedType SpecDoubleNaN = SpecDoublePureNaN | SpecDoubleImpureNaN; // It's definitely some kind of NaN. 89 static constexpr SpeculatedType SpecBytecodeDouble = SpecDoubleReal | SpecDoublePureNaN; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN. 90 static constexpr SpeculatedType SpecFullDouble = SpecDoubleReal | SpecDoubleNaN; // It's either a non-NaN or a NaN double. 91 static constexpr SpeculatedType SpecBytecodeRealNumber = SpecInt32Only | SpecDoubleReal; // It's either an Int32 or a DoubleReal. 92 static constexpr SpeculatedType SpecFullRealNumber = SpecInt32Only | SpecInt52Any | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or an Int52. 93 static constexpr SpeculatedType SpecBytecodeNumber = SpecInt32Only | SpecBytecodeDouble; // It's either an Int32 or a Double, and the Double cannot be an impure NaN. 94 static constexpr SpeculatedType SpecIntAnyFormat = SpecInt52Any | SpecInt32Only | SpecAnyIntAsDouble; 95 96 static constexpr SpeculatedType SpecFullNumber = SpecIntAnyFormat | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN. 97 static constexpr SpeculatedType SpecBoolean = 1ull << 38; // It's definitely a Boolean. 98 static constexpr SpeculatedType SpecOther = 1ull << 39; // It's definitely either Null or Undefined. 99 static constexpr SpeculatedType SpecMisc = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined. 100 static constexpr SpeculatedType SpecEmpty = 1ull << 40; // It's definitely an empty value marker. 101 static constexpr SpeculatedType SpecHeapBigInt = 1ull << 41; // It's definitely a BigInt that is allocated on the heap 102 static constexpr SpeculatedType SpecBigInt32 = 1ull << 42; // It's definitely a small BigInt that is inline the JSValue 103 #if USE(BIGINT32) 104 static constexpr SpeculatedType SpecBigInt = SpecBigInt32 | SpecHeapBigInt; 105 #else 106 // We should not include SpecBigInt32. We are using SpecBigInt in various places like prediction. If this includes SpecBigInt32, fixup phase is confused if !USE(BIGINT32) since it is not using AnyBigIntUse. 107 static constexpr SpeculatedType SpecBigInt = SpecHeapBigInt; 108 #endif 109 static constexpr SpeculatedType SpecDataViewObject = 1ull << 43; // It's definitely a JSDataView. 110 static constexpr SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue. 111 static constexpr SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecDateObject | SpecPromiseObject | SpecMapObject | SpecSetObject | SpecWeakMapObject | SpecWeakSetObject | SpecProxyObject | SpecDerivedArray | SpecObjectOther | SpecDataViewObject; // Bitmask used for testing for any kind of object prediction. 112 static constexpr SpeculatedType SpecCell = SpecObject | SpecString | SpecSymbol | SpecCellOther | SpecHeapBigInt; // It's definitely a JSCell. 113 static constexpr SpeculatedType SpecHeapTop = SpecCell | SpecBigInt32 | SpecBytecodeNumber | SpecMisc; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. 114 static constexpr SpeculatedType SpecBytecodeTop = SpecHeapTop | SpecEmpty; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. Corresponds to what could be found in a bytecode local. 115 static constexpr SpeculatedType SpecFullTop = SpecBytecodeTop | SpecFullNumber; // It can be anything that bytecode could see plus exotic encodings of numbers. 116 117 // SpecCellCheck is the type set representing the values that can flow through a cell check. 118 // On 64-bit platforms, the empty value passes a cell check. Also, ~SpecCellCheck is the type 119 // set that representing the values that flow through when testing that something is not a cell. 120 static constexpr SpeculatedType SpecCellCheck = is64Bit() ? (SpecCell | SpecEmpty) : SpecCell; 121 122 typedef bool (*SpeculatedTypeChecker)(SpeculatedType); 123 124 // Dummy prediction checker, only useful if someone insists on requiring a prediction checker. 125 inline bool isAnySpeculation(SpeculatedType) 126 { 127 return true; 128 } 129 130 inline bool isSubtypeSpeculation(SpeculatedType value, SpeculatedType category) 131 { 132 return !(value & ~category) && value; 133 } 134 135 inline bool speculationContains(SpeculatedType value, SpeculatedType category) 136 { 137 return !!(value & category) && value; 138 } 139 140 inline bool isCellSpeculation(SpeculatedType value) 141 { 142 return !!(value & SpecCell) && !(value & ~SpecCell); 143 } 144 145 inline bool isCellOrOtherSpeculation(SpeculatedType value) 146 { 147 return !!value && !(value & ~(SpecCell | SpecOther)); 148 } 149 150 inline bool isNotCellSpeculation(SpeculatedType value) 151 { 152 return !(value & SpecCellCheck) && value; 153 } 154 155 inline bool isNotCellNorBigIntSpeculation(SpeculatedType value) 156 { 157 return !(value & (SpecCellCheck | SpecBigInt)) && value; 158 } 159 160 inline bool isObjectSpeculation(SpeculatedType value) 161 { 162 return !!(value & SpecObject) && !(value & ~SpecObject); 163 } 164 165 inline bool isObjectOrOtherSpeculation(SpeculatedType value) 166 { 167 return !!(value & (SpecObject | SpecOther)) && !(value & ~(SpecObject | SpecOther)); 168 } 169 170 inline bool isFinalObjectSpeculation(SpeculatedType value) 171 { 172 return value == SpecFinalObject; 173 } 174 175 inline bool isFinalObjectOrOtherSpeculation(SpeculatedType value) 176 { 177 return !!(value & (SpecFinalObject | SpecOther)) && !(value & ~(SpecFinalObject | SpecOther)); 178 } 179 180 inline bool isStringIdentSpeculation(SpeculatedType value) 181 { 182 return value == SpecStringIdent; 183 } 184 185 inline bool isNotStringVarSpeculation(SpeculatedType value) 186 { 187 return !(value & SpecStringVar); 188 } 189 190 inline bool isStringSpeculation(SpeculatedType value) 191 { 192 return !!value && (value & SpecString) == value; 193 } 194 195 inline bool isNotStringSpeculation(SpeculatedType value) 196 { 197 return value && !(value & SpecString); 198 } 199 200 inline bool isStringOrOtherSpeculation(SpeculatedType value) 201 { 202 return !!value && (value & (SpecString | SpecOther)) == value; 203 } 204 205 inline bool isSymbolSpeculation(SpeculatedType value) 206 { 207 return value == SpecSymbol; 208 } 209 210 inline bool isBigInt32Speculation(SpeculatedType value) 211 { 212 return value == SpecBigInt32; 213 } 214 215 inline bool isHeapBigIntSpeculation(SpeculatedType value) 216 { 217 return value == SpecHeapBigInt; 218 } 219 220 inline bool isBigIntSpeculation(SpeculatedType value) 221 { 222 return !!value && (value & SpecBigInt) == value; 223 } 224 225 inline bool isArraySpeculation(SpeculatedType value) 226 { 227 return value == SpecArray; 228 } 229 230 inline bool isFunctionSpeculation(SpeculatedType value) 231 { 232 return value == SpecFunction; 233 } 234 235 inline bool isProxyObjectSpeculation(SpeculatedType value) 236 { 237 return value == SpecProxyObject; 238 } 239 240 inline bool isDerivedArraySpeculation(SpeculatedType value) 241 { 242 return value == SpecDerivedArray; 243 } 244 245 inline bool isInt8ArraySpeculation(SpeculatedType value) 246 { 247 return value == SpecInt8Array; 248 } 249 250 inline bool isInt16ArraySpeculation(SpeculatedType value) 251 { 252 return value == SpecInt16Array; 253 } 254 255 inline bool isInt32ArraySpeculation(SpeculatedType value) 256 { 257 return value == SpecInt32Array; 258 } 259 260 inline bool isUint8ArraySpeculation(SpeculatedType value) 261 { 262 return value == SpecUint8Array; 263 } 264 265 inline bool isUint8ClampedArraySpeculation(SpeculatedType value) 266 { 267 return value == SpecUint8ClampedArray; 268 } 269 270 inline bool isUint16ArraySpeculation(SpeculatedType value) 271 { 272 return value == SpecUint16Array; 273 } 274 275 inline bool isUint32ArraySpeculation(SpeculatedType value) 276 { 277 return value == SpecUint32Array; 278 } 279 280 inline bool isFloat32ArraySpeculation(SpeculatedType value) 281 { 282 return value == SpecFloat32Array; 283 } 284 285 inline bool isFloat64ArraySpeculation(SpeculatedType value) 286 { 287 return value == SpecFloat64Array; 288 } 289 290 inline bool isDirectArgumentsSpeculation(SpeculatedType value) 291 { 292 return value == SpecDirectArguments; 293 } 294 295 inline bool isScopedArgumentsSpeculation(SpeculatedType value) 296 { 297 return value == SpecScopedArguments; 298 } 299 300 inline bool isActionableIntMutableArraySpeculation(SpeculatedType value) 301 { 302 return isInt8ArraySpeculation(value) 303 || isInt16ArraySpeculation(value) 304 || isInt32ArraySpeculation(value) 305 || isUint8ArraySpeculation(value) 306 || isUint8ClampedArraySpeculation(value) 307 || isUint16ArraySpeculation(value) 308 || isUint32ArraySpeculation(value); 309 } 310 311 inline bool isActionableFloatMutableArraySpeculation(SpeculatedType value) 312 { 313 return isFloat32ArraySpeculation(value) 314 || isFloat64ArraySpeculation(value); 315 } 316 317 inline bool isActionableTypedMutableArraySpeculation(SpeculatedType value) 318 { 319 return isActionableIntMutableArraySpeculation(value) 320 || isActionableFloatMutableArraySpeculation(value); 321 } 322 323 inline bool isActionableMutableArraySpeculation(SpeculatedType value) 324 { 325 return isArraySpeculation(value) 326 || isActionableTypedMutableArraySpeculation(value); 327 } 328 329 inline bool isActionableArraySpeculation(SpeculatedType value) 330 { 331 return isStringSpeculation(value) 332 || isDirectArgumentsSpeculation(value) 333 || isScopedArgumentsSpeculation(value) 334 || isActionableMutableArraySpeculation(value); 335 } 336 337 inline bool isArrayOrOtherSpeculation(SpeculatedType value) 338 { 339 return !!(value & (SpecArray | SpecOther)) && !(value & ~(SpecArray | SpecOther)); 340 } 341 342 inline bool isStringObjectSpeculation(SpeculatedType value) 343 { 344 return value == SpecStringObject; 345 } 346 347 inline bool isStringOrStringObjectSpeculation(SpeculatedType value) 348 { 349 return !!value && !(value & ~(SpecString | SpecStringObject)); 350 } 351 352 inline bool isRegExpObjectSpeculation(SpeculatedType value) 353 { 354 return value == SpecRegExpObject; 355 } 356 357 inline bool isBoolInt32Speculation(SpeculatedType value) 358 { 359 return value == SpecBoolInt32; 360 } 361 362 inline bool isInt32Speculation(SpeculatedType value) 363 { 364 return value && !(value & ~SpecInt32Only); 365 } 366 367 inline bool isNotInt32Speculation(SpeculatedType value) 368 { 369 return value && !(value & SpecInt32Only); 370 } 371 372 inline bool isInt32OrBooleanSpeculation(SpeculatedType value) 373 { 374 return value && !(value & ~(SpecBoolean | SpecInt32Only)); 375 } 376 377 inline bool isInt32SpeculationForArithmetic(SpeculatedType value) 378 { 379 return !(value & (SpecFullDouble | SpecNonInt32AsInt52 | SpecBigInt)); 380 } 381 382 inline bool isInt32OrBooleanSpeculationForArithmetic(SpeculatedType value) 383 { 384 return !(value & (SpecFullDouble | SpecNonInt32AsInt52 | SpecBigInt)); 385 } 386 387 inline bool isInt32OrBooleanSpeculationExpectingDefined(SpeculatedType value) 388 { 389 return isInt32OrBooleanSpeculation(value & ~SpecOther); 390 } 391 392 inline bool isAnyInt52Speculation(SpeculatedType value) 393 { 394 return !!value && (value & SpecInt52Any) == value; 395 } 396 397 inline bool isInt32OrInt52Speculation(SpeculatedType value) 398 { 399 return !!value && (value & (SpecInt32Only | SpecInt52Any)) == value; 400 } 401 402 inline bool isIntAnyFormat(SpeculatedType value) 403 { 404 return !!value && (value & SpecIntAnyFormat) == value; 405 } 406 407 inline bool isAnyIntAsDoubleSpeculation(SpeculatedType value) 408 { 409 return value == SpecAnyIntAsDouble; 410 } 411 412 inline bool isDoubleRealSpeculation(SpeculatedType value) 413 { 414 return !!value && (value & SpecDoubleReal) == value; 415 } 416 417 inline bool isDoubleSpeculation(SpeculatedType value) 418 { 419 return !!value && (value & SpecFullDouble) == value; 420 } 421 422 inline bool isDoubleSpeculationForArithmetic(SpeculatedType value) 423 { 424 return !!(value & SpecFullDouble); 425 } 426 427 inline bool isBytecodeRealNumberSpeculation(SpeculatedType value) 428 { 429 return !!(value & SpecBytecodeRealNumber) && !(value & ~SpecBytecodeRealNumber); 430 } 431 432 inline bool isFullRealNumberSpeculation(SpeculatedType value) 433 { 434 return !!(value & SpecFullRealNumber) && !(value & ~SpecFullRealNumber); 435 } 436 437 inline bool isBytecodeNumberSpeculation(SpeculatedType value) 438 { 439 return !!(value & SpecBytecodeNumber) && !(value & ~SpecBytecodeNumber); 440 } 441 442 inline bool isFullNumberSpeculation(SpeculatedType value) 443 { 444 return !!(value & SpecFullNumber) && !(value & ~SpecFullNumber); 445 } 446 447 inline bool isFullNumberOrBooleanSpeculation(SpeculatedType value) 448 { 449 return value && !(value & ~(SpecFullNumber | SpecBoolean)); 450 } 451 452 inline bool isFullNumberOrBooleanSpeculationExpectingDefined(SpeculatedType value) 453 { 454 return isFullNumberOrBooleanSpeculation(value & ~SpecOther); 455 } 456 457 inline bool isBooleanSpeculation(SpeculatedType value) 458 { 459 return value == SpecBoolean; 460 } 461 462 inline bool isNotBooleanSpeculation(SpeculatedType value) 463 { 464 return value && !(value & SpecBoolean); 465 } 466 467 inline bool isOtherSpeculation(SpeculatedType value) 468 { 469 return value == SpecOther; 470 } 471 472 inline bool isMiscSpeculation(SpeculatedType value) 473 { 474 return !!value && !(value & ~SpecMisc); 475 } 476 477 inline bool isOtherOrEmptySpeculation(SpeculatedType value) 478 { 479 return !value || value == SpecOther; 480 } 481 482 inline bool isEmptySpeculation(SpeculatedType value) 483 { 484 return value == SpecEmpty; 485 } 486 487 inline bool isUntypedSpeculationForArithmetic(SpeculatedType value) 488 { 489 return !!(value & ~(SpecFullNumber | SpecBoolean)); 490 } 491 492 inline bool isUntypedSpeculationForBitOps(SpeculatedType value) 493 { 494 return !!(value & ~(SpecFullNumber | SpecBoolean | SpecOther)); 495 } 496 497 void dumpSpeculation(PrintStream&, SpeculatedType); 498 void dumpSpeculationAbbreviated(PrintStream&, SpeculatedType); 499 500 MAKE_PRINT_ADAPTOR(SpeculationDump, SpeculatedType, dumpSpeculation); 501 MAKE_PRINT_ADAPTOR(AbbreviatedSpeculationDump, SpeculatedType, dumpSpeculationAbbreviated); 502 503 // Merge two predictions. Note that currently this just does left | right. It may 504 // seem tempting to do so directly, but you would be doing so at your own peril, 505 // since the merging protocol SpeculatedType may change at any time (and has already 506 // changed several times in its history). 507 inline SpeculatedType mergeSpeculations(SpeculatedType left, SpeculatedType right) 508 { 509 return left | right; 510 } 511 512 template<typename T> 513 inline bool mergeSpeculation(T& left, SpeculatedType right) 514 { 515 SpeculatedType newSpeculation = static_cast<T>(mergeSpeculations(static_cast<SpeculatedType>(left), right)); 516 bool result = newSpeculation != static_cast<SpeculatedType>(left); 517 left = newSpeculation; 518 return result; 519 } 520 521 inline bool speculationChecked(SpeculatedType actual, SpeculatedType desired) 522 { 523 return (actual | desired) == desired; 524 } 525 526 // The SpeculatedType returned by this function for any cell, c, has the following invariant: 527 // ASSERT(!c->inherits(classInfo) || speculationChecked(speculationFromCell(c), speculationFromClassInfoInheritance(classInfo))); 528 SpeculatedType speculationFromClassInfoInheritance(const ClassInfo*); 529 530 SpeculatedType speculationFromStructure(Structure*); 531 SpeculatedType speculationFromCell(JSCell*); 532 JS_EXPORT_PRIVATE SpeculatedType speculationFromValue(JSValue); 533 // If it's an anyInt(), it'll return speculated types from the Int52 lattice. 534 // Otherwise, it'll return types from the JSValue lattice. 535 JS_EXPORT_PRIVATE SpeculatedType int52AwareSpeculationFromValue(JSValue); 536 Optional<SpeculatedType> speculationFromJSType(JSType); 537 538 SpeculatedType speculationFromTypedArrayType(TypedArrayType); // only valid for typed views. 539 TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType); 540 541 SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType); 542 543 bool valuesCouldBeEqual(SpeculatedType, SpeculatedType); 544 545 // Precise computation of the type of the result of a double computation after we 546 // already know that the inputs are doubles and that the result must be a double. Use 547 // the closest one of these that applies. 548 SpeculatedType typeOfDoubleSum(SpeculatedType, SpeculatedType); 549 SpeculatedType typeOfDoubleDifference(SpeculatedType, SpeculatedType); 550 SpeculatedType typeOfDoubleIncOrDec(SpeculatedType); 551 SpeculatedType typeOfDoubleProduct(SpeculatedType, SpeculatedType); 552 SpeculatedType typeOfDoubleQuotient(SpeculatedType, SpeculatedType); 553 SpeculatedType typeOfDoubleMinMax(SpeculatedType, SpeculatedType); 554 SpeculatedType typeOfDoubleNegation(SpeculatedType); 555 SpeculatedType typeOfDoubleAbs(SpeculatedType); 556 SpeculatedType typeOfDoubleRounding(SpeculatedType); 557 SpeculatedType typeOfDoublePow(SpeculatedType, SpeculatedType); 558 559 // This conservatively models the behavior of arbitrary double operations. 560 SpeculatedType typeOfDoubleBinaryOp(SpeculatedType, SpeculatedType); 561 SpeculatedType typeOfDoubleUnaryOp(SpeculatedType); 562 563 // This is mostly for debugging so we can fill profiles from strings. 564 SpeculatedType speculationFromString(const char*); 565 566 } // namespace JSC