Skip to content
Permalink
Browse files
Clean up Int52 code and some bugs in it
https://bugs.webkit.org/show_bug.cgi?id=196639
<rdar://problem/49515757>

Reviewed by Yusuke Suzuki.

JSTests:

* stress/spec-any-int-as-double-produces-any-int52-from-int52-rep.js: Added.

Source/JavaScriptCore:

This patch fixes bugs in our Int52 code. The primary change in this patch is
adopting a segregated type lattice for Int52. Previously, for Int52 values,
we represented them with SpecInt32Only and SpecInt52Only. For an Int52,
SpecInt32Only meant that the value is in int32 range. And SpecInt52Only meant
that the is outside of the int32 range.

However, this got confusing because we reused SpecInt32Only both for JSValue
representations and Int52 representations. This actually lead to some bugs.

1. It's possible that roundtripping through Int52 representation would say
it produces the wrong type. For example, consider this program and how we
used to annotate types in AI:
a: JSConstant(10.0) => m_type is SpecAnyIntAsDouble
b: Int52Rep(@A) => m_type is SpecInt52Only
c: ValueRep(@b) => m_type is SpecAnyIntAsDouble

In AI, for the above program, we'd say that @c produces SpecAnyIntAsDouble.
However, the execution semantics are such that it'd actually produce a boxed
Int32. This patch fixes the bug where we'd say that Int52Rep over SpecAnyIntAsDouble
would produce SpecInt52Only. This is clearly wrong, as SpecAnyIntAsDouble can
mean an int value in either int32 or int52 range.

2. AsbstractValue::validateTypeAcceptingBoxedInt52 was wrong in how it
accepted Int52 values. It was wrong in two different ways:
a: If the AbstractValue's type was SpecInt52Only, and the incoming value
was a boxed double, but represented a value in int32 range, the incoming
value would incorrectly validate as being acceptable. However, we should
have rejected this value.
b: If the AbstractValue's type was SpecInt32Only, and the incoming value
was an Int32 boxed in a double, this would not validate, even though
it should have validated.

Solving 2 was easiest if we segregated out the Int52 type into its own
lattice. This patch makes a new Int52 lattice, which is composed of
SpecInt32AsInt52 and SpecNonInt32AsInt52.

The conversion rules are now really simple.

Int52 rep => JSValue rep
SpecInt32AsInt52 => SpecInt32Only
SpecNonInt32AsInt52 => SpecAnyIntAsDouble

JSValue rep => Int52 rep
SpecInt32Only => SpecInt32AsInt52
SpecAnyIntAsDouble => SpecInt52Any

With these rules, the program in (1) will now correctly report that @c
returns SpecInt32Only | SpecAnyIntAsDouble.

* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::int52AwareSpeculationFromValue):
(JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
(JSC::speculationFromString):
* bytecode/SpeculatedType.h:
(JSC::isInt32SpeculationForArithmetic):
(JSC::isInt32OrBooleanSpeculationForArithmetic):
(JSC::isAnyInt52Speculation):
(JSC::isIntAnyFormat):
(JSC::isInt52Speculation): Deleted.
(JSC::isAnyIntSpeculation): Deleted.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::fixTypeForRepresentation):
(JSC::DFG::AbstractValue::checkConsistency const):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::isInt52Any const):
(JSC::DFG::AbstractValue::validateTypeAcceptingBoxedInt52 const):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupArithMul):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupGetPrototypeOf):
(JSC::DFG::FixupPhase::fixupToThis):
(JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
(JSC::DFG::FixupPhase::observeUseKindOnNode):
(JSC::DFG::FixupPhase::fixIntConvertingEdge):
(JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
(JSC::DFG::FixupPhase::fixupCompareStrictEqAndSameValue):
(JSC::DFG::FixupPhase::fixupChecksInBlock):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::addShouldSpeculateInt52):
(JSC::DFG::Graph::binaryArithShouldSpeculateInt52):
(JSC::DFG::Graph::unaryArithShouldSpeculateInt52):
(JSC::DFG::Graph::addShouldSpeculateAnyInt): Deleted.
(JSC::DFG::Graph::binaryArithShouldSpeculateAnyInt): Deleted.
(JSC::DFG::Graph::unaryArithShouldSpeculateAnyInt): Deleted.
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateInt52):
(JSC::DFG::Node::shouldSpeculateAnyInt): Deleted.
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::setIntTypedArrayLoadResult):
(JSC::DFG::SpeculativeJIT::compileArithAdd):
(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithNegate):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):
* dfg/DFGVariableAccessData.cpp:
(JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
(JSC::DFG::VariableAccessData::couldRepresentInt52Impl):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub):
(JSC::FTL::DFG::LowerDFGToB3::compileArithNegate):
(JSC::FTL::DFG::LowerDFGToB3::setIntTypedArrayLoadResult):


Canonical link: https://commits.webkit.org/211013@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244079 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
saambarati committed Apr 9, 2019
1 parent 993e32a commit bd19ce3d61336d9a2f6f2a816e7f09bdd14a2469
Showing 17 changed files with 334 additions and 158 deletions.
@@ -1,3 +1,13 @@
2019-04-09 Saam barati <sbarati@apple.com>

Clean up Int52 code and some bugs in it
https://bugs.webkit.org/show_bug.cgi?id=196639
<rdar://problem/49515757>

Reviewed by Yusuke Suzuki.

* stress/spec-any-int-as-double-produces-any-int52-from-int52-rep.js: Added.

2019-04-09 Tadeu Zagallo <tzagallo@apple.com>

ASSERTION FAILED: !scope.exception() || !hasProperty in JSObject::get
@@ -0,0 +1,10 @@
//@ runDefault("--useConcurrentJIT=0", "--validateAbstractInterpreterStateProbability=1.0", "--validateAbstractInterpreterState=1")

function foo(a, v) {
a[0] = v + 2000000000;
}
noInline(foo);

for (var i = 0; i < 100000; ++i) {
foo({}, 1000000000);
}
@@ -1,3 +1,121 @@
2019-04-09 Saam barati <sbarati@apple.com>

Clean up Int52 code and some bugs in it
https://bugs.webkit.org/show_bug.cgi?id=196639
<rdar://problem/49515757>

Reviewed by Yusuke Suzuki.

This patch fixes bugs in our Int52 code. The primary change in this patch is
adopting a segregated type lattice for Int52. Previously, for Int52 values,
we represented them with SpecInt32Only and SpecInt52Only. For an Int52,
SpecInt32Only meant that the value is in int32 range. And SpecInt52Only meant
that the is outside of the int32 range.

However, this got confusing because we reused SpecInt32Only both for JSValue
representations and Int52 representations. This actually lead to some bugs.

1. It's possible that roundtripping through Int52 representation would say
it produces the wrong type. For example, consider this program and how we
used to annotate types in AI:
a: JSConstant(10.0) => m_type is SpecAnyIntAsDouble
b: Int52Rep(@a) => m_type is SpecInt52Only
c: ValueRep(@b) => m_type is SpecAnyIntAsDouble

In AI, for the above program, we'd say that @c produces SpecAnyIntAsDouble.
However, the execution semantics are such that it'd actually produce a boxed
Int32. This patch fixes the bug where we'd say that Int52Rep over SpecAnyIntAsDouble
would produce SpecInt52Only. This is clearly wrong, as SpecAnyIntAsDouble can
mean an int value in either int32 or int52 range.

2. AsbstractValue::validateTypeAcceptingBoxedInt52 was wrong in how it
accepted Int52 values. It was wrong in two different ways:
a: If the AbstractValue's type was SpecInt52Only, and the incoming value
was a boxed double, but represented a value in int32 range, the incoming
value would incorrectly validate as being acceptable. However, we should
have rejected this value.
b: If the AbstractValue's type was SpecInt32Only, and the incoming value
was an Int32 boxed in a double, this would not validate, even though
it should have validated.

Solving 2 was easiest if we segregated out the Int52 type into its own
lattice. This patch makes a new Int52 lattice, which is composed of
SpecInt32AsInt52 and SpecNonInt32AsInt52.

The conversion rules are now really simple.

Int52 rep => JSValue rep
SpecInt32AsInt52 => SpecInt32Only
SpecNonInt32AsInt52 => SpecAnyIntAsDouble

JSValue rep => Int52 rep
SpecInt32Only => SpecInt32AsInt52
SpecAnyIntAsDouble => SpecInt52Any

With these rules, the program in (1) will now correctly report that @c
returns SpecInt32Only | SpecAnyIntAsDouble.

* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::int52AwareSpeculationFromValue):
(JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
(JSC::speculationFromString):
* bytecode/SpeculatedType.h:
(JSC::isInt32SpeculationForArithmetic):
(JSC::isInt32OrBooleanSpeculationForArithmetic):
(JSC::isAnyInt52Speculation):
(JSC::isIntAnyFormat):
(JSC::isInt52Speculation): Deleted.
(JSC::isAnyIntSpeculation): Deleted.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::fixTypeForRepresentation):
(JSC::DFG::AbstractValue::checkConsistency const):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::isInt52Any const):
(JSC::DFG::AbstractValue::validateTypeAcceptingBoxedInt52 const):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupArithMul):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupGetPrototypeOf):
(JSC::DFG::FixupPhase::fixupToThis):
(JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
(JSC::DFG::FixupPhase::observeUseKindOnNode):
(JSC::DFG::FixupPhase::fixIntConvertingEdge):
(JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
(JSC::DFG::FixupPhase::fixupCompareStrictEqAndSameValue):
(JSC::DFG::FixupPhase::fixupChecksInBlock):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::addShouldSpeculateInt52):
(JSC::DFG::Graph::binaryArithShouldSpeculateInt52):
(JSC::DFG::Graph::unaryArithShouldSpeculateInt52):
(JSC::DFG::Graph::addShouldSpeculateAnyInt): Deleted.
(JSC::DFG::Graph::binaryArithShouldSpeculateAnyInt): Deleted.
(JSC::DFG::Graph::unaryArithShouldSpeculateAnyInt): Deleted.
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateInt52):
(JSC::DFG::Node::shouldSpeculateAnyInt): Deleted.
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::setIntTypedArrayLoadResult):
(JSC::DFG::SpeculativeJIT::compileArithAdd):
(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithNegate):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):
* dfg/DFGVariableAccessData.cpp:
(JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
(JSC::DFG::VariableAccessData::couldRepresentInt52Impl):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub):
(JSC::FTL::DFG::LowerDFGToB3::compileArithNegate):
(JSC::FTL::DFG::LowerDFGToB3::setIntTypedArrayLoadResult):

2019-04-09 Tadeu Zagallo <tzagallo@apple.com>

ASSERTION FAILED: !scope.exception() || !hasProperty in JSObject::get
@@ -249,8 +249,11 @@ void dumpSpeculation(PrintStream& outStream, SpeculatedType value)
isTop = false;
}

if (value & SpecInt52Only)
strOut.print("Int52");
if (value & SpecInt32AsInt52)
strOut.print("Int32AsInt52");

if (value & SpecNonInt32AsInt52)
strOut.print("NonInt32AsInt52");

if ((value & SpecBytecodeDouble) == SpecBytecodeDouble)
strOut.print("BytecodeDouble");
@@ -343,10 +346,12 @@ static const char* speculationToAbbreviatedString(SpeculatedType prediction)
return "<Int32>";
if (isAnyIntAsDoubleSpeculation(prediction))
return "<AnyIntAsDouble>";
if (isInt52Speculation(prediction))
return "<Int52>";
if (isAnyIntSpeculation(prediction))
return "<AnyInt>";
if (prediction == SpecNonInt32AsInt52)
return "<NonInt32AsInt52>";
if (prediction == SpecInt32AsInt52)
return "<Int32AsInt52>";
if (isAnyInt52Speculation(prediction))
return "<Int52Any>";
if (isDoubleSpeculation(prediction))
return "<Double>";
if (isFullNumberSpeculation(prediction))
@@ -510,6 +515,18 @@ SpeculatedType speculationFromValue(JSValue value)
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))
@@ -578,8 +595,8 @@ SpeculatedType speculationFromJSType(JSType type)
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 & (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble))
type |= (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble);
if (type & (SpecIntAnyFormat | SpecNonIntAsDouble))
type |= (SpecIntAnyFormat | SpecNonIntAsDouble);

if (type & SpecString)
type |= SpecString;
@@ -803,10 +820,14 @@ SpeculatedType speculationFromString(const char* speculation)
return SpecNonBoolInt32;
if (!strncmp(speculation, "SpecInt32Only", strlen("SpecInt32Only")))
return SpecInt32Only;
if (!strncmp(speculation, "SpecInt52Only", strlen("SpecInt52Only")))
return SpecInt52Only;
if (!strncmp(speculation, "SpecAnyInt", strlen("SpecAnyInt")))
return SpecAnyInt;
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")))
@@ -73,26 +73,31 @@ static const SpeculatedType SpecCellOther = 1ull << 27;
static const SpeculatedType SpecBoolInt32 = 1ull << 28; // It's definitely an Int32 with value 0 or 1.
static const SpeculatedType SpecNonBoolInt32 = 1ull << 29; // It's definitely an Int32 with value other than 0 or 1.
static const SpeculatedType SpecInt32Only = SpecBoolInt32 | SpecNonBoolInt32; // It's definitely an Int32.
static const SpeculatedType SpecInt52Only = 1ull << 30; // It's definitely an Int52 and we intend it to unbox it. It's also definitely not an Int32.
static const SpeculatedType SpecAnyInt = SpecInt32Only | SpecInt52Only; // It's something that we can do machine int arithmetic on.
static const SpeculatedType SpecAnyIntAsDouble = 1ull << 31; // It's definitely an Int52 and it's inside a double.
static const SpeculatedType SpecNonIntAsDouble = 1ull << 32; // It's definitely not an Int52 but it's a real number and it's a double.

static const SpeculatedType SpecInt32AsInt52 = 1ull << 30; // It's an Int52 and it can fit in an int32.
static const SpeculatedType SpecNonInt32AsInt52 = 1ull << 31; // It's an Int52 and it can't fit in an int32.
static const SpeculatedType SpecInt52Any = SpecInt32AsInt52 | SpecNonInt32AsInt52; // It's any kind of Int52.

static const SpeculatedType SpecAnyIntAsDouble = 1ull << 32; // It's definitely an Int52 and it's inside a double.
static const SpeculatedType SpecNonIntAsDouble = 1ull << 33; // It's definitely not an Int52 but it's a real number and it's a double.
static const SpeculatedType SpecDoubleReal = SpecNonIntAsDouble | SpecAnyIntAsDouble; // It's definitely a non-NaN double.
static const SpeculatedType SpecDoublePureNaN = 1ull << 33; // It's definitely a NaN that is safe to tag (i.e. pure).
static const SpeculatedType SpecDoubleImpureNaN = 1ull << 34; // It's definitely a NaN that is unsafe to tag (i.e. impure).
static const SpeculatedType SpecDoublePureNaN = 1ull << 34; // It's definitely a NaN that is safe to tag (i.e. pure).
static const SpeculatedType SpecDoubleImpureNaN = 1ull << 35; // It's definitely a NaN that is unsafe to tag (i.e. impure).
static const SpeculatedType SpecDoubleNaN = SpecDoublePureNaN | SpecDoubleImpureNaN; // It's definitely some kind of NaN.
static const SpeculatedType SpecBytecodeDouble = SpecDoubleReal | SpecDoublePureNaN; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN.
static const SpeculatedType SpecFullDouble = SpecDoubleReal | SpecDoubleNaN; // It's either a non-NaN or a NaN double.
static const SpeculatedType SpecBytecodeRealNumber = SpecInt32Only | SpecDoubleReal; // It's either an Int32 or a DoubleReal.
static const SpeculatedType SpecFullRealNumber = SpecAnyInt | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or a Int52.
static const SpeculatedType SpecFullRealNumber = SpecInt32Only | SpecInt52Any | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or an Int52.
static const SpeculatedType SpecBytecodeNumber = SpecInt32Only | SpecBytecodeDouble; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
static const SpeculatedType SpecFullNumber = SpecAnyInt | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
static const SpeculatedType SpecBoolean = 1ull << 35; // It's definitely a Boolean.
static const SpeculatedType SpecOther = 1ull << 36; // It's definitely either Null or Undefined.
static const SpeculatedType SpecIntAnyFormat = SpecInt52Any | SpecInt32Only | SpecAnyIntAsDouble;

static const SpeculatedType SpecFullNumber = SpecIntAnyFormat | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
static const SpeculatedType SpecBoolean = 1ull << 36; // It's definitely a Boolean.
static const SpeculatedType SpecOther = 1ull << 37; // It's definitely either Null or Undefined.
static const SpeculatedType SpecMisc = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined.
static const SpeculatedType SpecEmpty = 1ull << 37; // It's definitely an empty value marker.
static const SpeculatedType SpecBigInt = 1ull << 38; // It's definitely a BigInt.
static const SpeculatedType SpecDataViewObject = 1ull << 39; // It's definitely a JSDataView.
static const SpeculatedType SpecEmpty = 1ull << 38; // It's definitely an empty value marker.
static const SpeculatedType SpecBigInt = 1ull << 39; // It's definitely a BigInt.
static const SpeculatedType SpecDataViewObject = 1ull << 40; // It's definitely a JSDataView.
static const SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue.
static const SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecWeakMapObject | SpecWeakSetObject | SpecProxyObject | SpecDerivedArray | SpecObjectOther | SpecDataViewObject; // Bitmask used for testing for any kind of object prediction.
static const SpeculatedType SpecCell = SpecObject | SpecString | SpecSymbol | SpecCellOther | SpecBigInt; // It's definitely a JSCell.
@@ -337,27 +342,27 @@ inline bool isInt32OrBooleanSpeculation(SpeculatedType value)

inline bool isInt32SpeculationForArithmetic(SpeculatedType value)
{
return !(value & (SpecFullDouble | SpecInt52Only));
return !(value & (SpecFullDouble | SpecInt52Any));
}

inline bool isInt32OrBooleanSpeculationForArithmetic(SpeculatedType value)
{
return !(value & (SpecFullDouble | SpecInt52Only));
return !(value & (SpecFullDouble | SpecInt52Any));
}

inline bool isInt32OrBooleanSpeculationExpectingDefined(SpeculatedType value)
{
return isInt32OrBooleanSpeculation(value & ~SpecOther);
}

inline bool isInt52Speculation(SpeculatedType value)
inline bool isAnyInt52Speculation(SpeculatedType value)
{
return value == SpecInt52Only;
return !!value && (value & SpecInt52Any) == value;
}

inline bool isAnyIntSpeculation(SpeculatedType value)
inline bool isIntAnyFormat(SpeculatedType value)
{
return !!value && (value & SpecAnyInt) == value;
return !!value && (value & SpecIntAnyFormat) == value;
}

inline bool isAnyIntAsDoubleSpeculation(SpeculatedType value)
@@ -483,6 +488,9 @@ SpeculatedType speculationFromClassInfo(const ClassInfo*);
SpeculatedType speculationFromStructure(Structure*);
SpeculatedType speculationFromCell(JSCell*);
JS_EXPORT_PRIVATE SpeculatedType speculationFromValue(JSValue);
// If it's an anyInt(), it'll return speculated types from the Int52 lattice.
// Otherwise, it'll return types from the JSValue lattice.
JS_EXPORT_PRIVATE SpeculatedType int52AwareSpeculationFromValue(JSValue);
SpeculatedType speculationFromJSType(JSType);

SpeculatedType speculationFromTypedArrayType(TypedArrayType); // only valid for typed views.

0 comments on commit bd19ce3

Please sign in to comment.