diff --git a/js/src/builtin/String.js b/js/src/builtin/String.js index 59fbf6c79d8e..2f8cce4fa02e 100644 --- a/js/src/builtin/String.js +++ b/js/src/builtin/String.js @@ -257,7 +257,7 @@ function String_sup() { function EscapeAttributeValue(v) { var inputStr = ToString(v); var inputLen = inputStr.length; - var outputStr = ''; + var outputStr = ""; var chunkStart = 0; for (var i = 0; i < inputLen; i++) { if (inputStr[i] === '"') { diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 2a7de06be90a..07f8df0bbc0b 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -736,6 +736,7 @@ class IonBuilder : public MIRGenerator InliningStatus inlineHaveSameClass(CallInfo &callInfo); InliningStatus inlineToObject(CallInfo &callInfo); InliningStatus inlineToInteger(CallInfo &callInfo); + InliningStatus inlineToString(CallInfo &callInfo); InliningStatus inlineDump(CallInfo &callInfo); InliningStatus inlineHasClass(CallInfo &callInfo, const Class *clasp) { return inlineHasClasses(callInfo, clasp, nullptr); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index d5642a893b29..294024bac103 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -165,6 +165,8 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target) return inlineToObject(callInfo); if (native == intrinsic_ToInteger) return inlineToInteger(callInfo); + if (native == intrinsic_ToString) + return inlineToString(callInfo); // TypedObject intrinsics. if (native == intrinsic_ObjectIsTypedObject) @@ -1914,6 +1916,22 @@ IonBuilder::inlineToInteger(CallInfo &callInfo) return InliningStatus_Inlined; } +IonBuilder::InliningStatus +IonBuilder::inlineToString(CallInfo &callInfo) +{ + if (callInfo.argc() != 1 || callInfo.constructing()) + return InliningStatus_NotInlined; + + if (getInlineReturnType() != MIRType_String) + return InliningStatus_NotInlined; + + callInfo.setImplicitlyUsedUnchecked(); + MToString *toString = MToString::New(alloc(), callInfo.getArg(0)); + current->add(toString); + current->push(toString); + return InliningStatus_Inlined; +} + IonBuilder::InliningStatus IonBuilder::inlineBailout(CallInfo &callInfo) { diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index fb46efcb9637..37531a032629 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -1002,6 +1002,7 @@ class ContextAllocPolicy /* Exposed intrinsics so that Ion may inline them. */ bool intrinsic_ToObject(JSContext *cx, unsigned argc, Value *vp); bool intrinsic_ToInteger(JSContext *cx, unsigned argc, Value *vp); +bool intrinsic_ToString(JSContext *cx, unsigned argc, Value *vp); bool intrinsic_IsCallable(JSContext *cx, unsigned argc, Value *vp); bool intrinsic_ThrowError(JSContext *cx, unsigned argc, Value *vp); bool intrinsic_NewDenseArray(JSContext *cx, unsigned argc, Value *vp); diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 3c76f0e451a9..638532c28f8c 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -73,13 +73,13 @@ js::intrinsic_ToInteger(JSContext *cx, unsigned argc, Value *vp) } bool -intrinsic_ToString(JSContext *cx, unsigned argc, Value *vp) +js::intrinsic_ToString(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedString str(cx); str = ToString(cx, args[0]); - if (!str) - return false; + if (!str) + return false; args.rval().setString(str); return true; }