--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -779,36 +779,36 @@ FormatValue(JSContext* cx, const Value&
const char* found = strstr(buf, "function ");
if (found && (found - buf <= 2))
return "[function]";
return buf;
}
// Wrapper for JS_sprintf_append() that reports allocation failure to the
// context.
-static char*
+static JS::UniqueChars
MOZ_FORMAT_PRINTF(3, 4)
-sprintf_append(JSContext* cx, char* buf, const char* fmt, ...)
+sprintf_append(JSContext* cx, JS::UniqueChars&& buf, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- char* result = JS_vsprintf_append(UniqueChars(buf), fmt, ap).release();
+ JS::UniqueChars result = JS_vsprintf_append(Move(buf), fmt, ap);
va_end(ap);
if (!result) {
ReportOutOfMemory(cx);
return nullptr;
}
return result;
}
-static char*
-FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
+static JS::UniqueChars
+FormatFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num,
bool showArgs, bool showLocals, bool showThisProps)
{
MOZ_ASSERT(!cx->isExceptionPending());
RootedScript script(cx, iter.script());
jsbytecode* pc = iter.pc();
RootedObject envChain(cx, iter.environmentChain(cx));
JSAutoCompartment ac(cx, envChain);
@@ -826,26 +826,27 @@ FormatFrame(JSContext* cx, const FrameIt
fun && !fun->isArrow() && !fun->isDerivedClassConstructor() &&
!(fun->isBoundFunction() && iter.isConstructing()))
{
if (!GetFunctionThis(cx, iter.abstractFramePtr(), &thisVal))
return nullptr;
}
// print the frame number and function name
+ JS::UniqueChars buf(Move(inBuf));
if (funname) {
JSAutoByteString funbytes;
char* str = funbytes.encodeLatin1(cx, funname);
if (!str)
return nullptr;
- buf = sprintf_append(cx, buf, "%d %s(", num, str);
+ buf = sprintf_append(cx, Move(buf), "%d %s(", num, str);
} else if (fun) {
- buf = sprintf_append(cx, buf, "%d anonymous(", num);
+ buf = sprintf_append(cx, Move(buf), "%d anonymous(", num);
} else {
- buf = sprintf_append(cx, buf, "%d <TOP LEVEL>", num);
+ buf = sprintf_append(cx, Move(buf), "%d <TOP LEVEL>", num);
}
if (!buf)
return nullptr;
if (showArgs && iter.hasArgs()) {
PositionalFormalParameterIter fi(script);
bool first = true;
for (unsigned i = 0; i < iter.numActualArgs(); i++) {
@@ -884,39 +885,39 @@ FormatFrame(JSContext* cx, const FrameIt
return nullptr;
} else {
name = "(destructured parameter)";
}
fi++;
}
if (value) {
- buf = sprintf_append(cx, buf, "%s%s%s%s%s%s",
+ buf = sprintf_append(cx, Move(buf), "%s%s%s%s%s%s",
!first ? ", " : "",
name ? name :"",
name ? " = " : "",
arg.isString() ? "\"" : "",
value,
arg.isString() ? "\"" : "");
if (!buf)
return nullptr;
first = false;
} else {
- buf = sprintf_append(cx, buf,
+ buf = sprintf_append(cx, Move(buf),
" <Failed to get argument while inspecting stack frame>\n");
if (!buf)
return nullptr;
}
}
}
// print filename and line number
- buf = sprintf_append(cx, buf, "%s [\"%s\":%d]\n",
+ buf = sprintf_append(cx, Move(buf), "%s [\"%s\":%d]\n",
fun ? ")" : "",
filename ? filename : "<unknown>",
lineno);
if (!buf)
return nullptr;
// Note: Right now we don't dump the local variables anymore, because
@@ -931,19 +932,19 @@ FormatFrame(JSContext* cx, const FrameIt
if (cx->isThrowingOutOfMemory())
return nullptr;
cx->clearPendingException();
}
if (thisValStr) {
const char* str = thisValBytes.encodeLatin1(cx, thisValStr);
if (!str)
return nullptr;
- buf = sprintf_append(cx, buf, " this = %s\n", str);
+ buf = sprintf_append(cx, Move(buf), " this = %s\n", str);
} else {
- buf = sprintf_append(cx, buf, " <failed to get 'this' value>\n");
+ buf = sprintf_append(cx, Move(buf), " <failed to get 'this' value>\n");
}
if (!buf)
return nullptr;
}
}
if (showThisProps && thisVal.isObject()) {
RootedObject obj(cx, &thisVal.toObject());
@@ -960,17 +961,17 @@ FormatFrame(JSContext* cx, const FrameIt
RootedId id(cx, keys[i]);
RootedValue key(cx, IdToValue(id));
RootedValue v(cx);
if (!GetProperty(cx, obj, obj, id, &v)) {
if (cx->isThrowingOutOfMemory())
return nullptr;
cx->clearPendingException();
- buf = sprintf_append(cx, buf,
+ buf = sprintf_append(cx, Move(buf),
" <Failed to fetch property while inspecting stack frame>\n");
if (!buf)
return nullptr;
continue;
}
JSAutoByteString nameBytes;
const char* name = FormatValue(cx, key, nameBytes);
@@ -984,74 +985,77 @@ FormatFrame(JSContext* cx, const FrameIt
const char* value = FormatValue(cx, v, valueBytes);
if (!value) {
if (cx->isThrowingOutOfMemory())
return nullptr;
cx->clearPendingException();
}
if (name && value) {
- buf = sprintf_append(cx, buf, " this.%s = %s%s%s\n",
+ buf = sprintf_append(cx, Move(buf), " this.%s = %s%s%s\n",
name,
v.isString() ? "\"" : "",
value,
v.isString() ? "\"" : "");
} else {
- buf = sprintf_append(cx, buf,
+ buf = sprintf_append(cx, Move(buf),
" <Failed to format values while inspecting stack frame>\n");
}
if (!buf)
return nullptr;
}
}
MOZ_ASSERT(!cx->isExceptionPending());
return buf;
}
-static char*
-FormatWasmFrame(JSContext* cx, const FrameIter& iter, char* buf, int num, bool showArgs)
+static JS::UniqueChars
+FormatWasmFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num,
+ bool showArgs)
{
JSAtom* functionDisplayAtom = iter.functionDisplayAtom();
UniqueChars nameStr;
if (functionDisplayAtom)
nameStr = StringToNewUTF8CharsZ(cx, *functionDisplayAtom);
- buf = sprintf_append(cx, buf, "%d %s()",
- num,
- nameStr ? nameStr.get() : "<wasm-function>");
+ JS::UniqueChars buf = sprintf_append(cx, Move(inBuf), "%d %s()",
+ num,
+ nameStr ? nameStr.get() : "<wasm-function>");
if (!buf)
return nullptr;
const char* filename = iter.filename();
uint32_t lineno = iter.computeLine();
- buf = sprintf_append(cx, buf, " [\"%s\":%d]\n",
+ buf = sprintf_append(cx, Move(buf), " [\"%s\":%d]\n",
filename ? filename : "<unknown>",
lineno);
MOZ_ASSERT(!cx->isExceptionPending());
return buf;
}
-JS_FRIEND_API(char*)
-JS::FormatStackDump(JSContext* cx, char* buf, bool showArgs, bool showLocals, bool showThisProps)
+JS_FRIEND_API(JS::UniqueChars)
+JS::FormatStackDump(JSContext* cx, JS::UniqueChars&& inBuf, bool showArgs, bool showLocals,
+ bool showThisProps)
{
int num = 0;
+ JS::UniqueChars buf(Move(inBuf));
for (AllFramesIter i(cx); !i.done(); ++i) {
if (i.hasScript())
- buf = FormatFrame(cx, i, buf, num, showArgs, showLocals, showThisProps);
+ buf = FormatFrame(cx, i, Move(buf), num, showArgs, showLocals, showThisProps);
else
- buf = FormatWasmFrame(cx, i, buf, num, showArgs);
+ buf = FormatWasmFrame(cx, i, Move(buf), num, showArgs);
if (!buf)
return nullptr;
num++;
}
if (!num)
- buf = JS_sprintf_append(UniqueChars(buf), "JavaScript stack is empty\n").release();
+ buf = JS_sprintf_append(Move(buf), "JavaScript stack is empty\n");
return buf;
}
extern JS_FRIEND_API(bool)
JS::ForceLexicalInitialization(JSContext *cx, HandleObject obj)
{
AssertHeapIsIdle();