Beispiel #1
0
SavedStacks::FrameState::FrameState(const FrameIter &iter)
    : principals(iter.compartment()->principals),
      name(iter.isNonEvalFunctionFrame() ? iter.functionDisplayAtom() : nullptr),
      location()
{
    if (principals)
        JS_HoldPrincipals(principals);
}
Beispiel #2
0
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);

    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, Move(buf), " [\"%s\":%d]\n",
                         filename ? filename : "<unknown>",
                         lineno);

    MOZ_ASSERT(!cx->isExceptionPending());
    return buf;
}
Beispiel #3
0
bool
SavedStacks::insertFrames(JSContext *cx, FrameIter &iter, MutableHandleSavedFrame frame,
                          unsigned maxFrameCount)
{
    if (iter.done()) {
        frame.set(nullptr);
        return true;
    }

    // Don't report the over-recursion error because if we are blowing the stack
    // here, we already blew the stack in JS, reported it, and we are creating
    // the saved stack for the over-recursion error object. We do this check
    // here, rather than inside saveCurrentStack, because in some cases we will
    // pass the check there, despite later failing the check here (for example,
    // in js/src/jit-test/tests/saved-stacks/bug-1006876-too-much-recursion.js).
    JS_CHECK_RECURSION_DONT_REPORT(cx, return false);

    JSPrincipals* principals = iter.compartment()->principals;
    RootedAtom name(cx, iter.isNonEvalFunctionFrame() ? iter.functionDisplayAtom() : nullptr);

    // When we have a |JSScript| for this frame, use |getLocation| to get a
    // potentially memoized location result and copy it into |location|. When we
    // do not have a |JSScript| for this frame (asm.js frames), we take a slow
    // path that doesn't employ memoization, and update |location|'s slots
    // directly.
    AutoLocationValueRooter location(cx);
    if (iter.hasScript()) {
        JSScript *script = iter.script();
        jsbytecode *pc = iter.pc();
        {
            AutoCompartment ac(cx, iter.compartment());
            if (!cx->compartment()->savedStacks().getLocation(cx, script, pc, &location))
                return false;
        }
    } else {
        const char *filename = iter.scriptFilename();
        if (!filename)
            filename = "";
        location.get().source = Atomize(cx, filename, strlen(filename));
        if (!location.get().source)
            return false;
        uint32_t column;
        location.get().line = iter.computeLine(&column);
        location.get().column = column;
    }

    RootedSavedFrame parentFrame(cx);

    // If maxFrameCount is zero, then there's no limit on the number of frames.
    if (maxFrameCount == 0) {
        if (!insertFrames(cx, ++iter, &parentFrame, 0))
            return false;
    } else if (maxFrameCount == 1) {
        // Since we were only asked to save one frame, the SavedFrame we're
        // building here should have no parent, even if there are older frames
        // on the stack.
        parentFrame = nullptr;
    } else {
        if (!insertFrames(cx, ++iter, &parentFrame, maxFrameCount - 1))
            return false;
    }

    SavedFrame::AutoLookupRooter lookup(cx,
                                        location.get().source,
                                        location.get().line,
                                        location.get().column,
                                        name,
                                        parentFrame,
                                        principals);

    frame.set(getOrCreateSavedFrame(cx, lookup));
    return frame.get() != nullptr;
}