Bug 719294 - Eliminate the bytecode space optimization where it omits the starting line number. r=luke

As per this comment:

/*
 * Special case: function definition needs no line number note because
 * the function's script contains its starting line number.
 */

But this is the only reason why you need a JSContext in js_PCToLineNumber, and I have a user that needs to do the lookup without a context.

--HG--
extra : rebase_source : 73064dbbbf31949d19c8f1e1b18eb4febf127c87
This commit is contained in:
Steve Fink 2011-06-06 14:11:08 -07:00
Родитель 06b937d2cc
Коммит 4c2d3b949d
8 изменённых файлов: 34 добавлений и 28 удалений

Просмотреть файл

@ -5110,6 +5110,8 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
MOZ_ASSERT(!fun->isFlatClosure(), MOZ_ASSERT(!fun->isFlatClosure(),
"global functions can't have upvars, so they are never flat"); "global functions can't have upvars, so they are never flat");
if (!EmitFunctionOp(cx, JSOP_DEFFUN, index, bce)) if (!EmitFunctionOp(cx, JSOP_DEFFUN, index, bce))
if (!UpdateLineNumberNotes(cx, bce, pn->pn_pos.begin.lineno))
return JS_FALSE;
return false; return false;
bce->switchToMain(); bce->switchToMain();
} }

Просмотреть файл

@ -379,7 +379,7 @@ PopulateReportBlame(JSContext *cx, JSErrorReport *report)
for (FrameRegsIter iter(cx); !iter.done(); ++iter) { for (FrameRegsIter iter(cx); !iter.done(); ++iter) {
if (iter.fp()->isScriptFrame()) { if (iter.fp()->isScriptFrame()) {
report->filename = iter.fp()->script()->filename; report->filename = iter.fp()->script()->filename;
report->lineno = js_PCToLineNumber(cx, iter.fp()->script(), iter.pc()); report->lineno = PCToLineNumber(iter.fp()->script(), iter.pc());
report->originPrincipals = iter.fp()->script()->originPrincipals; report->originPrincipals = iter.fp()->script()->originPrincipals;
break; break;
} }

Просмотреть файл

@ -351,7 +351,7 @@ JS_ClearAllWatchPoints(JSContext *cx)
JS_PUBLIC_API(unsigned) JS_PUBLIC_API(unsigned)
JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc) JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
{ {
return js_PCToLineNumber(cx, script, pc); return js::PCToLineNumber(script, pc);
} }
JS_PUBLIC_API(jsbytecode *) JS_PUBLIC_API(jsbytecode *)

Просмотреть файл

@ -343,7 +343,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
} }
if (fp->isScriptFrame()) { if (fp->isScriptFrame()) {
frame.filename = fp->script()->filename; frame.filename = fp->script()->filename;
frame.ulineno = js_PCToLineNumber(cx, fp->script(), i.pc()); frame.ulineno = PCToLineNumber(fp->script(), i.pc());
} else { } else {
frame.ulineno = 0; frame.ulineno = 0;
frame.filename = NULL; frame.filename = NULL;
@ -783,7 +783,7 @@ Exception(JSContext *cx, unsigned argc, Value *vp)
if (!ToUint32(cx, args[2], &lineno)) if (!ToUint32(cx, args[2], &lineno))
return false; return false;
} else { } else {
lineno = iter.done() ? 0 : js_PCToLineNumber(cx, iter.fp()->script(), iter.pc()); lineno = iter.done() ? 0 : PCToLineNumber(iter.fp()->script(), iter.pc());
} }
int exnType = args.callee().toFunction()->getExtendedSlot(0).toInt32(); int exnType = args.callee().toFunction()->getExtendedSlot(0).toInt32();

Просмотреть файл

@ -1571,28 +1571,18 @@ js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)
} }
unsigned unsigned
js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc) js::PCToLineNumber(unsigned startLine, jssrcnote *notes, jsbytecode *code, jsbytecode *pc)
{ {
/* Cope with StackFrame.pc value prior to entering js_Interpret. */ unsigned lineno = startLine;
if (!pc)
return 0;
/* /*
* Special case: function definition needs no line number note because * Walk through source notes accumulating their deltas, keeping track of
* the function's script contains its starting line number. * line-number notes, until we pass the note for pc's offset within
* script->code.
*/ */
if (*pc == JSOP_DEFFUN)
return script->getFunction(GET_UINT32_INDEX(pc))->script()->lineno;
/*
* General case: walk through source notes accumulating their deltas,
* keeping track of line-number notes, until we pass the note for pc's
* offset within script->code.
*/
unsigned lineno = script->lineno;
ptrdiff_t offset = 0; ptrdiff_t offset = 0;
ptrdiff_t target = pc - script->code; ptrdiff_t target = pc - code;
for (jssrcnote *sn = script->notes(); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { for (jssrcnote *sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
offset += SN_DELTA(sn); offset += SN_DELTA(sn);
SrcNoteType type = (SrcNoteType) SN_TYPE(sn); SrcNoteType type = (SrcNoteType) SN_TYPE(sn);
if (type == SRC_SETLINE) { if (type == SRC_SETLINE) {
@ -1605,9 +1595,20 @@ js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
if (offset > target) if (offset > target)
break; break;
} }
return lineno; return lineno;
} }
unsigned
js::PCToLineNumber(JSScript *script, jsbytecode *pc)
{
/* Cope with StackFrame.pc value prior to entering js_Interpret. */
if (!pc)
return 0;
return PCToLineNumber(script->lineno, script->notes(), script->code, pc);
}
/* The line number limit is the same as the jssrcnote offset limit. */ /* The line number limit is the same as the jssrcnote offset limit. */
#define SN_LINE_LIMIT (SN_3BYTE_OFFSET_FLAG << 16) #define SN_LINE_LIMIT (SN_3BYTE_OFFSET_FLAG << 16)
@ -1680,7 +1681,7 @@ namespace js {
unsigned unsigned
CurrentLine(JSContext *cx) CurrentLine(JSContext *cx)
{ {
return js_PCToLineNumber(cx, cx->fp()->script(), cx->regs().pc); return PCToLineNumber(cx->fp()->script(), cx->regs().pc);
} }
void void
@ -1700,7 +1701,7 @@ CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *line
JSScript *script = iter.fp()->script(); JSScript *script = iter.fp()->script();
*file = script->filename; *file = script->filename;
*linenop = js_PCToLineNumber(cx, iter.fp()->script(), iter.pc()); *linenop = PCToLineNumber(iter.fp()->script(), iter.pc());
*origin = script->originPrincipals; *origin = script->originPrincipals;
} }

Просмотреть файл

@ -902,9 +902,6 @@ CheckScript(JSScript *script, JSScript *prev)
extern jssrcnote * extern jssrcnote *
js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc); js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc);
extern unsigned
js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
extern jsbytecode * extern jsbytecode *
js_LineNumberToPC(JSScript *script, unsigned lineno); js_LineNumberToPC(JSScript *script, unsigned lineno);
@ -913,6 +910,12 @@ js_GetScriptLineExtent(JSScript *script);
namespace js { namespace js {
extern unsigned
PCToLineNumber(JSScript *script, jsbytecode *pc);
extern unsigned
PCToLineNumber(unsigned startLine, jssrcnote *notes, jsbytecode *code, jsbytecode *pc);
extern unsigned extern unsigned
CurrentLine(JSContext *cx); CurrentLine(JSContext *cx);

Просмотреть файл

@ -1790,7 +1790,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
op = (JSOp) *i.pc(); op = (JSOp) *i.pc();
if (op == JSOP_TOXML || op == JSOP_TOXMLLIST) { if (op == JSOP_TOXML || op == JSOP_TOXMLLIST) {
filename = i.fp()->script()->filename; filename = i.fp()->script()->filename;
lineno = js_PCToLineNumber(cx, i.fp()->script(), i.pc()); lineno = PCToLineNumber(i.fp()->script(), i.pc());
for (endp = srcp + srclen; srcp < endp; srcp++) { for (endp = srcp + srclen; srcp < endp; srcp++) {
if (*srcp == '\n') if (*srcp == '\n')
--lineno; --lineno;

Просмотреть файл

@ -800,7 +800,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
#ifdef JS_METHODJIT_SPEW #ifdef JS_METHODJIT_SPEW
JaegerSpew(JSpew_Recompile, "interpreter rejoin (file \"%s\") (line \"%d\") (op %s) (opline \"%d\")\n", JaegerSpew(JSpew_Recompile, "interpreter rejoin (file \"%s\") (line \"%d\") (op %s) (opline \"%d\")\n",
script->filename, script->lineno, OpcodeNames[op], js_PCToLineNumber(cx, script, pc)); script->filename, script->lineno, OpcodeNames[op], PCToLineNumber(script, pc));
#endif #endif
uint32_t nextDepth = UINT32_MAX; uint32_t nextDepth = UINT32_MAX;