/* static */ bool
RematerializedFrame::RematerializeInlineFrames(JSContext *cx, uint8_t *top,
                                               InlineFrameIterator &iter,
                                               MaybeReadFallback &fallback,
                                               Vector<RematerializedFrame *> &frames)
{
    if (!frames.resize(iter.frameCount()))
        return false;

    while (true) {
        size_t frameNo = iter.frameNo();
        RematerializedFrame *frame = RematerializedFrame::New(cx, top, iter, fallback);
        if (!frame)
            return false;
        if (frame->scopeChain()) {
            if (!EnsureHasScopeObjects(cx, frame))
                return false;
        }

        frames[frameNo] = frame;

        if (!iter.more())
            break;
        ++iter;
    }

    return true;
}
/* static */ bool
RematerializedFrame::RematerializeInlineFrames(JSContext* cx, uint8_t* top,
                                               InlineFrameIterator& iter,
                                               MaybeReadFallback& fallback,
                                               GCVector<RematerializedFrame*>& frames)
{
    Rooted<GCVector<RematerializedFrame*>> tempFrames(cx, GCVector<RematerializedFrame*>(cx));
    if (!tempFrames.resize(iter.frameCount()))
        return false;

    while (true) {
        size_t frameNo = iter.frameNo();
        tempFrames[frameNo].set(RematerializedFrame::New(cx, top, iter, fallback));
        if (!tempFrames[frameNo])
            return false;
        if (tempFrames[frameNo]->environmentChain()) {
            if (!EnsureHasEnvironmentObjects(cx, tempFrames[frameNo].get()))
                return false;
        }

        if (!iter.more())
            break;
        ++iter;
    }

    frames = Move(tempFrames.get());
    return true;
}
RematerializedFrame::RematerializedFrame(ThreadSafeContext *cx, uint8_t *top,
                                         InlineFrameIterator &iter)
  : prevUpToDate_(false),
    top_(top),
    frameNo_(iter.frameNo()),
    numActualArgs_(iter.numActualArgs()),
    script_(iter.script())
{
    CopyValueToRematerializedFrame op(slots_);
    iter.readFrameArgsAndLocals(cx, op, op, &scopeChain_, &returnValue_,
                                &argsObj_, &thisValue_, ReadFrame_Actuals);
}
RematerializedFrame::RematerializedFrame(JSContext *cx, uint8_t *top, unsigned numActualArgs,
                                         InlineFrameIterator &iter, MaybeReadFallback &fallback)
  : prevUpToDate_(false),
    isDebuggee_(iter.script()->isDebuggee()),
    top_(top),
    pc_(iter.pc()),
    frameNo_(iter.frameNo()),
    numActualArgs_(numActualArgs),
    script_(iter.script())
{
    CopyValueToRematerializedFrame op(slots_);
    iter.readFrameArgsAndLocals(cx, op, op, &scopeChain_, &hasCallObj_, &returnValue_,
                                &argsObj_, &thisValue_, ReadFrame_Actuals,
                                fallback);
}
RematerializedFrame::RematerializedFrame(JSContext* cx, uint8_t* top, unsigned numActualArgs,
                                         InlineFrameIterator& iter, MaybeReadFallback& fallback)
  : prevUpToDate_(false),
    isDebuggee_(iter.script()->isDebuggee()),
    isConstructing_(iter.isConstructing()),
    hasCachedSavedFrame_(false),
    top_(top),
    pc_(iter.pc()),
    frameNo_(iter.frameNo()),
    numActualArgs_(numActualArgs),
    script_(iter.script())
{
    if (iter.isFunctionFrame())
        callee_ = iter.callee(fallback);
    else
        callee_ = nullptr;

    CopyValueToRematerializedFrame op(slots_);
    iter.readFrameArgsAndLocals(cx, op, op, &scopeChain_, &hasCallObj_, &returnValue_,
                                &argsObj_, &thisArgument_, ReadFrame_Actuals,
                                fallback);
}