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; }
bool SavedStacks::getLocation(JSContext *cx, const FrameIter &iter, MutableHandleLocationValue locationp) { // We should only ever be caching location values for scripts in this // compartment. Otherwise, we would get dead cross-compartment scripts in // the cache because our compartment's sweep method isn't called when their // compartment gets collected. assertSameCompartment(cx, this, iter.compartment()); // When we have a |JSScript| for this frame, use a potentially memoized // location from our PCLocationMap and copy it into |locationp|. 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 |locationp|'s slots directly. if (!iter.hasScript()) { if (const char16_t *displayURL = iter.scriptDisplayURL()) { locationp->source = AtomizeChars(cx, displayURL, js_strlen(displayURL)); } else { const char *filename = iter.scriptFilename() ? iter.scriptFilename() : ""; locationp->source = Atomize(cx, filename, strlen(filename)); } if (!locationp->source) return false; locationp->line = iter.computeLine(&locationp->column); return true; } RootedScript script(cx, iter.script()); jsbytecode *pc = iter.pc(); PCKey key(script, pc); PCLocationMap::AddPtr p = pcLocationMap.lookupForAdd(key); if (!p) { RootedAtom source(cx); if (const char16_t *displayURL = iter.scriptDisplayURL()) { source = AtomizeChars(cx, displayURL, js_strlen(displayURL)); } else { const char *filename = script->filename() ? script->filename() : ""; source = Atomize(cx, filename, strlen(filename)); } if (!source) return false; uint32_t column; uint32_t line = PCToLineNumber(script, pc, &column); LocationValue value(source, line, column); if (!pcLocationMap.add(p, key, value)) return false; } locationp.set(p->value()); return true; }