blob: 419eebd8dd9581670d2f00abe03a0eec9ee6d59a [file] [log] [blame]
/*
* Copyright (C) 2011-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "SpeculatedType.h"
#include "DateInstance.h"
#include "DirectArguments.h"
#include "JSArray.h"
#include "JSBigInt.h"
#include "JSBoundFunction.h"
#include "JSCInlines.h"
#include "JSFunction.h"
#include "JSMap.h"
#include "JSSet.h"
#include "JSWeakMap.h"
#include "JSWeakSet.h"
#include "ProxyObject.h"
#include "RegExpObject.h"
#include "ScopedArguments.h"
#include "StringObject.h"
#include "ValueProfile.h"
#include <wtf/CommaPrinter.h>
#include <wtf/StringPrintStream.h>
namespace JSC {
struct PrettyPrinter {
PrettyPrinter(PrintStream& out)
: out(out)
, separator("|")
{ }
template<typename T>
void print(const T& value)
{
out.print(separator, value);
}
PrintStream& out;
CommaPrinter separator;
};
void dumpSpeculation(PrintStream& outStream, SpeculatedType value)
{
StringPrintStream strStream;
PrettyPrinter out(outStream);
PrettyPrinter strOut(strStream);
if (value == SpecNone) {
out.print("None");
return;
}
bool isTop = true;
if ((value & SpecCell) == SpecCell)
strOut.print("Cell");
else {
if ((value & SpecObject) == SpecObject)
strOut.print("Object");
else {
if (value & SpecCellOther)
strOut.print("OtherCell");
else
isTop = false;
if (value & SpecObjectOther)
strOut.print("OtherObj");
else
isTop = false;
if (value & SpecFinalObject)
strOut.print("Final");
else
isTop = false;
if (value & SpecArray)
strOut.print("Array");
else
isTop = false;
if (value & SpecInt8Array)
strOut.print("Int8Array");
else
isTop = false;
if (value & SpecInt16Array)
strOut.print("Int16Array");
else
isTop = false;
if (value & SpecInt32Array)
strOut.print("Int32Array");
else
isTop = false;
if (value & SpecUint8Array)
strOut.print("Uint8Array");
else
isTop = false;
if (value & SpecUint8ClampedArray)
strOut.print("Uint8ClampedArray");
else
isTop = false;
if (value & SpecUint16Array)
strOut.print("Uint16Array");
else
isTop = false;
if (value & SpecUint32Array)
strOut.print("Uint32Array");
else
isTop = false;
if (value & SpecFloat32Array)
strOut.print("Float32array");
else
isTop = false;
if (value & SpecFloat64Array)
strOut.print("Float64Array");
else
isTop = false;
if (value & SpecFunction)
strOut.print("Function");
else
isTop = false;
if (value & SpecDirectArguments)
strOut.print("DirectArguments");
else
isTop = false;
if (value & SpecScopedArguments)
strOut.print("ScopedArguments");
else
isTop = false;
if (value & SpecStringObject)
strOut.print("StringObject");
else
isTop = false;
if (value & SpecRegExpObject)
strOut.print("RegExpObject");
else
isTop = false;
if (value & SpecDateObject)
strOut.print("DateObject");
else
isTop = false;
if (value & SpecPromiseObject)
strOut.print("PromiseObject");
else
isTop = false;
if (value & SpecMapObject)
strOut.print("MapObject");
else
isTop = false;
if (value & SpecSetObject)
strOut.print("SetObject");
else
isTop = false;
if (value & SpecWeakMapObject)
strOut.print("WeakMapObject");
else
isTop = false;
if (value & SpecWeakSetObject)
strOut.print("WeakSetObject");
else
isTop = false;
if (value & SpecProxyObject)
strOut.print("ProxyObject");
else
isTop = false;
if (value & SpecDerivedArray)
strOut.print("DerivedArray");
else
isTop = false;
if (value & SpecDataViewObject)
strOut.print("DataView");
else
isTop = false;
}
if ((value & SpecString) == SpecString)
strOut.print("String");
else {
if (value & SpecStringIdent)
strOut.print("StringIdent");
else
isTop = false;
if (value & SpecStringVar)
strOut.print("StringVar");
else
isTop = false;
}
if (value & SpecSymbol)
strOut.print("Symbol");
else
isTop = false;
if (value & SpecBigInt)
strOut.print("BigInt");
else
isTop = false;
}
if (value == SpecInt32Only)
strOut.print("Int32");
else {
if (value & SpecBoolInt32)
strOut.print("BoolInt32");
else
isTop = false;
if (value & SpecNonBoolInt32)
strOut.print("NonBoolInt32");
else
isTop = false;
}
if ((value & SpecBytecodeDouble) == SpecBytecodeDouble)
strOut.print("BytecodeDouble");
else {
if (value & SpecAnyIntAsDouble)
strOut.print("AnyIntAsDouble");
else
isTop = false;
if (value & SpecNonIntAsDouble)
strOut.print("NonIntAsDouble");
else
isTop = false;
if (value & SpecDoublePureNaN)
strOut.print("DoublePureNaN");
else
isTop = false;
}
if (value & SpecDoubleImpureNaN)
strOut.print("DoubleImpureNaN");
if (value & SpecBoolean)
strOut.print("Bool");
else
isTop = false;
if (value & SpecOther)
strOut.print("Other");
else
isTop = false;
if (value & SpecEmpty)
strOut.print("Empty");
else
isTop = false;
if (value & SpecInt52Any) {
if ((value & SpecInt52Any) == SpecInt52Any)
strOut.print("Int52Any");
else if (value & SpecInt32AsInt52)
strOut.print("Int32AsInt52");
else if (value & SpecNonInt32AsInt52)
strOut.print("NonInt32AsInt52");
} else
isTop = false;
if (value == SpecBytecodeTop)
out.print("BytecodeTop");
else if (value == SpecHeapTop)
out.print("HeapTop");
else if (value == SpecFullTop)
out.print("FullTop");
else if (isTop)
out.print("Top");
else
out.print(strStream.toCString());
}
// We don't expose this because we don't want anyone relying on the fact that this method currently
// just returns string constants.
static const char* speculationToAbbreviatedString(SpeculatedType prediction)
{
if (isFinalObjectSpeculation(prediction))
return "<Final>";
if (isArraySpeculation(prediction))
return "<Array>";
if (isStringIdentSpeculation(prediction))
return "<StringIdent>";
if (isStringSpeculation(prediction))
return "<String>";
if (isFunctionSpeculation(prediction))
return "<Function>";
if (isInt8ArraySpeculation(prediction))
return "<Int8array>";
if (isInt16ArraySpeculation(prediction))
return "<Int16array>";
if (isInt32ArraySpeculation(prediction))
return "<Int32array>";
if (isUint8ArraySpeculation(prediction))
return "<Uint8array>";
if (isUint16ArraySpeculation(prediction))
return "<Uint16array>";
if (isUint32ArraySpeculation(prediction))
return "<Uint32array>";
if (isFloat32ArraySpeculation(prediction))
return "<Float32array>";
if (isFloat64ArraySpeculation(prediction))
return "<Float64array>";
if (isDirectArgumentsSpeculation(prediction))
return "<DirectArguments>";
if (isScopedArgumentsSpeculation(prediction))
return "<ScopedArguments>";
if (isStringObjectSpeculation(prediction))
return "<StringObject>";
if (isRegExpObjectSpeculation(prediction))
return "<RegExpObject>";
if (isStringOrStringObjectSpeculation(prediction))
return "<StringOrStringObject>";
if (isObjectSpeculation(prediction))
return "<Object>";
if (isCellSpeculation(prediction))
return "<Cell>";
if (isBoolInt32Speculation(prediction))
return "<BoolInt32>";
if (isInt32Speculation(prediction))
return "<Int32>";
if (isAnyIntAsDoubleSpeculation(prediction))
return "<AnyIntAsDouble>";
if (prediction == SpecNonInt32AsInt52)
return "<NonInt32AsInt52>";
if (prediction == SpecInt32AsInt52)
return "<Int32AsInt52>";
if (isAnyInt52Speculation(prediction))
return "<Int52Any>";
if (isDoubleSpeculation(prediction))
return "<Double>";
if (isFullNumberSpeculation(prediction))
return "<Number>";
if (isBooleanSpeculation(prediction))
return "<Boolean>";
if (isOtherSpeculation(prediction))
return "<Other>";
if (isMiscSpeculation(prediction))
return "<Misc>";
return "";
}
void dumpSpeculationAbbreviated(PrintStream& out, SpeculatedType value)
{
out.print(speculationToAbbreviatedString(value));
}
SpeculatedType speculationFromTypedArrayType(TypedArrayType type)
{
switch (type) {
case TypeInt8:
return SpecInt8Array;
case TypeInt16:
return SpecInt16Array;
case TypeInt32:
return SpecInt32Array;
case TypeUint8:
return SpecUint8Array;
case TypeUint8Clamped:
return SpecUint8ClampedArray;
case TypeUint16:
return SpecUint16Array;
case TypeUint32:
return SpecUint32Array;
case TypeFloat32:
return SpecFloat32Array;
case TypeFloat64:
return SpecFloat64Array;
case NotTypedArray:
case TypeDataView:
break;
}
RELEASE_ASSERT_NOT_REACHED();
return SpecNone;
}
SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
{
if (classInfo == JSString::info())
return SpecString;
if (classInfo == Symbol::info())
return SpecSymbol;
if (classInfo == JSBigInt::info())
return SpecBigInt;
if (classInfo == JSFinalObject::info())
return SpecFinalObject;
if (classInfo == JSArray::info())
return SpecArray;
if (classInfo == DirectArguments::info())
return SpecDirectArguments;
if (classInfo == ScopedArguments::info())
return SpecScopedArguments;
if (classInfo == StringObject::info())
return SpecStringObject;
if (classInfo == RegExpObject::info())
return SpecRegExpObject;
if (classInfo == DateInstance::info())
return SpecDateObject;
if (classInfo == JSMap::info())
return SpecMapObject;
if (classInfo == JSSet::info())
return SpecSetObject;
if (classInfo == JSWeakMap::info())
return SpecWeakMapObject;
if (classInfo == JSWeakSet::info())
return SpecWeakSetObject;
if (classInfo == ProxyObject::info())
return SpecProxyObject;
if (classInfo == JSDataView::info())
return SpecDataViewObject;
if (classInfo->isSubClassOf(JSFunction::info())) {
if (classInfo == JSBoundFunction::info())
return SpecFunctionWithNonDefaultHasInstance;
return SpecFunctionWithDefaultHasInstance;
}
if (classInfo->isSubClassOf(JSPromise::info()))
return SpecPromiseObject;
if (isTypedView(classInfo->typedArrayStorageType))
return speculationFromTypedArrayType(classInfo->typedArrayStorageType);
if (classInfo->isSubClassOf(JSArray::info()))
return SpecDerivedArray;
if (classInfo->isSubClassOf(JSObject::info()))
return SpecObjectOther;
return SpecCellOther;
}
SpeculatedType speculationFromStructure(Structure* structure)
{
if (structure->typeInfo().type() == StringType)
return SpecString;
if (structure->typeInfo().type() == SymbolType)
return SpecSymbol;
if (structure->typeInfo().type() == BigIntType)
return SpecBigInt;
if (structure->typeInfo().type() == DerivedArrayType)
return SpecDerivedArray;
return speculationFromClassInfo(structure->classInfo());
}
SpeculatedType speculationFromCell(JSCell* cell)
{
if (cell->isString()) {
JSString* string = jsCast<JSString*>(cell);
if (const StringImpl* impl = string->tryGetValueImpl()) {
if (impl->isAtom())
return SpecStringIdent;
}
return SpecString;
}
return speculationFromStructure(cell->structure());
}
SpeculatedType speculationFromValue(JSValue value)
{
if (value.isEmpty())
return SpecEmpty;
if (value.isInt32()) {
if (value.asInt32() & ~1)
return SpecNonBoolInt32;
return SpecBoolInt32;
}
if (value.isDouble()) {
double number = value.asNumber();
if (number != number)
return SpecDoublePureNaN;
if (value.isAnyInt())
return SpecAnyIntAsDouble;
return SpecNonIntAsDouble;
}
if (value.isCell())
return speculationFromCell(value.asCell());
if (value.isBoolean())
return SpecBoolean;
ASSERT(value.isUndefinedOrNull());
return SpecOther;
}
SpeculatedType int52AwareSpeculationFromValue(JSValue value)
{
if (!value.isAnyInt())
return speculationFromValue(value);
int64_t intValue = value.asAnyInt();
bool isI32 = static_cast<int64_t>(static_cast<int32_t>(intValue)) == intValue;
if (isI32)
return SpecInt32AsInt52;
return SpecNonInt32AsInt52;
}
TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType type)
{
if (isInt8ArraySpeculation(type))
return TypeInt8;
if (isInt16ArraySpeculation(type))
return TypeInt16;
if (isInt32ArraySpeculation(type))
return TypeInt32;
if (isUint8ArraySpeculation(type))
return TypeUint8;
if (isUint8ClampedArraySpeculation(type))
return TypeUint8Clamped;
if (isUint16ArraySpeculation(type))
return TypeUint16;
if (isUint32ArraySpeculation(type))
return TypeUint32;
if (isFloat32ArraySpeculation(type))
return TypeFloat32;
if (isFloat64ArraySpeculation(type))
return TypeFloat64;
return NotTypedArray;
}
Optional<SpeculatedType> speculationFromJSType(JSType type)
{
switch (type) {
case StringType:
return SpecString;
case SymbolType:
return SpecSymbol;
case BigIntType:
return SpecBigInt;
case ArrayType:
return SpecArray;
case DerivedArrayType:
return SpecDerivedArray;
case RegExpObjectType:
return SpecRegExpObject;
case JSDateType:
return SpecDateObject;
case ProxyObjectType:
return SpecProxyObject;
case JSPromiseType:
return SpecPromiseObject;
case JSMapType:
return SpecMapObject;
case JSSetType:
return SpecSetObject;
case JSWeakMapType:
return SpecWeakMapObject;
case JSWeakSetType:
return SpecWeakSetObject;
case DataViewType:
return SpecDataViewObject;
default:
return WTF::nullopt;
}
}
SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType type)
{
// SpecNonIntAsDouble includes negative zero (-0.0), which can be equal to 0 and 0.0 in the context of == and ===.
if (type & (SpecIntAnyFormat | SpecNonIntAsDouble))
type |= (SpecIntAnyFormat | SpecNonIntAsDouble);
if (type & SpecString)
type |= SpecString;
return type;
}
static inline SpeculatedType leastUpperBoundOfEquivalentSpeculations(SpeculatedType type)
{
type = leastUpperBoundOfStrictlyEquivalentSpeculations(type);
// Boolean or BigInt can be converted to Number when performing non-strict equal.
if (type & (SpecIntAnyFormat | SpecNonIntAsDouble | SpecBoolean | SpecBigInt))
type |= (SpecIntAnyFormat | SpecNonIntAsDouble | SpecBoolean | SpecBigInt);
return type;
}
bool valuesCouldBeEqual(SpeculatedType a, SpeculatedType b)
{
a = leastUpperBoundOfEquivalentSpeculations(a);
b = leastUpperBoundOfEquivalentSpeculations(b);
// Anything could be equal to a string.
if (a & SpecString)
return true;
if (b & SpecString)
return true;
// If both sides are definitely only objects, then equality is fairly sane.
if (isObjectSpeculation(a) && isObjectSpeculation(b))
return !!(a & b);
// If either side could be an object or not, then we could call toString or
// valueOf, which could return anything.
if (a & SpecObject)
return true;
if (b & SpecObject)
return true;
// Neither side is an object or string, so the world is relatively sane.
return !!(a & b);
}
static SpeculatedType typeOfDoubleSumOrDifferenceOrProduct(SpeculatedType a, SpeculatedType b)
{
SpeculatedType result = a | b;
if (result & SpecNonIntAsDouble) {
// NaN can be produced by:
// Infinity - Infinity
// Infinity + (-Infinity)
// Infinity * 0
result |= SpecDoublePureNaN;
}
// Impure NaN could become pure NaN during addition because addition may clear bits.
if (result & SpecDoubleImpureNaN)
result |= SpecDoublePureNaN;
// Values could overflow, or fractions could become integers.
if (result & SpecDoubleReal)
result |= SpecDoubleReal;
return result;
}
SpeculatedType typeOfDoubleSum(SpeculatedType a, SpeculatedType b)
{
return typeOfDoubleSumOrDifferenceOrProduct(a, b);
}
SpeculatedType typeOfDoubleDifference(SpeculatedType a, SpeculatedType b)
{
return typeOfDoubleSumOrDifferenceOrProduct(a, b);
}
SpeculatedType typeOfDoubleProduct(SpeculatedType a, SpeculatedType b)
{
return typeOfDoubleSumOrDifferenceOrProduct(a, b);
}
static SpeculatedType polluteDouble(SpeculatedType value)
{
// Impure NaN could become pure NaN because the operation could clear some bits.
if (value & SpecDoubleImpureNaN)
value |= SpecDoubleNaN;
// Values could overflow, fractions could become integers, or an error could produce
// PureNaN.
if (value & SpecDoubleReal)
value |= SpecDoubleReal | SpecDoublePureNaN;
return value;
}
SpeculatedType typeOfDoubleQuotient(SpeculatedType a, SpeculatedType b)
{
return polluteDouble(a | b);
}
SpeculatedType typeOfDoubleMinMax(SpeculatedType a, SpeculatedType b)
{
SpeculatedType result = a | b;
// Impure NaN could become pure NaN during addition because addition may clear bits.
if (result & SpecDoubleImpureNaN)
result |= SpecDoublePureNaN;
return result;
}
SpeculatedType typeOfDoubleNegation(SpeculatedType value)
{
// Changing bits can make pure NaN impure and vice versa:
// 0xefff000000000000 (pure) - 0xffff000000000000 (impure)
if (value & SpecDoubleNaN)
value |= SpecDoubleNaN;
// We could get negative zero, which mixes SpecAnyIntAsDouble and SpecNotIntAsDouble.
// We could also overflow a large negative int into something that is no longer
// representable as an int.
if (value & SpecDoubleReal)
value |= SpecDoubleReal;
return value;
}
SpeculatedType typeOfDoubleAbs(SpeculatedType value)
{
return typeOfDoubleNegation(value);
}
SpeculatedType typeOfDoubleRounding(SpeculatedType value)
{
// Double Pure NaN can becomes impure when converted back from Float.
// and vice versa.
if (value & SpecDoubleNaN)
value |= SpecDoubleNaN;
// We might lose bits, which leads to a value becoming integer-representable.
if (value & SpecNonIntAsDouble)
value |= SpecAnyIntAsDouble;
return value;
}
SpeculatedType typeOfDoublePow(SpeculatedType xValue, SpeculatedType yValue)
{
// Math.pow() always return NaN if the exponent is NaN, unlike std::pow().
// We always set a pure NaN in that case.
if (yValue & SpecDoubleNaN)
xValue |= SpecDoublePureNaN;
// Handle the wierd case of NaN ^ 0, which returns 1. See https://tc39.github.io/ecma262/#sec-applying-the-exp-operator
if (xValue & SpecDoubleNaN)
xValue |= SpecFullDouble;
return polluteDouble(xValue);
}
SpeculatedType typeOfDoubleBinaryOp(SpeculatedType a, SpeculatedType b)
{
return polluteDouble(a | b);
}
SpeculatedType typeOfDoubleUnaryOp(SpeculatedType value)
{
return polluteDouble(value);
}
SpeculatedType speculationFromString(const char* speculation)
{
if (!strncmp(speculation, "SpecNone", strlen("SpecNone")))
return SpecNone;
if (!strncmp(speculation, "SpecFinalObject", strlen("SpecFinalObject")))
return SpecFinalObject;
if (!strncmp(speculation, "SpecArray", strlen("SpecArray")))
return SpecArray;
if (!strncmp(speculation, "SpecFunction", strlen("SpecFunction")))
return SpecFunction;
if (!strncmp(speculation, "SpecInt8Array", strlen("SpecInt8Array")))
return SpecInt8Array;
if (!strncmp(speculation, "SpecInt16Array", strlen("SpecInt16Array")))
return SpecInt16Array;
if (!strncmp(speculation, "SpecInt32Array", strlen("SpecInt32Array")))
return SpecInt32Array;
if (!strncmp(speculation, "SpecUint8Array", strlen("SpecUint8Array")))
return SpecUint8Array;
if (!strncmp(speculation, "SpecUint8ClampedArray", strlen("SpecUint8ClampedArray")))
return SpecUint8ClampedArray;
if (!strncmp(speculation, "SpecUint16Array", strlen("SpecUint16Array")))
return SpecUint16Array;
if (!strncmp(speculation, "SpecUint32Array", strlen("SpecUint32Array")))
return SpecUint32Array;
if (!strncmp(speculation, "SpecFloat32Array", strlen("SpecFloat32Array")))
return SpecFloat32Array;
if (!strncmp(speculation, "SpecFloat64Array", strlen("SpecFloat64Array")))
return SpecFloat64Array;
if (!strncmp(speculation, "SpecTypedArrayView", strlen("SpecTypedArrayView")))
return SpecTypedArrayView;
if (!strncmp(speculation, "SpecDirectArguments", strlen("SpecDirectArguments")))
return SpecDirectArguments;
if (!strncmp(speculation, "SpecScopedArguments", strlen("SpecScopedArguments")))
return SpecScopedArguments;
if (!strncmp(speculation, "SpecStringObject", strlen("SpecStringObject")))
return SpecStringObject;
if (!strncmp(speculation, "SpecRegExpObject", strlen("SpecRegExpObject")))
return SpecRegExpObject;
if (!strncmp(speculation, "SpecDateObject", strlen("SpecDateObject")))
return SpecDateObject;
if (!strncmp(speculation, "SpecPromiseObject", strlen("SpecPromiseObject")))
return SpecPromiseObject;
if (!strncmp(speculation, "SpecMapObject", strlen("SpecMapObject")))
return SpecMapObject;
if (!strncmp(speculation, "SpecSetObject", strlen("SpecSetObject")))
return SpecSetObject;
if (!strncmp(speculation, "SpecWeakMapObject", strlen("SpecWeakMapObject")))
return SpecWeakMapObject;
if (!strncmp(speculation, "SpecWeakSetObject", strlen("SpecWeakSetObject")))
return SpecWeakSetObject;
if (!strncmp(speculation, "SpecProxyObject", strlen("SpecProxyObject")))
return SpecProxyObject;
if (!strncmp(speculation, "SpecDerivedArray", strlen("SpecDerivedArray")))
return SpecDerivedArray;
if (!strncmp(speculation, "SpecDataViewObject", strlen("SpecDataViewObject")))
return SpecDataViewObject;
if (!strncmp(speculation, "SpecObjectOther", strlen("SpecObjectOther")))
return SpecObjectOther;
if (!strncmp(speculation, "SpecObject", strlen("SpecObject")))
return SpecObject;
if (!strncmp(speculation, "SpecStringIdent", strlen("SpecStringIdent")))
return SpecStringIdent;
if (!strncmp(speculation, "SpecStringVar", strlen("SpecStringVar")))
return SpecStringVar;
if (!strncmp(speculation, "SpecString", strlen("SpecString")))
return SpecString;
if (!strncmp(speculation, "SpecSymbol", strlen("SpecSymbol")))
return SpecSymbol;
if (!strncmp(speculation, "SpecBigInt", strlen("SpecBigInt")))
return SpecBigInt;
if (!strncmp(speculation, "SpecCellOther", strlen("SpecCellOther")))
return SpecCellOther;
if (!strncmp(speculation, "SpecCell", strlen("SpecCell")))
return SpecCell;
if (!strncmp(speculation, "SpecBoolInt32", strlen("SpecBoolInt32")))
return SpecBoolInt32;
if (!strncmp(speculation, "SpecNonBoolInt32", strlen("SpecNonBoolInt32")))
return SpecNonBoolInt32;
if (!strncmp(speculation, "SpecInt32Only", strlen("SpecInt32Only")))
return SpecInt32Only;
if (!strncmp(speculation, "SpecInt32AsInt52", strlen("SpecInt32AsInt52")))
return SpecInt32AsInt52;
if (!strncmp(speculation, "SpecNonInt32AsInt52", strlen("SpecNonInt32AsInt52")))
return SpecNonInt32AsInt52;
if (!strncmp(speculation, "SpecInt52Any", strlen("SpecInt52Any")))
return SpecInt52Any;
if (!strncmp(speculation, "SpecIntAnyFormat", strlen("SpecIntAnyFormat")))
return SpecIntAnyFormat;
if (!strncmp(speculation, "SpecAnyIntAsDouble", strlen("SpecAnyIntAsDouble")))
return SpecAnyIntAsDouble;
if (!strncmp(speculation, "SpecNonIntAsDouble", strlen("SpecNonIntAsDouble")))
return SpecNonIntAsDouble;
if (!strncmp(speculation, "SpecDoubleReal", strlen("SpecDoubleReal")))
return SpecDoubleReal;
if (!strncmp(speculation, "SpecDoublePureNaN", strlen("SpecDoublePureNaN")))
return SpecDoublePureNaN;
if (!strncmp(speculation, "SpecDoubleImpureNaN", strlen("SpecDoubleImpureNaN")))
return SpecDoubleImpureNaN;
if (!strncmp(speculation, "SpecDoubleNaN", strlen("SpecDoubleNaN")))
return SpecDoubleNaN;
if (!strncmp(speculation, "SpecBytecodeDouble", strlen("SpecBytecodeDouble")))
return SpecBytecodeDouble;
if (!strncmp(speculation, "SpecFullDouble", strlen("SpecFullDouble")))
return SpecFullDouble;
if (!strncmp(speculation, "SpecBytecodeRealNumber", strlen("SpecBytecodeRealNumber")))
return SpecBytecodeRealNumber;
if (!strncmp(speculation, "SpecFullRealNumber", strlen("SpecFullRealNumber")))
return SpecFullRealNumber;
if (!strncmp(speculation, "SpecBytecodeNumber", strlen("SpecBytecodeNumber")))
return SpecBytecodeNumber;
if (!strncmp(speculation, "SpecFullNumber", strlen("SpecFullNumber")))
return SpecFullNumber;
if (!strncmp(speculation, "SpecBoolean", strlen("SpecBoolean")))
return SpecBoolean;
if (!strncmp(speculation, "SpecOther", strlen("SpecOther")))
return SpecOther;
if (!strncmp(speculation, "SpecMisc", strlen("SpecMisc")))
return SpecMisc;
if (!strncmp(speculation, "SpecHeapTop", strlen("SpecHeapTop")))
return SpecHeapTop;
if (!strncmp(speculation, "SpecPrimitive", strlen("SpecPrimitive")))
return SpecPrimitive;
if (!strncmp(speculation, "SpecEmpty", strlen("SpecEmpty")))
return SpecEmpty;
if (!strncmp(speculation, "SpecBytecodeTop", strlen("SpecBytecodeTop")))
return SpecBytecodeTop;
if (!strncmp(speculation, "SpecFullTop", strlen("SpecFullTop")))
return SpecFullTop;
if (!strncmp(speculation, "SpecCellCheck", strlen("SpecCellCheck")))
return SpecCellCheck;
RELEASE_ASSERT_NOT_REACHED();
}
} // namespace JSC