diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index f75b718706b4..efcef562f192 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -4047,9 +4047,11 @@ BaselineCompiler::emit_JSOP_TOID() frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); - // No-op if index is int32. + // No-op if the index is trivally convertable to an id. Label done; masm.branchTestInt32(Assembler::Equal, R0, &done); + masm.branchTestString(Assembler::Equal, R0, &done); + masm.branchTestSymbol(Assembler::Equal, R0, &done); prepareVMCall(); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 6fceb11066c0..576575d0cbc6 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -12477,8 +12477,9 @@ IonBuilder::jsop_toasynciter() AbortReasonOr IonBuilder::jsop_toid() { - // No-op if the index is an integer. - if (current->peek(-1)->type() == MIRType::Int32) + // No-op if the index is trivally convertable to an id. + MIRType type = current->peek(-1)->type(); + if (type == MIRType::Int32 || type == MIRType::String || type == MIRType::Symbol) return Ok(); MDefinition* index = current->pop(); diff --git a/js/src/jit/IonIC.cpp b/js/src/jit/IonIC.cpp index d71dbc7a7a43..d74fcb22a5cd 100644 --- a/js/src/jit/IonIC.cpp +++ b/js/src/jit/IonIC.cpp @@ -189,7 +189,7 @@ IonGetPropertyIC::update(JSContext* cx, HandleScript outerScript, IonGetProperty /* static */ bool IonSetPropertyIC::update(JSContext* cx, HandleScript outerScript, IonSetPropertyIC* ic, - HandleObject obj, HandleValue idVal, HandleValue rhs) + HandleObject obj, HandleValue idVal, HandleValue rhs) { RootedShape oldShape(cx); RootedObjectGroup oldGroup(cx); @@ -225,6 +225,8 @@ IonSetPropertyIC::update(JSContext* cx, HandleScript outerScript, IonSetProperty } jsbytecode* pc = ic->pc(); + + if (ic->kind() == CacheKind::SetElem) { if (IsPropertyInitOp(JSOp(*pc))) { if (!InitElemOperation(cx, pc, obj, idVal, rhs)) @@ -241,7 +243,12 @@ IonSetPropertyIC::update(JSContext* cx, HandleScript outerScript, IonSetProperty RootedScript script(cx, ic->script()); MOZ_ASSERT(!script->hasNonSyntacticScope()); InitGlobalLexicalOperation(cx, &cx->global()->lexicalEnvironment(), script, pc, rhs); + } else if (IsPropertyInitOp(JSOp(*pc))) { + RootedId id(cx, AtomToId(&idVal.toString()->asAtom())); + if (!InitPropertyOperation(cx, JSOp(*pc), obj, id, rhs)) + return false; } else { + MOZ_ASSERT(IsPropertySetOp(JSOp(*pc))); RootedPropertyName name(cx, idVal.toString()->asAtom().asPropertyName()); if (!SetProperty(cx, obj, name, rhs, ic->strict(), pc)) return false; diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h index bce383995b8c..0d2f9c481419 100644 --- a/js/src/vm/Interpreter-inl.h +++ b/js/src/vm/Interpreter-inl.h @@ -649,7 +649,7 @@ InitElemOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, HandleValue i if (!ToPropertyKey(cx, idval, &id)) return false; - unsigned flags = JSOp(*pc) == JSOP_INITHIDDENELEM ? 0 : JSPROP_ENUMERATE; + unsigned flags = GetInitDataPropAttrs(JSOp(*pc)); return DefineProperty(cx, obj, id, val, nullptr, nullptr, flags); } diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 01effb5d6780..44560c91a997 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -4761,10 +4761,12 @@ js::GetInitDataPropAttrs(JSOp op) { switch (op) { case JSOP_INITPROP: + case JSOP_INITELEM: return JSPROP_ENUMERATE; case JSOP_INITLOCKEDPROP: return JSPROP_PERMANENT | JSPROP_READONLY; case JSOP_INITHIDDENPROP: + case JSOP_INITHIDDENELEM: // Non-enumerable, but writable and configurable return 0; default:;