Bug 808181: Do not allow implicit conversion of Return<T>; r=jorendorff

This will allow the compiler to catch more usage errors.
This commit is contained in:
Terrence Cole 2012-11-05 10:53:04 -08:00
parent ab77043eb7
commit f227398047
30 changed files with 72 additions and 67 deletions

View File

@ -77,6 +77,8 @@ class MutableHandleBase {};
namespace JS {
class AutoAssertNoGC;
template <typename T> class MutableHandle;
JS_FRIEND_API(void) EnterAssertNoGCScope();
@ -405,16 +407,16 @@ class Return
Return(NullPtr) : ptr_(NULL) {}
/*
* |operator const T &| is the safest way to access a Return<T> without
* rooting it first: it will assert when used outside of an AutoAssertNoGC
* guard scope.
* |get(AutoAssertNoGC &)| is the safest way to access a Return<T> without
* rooting it first: it is impossible to call this method without an
* AutoAssertNoGC in scope, so the compiler will automatically catch any
* incorrect usage.
*
* Example:
* AutoAssertNoGC nogc;
* RawScript script = fun->script();
* RawScript script = fun->script().get(nogc);
*/
operator const T &() const {
JS_ASSERT(InNoGCScope());
const T &get(AutoAssertNoGC &) const {
return ptr_;
}
@ -477,6 +479,7 @@ class Return
* instead of direct pointer comparison.
*/
bool operator==(const T &other) { return ptr_ == other; }
bool operator!=(const T &other) { return ptr_ != other; }
bool operator==(const Return<T> &other) { return ptr_ == other.ptr_; }
bool operator==(const JS::Handle<T> &other) { return ptr_ == other.get(); }
inline bool operator==(const Rooted<T> &other);

View File

@ -85,7 +85,7 @@ GetBailedJSScript(JSContext *cx)
switch (GetCalleeTokenTag(frame->calleeToken())) {
case CalleeToken_Function: {
JSFunction *fun = CalleeTokenToFunction(frame->calleeToken());
return fun->script();
return fun->script().get(nogc);
}
case CalleeToken_Script:
return CalleeTokenToScript(frame->calleeToken());
@ -178,8 +178,8 @@ StackFrame::initFromBailout(JSContext *cx, SnapshotIterator &iter)
regs.pc = GetNextPc(regs.pc);
IonSpew(IonSpew_Bailouts, " new PC is offset %u within script %p (line %d)",
pcOff, (void *)script(), PCToLineNumber(script(), regs.pc));
JS_ASSERT(exprStackSlots == js_ReconstructStackDepth(cx, script(), regs.pc));
pcOff, (void *)script().get(nogc), PCToLineNumber(script().get(nogc), regs.pc));
JS_ASSERT(exprStackSlots == js_ReconstructStackDepth(cx, script().get(nogc), regs.pc));
}
static StackFrame *
@ -663,7 +663,7 @@ ion::ThunkToInterpreter(Value *vp)
IonSpew(IonSpew_Bailouts, "Performing inline OSR %s:%d",
cx->fp()->script()->filename,
PCToLineNumber(cx->fp()->script(), cx->regs().pc));
PCToLineNumber(cx->fp()->script().unsafeGet(), cx->regs().pc));
// We want to OSR again. We need to avoid the problem where frequent
// bailouts cause recursive nestings of Interpret and EnterIon. The

View File

@ -149,7 +149,7 @@ IonBuilder::getSingleCallTarget(uint32 argc, jsbytecode *pc)
{
AutoAssertNoGC nogc;
types::StackTypeSet *calleeTypes = oracle->getCallTarget(script(), argc, pc);
types::StackTypeSet *calleeTypes = oracle->getCallTarget(script().get(nogc), argc, pc);
if (!calleeTypes)
return NULL;

View File

@ -1629,7 +1629,7 @@ GenerateScopeChainGuard(MacroAssembler &masm, JSObject *scopeObj,
CallObject *callObj = &scopeObj->asCall();
if (!callObj->isForEval()) {
RawFunction fun = &callObj->callee();
RawScript script = fun->script();
RawScript script = fun->script().get(nogc);
if (!script->funHasExtensibleScope)
return;
}

View File

@ -929,7 +929,7 @@ InlineFrameIterator::findNextFrame()
si_.nextFrame();
callee_ = funval.toObject().toFunction();
script_ = callee_->script();
script_ = callee_->script().get(nogc);
pc_ = script_->code + si_.pcOffset();
}

View File

@ -72,7 +72,7 @@ ScriptFromCalleeToken(CalleeToken token)
case CalleeToken_Script:
return CalleeTokenToScript(token);
case CalleeToken_Function:
return CalleeTokenToFunction(token)->script();
return CalleeTokenToFunction(token)->script().get(nogc);
}
JS_NOT_REACHED("invalid callee token tag");
return NULL;

View File

@ -7079,9 +7079,9 @@ JS_DescribeScriptedCaller(JSContext *cx, JSScript **script, unsigned *lineno)
return JS_FALSE;
if (script)
*script = i.script();
*script = i.script().get(nogc);
if (lineno)
*lineno = js::PCToLineNumber(i.script(), i.pc());
*lineno = js::PCToLineNumber(i.script().get(nogc), i.pc());
return JS_TRUE;
}

View File

@ -618,7 +618,7 @@ PopulateReportBlame(JSContext *cx, JSErrorReport *report)
return;
report->filename = iter.script()->filename;
report->lineno = PCToLineNumber(iter.script(), iter.pc(), &report->column);
report->lineno = PCToLineNumber(iter.script().get(nogc), iter.pc(), &report->column);
report->originPrincipals = iter.script()->originPrincipals;
}

View File

@ -452,7 +452,7 @@ JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
{
AutoAssertNoGC nogc;
return fun->maybeScript();
return fun->maybeScript().get(nogc);
}
JS_PUBLIC_API(JSNative)
@ -501,7 +501,7 @@ JS_PUBLIC_API(JSScript *)
JS_GetFrameScript(JSContext *cx, JSStackFrame *fpArg)
{
AutoAssertNoGC nogc;
return Valueify(fpArg)->script();
return Valueify(fpArg)->script().get(nogc);
}
JS_PUBLIC_API(jsbytecode *)
@ -546,7 +546,7 @@ JS_SetTopFrameAnnotation(JSContext *cx, void *annotation)
// because we will never EnterIon on a frame with an annotation.
fp->setAnnotation(annotation);
RawScript script = fp->script();
RawScript script = fp->script().get(nogc);
ReleaseAllJITCode(cx->runtime->defaultFreeOp());
@ -1015,7 +1015,7 @@ JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
size_t nbytes = sizeof *fun;
nbytes += JS_GetObjectTotalSize(cx, fun);
if (fun->isInterpreted())
nbytes += JS_GetScriptTotalSize(cx, fun->script());
nbytes += JS_GetScriptTotalSize(cx, fun->script().get(nogc));
if (fun->displayAtom())
nbytes += GetAtomTotalSize(cx, fun->displayAtom());
return nbytes;
@ -1207,8 +1207,8 @@ JS::DescribeStack(JSContext *cx, unsigned maxFrames)
for (ScriptFrameIter i(cx); !i.done(); ++i) {
FrameDescription desc;
desc.script = i.script();
desc.lineno = PCToLineNumber(i.script(), i.pc());
desc.script = i.script().get(nogc);
desc.lineno = PCToLineNumber(i.script().get(nogc), i.pc());
desc.fun = i.maybeCallee();
if (!frames.append(desc))
return NULL;

View File

@ -130,7 +130,7 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu
// be compiled. IonMonkey does not guarantee |f.arguments| can be
// fully recovered, so we try to mitigate observing this behavior by
// detecting its use early.
RawScript script = iter.script();
RawScript script = iter.script().get(nogc);
if (!script->hasIonScript())
ion::ForbidCompilation(cx, script);
#endif
@ -1123,7 +1123,7 @@ fun_isGenerator(JSContext *cx, unsigned argc, Value *vp)
bool result = false;
if (fun->isInterpreted()) {
RawScript script = fun->script();
RawScript script = fun->script().get(nogc);
JS_ASSERT(script->length != 0);
result = script->isGenerator;
}

View File

@ -684,7 +684,7 @@ UseNewTypeForClone(JSFunction *fun)
* instance a singleton type and clone the underlying script.
*/
RawScript script = fun->script();
RawScript script = fun->script().get(nogc);
if (script->length >= 50)
return false;
@ -886,7 +886,7 @@ TypeScript::GetPcScript(JSContext *cx, MutableHandleScript script, jsbytecode **
return;
}
#endif
script.set(cx->fp()->script());
script.set(cx->fp()->script().get(nogc));
*pc = cx->regs().pc;
}

View File

@ -5260,6 +5260,7 @@ js_GetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBo
void
dumpValue(const Value &v)
{
AutoAssertNoGC nogc;
if (v.isNull())
fprintf(stderr, "null");
else if (v.isUndefined())
@ -5279,7 +5280,7 @@ dumpValue(const Value &v)
fputs("<unnamed function", stderr);
}
if (fun->isInterpreted()) {
JSScript *script = fun->script();
JSScript *script = fun->script().get(nogc);
fprintf(stderr, " (%s:%u)",
script->filename ? script->filename : "", script->lineno);
}
@ -5545,9 +5546,9 @@ js_DumpBacktrace(JSContext *cx)
size_t depth = 0;
for (StackIter i(cx); !i.done(); ++i, ++depth) {
if (i.isScript()) {
const char *filename = JS_GetScriptFilename(cx, i.script());
unsigned line = JS_PCToLineNumber(cx, i.script(), i.pc());
RawScript script = i.script();
const char *filename = JS_GetScriptFilename(cx, i.script().get(nogc));
unsigned line = JS_PCToLineNumber(cx, i.script().get(nogc), i.pc());
RawScript script = i.script().get(nogc);
sprinter.printf("#%d %14p %s:%d (%p @ %d)\n",
depth, (i.isIon() ? 0 : i.interpFrame()), filename, line,
script, i.pc() - script->code);

View File

@ -1846,7 +1846,7 @@ JSScript::enclosingScriptsCompiledSuccessfully() const
while (enclosing) {
if (enclosing->isFunction()) {
RawFunction fun = enclosing->toFunction();
if (!fun->script())
if (!fun->script().get(nogc))
return false;
enclosing = fun->script()->enclosingScope_;
} else {
@ -2114,7 +2114,7 @@ unsigned
CurrentLine(JSContext *cx)
{
AutoAssertNoGC nogc;
return PCToLineNumber(cx->fp()->script(), cx->regs().pc);
return PCToLineNumber(cx->fp()->script().get(nogc), cx->regs().pc);
}
void
@ -2131,9 +2131,9 @@ CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *line
return;
}
RawScript script = iter.script();
RawScript script = iter.script().get(nogc);
*file = script->filename;
*linenop = PCToLineNumber(iter.script(), iter.pc());
*linenop = PCToLineNumber(iter.script().get(nogc), iter.pc());
*origin = script->originPrincipals;
}

View File

@ -48,7 +48,7 @@ CurrentScriptFileLineOrigin(JSContext *cx, const char **file, unsigned *linenop,
AutoAssertNoGC nogc;
JS_ASSERT(JSOp(*cx->regs().pc) == JSOP_EVAL);
JS_ASSERT(*(cx->regs().pc + JSOP_EVAL_LENGTH) == JSOP_LINENO);
RawScript script = cx->fp()->script();
RawScript script = cx->fp()->script().get(nogc);
*file = script->filename;
*linenop = GET_UINT16(cx->regs().pc + JSOP_EVAL_LENGTH);
*origin = script->originPrincipals;

View File

@ -2369,7 +2369,7 @@ LambdaIsGetElem(JSObject &lambda)
if (!fun->isInterpreted())
return NULL;
RawScript script = fun->script();
RawScript script = fun->script().get(nogc);
jsbytecode *pc = script->code;
/*

View File

@ -88,7 +88,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
/* Cancel any pending entries for which processing hasn't started. */
for (size_t i = 0; i < state.ionWorklist.length(); i++) {
ion::IonBuilder *builder = state.ionWorklist[i];
if (CompiledScriptMatches(compartment, script, builder->script())) {
if (CompiledScriptMatches(compartment, script, builder->script().unsafeGet())) {
FinishOffThreadIonCompile(builder);
state.ionWorklist[i--] = state.ionWorklist.back();
state.ionWorklist.popBack();
@ -99,7 +99,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
for (size_t i = 0; i < state.numThreads; i++) {
const WorkerThread &helper = state.threads[i];
while (helper.ionBuilder &&
CompiledScriptMatches(compartment, script, helper.ionBuilder->script()))
CompiledScriptMatches(compartment, script, helper.ionBuilder->script().unsafeGet()))
{
helper.ionBuilder->cancel();
state.wait(WorkerThreadState::MAIN);
@ -111,7 +111,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
/* Cancel code generation for any completed entries. */
for (size_t i = 0; i < compilations.length(); i++) {
ion::IonBuilder *builder = compilations[i];
if (CompiledScriptMatches(compartment, script, builder->script())) {
if (CompiledScriptMatches(compartment, script, builder->script().unsafeGet())) {
ion::FinishOffThreadBuilder(builder);
compilations[i--] = compilations.back();
compilations.popBack();

View File

@ -146,7 +146,7 @@ class Assembler : public ValueAssembler
AutoAssertNoGC nogc;
startLabel = label();
if (vmframe)
sps->setPushed(vmframe->script());
sps->setPushed(vmframe->script().get(nogc));
}
Assembler(MJITInstrumentation *sps, jsbytecode **pc)

View File

@ -138,7 +138,7 @@ class LinkerHelper : public JSC::LinkBuffer
AutoAssertNoGC nogc;
masm.finalize(*this);
JSC::CodeLocationLabel label = finalizeCodeAddendum();
Probes::registerICCode(f.cx, f.chunk(), f.script(), f.pc(),
Probes::registerICCode(f.cx, f.chunk(), f.script().get(nogc), f.pc(),
label.executableAddress(), masm.size());
return label;
}

View File

@ -685,14 +685,14 @@ void JS_FASTCALL
stubs::ScriptProbeOnlyPrologue(VMFrame &f)
{
AutoAssertNoGC nogc;
Probes::enterScript(f.cx, f.script(), f.script()->function(), f.fp());
Probes::enterScript(f.cx, f.script().get(nogc), f.script()->function(), f.fp());
}
void JS_FASTCALL
stubs::ScriptProbeOnlyEpilogue(VMFrame &f)
{
AutoAssertNoGC nogc;
Probes::exitScript(f.cx, f.script(), f.script()->function(), f.fp());
Probes::exitScript(f.cx, f.script().get(nogc), f.script()->function(), f.fp());
}
void JS_FASTCALL

View File

@ -884,7 +884,7 @@ class CallCompiler : public BaseCompiler
masm.storePtr(ImmPtr((void *) ic.frameSize.rejoinState(f.pc(), false)),
FrameAddress(offsetof(VMFrame, stubRejoin)));
masm.bumpStubCount(f.script(), f.pc(), Registers::tempCallReg());
masm.bumpStubCount(f.script().get(nogc), f.pc(), Registers::tempCallReg());
/* Try and compile. On success we get back the nmap pointer. */
void *compilePtr = JS_FUNC_TO_DATA_PTR(void *, stubs::CompileFunction);
@ -1001,7 +1001,7 @@ class CallCompiler : public BaseCompiler
/* Guard that it's the same script. */
Address scriptAddr(ic.funObjReg, JSFunction::offsetOfNativeOrScript());
Jump funGuard = masm.branchPtr(Assembler::NotEqual, scriptAddr,
ImmPtr(obj->toFunction()->script()));
ImmPtr(obj->toFunction()->script().get(nogc)));
Jump done = masm.jump();
LinkerHelper linker(masm, JSC::JAEGER_CODE);
@ -1261,7 +1261,7 @@ class CallCompiler : public BaseCompiler
AutoAssertNoGC nogc;
JS_ASSERT(fun);
JSScript *script = fun->script();
JSScript *script = fun->script().get(nogc);
JS_ASSERT(script);
uint32_t flags = callingNew ? StackFrame::CONSTRUCTING : 0;
@ -1432,7 +1432,7 @@ ic::GenerateArgumentCheckStub(VMFrame &f)
JITScript *jit = f.jit();
StackFrame *fp = f.fp();
JSFunction *fun = fp->fun();
JSScript *script = fun->script();
JSScript *script = fun->script().get(nogc);
if (jit->argsCheckPool)
jit->resetArgsCheck();

View File

@ -1080,7 +1080,7 @@ class GetPropCompiler : public PICStubCompiler
}
RegisterID t0 = tempRegs.takeAnyReg().reg();
masm.bumpStubCount(f.script(), f.pc(), t0);
masm.bumpStubCount(f.script().get(nogc), f.pc(), t0);
/*
* Use three values above sp on the stack for use by the call to store
@ -1194,7 +1194,7 @@ class GetPropCompiler : public PICStubCompiler
}
RegisterID t0 = tempRegs.takeAnyReg().reg();
masm.bumpStubCount(f.script(), f.pc(), t0);
masm.bumpStubCount(f.script().get(nogc), f.pc(), t0);
/*
* A JSNative has the following signature:

View File

@ -348,7 +348,7 @@ ClearAllFrames(JSCompartment *compartment)
if (f->entryfp->compartment() != compartment)
continue;
Recompiler::patchFrame(compartment, f, f->fp()->script());
Recompiler::patchFrame(compartment, f, f->fp()->script().get(nogc));
// Clear ncode values from all frames associated with the VMFrame.
// Patching the VMFrame's return address will cause all its frames to

View File

@ -837,7 +837,7 @@ stubs::RecompileForInline(VMFrame &f)
{
AutoAssertNoGC nogc;
ExpandInlineFrames(f.cx->compartment);
Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), f.script());
Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), f.script().get(nogc));
f.jit()->destroyChunk(f.cx->runtime->defaultFreeOp(), f.chunkIndex(), /* resetUses = */ false);
}
@ -1305,7 +1305,7 @@ stubs::LookupSwitch(VMFrame &f, jsbytecode *pc)
{
AutoAssertNoGC nogc;
jsbytecode *jpc = pc;
JSScript *script = f.fp()->script();
JSScript *script = f.fp()->script().get(nogc);
/* This is correct because the compiler adjusts the stack beforehand. */
Value lval = f.regs.sp[-1];
@ -1631,7 +1631,7 @@ stubs::AssertArgumentTypes(VMFrame &f)
AutoAssertNoGC nogc;
StackFrame *fp = f.fp();
JSFunction *fun = fp->fun();
RawScript script = fun->script();
RawScript script = fun->script().get(nogc);
/*
* Don't check the type of 'this' for constructor frames, the 'this' value
@ -1676,7 +1676,7 @@ stubs::InvariantFailure(VMFrame &f, void *rval)
*frameAddr = repatchCode;
/* Recompile the outermost script, and don't hoist any bounds checks. */
RawScript script = f.fp()->script();
RawScript script = f.fp()->script().get(nogc);
JS_ASSERT(!script->failedBoundsCheck);
script->failedBoundsCheck = true;

View File

@ -74,7 +74,7 @@ ArgumentsObject::element(uint32_t i) const
const Value &v = data()->args[i];
if (v.isMagic(JS_FORWARD_TO_CALL_OBJECT)) {
CallObject &callobj = getFixedSlot(MAYBE_CALL_SLOT).toObject().asCall();
for (AliasedFormalIter fi(callobj.callee().script()); ; fi++) {
for (AliasedFormalIter fi(callobj.callee().script().get(nogc)); ; fi++) {
if (fi.frameIndex() == i)
return callobj.aliasedVar(fi);
}
@ -90,7 +90,7 @@ ArgumentsObject::setElement(uint32_t i, const Value &v)
HeapValue &lhs = data()->args[i];
if (lhs.isMagic(JS_FORWARD_TO_CALL_OBJECT)) {
CallObject &callobj = getFixedSlot(MAYBE_CALL_SLOT).toObject().asCall();
for (AliasedFormalIter fi(callobj.callee().script()); ; fi++) {
for (AliasedFormalIter fi(callobj.callee().script().get(nogc)); ; fi++) {
if (fi.frameIndex() == i) {
callobj.setAliasedVar(fi, v);
return;

View File

@ -49,7 +49,7 @@ CopyStackFrameArguments(const StackFrame *fp, HeapValue *dst)
ArgumentsObject::MaybeForwardToCallObject(StackFrame *fp, JSObject *obj, ArgumentsData *data)
{
AutoAssertNoGC nogc;
RawScript script = fp->script();
RawScript script = fp->script().get(nogc);
if (fp->fun()->isHeavyweight() && script->argsObjAliasesFormals()) {
obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(fp->callObj()));
for (AliasedFormalIter fi(script); fi; fi++)

View File

@ -1195,7 +1195,7 @@ Debugger::onSingleStep(JSContext *cx, Value *vp)
{
AutoAssertNoGC nogc;
uint32_t stepperCount = 0;
JSScript *trappingScript = fp->script();
JSScript *trappingScript = fp->script().get(nogc);
GlobalObject *global = &fp->global();
if (GlobalObject::DebuggerVector *debuggers = global->getDebuggers()) {
for (Debugger **p = debuggers->begin(); p != debuggers->end(); p++) {
@ -3462,7 +3462,7 @@ DebuggerFrame_getOffset(JSContext *cx, unsigned argc, Value *vp)
{
THIS_FRAME(cx, argc, vp, "get offset", args, thisobj, fp);
AutoAssertNoGC nogc;
RawScript script = fp->script();
RawScript script = fp->script().get(nogc);
jsbytecode *pc = fp->pcQuadratic(cx);
JS_ASSERT(script->code <= pc);
JS_ASSERT(pc < script->code + script->length);

View File

@ -359,12 +359,13 @@ void
SPSProfiler::discardMJITCode(mjit::JITScript *jscr,
mjit::JITChunk *chunk, void* address)
{
AutoAssertNoGC nogc;
if (!jminfo.initialized())
return;
unregisterScript(jscr->script, chunk);
for (unsigned i = 0; i < chunk->nInlineFrames; i++)
unregisterScript(chunk->inlineFrames()[i].fun->script(), chunk);
unregisterScript(chunk->inlineFrames()[i].fun->script().get(nogc), chunk);
}
void

View File

@ -86,7 +86,7 @@ StaticScopeIter::funScript() const
{
AutoAssertNoGC nogc;
JS_ASSERT(type() == FUNCTION);
return obj->toFunction()->script();
return obj->toFunction()->script().get(nogc);
}
/*****************************************************************************/
@ -1208,7 +1208,7 @@ class DebugScopeProxy : public BaseProxyHandler
return false;
if (maybefp) {
RawScript script = maybefp->script();
RawScript script = maybefp->script().get(nogc);
unsigned local = block.slotToLocalIndex(script->bindings, shape->slot());
if (action == GET)
*vp = maybefp->unaliasedLocal(local);

View File

@ -138,7 +138,7 @@ StackFrame::initCallFrame(JSContext *cx, JSFunction &callee,
LOWERED_CALL_APPLY |
OVERFLOW_ARGS |
UNDERFLOW_ARGS)) == 0);
JS_ASSERT(script == callee.script());
JS_ASSERT(callee.script() == script);
/* Initialize stack frame members. */
flags_ = FUNCTION | HAS_PREVPC | HAS_SCOPECHAIN | HAS_BLOCKCHAIN | flagsArg;
@ -563,7 +563,7 @@ ContextStack::currentScript(jsbytecode **ppc,
mjit::JITChunk *chunk = fp->jit()->chunk(regs.pc);
JS_ASSERT(inlined->inlineIndex < chunk->nInlineFrames);
mjit::InlineFrame *frame = &chunk->inlineFrames()[inlined->inlineIndex];
RawScript script = frame->fun->script();
RawScript script = frame->fun->script().get(nogc);
if (!allowCrossCompartment && script->compartment() != cx_->compartment)
return NULL;
if (ppc)
@ -572,7 +572,7 @@ ContextStack::currentScript(jsbytecode **ppc,
}
#endif
RawScript script = fp->script();
RawScript script = fp->script().get(nogc);
if (!allowCrossCompartment && script->compartment() != cx_->compartment)
return NULL;

View File

@ -1197,7 +1197,7 @@ class FrameRegs
void setToEndOfScript() {
AutoAssertNoGC nogc;
RawScript script = fp()->script();
RawScript script = fp()->script().get(nogc);
sp = fp()->base();
pc = script->code + script->length - JSOP_STOP_LENGTH;
JS_ASSERT(*pc == JSOP_STOP);