From 6895d48e3b8ff9dd51281828d627fc4f1f8721f3 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Fri, 18 May 2012 21:09:23 +0200 Subject: [PATCH] Bug 756247 - Fix JSOP_POS inference failure. r=dvander --- js/src/ion/IonBuilder.cpp | 24 ++++++++---------------- js/src/ion/MIR.h | 10 ++-------- js/src/ion/TypeOracle.cpp | 4 ++-- js/src/jit-test/tests/ion/bug756247.js | 13 +++++++++++++ 4 files changed, 25 insertions(+), 26 deletions(-) create mode 100644 js/src/jit-test/tests/ion/bug756247.js diff --git a/js/src/ion/IonBuilder.cpp b/js/src/ion/IonBuilder.cpp index 61030973216..04c6e74c1f3 100644 --- a/js/src/ion/IonBuilder.cpp +++ b/js/src/ion/IonBuilder.cpp @@ -2558,26 +2558,18 @@ bool IonBuilder::jsop_pos() { TypeOracle::Unary types = oracle->unaryOp(script, pc); - MDefinition *value = current->pop(); - if (types.ival == MIRType_Int32) { - // Already an int32, no semantic difference! - current->push(value); + if (IsNumberType(types.ival)) { + // Already int32 or double. + JS_ASSERT(types.ival == types.rval); return true; } - MToDouble *ins = MToDouble::New(value); - current->add(ins); - current->push(ins); + // Compile +x as x * 1. + MDefinition *value = current->pop(); + MConstant *one = MConstant::New(Int32Value(1)); + current->add(one); - // If the expected type is >= string, we compile this as a more expensive - // variant and consider it effectful. - if (types.ival >= MIRType_String) { - ins->unspecialize(); - if (!resumeAfter(ins)) - return false; - } - - return true; + return jsop_binary(JSOP_MUL, value, one); } bool diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index 28d5f3c8dd4..5ee7818b0e0 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -1571,8 +1571,7 @@ class MPassArg // Converts a primitive (either typed or untyped) to a double. If the input is // not primitive at runtime, a bailout occurs. class MToDouble - : public MUnaryInstruction, - public SimplePolicy + : public MUnaryInstruction { MToDouble(MDefinition *def) : MUnaryInstruction(def) @@ -1596,12 +1595,7 @@ class MToDouble return congruentIfOperandsEqual(ins); } AliasSet getAliasSet() const { - return specialized() - ? AliasSet::None() - : AliasSet::Store(AliasSet::Any); - } - TypePolicy *typePolicy() { - return this; + return AliasSet::None(); } }; diff --git a/js/src/ion/TypeOracle.cpp b/js/src/ion/TypeOracle.cpp index 7d2bfe0fe29..32ee375faf6 100644 --- a/js/src/ion/TypeOracle.cpp +++ b/js/src/ion/TypeOracle.cpp @@ -103,7 +103,7 @@ TypeInferenceOracle::binaryTypes(JSScript *script, jsbytecode *pc) JSOp op = (JSOp)*pc; BinaryTypes res; - if ((js_CodeSpec[op].format & JOF_INCDEC) || op == JSOP_NEG) { + if ((js_CodeSpec[op].format & JOF_INCDEC) || op == JSOP_NEG || op == JSOP_POS) { res.lhsTypes = script->analysis()->poppedTypes(pc, 0); res.rhsTypes = NULL; res.outTypes = script->analysis()->pushedTypes(pc, 0); @@ -134,7 +134,7 @@ TypeInferenceOracle::binaryOp(JSScript *script, jsbytecode *pc) JSOp op = (JSOp)*pc; Binary res; - if ((js_CodeSpec[op].format & JOF_INCDEC) || op == JSOP_NEG) { + if ((js_CodeSpec[op].format & JOF_INCDEC) || op == JSOP_NEG || op == JSOP_POS) { res.lhs = getMIRType(script->analysis()->poppedTypes(pc, 0)); res.rhs = MIRType_Int32; res.rval = getMIRType(script->analysis()->pushedTypes(pc, 0)); diff --git a/js/src/jit-test/tests/ion/bug756247.js b/js/src/jit-test/tests/ion/bug756247.js new file mode 100644 index 00000000000..83de1c57d5e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug756247.js @@ -0,0 +1,13 @@ +function foo(i) { + var n = 0; + for (var i = 0; i < false; i++) + n = a++; + assertEq(n, 0); +} +var a = foo(10); + +function bar(x) { + var y = +(x ? x : "foo"); + assertEq(y, 10); +} +bar(10);