diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 519564e6b695..c2764cf0f86e 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -699,6 +699,7 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock* entry, jsbytecode* start, jsbytecod type = MIRType_Double; break; case JSOP_STRING: + case JSOP_TOSTRING: case JSOP_TYPEOF: case JSOP_TYPEOFEXPR: type = MIRType_String; @@ -1524,6 +1525,7 @@ IonBuilder::traverseBytecode() case JSOP_POS: case JSOP_TOID: + case JSOP_TOSTRING: // These ops may leave their input on the stack without setting // the ImplicitlyUsed flag. If this value will be popped immediately, // we may replace it with |undefined|, but the difference is @@ -1665,6 +1667,9 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_NEG: return jsop_neg(); + case JSOP_TOSTRING: + return jsop_tostring(); + case JSOP_AND: case JSOP_OR: return jsop_andor(op); @@ -4548,6 +4553,7 @@ IonBuilder::jsop_bitnot() MOZ_ASSERT(ins->isEffectful()); return resumeAfter(ins); } + bool IonBuilder::jsop_bitop(JSOp op) { @@ -4865,6 +4871,20 @@ IonBuilder::jsop_neg() return jsop_binary_arith(JSOP_MUL, negator, right); } +bool +IonBuilder::jsop_tostring() +{ + if (current->peek(-1)->type() == MIRType_String) + return true; + + MDefinition* value = current->pop(); + MToString* ins = MToString::New(alloc(), value); + current->add(ins); + current->push(ins); + MOZ_ASSERT(!ins->isEffectful()); + return true; +} + class AutoAccumulateReturns { MIRGraph& graph_; diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index c7fccd2cd7ba..58868fac6e70 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -649,6 +649,7 @@ class IonBuilder bool jsop_pow(); bool jsop_pos(); bool jsop_neg(); + bool jsop_tostring(); bool jsop_setarg(uint32_t arg); bool jsop_defvar(uint32_t index); bool jsop_deffun(uint32_t index);