Diff
Modified: trunk/LayoutTests/ChangeLog (184932 => 184933)
--- trunk/LayoutTests/ChangeLog 2015-05-28 00:39:35 UTC (rev 184932)
+++ trunk/LayoutTests/ChangeLog 2015-05-28 01:30:58 UTC (rev 184933)
@@ -1,3 +1,14 @@
+2015-05-27 Benjamin Poulain <[email protected]>
+
+ [JSC] Add undefined->double conversion to DoubleRep
+ https://bugs.webkit.org/show_bug.cgi?id=145293
+
+ Reviewed by Filip Pizlo.
+
+ * js/regress/math-with-out-of-bounds-array-values-expected.txt: Added.
+ * js/regress/math-with-out-of-bounds-array-values.html: Added.
+ * js/regress/script-tests/math-with-out-of-bounds-array-values.js: Added.
+
2015-05-27 Simon Fraser <[email protected]>
REGRESSION (r183820): webkit.org/blog/ background painting issue on reload, when the page contains videos
Added: trunk/LayoutTests/js/regress/math-with-out-of-bounds-array-values-expected.txt (0 => 184933)
--- trunk/LayoutTests/js/regress/math-with-out-of-bounds-array-values-expected.txt (rev 0)
+++ trunk/LayoutTests/js/regress/math-with-out-of-bounds-array-values-expected.txt 2015-05-28 01:30:58 UTC (rev 184933)
@@ -0,0 +1,10 @@
+JSRegress/math-with-out-of-bounds-array-values
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/regress/math-with-out-of-bounds-array-values.html (0 => 184933)
--- trunk/LayoutTests/js/regress/math-with-out-of-bounds-array-values.html (rev 0)
+++ trunk/LayoutTests/js/regress/math-with-out-of-bounds-array-values.html 2015-05-28 01:30:58 UTC (rev 184933)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/regress/script-tests/math-with-out-of-bounds-array-values.js (0 => 184933)
--- trunk/LayoutTests/js/regress/script-tests/math-with-out-of-bounds-array-values.js (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/math-with-out-of-bounds-array-values.js 2015-05-28 01:30:58 UTC (rev 184933)
@@ -0,0 +1,19 @@
+function mathWithOutOfBoundsAccess(arrayA, arrayB)
+{
+ var output = 0;
+ for (var i = 0; i < 10; ++i) {
+ output += (arrayA[i] + arrayB[i]);
+ }
+ return output;
+}
+
+noInline(mathWithOutOfBoundsAccess);
+
+function test() {
+ var integerArray = [0, 1, 2, 3, 4];
+ var doubleArray = [0.1, 1.2, 2.3, 3.4, 4.5];
+
+ for (var i = 0; i < 1e5; ++i)
+ mathWithOutOfBoundsAccess(integerArray, doubleArray);
+}
+test();
\ No newline at end of file
Modified: trunk/Source/_javascript_Core/ChangeLog (184932 => 184933)
--- trunk/Source/_javascript_Core/ChangeLog 2015-05-28 00:39:35 UTC (rev 184932)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-05-28 01:30:58 UTC (rev 184933)
@@ -1,3 +1,61 @@
+2015-05-27 Benjamin Poulain <[email protected]>
+
+ [JSC] Add undefined->double conversion to DoubleRep
+ https://bugs.webkit.org/show_bug.cgi?id=145293
+
+ Reviewed by Filip Pizlo.
+
+ This patch adds undefined to double conversion to the DoubleRep
+ node for the cases were we speculate "undefined" as part of the types
+ processed.
+
+ The use case is doing math with accidental out-of-bounds access. For example,
+ something like:
+ for (var i = 0; i <= length; ++i)
+ ouptput += array[i];
+
+ would cause us to OSR exit every time i === length.
+
+ When hitting one of those cases, we would already speculate double math,
+ but the DoubleRep node was unable to convert the undefined and would exit.
+
+ With this patch the use kind NotCellUse cover this conversion for DoubleRep.
+ I have been quite conservative so in general we will not find "undefined"
+ until a few recompile but being optimistic seems better since this is a corner case.
+
+ This patch is a 80% progression on WebXPRT's DNA Sequencing test.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::sawUndefined):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::SafeToExecuteEdge::operator()):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+ * dfg/DFGUseKind.cpp:
+ (WTF::printInternal):
+ * dfg/DFGUseKind.h:
+ (JSC::DFG::typeFilterFor):
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+ (JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
+ * tests/stress/double-rep-with-undefined.js: Added.
+ (addArgsNumberAndUndefined):
+ (addArgsInt32AndUndefined):
+ (testFallbackWithDouble):
+ (addArgsDoubleAndUndefined):
+ (testFallbackWithObject.):
+ (testFallbackWithObject):
+ (addArgsOnlyUndefined):
+ (testFallbackWithString):
+
2015-05-27 Dean Jackson <[email protected]>
img.currentSrc problem in strict mode with old picturefill
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (184932 => 184933)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2015-05-28 00:39:35 UTC (rev 184932)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2015-05-28 01:30:58 UTC (rev 184933)
@@ -360,7 +360,30 @@
setConstant(node, jsDoubleNumber(child.asNumber()));
break;
}
- forNode(node).setType(m_graph, forNode(node->child1()).m_type);
+
+ SpeculatedType type = forNode(node->child1()).m_type;
+ switch (node->child1().useKind()) {
+ case NotCellUse: {
+ if (type & SpecOther) {
+ type &= ~SpecOther;
+ type |= SpecDoublePureNaN | SpecBoolInt32; // Null becomes zero, undefined becomes NaN.
+ }
+ if (type & SpecBoolean) {
+ type &= ~SpecBoolean;
+ type |= SpecBoolInt32; // True becomes 1, false becomes 0.
+ }
+ type &= SpecBytecodeNumber;
+ break;
+ }
+
+ case Int52RepUse:
+ case NumberUse:
+ break;
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ forNode(node).setType(type);
forNode(node).fixTypeForRepresentation(m_graph, node);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (184932 => 184933)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2015-05-28 00:39:35 UTC (rev 184932)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2015-05-28 01:30:58 UTC (rev 184933)
@@ -2128,9 +2128,13 @@
m_indexInBlock, SpecInt52AsDouble, DoubleRep, node->origin,
Edge(edge.node(), Int52RepUse));
} else {
+ UseKind useKind = NotCellUse;
+ if (edge->shouldSpeculateNumber())
+ useKind = NumberUse;
+
result = m_insertionSet.insertNode(
m_indexInBlock, SpecBytecodeDouble, DoubleRep, node->origin,
- Edge(edge.node(), NumberUse));
+ Edge(edge.node(), useKind));
}
edge.setNode(result);
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (184932 => 184933)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2015-05-28 00:39:35 UTC (rev 184932)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2015-05-28 01:30:58 UTC (rev 184933)
@@ -402,6 +402,12 @@
SpecNone);
switch (arrayMode.type()) {
+ case Array::Int32:
+ if (arrayMode.isOutOfBounds())
+ changed |= mergePrediction(node->getHeapPrediction() | SpecInt32);
+ else
+ changed |= mergePrediction(SpecInt32);
+ break;
case Array::Double:
if (arrayMode.isOutOfBounds())
changed |= mergePrediction(node->getHeapPrediction() | SpecDoubleReal);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (184932 => 184933)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2015-05-28 00:39:35 UTC (rev 184932)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2015-05-28 01:30:58 UTC (rev 184933)
@@ -2066,31 +2066,58 @@
void SpeculativeJIT::compileDoubleRep(Node* node)
{
switch (node->child1().useKind()) {
+ case NotCellUse:
case NumberUse: {
ASSERT(!node->child1()->isNumberConstant()); // This should have been constant folded.
-
- if (isInt32Speculation(m_state.forNode(node->child1()).m_type)) {
+
+ SpeculatedType possibleTypes = m_state.forNode(node->child1()).m_type;
+ if (isInt32Speculation(possibleTypes)) {
SpeculateInt32Operand op1(this, node->child1(), ManualOperandSpeculation);
FPRTemporary result(this);
m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
doubleResult(result.fpr(), node);
return;
}
-
+
JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
FPRTemporary result(this);
-
+
#if USE(JSVALUE64)
GPRTemporary temp(this);
GPRReg op1GPR = op1.gpr();
GPRReg tempGPR = temp.gpr();
FPRReg resultFPR = result.fpr();
-
+ JITCompiler::JumpList done;
+
JITCompiler::Jump isInteger = m_jit.branch64(
MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
-
- if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
+
+ if (node->child1().useKind() == NotCellUse) {
+ JITCompiler::Jump isNumber = m_jit.branchTest64(MacroAssembler::NonZero, op1GPR, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::Jump isUndefined = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueUndefined));
+
+ static const double zero = 0;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&zero), resultFPR);
+
+ JITCompiler::Jump isNull = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueNull));
+ done.append(isNull);
+
+ DFG_TYPE_CHECK(JSValueRegs(op1GPR), node->child1(), ~SpecCell,
+ m_jit.branchTest64(JITCompiler::NonZero, op1GPR, TrustedImm32(static_cast<int32_t>(~1))));
+
+ JITCompiler::Jump isFalse = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueFalse));
+ static const double _one_ = 1;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&one), resultFPR);
+ done.append(isFalse);
+
+ isUndefined.link(&m_jit);
+ static const double NaN = PNaN;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&NaN), resultFPR);
+ done.append(m_jit.jump());
+
+ isNumber.link(&m_jit);
+ } else if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
typeCheck(
JSValueRegs(op1GPR), node->child1(), SpecBytecodeNumber,
m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
@@ -2098,7 +2125,7 @@
m_jit.move(op1GPR, tempGPR);
unboxDouble(tempGPR, resultFPR);
- JITCompiler::Jump done = m_jit.jump();
+ done.append(m_jit.jump());
isInteger.link(&m_jit);
m_jit.convertInt32ToDouble(op1GPR, resultFPR);
@@ -2110,18 +2137,42 @@
GPRReg op1PayloadGPR = op1.payloadGPR();
FPRReg tempFPR = temp.fpr();
FPRReg resultFPR = result.fpr();
+ JITCompiler::JumpList done;
JITCompiler::Jump isInteger = m_jit.branch32(
MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
-
- if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
+
+ if (node->child1().useKind() == NotCellUse) {
+ JITCompiler::Jump isNumber = m_jit.branch32(JITCompiler::Below, op1TagGPR, JITCompiler::TrustedImm32(JSValue::LowestTag + 1));
+ JITCompiler::Jump isUndefined = m_jit.branch32(JITCompiler::Equal, op1TagGPR, TrustedImm32(JSValue::UndefinedTag));
+
+ static const double zero = 0;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&zero), resultFPR);
+
+ JITCompiler::Jump isNull = m_jit.branch32(JITCompiler::Equal, op1TagGPR, TrustedImm32(JSValue::NullTag));
+ done.append(isNull);
+
+ DFG_TYPE_CHECK(JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), ~SpecCell, m_jit.branch32(JITCompiler::NotEqual, op1TagGPR, TrustedImm32(JSValue::BooleanTag)));
+
+ JITCompiler::Jump isFalse = m_jit.branchTest32(JITCompiler::Zero, op1PayloadGPR, TrustedImm32(1));
+ static const double _one_ = 1;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&one), resultFPR);
+ done.append(isFalse);
+
+ isUndefined.link(&m_jit);
+ static const double NaN = PNaN;
+ m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&NaN), resultFPR);
+ done.append(m_jit.jump());
+
+ isNumber.link(&m_jit);
+ } else if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
typeCheck(
JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecBytecodeNumber,
m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
}
-
+
unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
- JITCompiler::Jump done = m_jit.jump();
+ done.append(m_jit.jump());
isInteger.link(&m_jit);
m_jit.convertInt32ToDouble(op1PayloadGPR, resultFPR);
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (184932 => 184933)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2015-05-28 00:39:35 UTC (rev 184932)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2015-05-28 01:30:58 UTC (rev 184933)
@@ -958,9 +958,12 @@
void compileDoubleRep()
{
switch (m_node->child1().useKind()) {
+ case NotCellUse:
case NumberUse: {
+ bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
+
LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
- setDouble(jsValueToDouble(m_node->child1(), value));
+ setDouble(jsValueToDouble(m_node->child1(), value, shouldConvertNonNumber));
return;
}
@@ -7199,10 +7202,12 @@
{
return m_out.sub(m_out.bitCast(doubleValue, m_out.int64), m_tagTypeNumber);
}
- LValue jsValueToDouble(Edge edge, LValue boxedValue)
+ LValue jsValueToDouble(Edge edge, LValue boxedValue, bool shouldConvertNonNumber)
{
LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing int case"));
+ LBasicBlock doubleTesting = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing double case"));
LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing double case"));
+ LBasicBlock nonDoubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing undefined case"));
LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing continuation"));
LValue isNotInt32;
@@ -7212,24 +7217,70 @@
isNotInt32 = m_out.booleanTrue;
else
isNotInt32 = this->isNotInt32(boxedValue);
- m_out.branch(isNotInt32, unsure(doubleCase), unsure(intCase));
+ m_out.branch(isNotInt32, unsure(doubleTesting), unsure(intCase));
- LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
+ LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
ValueFromBlock intToDouble = m_out.anchor(
m_out.intToDouble(unboxInt32(boxedValue)));
m_out.jump(continuation);
- m_out.appendTo(doubleCase, continuation);
-
- FTL_TYPE_CHECK(
- jsValueValue(boxedValue), edge, SpecBytecodeNumber, isCellOrMisc(boxedValue));
-
+ m_out.appendTo(doubleTesting, doubleCase);
+ LValue valueIsNumber = isNumber(boxedValue);
+ m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
+
+ m_out.appendTo(doubleCase, nonDoubleCase);
ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedValue));
m_out.jump(continuation);
-
+
+ if (shouldConvertNonNumber) {
+ LBasicBlock undefinedCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting undefined case"));
+ LBasicBlock testNullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing null case"));
+ LBasicBlock nullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting null case"));
+ LBasicBlock testBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing boolean true case"));
+ LBasicBlock convertBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean true case"));
+ LBasicBlock convertBooleanFalseCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean false case"));
+
+ m_out.appendTo(nonDoubleCase, undefinedCase);
+ LValue valueIsUndefined = m_out.equal(boxedValue, m_out.constInt64(ValueUndefined));
+ m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
+
+ m_out.appendTo(undefinedCase, testNullCase);
+ ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
+ m_out.jump(continuation);
+
+ m_out.appendTo(testNullCase, nullCase);
+ LValue valueIsNull = m_out.equal(boxedValue, m_out.constInt64(ValueNull));
+ m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
+
+ m_out.appendTo(nullCase, testBooleanTrueCase);
+ ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
+ m_out.jump(continuation);
+
+ m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
+ LValue valueIsBooleanTrue = m_out.equal(boxedValue, m_out.constInt64(ValueTrue));
+ m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
+
+ m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
+ ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
+ m_out.jump(continuation);
+
+ m_out.appendTo(convertBooleanFalseCase, continuation);
+
+ LValue valueIsNotBooleanFalse = m_out.notEqual(boxedValue, m_out.constInt64(ValueFalse));
+ FTL_TYPE_CHECK(jsValueValue(boxedValue), edge, ~SpecCell, valueIsNotBooleanFalse);
+ ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
+ m_out.jump(continuation);
+
+ m_out.appendTo(continuation, lastNext);
+ return m_out.phi(m_out.doubleType, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse);
+ }
+ m_out.appendTo(nonDoubleCase, continuation);
+ FTL_TYPE_CHECK(jsValueValue(boxedValue), edge, SpecBytecodeNumber, m_out.booleanTrue);
+ m_out.unreachable();
+
m_out.appendTo(continuation, lastNext);
-
+
return m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
}
Added: trunk/Source/_javascript_Core/tests/stress/double-rep-with-non-cell.js (0 => 184933)
--- trunk/Source/_javascript_Core/tests/stress/double-rep-with-non-cell.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/double-rep-with-non-cell.js 2015-05-28 01:30:58 UTC (rev 184933)
@@ -0,0 +1,32 @@
+// Only bool, undefined and null
+function addNullBoolUndefined(a, b) {
+ return a + b;
+}
+noInline(addNullBoolUndefined);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addNullBoolUndefined(0.5, null);
+ if (value !== 0.5)
+ throw "addNullBoolUndefined(0.5, null) failed with i = " + i + " returned value = " + value;
+
+ var value = addNullBoolUndefined(null, undefined);
+ if (value === value)
+ throw "addNullBoolUndefined(null, undefined) failed with i = " + i + " returned value = " + value;
+
+ var value = addNullBoolUndefined(true, null);
+ if (value !== 1)
+ throw "addNullBoolUndefined(true, null) failed with i = " + i + " returned value = " + value;
+
+ var value = addNullBoolUndefined(undefined, false);
+ if (value === value)
+ throw "addNullBoolUndefined(undefined, false) failed with i = " + i + " returned value = " + value;
+
+ var value = addNullBoolUndefined(false, true);
+ if (value !== 1)
+ throw "addNullBoolUndefined(false, true) failed with i = " + i + " returned value = " + value;
+
+ var value = addNullBoolUndefined(null, 42);
+ if (value !== 42)
+ throw "addNullBoolUndefined(null, 42) failed with i = " + i + " returned value = " + value;
+
+}
Added: trunk/Source/_javascript_Core/tests/stress/double-rep-with-null.js (0 => 184933)
--- trunk/Source/_javascript_Core/tests/stress/double-rep-with-null.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/double-rep-with-null.js 2015-05-28 01:30:58 UTC (rev 184933)
@@ -0,0 +1,107 @@
+// Using full number + null for math.
+function addArgsNumberAndNull(a, b) {
+ return a + b;
+}
+noInline(addArgsNumberAndNull);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addArgsNumberAndNull(i, 1);
+ if (value !== (i + 1))
+ throw "addArgsNumberAndNull(i, 1) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndNull(0.5, i);
+ if (value !== (i + 0.5))
+ throw "addArgsNumberAndNull(0.5, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndNull(null, i);
+ if (value !== i)
+ throw "addArgsNumberAndNull(null, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndNull(i, null);
+ if (value !== i)
+ throw "addArgsNumberAndNull(i, null) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndNull(null, null);
+ if (value !== 0)
+ throw "addArgsNumberAndNull(null, null) failed with i = " + i + " returned value = " + value;
+}
+
+
+// Using int32 + null for math.
+function addArgsInt32AndNull(a, b) {
+ return a + b;
+}
+noInline(addArgsInt32AndNull);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addArgsInt32AndNull(i, 1);
+ if (value !== (i + 1))
+ throw "addArgsInt32AndNull(i, 1) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsInt32AndNull(null, i);
+ if (value !== i)
+ throw "addArgsInt32AndNull(null, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsInt32AndNull(i, null);
+ if (value !== i)
+ throw "addArgsInt32AndNull(i, null) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsInt32AndNull(null, null);
+ if (value !== 0)
+ throw "addArgsInt32AndNull(null, null) failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithDouble() {
+ var value = addArgsNumberAndNull(Math.PI, Math.PI);
+ if (value !== 2 * Math.PI)
+ throw "addArgsNumberAndNull(Math.PI, Math.PI) failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithDouble();
+
+
+// Using full number + null for math.
+function addArgsDoubleAndNull(a, b) {
+ return a + b;
+}
+noInline(addArgsDoubleAndNull);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addArgsDoubleAndNull(0.5, i);
+ if (value !== (i + 0.5))
+ throw "addArgsDoubleAndNull(0.5, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsDoubleAndNull(null, 0.1);
+ if (value !== 0.1)
+ throw "addArgsDoubleAndNull(null, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsDoubleAndNull(0.6, null);
+ if (value !== 0.6)
+ throw "addArgsDoubleAndNull(i, null) failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithObject() {
+ var value = addArgsDoubleAndNull(Math.PI, { valueOf: function() { return 5; }});
+ if (value !== 5 + Math.PI)
+ throw "addArgsDoubleAndNull(Math.PI, { valueOf: function() { return 5; }}) failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithObject();
+
+
+// Using only null
+function addArgsOnlyNull(a, b) {
+ return a + b;
+}
+noInline(addArgsOnlyNull);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addArgsOnlyNull(null, null);
+ if (value !== 0)
+ throw "addArgsOnlyNull(null, null) failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithString() {
+ var value = addArgsOnlyNull("foo", "bar");
+ if (value !== "foobar")
+ throw "addArgsOnlyNull(\"foo\", \"bar\") failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithString();
\ No newline at end of file
Added: trunk/Source/_javascript_Core/tests/stress/double-rep-with-undefined.js (0 => 184933)
--- trunk/Source/_javascript_Core/tests/stress/double-rep-with-undefined.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/double-rep-with-undefined.js 2015-05-28 01:30:58 UTC (rev 184933)
@@ -0,0 +1,131 @@
+// Using full number + undefined for math.
+function addArgsNumberAndUndefined(a, b) {
+ return a + b;
+}
+noInline(addArgsNumberAndUndefined);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addArgsNumberAndUndefined(i, 1);
+ if (value !== (i + 1))
+ throw "addArgsNumberAndUndefined(i, 1) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndUndefined(0.5, i);
+ if (value !== (i + 0.5))
+ throw "addArgsNumberAndUndefined(0.5, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndUndefined(undefined, i);
+ if (value === value)
+ throw "addArgsNumberAndUndefined(undefined, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndUndefined(i, undefined);
+ if (value === value)
+ throw "addArgsNumberAndUndefined(i, undefined) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndUndefined(i);
+ if (value === value)
+ throw "addArgsNumberAndUndefined(i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndUndefined(undefined, undefined);
+ if (value === value)
+ throw "addArgsNumberAndUndefined(undefined, undefined) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsNumberAndUndefined();
+ if (value === value)
+ throw "addArgsNumberAndUndefined() failed with i = " + i + " returned value = " + value;
+}
+
+
+// Using int32 + undefined for math.
+function addArgsInt32AndUndefined(a, b) {
+ return a + b;
+}
+noInline(addArgsInt32AndUndefined);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addArgsInt32AndUndefined(i, 1);
+ if (value !== (i + 1))
+ throw "addArgsInt32AndUndefined(i, 1) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsInt32AndUndefined(undefined, i);
+ if (value === value)
+ throw "addArgsInt32AndUndefined(undefined, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsInt32AndUndefined(i, undefined);
+ if (value === value)
+ throw "addArgsInt32AndUndefined(i, undefined) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsInt32AndUndefined(i);
+ if (value === value)
+ throw "addArgsInt32AndUndefined(i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsInt32AndUndefined(undefined, undefined);
+ if (value === value)
+ throw "addArgsInt32AndUndefined(undefined, undefined) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsInt32AndUndefined();
+ if (value === value)
+ throw "addArgsInt32AndUndefined() failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithDouble() {
+ var value = addArgsNumberAndUndefined(Math.PI, Math.PI);
+ if (value !== 2 * Math.PI)
+ throw "addArgsNumberAndUndefined(Math.PI, Math.PI) failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithDouble();
+
+
+// Using full number + undefined for math.
+function addArgsDoubleAndUndefined(a, b) {
+ return a + b;
+}
+noInline(addArgsDoubleAndUndefined);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addArgsDoubleAndUndefined(0.5, i);
+ if (value !== (i + 0.5))
+ throw "addArgsDoubleAndUndefined(0.5, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsDoubleAndUndefined(undefined, 0.1);
+ if (value === value)
+ throw "addArgsDoubleAndUndefined(undefined, i) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsDoubleAndUndefined(0.6, undefined);
+ if (value === value)
+ throw "addArgsDoubleAndUndefined(i, undefined) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsDoubleAndUndefined(42.8);
+ if (value === value)
+ throw "addArgsDoubleAndUndefined(i) failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithObject() {
+ var value = addArgsDoubleAndUndefined(Math.PI, { valueOf: function() { return 5; }});
+ if (value !== 5 + Math.PI)
+ throw "addArgsDoubleAndUndefined(Math.PI, { valueOf: function() { return 5; }}) failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithObject();
+
+
+// Using full number + undefined for math.
+function addArgsOnlyUndefined(a, b) {
+ return a + b;
+}
+noInline(addArgsOnlyUndefined);
+
+for (var i = 0; i < 1e7; ++i) {
+ var value = addArgsOnlyUndefined(undefined, undefined);
+ if (value === value)
+ throw "addArgsOnlyUndefined(undefined, undefined) failed with i = " + i + " returned value = " + value;
+
+ var value = addArgsOnlyUndefined();
+ if (value === value)
+ throw "addArgsOnlyUndefined() failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithString() {
+ var value = addArgsOnlyUndefined("foo", "bar");
+ if (value !== "foobar")
+ throw "addArgsOnlyUndefined(\"foo\", \"bar\") failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithString();
\ No newline at end of file