コード例 #1
0
ファイル: SavedStacks.cpp プロジェクト: JasonGross/mozjs
bool
SavedStacks::insertFrames(JSContext *cx, ScriptFrameIter &iter, MutableHandle<SavedFrame*> frame)
{
    if (iter.done()) {
        frame.set(nullptr);
        return true;
    }

    ScriptFrameIter thisFrame(iter);
    Rooted<SavedFrame*> parentFrame(cx);
    if (!insertFrames(cx, ++iter, &parentFrame))
        return false;

    RootedScript script(cx, thisFrame.script());
    RootedFunction callee(cx, thisFrame.maybeCallee());
    const char *filename = script->filename();
    RootedAtom source(cx, Atomize(cx, filename, strlen(filename)));
    if (!source)
        return false;
    uint32_t column;
    uint32_t line = PCToLineNumber(script, thisFrame.pc(), &column);

    SavedFrame::Lookup lookup(source,
                              line,
                              column,
                              callee ? callee->displayAtom() : nullptr,
                              parentFrame,
                              thisFrame.compartment()->principals);

    frame.set(getOrCreateSavedFrame(cx, lookup));
    return frame.address() != nullptr;
}
コード例 #2
0
ファイル: SavedStacks.cpp プロジェクト: chenhequn/gecko
bool
SavedStacks::insertFrames(JSContext *cx, FrameIter &iter, MutableHandleSavedFrame frame,
                          unsigned maxFrameCount)
{
    // In order to lookup a cached SavedFrame object, we need to have its parent
    // SavedFrame, which means we need to walk the stack from oldest frame to
    // youngest. However, FrameIter walks the stack from youngest frame to
    // oldest. The solution is to append stack frames to a vector as we walk the
    // stack with FrameIter, and then do a second pass through that vector in
    // reverse order after the traversal has completed and get or create the
    // SavedFrame objects at that time.
    //
    // To avoid making many copies of FrameIter (whose copy constructor is
    // relatively slow), we save the subset of FrameIter's data that is relevant
    // to our needs in a FrameState object, and maintain a vector of FrameState
    // objects instead of a vector of FrameIter objects.

    // Accumulate the vector of FrameState objects in |stackState|.
    AutoFrameStateVector stackState(cx);
    while (!iter.done()) {
        AutoLocationValueRooter location(cx);

        {
            AutoCompartment ac(cx, iter.compartment());
            if (!cx->compartment()->savedStacks().getLocation(cx, iter, &location))
                return false;
        }

        {
            FrameState frameState(iter);
            frameState.location = location.get();
            if (!stackState->append(frameState))
                return false;
        }

        ++iter;

        if (maxFrameCount == 0) {
            // If maxFrameCount is zero, then there's no limit on the number of
            // frames.
            continue;
        } else if (maxFrameCount == 1) {
            // Since we were only asked to save one frame, do not continue
            // walking the stack and saving frame state.
            break;
        } else {
            maxFrameCount--;
        }
    }

    // Iterate through |stackState| in reverse order and get or create the
    // actual SavedFrame instances.
    RootedSavedFrame parentFrame(cx, nullptr);
    for (size_t i = stackState->length(); i != 0; i--) {
        SavedFrame::AutoLookupRooter lookup(cx,
                                            stackState[i-1].location.source,
                                            stackState[i-1].location.line,
                                            stackState[i-1].location.column,
                                            stackState[i-1].name,
                                            parentFrame,
                                            stackState[i-1].principals);
        parentFrame.set(getOrCreateSavedFrame(cx, lookup));
        if (!parentFrame)
            return false;
    }

    frame.set(parentFrame);
    return true;
}