Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- jsfriendapi.cpp
- +++ jsfriendapi.cpp
- @@ -803,72 +804,44 @@ JS_FRIEND_API(bool)
- js::DumpScript(JSContext* cx, JSScript* scriptArg)
- {
- return DumpScript(cx, scriptArg, stdout);
- }
- #endif
- static const char*
- -FormatValue(JSContext* cx, const Value& vArg, UniqueChars& bytes)
- +FormatValue(JSContext* cx, HandleValue v, UniqueChars& bytes)
- {
- - RootedValue v(cx, vArg);
- -
- if (v.isMagic(JS_OPTIMIZED_OUT))
- return "[unavailable]";
- - /*
- - * We could use Maybe<AutoRealm> here, but G++ can't quite follow
- - * that, and warns about uninitialized members being used in the
- - * destructor.
- - */
- - RootedString str(cx);
- - if (v.isObject()) {
- - if (IsCrossCompartmentWrapper(&v.toObject()))
- - return "[cross-compartment wrapper]";
- - AutoRealm ar(cx, &v.toObject());
- + if (IsCallable(v))
- + return "[function]";
- +
- + if (v.isObject() && IsCrossCompartmentWrapper(&v.toObject()))
- + return "[cross-compartment wrapper]";
- +
- + JSString* str;
- + {
- + mozilla::Maybe<AutoRealm> ar;
- + if (v.isObject())
- + ar.emplace(cx, &v.toObject());
- +
- str = ToString<CanGC>(cx, v);
- - } else {
- - str = ToString<CanGC>(cx, v);
- + if (!str)
- + return nullptr;
- }
- - if (!str)
- - return nullptr;
- bytes = JS_EncodeStringToLatin1(cx, str);
- - if (!bytes)
- - return nullptr;
- - const char* buf = bytes.get();
- - const char* found = strstr(buf, "function ");
- - if (found && (found - buf <= 2))
- - return "[function]";
- - return buf;
- + return bytes.get();
- }
- -// Wrapper for JS_sprintf_append() that reports allocation failure to the
- -// context.
- -static JS::UniqueChars
- -MOZ_FORMAT_PRINTF(3, 4)
- -sprintf_append(JSContext* cx, JS::UniqueChars&& buf, const char* fmt, ...)
- -{
- - va_list ap;
- -
- - va_start(ap, fmt);
- - JS::UniqueChars result = JS_vsprintf_append(std::move(buf), fmt, ap);
- - va_end(ap);
- -
- - if (!result) {
- - ReportOutOfMemory(cx);
- - return nullptr;
- - }
- -
- - return result;
- -}
- -
- -static JS::UniqueChars
- -FormatFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num,
- +static bool
- +FormatFrame(JSContext* cx, const FrameIter& iter, Sprinter& sp, 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));
- JSAutoRealm ar(cx, envChain);
- @@ -882,33 +855,33 @@ FormatFrame(JSContext* cx, const FrameIt
- RootedValue thisVal(cx);
- if (iter.hasUsableAbstractFramePtr() &&
- iter.isFunctionFrame() &&
- fun && !fun->isArrow() && !fun->isDerivedClassConstructor() &&
- !(fun->isBoundFunction() && iter.isConstructing()))
- {
- if (!GetFunctionThis(cx, iter.abstractFramePtr(), &thisVal))
- - return nullptr;
- + return false;
- }
- // print the frame number and function name
- - JS::UniqueChars buf(std::move(inBuf));
- if (funname) {
- UniqueChars funbytes = JS_EncodeStringToLatin1(cx, funname);
- if (!funbytes)
- - return nullptr;
- - buf = sprintf_append(cx, std::move(buf), "%d %s(", num, funbytes.get());
- + return false;
- + if (!sp.printf("%d %s(", num, funbytes.get()))
- + return false;
- } else if (fun) {
- - buf = sprintf_append(cx, std::move(buf), "%d anonymous(", num);
- + if (!sp.printf("%d anonymous(", num))
- + return false;
- } else {
- - buf = sprintf_append(cx, std::move(buf), "%d <TOP LEVEL>", num);
- + if (!sp.printf("%d <TOP LEVEL>", num))
- + return false;
- }
- - if (!buf)
- - return nullptr;
- if (showArgs && iter.hasArgs()) {
- PositionalFormalParameterIter fi(script);
- bool first = true;
- for (unsigned i = 0; i < iter.numActualArgs(); i++) {
- RootedValue arg(cx);
- if (i < iter.numFormalArgs() && fi.closedOver()) {
- arg = iter.callObj(cx).aliasedBinding(fi);
- @@ -924,203 +897,200 @@ FormatFrame(JSContext* cx, const FrameIt
- } else {
- arg = MagicValue(JS_OPTIMIZED_OUT);
- }
- UniqueChars valueBytes;
- const char* value = FormatValue(cx, arg, valueBytes);
- if (!value) {
- if (cx->isThrowingOutOfMemory())
- - return nullptr;
- + return false;
- cx->clearPendingException();
- }
- UniqueChars nameBytes;
- const char* name = nullptr;
- if (i < iter.numFormalArgs()) {
- MOZ_ASSERT(fi.argumentSlot() == i);
- if (!fi.isDestructured()) {
- nameBytes = JS_EncodeStringToLatin1(cx, fi.name());
- name = nameBytes.get();
- if (!name)
- - return nullptr;
- + return false;
- } else {
- name = "(destructured parameter)";
- }
- fi++;
- }
- if (value) {
- - buf = sprintf_append(cx, std::move(buf), "%s%s%s%s%s%s",
- - !first ? ", " : "",
- - name ? name :"",
- - name ? " = " : "",
- - arg.isString() ? "\"" : "",
- - value,
- - arg.isString() ? "\"" : "");
- - if (!buf)
- - return nullptr;
- + if (!sp.printf("%s%s%s%s%s%s",
- + !first ? ", " : "",
- + name ? name :"",
- + name ? " = " : "",
- + arg.isString() ? "\"" : "",
- + value,
- + arg.isString() ? "\"" : ""))
- + {
- + return false;
- + }
- first = false;
- } else {
- - buf = sprintf_append(cx, std::move(buf),
- - " <Failed to get argument while inspecting stack frame>\n");
- - if (!buf)
- - return nullptr;
- + if (!sp.put(" <Failed to get argument while inspecting stack frame>\n"))
- + return false;
- }
- }
- }
- // print filename and line number
- - buf = sprintf_append(cx, std::move(buf), "%s [\"%s\":%d]\n",
- - fun ? ")" : "",
- - filename ? filename : "<unknown>",
- - lineno);
- - if (!buf)
- - return nullptr;
- -
- + if (!sp.printf("%s [\"%s\":%d]\n",
- + fun ? ")" : "",
- + filename ? filename : "<unknown>",
- + lineno))
- + {
- + return false;
- + }
- // Note: Right now we don't dump the local variables anymore, because
- // that is hard to support across all the JITs etc.
- // print the value of 'this'
- if (showLocals) {
- if (!thisVal.isUndefined()) {
- - UniqueChars thisValBytes;
- RootedString thisValStr(cx, ToString<CanGC>(cx, thisVal));
- if (!thisValStr) {
- if (cx->isThrowingOutOfMemory())
- - return nullptr;
- + return false;
- cx->clearPendingException();
- }
- if (thisValStr) {
- - thisValBytes = JS_EncodeStringToLatin1(cx, thisValStr);
- + UniqueChars thisValBytes = JS_EncodeStringToLatin1(cx, thisValStr);
- if (!thisValBytes)
- - return nullptr;
- - buf = sprintf_append(cx, std::move(buf), " this = %s\n", thisValBytes.get());
- + return false;
- + if (!sp.printf(" this = %s\n", thisValBytes.get()))
- + return false;
- } else {
- - buf = sprintf_append(cx, std::move(buf), " <failed to get 'this' value>\n");
- + if (!sp.put(" <failed to get 'this' value>\n"))
- + return false;
- }
- - if (!buf)
- - return nullptr;
- }
- }
- if (showThisProps && thisVal.isObject()) {
- RootedObject obj(cx, &thisVal.toObject());
- AutoIdVector keys(cx);
- if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY, &keys)) {
- if (cx->isThrowingOutOfMemory())
- - return nullptr;
- + return false;
- cx->clearPendingException();
- }
- - RootedId id(cx);
- for (size_t i = 0; i < keys.length(); i++) {
- 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;
- + return false;
- cx->clearPendingException();
- - buf = sprintf_append(cx, std::move(buf),
- - " <Failed to fetch property while inspecting stack frame>\n");
- - if (!buf)
- - return nullptr;
- + if (!sp.put(" <Failed to fetch property while inspecting stack frame>\n"))
- + return false;
- continue;
- }
- UniqueChars nameBytes;
- const char* name = FormatValue(cx, key, nameBytes);
- if (!name) {
- if (cx->isThrowingOutOfMemory())
- - return nullptr;
- + return false;
- cx->clearPendingException();
- }
- UniqueChars valueBytes;
- const char* value = FormatValue(cx, v, valueBytes);
- if (!value) {
- if (cx->isThrowingOutOfMemory())
- - return nullptr;
- + return false;
- cx->clearPendingException();
- }
- if (name && value) {
- - buf = sprintf_append(cx, std::move(buf), " this.%s = %s%s%s\n",
- - name,
- - v.isString() ? "\"" : "",
- - value,
- - v.isString() ? "\"" : "");
- + if (!sp.printf(" this.%s = %s%s%s\n",
- + name,
- + v.isString() ? "\"" : "",
- + value,
- + v.isString() ? "\"" : ""))
- + {
- + return false;
- + }
- } else {
- - buf = sprintf_append(cx, std::move(buf),
- - " <Failed to format values while inspecting stack frame>\n");
- + if (!sp.put(" <Failed to format values while inspecting stack frame>\n"))
- + return false;
- }
- - if (!buf)
- - return nullptr;
- }
- }
- MOZ_ASSERT(!cx->isExceptionPending());
- - return buf;
- + return true;
- }
- -static JS::UniqueChars
- -FormatWasmFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num)
- +static bool
- +FormatWasmFrame(JSContext* cx, const FrameIter& iter, Sprinter& sp, int num)
- {
- UniqueChars nameStr;
- if (JSAtom* functionDisplayAtom = iter.maybeFunctionDisplayAtom()) {
- nameStr = StringToNewUTF8CharsZ(cx, *functionDisplayAtom);
- if (!nameStr)
- - return nullptr;
- + return false;
- }
- - JS::UniqueChars buf = sprintf_append(cx, std::move(inBuf), "%d %s()",
- - num,
- - nameStr ? nameStr.get() : "<wasm-function>");
- - if (!buf)
- - return nullptr;
- + if (!sp.printf("%d %s()", num, nameStr ? nameStr.get() : "<wasm-function>"))
- + return false;
- - buf = sprintf_append(cx, std::move(buf), " [\"%s\":wasm-function[%d]:0x%x]\n",
- - iter.filename() ? iter.filename() : "<unknown>",
- - iter.wasmFuncIndex(),
- - iter.wasmBytecodeOffset());
- - if (!buf)
- - return nullptr;
- + if (!sp.printf(" [\"%s\":wasm-function[%d]:0x%x]\n",
- + iter.filename() ? iter.filename() : "<unknown>",
- + iter.wasmFuncIndex(),
- + iter.wasmBytecodeOffset()))
- + {
- + return false;
- + }
- MOZ_ASSERT(!cx->isExceptionPending());
- - return buf;
- + return true;
- }
- JS_FRIEND_API(JS::UniqueChars)
- -JS::FormatStackDump(JSContext* cx, JS::UniqueChars&& inBuf, bool showArgs, bool showLocals,
- - bool showThisProps)
- +JS::FormatStackDump(JSContext* cx, bool showArgs, bool showLocals, bool showThisProps)
- {
- int num = 0;
- - JS::UniqueChars buf(std::move(inBuf));
- + Sprinter sp(cx);
- + if (!sp.init())
- + return nullptr;
- +
- for (AllFramesIter i(cx); !i.done(); ++i) {
- - if (i.hasScript())
- - buf = FormatFrame(cx, i, std::move(buf), num, showArgs, showLocals, showThisProps);
- - else
- - buf = FormatWasmFrame(cx, i, std::move(buf), num);
- - if (!buf)
- + bool ok = i.hasScript()
- + ? FormatFrame(cx, i, sp, num, showArgs, showLocals, showThisProps)
- + : FormatWasmFrame(cx, i, sp, num);
- + if (!ok)
- return nullptr;
- num++;
- }
- - if (!num)
- - buf = JS_sprintf_append(std::move(buf), "JavaScript stack is empty\n");
- + if (num == 0) {
- + if (!sp.put("JavaScript stack is empty\n"))
- + return nullptr;
- + }
- - return buf;
- + return sp.release();
- }
- extern JS_FRIEND_API(bool)
- JS::ForceLexicalInitialization(JSContext *cx, HandleObject obj)
- {
- AssertHeapIsIdle();
- CHECK_THREAD(cx);
- cx->check(obj);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement