--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -550,16 +550,19 @@ IonBuilder::inspectOpcode(JSOp op)
return jsop_bitop(op);
case JSOP_ADD:
case JSOP_SUB:
case JSOP_MUL:
case JSOP_DIV:
return jsop_binary(op);
+ case JSOP_POS:
+ return jsop_pos();
+
case JSOP_NEG:
return jsop_neg();
case JSOP_AND:
case JSOP_OR:
return jsop_andor(op);
case JSOP_LOCALINC:
@@ -1949,16 +1952,31 @@ IonBuilder::jsop_binary(JSOp op)
{
MDefinition *right = current->pop();
MDefinition *left = current->pop();
return jsop_binary(op, left, right);
}
bool
+IonBuilder::jsop_pos()
+{
+ TypeOracle::Unary types = oracle->unaryOp(script, pc);
+ MDefinition *value = current->pop();
+ MInstruction *ins;
+ if (types.rval == MIRType_Int32)
+ ins = MToInt32::New(value);
+ else
+ ins = MToDouble::New(value);
+ current->add(ins);
+ current->push(ins);
+ return true;
+}
+
+bool
IonBuilder::jsop_neg()
{
// Since JSOP_NEG does not use a slot, we cannot push the MConstant.
// The MConstant is therefore passed to JSOP_MUL without slot traffic.
MConstant *negator = MConstant::New(Int32Value(-1));
current->add(negator);
MDefinition *right = current->pop();
--- a/js/src/ion/IonBuilder.h
+++ b/js/src/ion/IonBuilder.h
@@ -268,16 +268,17 @@ class IonBuilder : public MIRGenerator
void initParameters();
void rewriteParameters();
bool pushConstant(const Value &v);
bool pushTypeBarrier(MInstruction *ins, types::TypeSet *actual, types::TypeSet *observed);
bool jsop_bitnot();
bool jsop_bitop(JSOp op);
bool jsop_binary(JSOp op);
bool jsop_binary(JSOp op, MDefinition *left, MDefinition *right);
+ bool jsop_pos();
bool jsop_neg();
bool jsop_notearg();
bool jsop_call(uint32 argc);
bool jsop_ifeq(JSOp op);
bool jsop_andor(JSOp op);
bool jsop_dup2();
bool jsop_incslot(JSOp op, uint32 slot);
bool jsop_localinc(JSOp op);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/testPos.js
@@ -0,0 +1,32 @@
+// vim: set ts=4 sw=4 tw=99 et:
+function f_int(x) {
+ return +x;
+}
+
+function f_double(x) {
+ return +x;
+}
+
+for (var i = 0; i < 1000; i++) {
+ assertEq(f_int(0), 0);
+ assertEq(f_int(1), 1);
+ assertEq(f_int(-1), -1);
+ assertEq(f_int(-2147483648), -2147483648);
+ assertEq(f_int(2147483647), 2147483647);
+}
+
+for (var i = 0; i < 1000; i++) {
+ assertEq(f_double(0.0), 0.0);
+ assertEq(f_double(1.0), 1.0);
+ assertEq(f_double(-1.0), -1.0);
+ assertEq(f_double(-2.147483648), -2.147483648);
+ assertEq(f_double(2.147483647), 2.147483647);
+}
+
+for (var i = 0; i < 1000; i++) {
+ assertEq(f_double("0.0"), 0.0);
+ assertEq(f_double("1.0"), 1.0);
+ assertEq(f_double("-1.0"), -1.0);
+ assertEq(f_double("-2.147483648"), -2.147483648);
+ assertEq(f_double("2.147483647"), 2.147483647);
+}