Bug 1191177 - Kill staticLevel. (r=efaust)

This commit is contained in:
Shu-yu Guo 2015-08-11 03:01:25 -07:00
Родитель 0d661e6913
Коммит 7ed7ff522b
21 изменённых файлов: 73 добавлений и 199 удалений

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

@ -9815,7 +9815,7 @@ ParseFunction(ModuleCompiler& m, ParseNode** fnOut)
Directives newDirectives = directives;
AsmJSParseContext funpc(&m.parser(), outerpc, fn, funbox, &newDirectives,
outerpc->staticLevel + 1, /* blockScopeDepth = */ 0);
/* blockScopeDepth = */ 0);
if (!funpc.init(m.parser()))
return false;

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

@ -260,11 +260,9 @@ EvalKernel(JSContext* cx, const CallArgs& args, EvalType evalType, AbstractFrame
// Per ES5, indirect eval runs in the global scope. (eval is specified this
// way so that the compiler can make assumptions about what bindings may or
// may not exist in the current frame if it doesn't see 'eval'.)
unsigned staticLevel;
RootedValue thisv(cx);
if (evalType == DIRECT_EVAL) {
MOZ_ASSERT_IF(caller.isInterpreterFrame(), !caller.asInterpreterFrame()->runningInJit());
staticLevel = caller.script()->staticLevel() + 1;
// Direct calls to eval are supposed to see the caller's |this|. If we
// haven't wrapped that yet, do so now, before we make a copy of it for
@ -274,7 +272,6 @@ EvalKernel(JSContext* cx, const CallArgs& args, EvalType evalType, AbstractFrame
thisv = caller.thisValue();
} else {
MOZ_ASSERT(args.callee().global() == *scopeobj);
staticLevel = 0;
// Use the global as 'this', modulo outerization.
JSObject* thisobj = GetThisObject(cx, scopeobj);
@ -340,7 +337,7 @@ EvalKernel(JSContext* cx, const CallArgs& args, EvalType evalType, AbstractFrame
SourceBufferHolder srcBuf(chars, linearStr->length(), ownership);
JSScript* compiled = frontend::CompileScript(cx, &cx->tempLifoAlloc(),
scopeobj, staticScope, callerScript,
options, srcBuf, linearStr, staticLevel);
options, srcBuf, linearStr);
if (!compiled)
return false;
@ -372,8 +369,6 @@ js::DirectEvalStringFromIon(JSContext* cx,
// ES5 15.1.2.1 steps 2-8.
unsigned staticLevel = callerScript->staticLevel() + 1;
RootedLinearString linearStr(cx, str->ensureLinear(cx));
if (!linearStr)
return false;
@ -424,7 +419,7 @@ js::DirectEvalStringFromIon(JSContext* cx,
SourceBufferHolder srcBuf(chars, linearStr->length(), ownership);
JSScript* compiled = frontend::CompileScript(cx, &cx->tempLifoAlloc(),
scopeobj, staticScope, callerScript,
options, srcBuf, linearStr, staticLevel);
options, srcBuf, linearStr);
if (!compiled)
return false;

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

@ -114,39 +114,6 @@ from its prototype:
scope this script runs. The result refers to the global directly, not
via a wrapper or a `WindowProxy` ("outer window", in Firefox).
`staticLevel`
: The number of function bodies enclosing this script's code.
Global code is at level zero; bodies of functions defined at the top
level in global code are at level one; bodies of functions nested within
those are at level two; and so on.
A script for code passed to direct `eval` is at a static level one
greater than that of the script containing the call to `eval`, because
direct eval code runs within the caller's scope. However, a script for
code passed to an indirect `eval` call is at static level zero, since it
is evaluated in the global scope.
Note that a generator's expressions are considered to be part of the
body of a synthetic function, produced by the compiler.
Scripts' static level be useful in deciding where to set breakpoints.
For example, a breakpoint set on line 3 in this code:
```language-js
function f() {
x = function g() { // line 2
// line 3; no code here
...;
}
}
```
should be set in `g`'s script, not in `f`'s, even though neither script
contains code at that line. In such a case, the most deeply nested
script—the one with the highest static level—should receive the
breakpoint.
`strictMode`
: This is `true` if this script's code is ECMAScript strict mode code, and
`false` otherwise.

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

@ -56,8 +56,7 @@ class MOZ_STACK_CLASS BytecodeCompiler
void maybeSetSourceCompressor(SourceCompressionTask* sourceCompressor);
void setSourceArgumentsNotIncluded();
JSScript* compileScript(HandleObject scopeChain, HandleScript evalCaller,
unsigned staticLevel);
JSScript* compileScript(HandleObject scopeChain, HandleScript evalCaller);
bool compileFunctionBody(MutableHandleFunction fun, const AutoNameVector& formals,
GeneratorKind generatorKind);
@ -68,16 +67,14 @@ class MOZ_STACK_CLASS BytecodeCompiler
bool canLazilyParse();
bool createParser();
bool createSourceAndParser();
bool createScript(bool savedCallerFun = false, unsigned staticLevel = 0);
bool createScript(bool savedCallerFun = false);
bool createEmitter(SharedContext* sharedContext, HandleScript evalCaller = nullptr,
bool insideNonGlobalEval = false);
bool isInsideNonGlobalEval();
bool createParseContext(Maybe<ParseContext<FullParseHandler>>& parseContext,
SharedContext& globalsc, unsigned staticLevel = 0,
uint32_t blockScopeDepth = 0);
SharedContext& globalsc, uint32_t blockScopeDepth = 0);
bool saveCallerFun(HandleScript evalCaller, ParseContext<FullParseHandler>& parseContext);
bool handleStatementParseFailure(HandleObject scopeChain, HandleScript evalCaller,
unsigned staticLevel,
Maybe<ParseContext<FullParseHandler>>& parseContext,
SharedContext& globalsc);
bool handleParseFailure(const Directives& newDirectives);
@ -255,12 +252,10 @@ BytecodeCompiler::createSourceAndParser()
}
bool
BytecodeCompiler::createScript(bool savedCallerFun, unsigned staticLevel)
BytecodeCompiler::createScript(bool savedCallerFun)
{
script = JSScript::Create(cx, enclosingStaticScope, savedCallerFun,
options, staticLevel,
sourceObject, /* sourceStart = */ 0,
sourceBuffer.length());
script = JSScript::Create(cx, enclosingStaticScope, savedCallerFun, options,
sourceObject, /* sourceStart = */ 0, sourceBuffer.length());
return script != nullptr;
}
@ -285,11 +280,10 @@ bool BytecodeCompiler::isInsideNonGlobalEval()
bool
BytecodeCompiler::createParseContext(Maybe<ParseContext<FullParseHandler>>& parseContext,
SharedContext& globalsc, unsigned staticLevel,
uint32_t blockScopeDepth)
SharedContext& globalsc, uint32_t blockScopeDepth)
{
parseContext.emplace(parser.ptr(), (GenericParseContext*) nullptr, (ParseNode*) nullptr,
&globalsc, (Directives*) nullptr, staticLevel, blockScopeDepth);
&globalsc, (Directives*) nullptr, blockScopeDepth);
return parseContext->init(*parser);
}
@ -318,7 +312,6 @@ BytecodeCompiler::saveCallerFun(HandleScript evalCaller,
bool
BytecodeCompiler::handleStatementParseFailure(HandleObject scopeChain, HandleScript evalCaller,
unsigned staticLevel,
Maybe<ParseContext<FullParseHandler>>& parseContext,
SharedContext& globalsc)
{
@ -340,7 +333,7 @@ BytecodeCompiler::handleStatementParseFailure(HandleObject scopeChain, HandleScr
return false;
parseContext.reset();
if (!createParseContext(parseContext, globalsc, staticLevel, script->bindings.numBlockScoped()))
if (!createParseContext(parseContext, globalsc, script->bindings.numBlockScoped()))
return false;
MOZ_ASSERT(parser->pc == parseContext.ptr());
@ -563,14 +556,13 @@ BytecodeCompiler::maybeCompleteCompressSource()
}
JSScript*
BytecodeCompiler::compileScript(HandleObject scopeChain, HandleScript evalCaller,
unsigned staticLevel)
BytecodeCompiler::compileScript(HandleObject scopeChain, HandleScript evalCaller)
{
if (!createSourceAndParser())
return nullptr;
bool savedCallerFun = evalCaller && evalCaller->functionOrCallerFunction();
if (!createScript(savedCallerFun, staticLevel))
if (!createScript(savedCallerFun))
return nullptr;
GlobalSharedContext globalsc(cx, enclosingStaticScope, directives, options.extraWarningsOption);
@ -581,7 +573,7 @@ BytecodeCompiler::compileScript(HandleObject scopeChain, HandleScript evalCaller
// statements in the script. Use Maybe<> so that the parse context can be
// reset when this occurs.
Maybe<ParseContext<FullParseHandler>> pc;
if (!createParseContext(pc, globalsc, staticLevel))
if (!createParseContext(pc, globalsc))
return nullptr;
if (savedCallerFun && !saveCallerFun(evalCaller, pc.ref()))
@ -599,7 +591,7 @@ BytecodeCompiler::compileScript(HandleObject scopeChain, HandleScript evalCaller
ParseNode* pn = parser->statement(YieldIsName, canHaveDirectives);
if (!pn) {
if (!handleStatementParseFailure(scopeChain, evalCaller, staticLevel, pc, globalsc))
if (!handleStatementParseFailure(scopeChain, evalCaller, pc, globalsc))
return nullptr;
pn = parser->statement(YieldIsName);
@ -747,7 +739,6 @@ frontend::CompileScript(ExclusiveContext* cx, LifoAlloc* alloc, HandleObject sco
const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf,
JSString* source_ /* = nullptr */,
unsigned staticLevel /* = 0 */,
SourceCompressionTask* extraSct /* = nullptr */)
{
MOZ_ASSERT(srcBuf.get());
@ -759,13 +750,11 @@ frontend::CompileScript(ExclusiveContext* cx, LifoAlloc* alloc, HandleObject sco
MOZ_ASSERT_IF(evalCaller, options.isRunOnce);
MOZ_ASSERT_IF(evalCaller, options.forEval);
MOZ_ASSERT_IF(evalCaller && evalCaller->strict(), options.strictOption);
MOZ_ASSERT_IF(staticLevel != 0, evalCaller);
MOZ_ASSERT_IF(staticLevel != 0, !options.sourceIsLazy);
BytecodeCompiler compiler(cx, alloc, options, srcBuf, enclosingStaticScope,
TraceLogger_ParserCompileScript);
compiler.maybeSetSourceCompressor(extraSct);
return compiler.compileScript(scopeChain, evalCaller, staticLevel);
return compiler.compileScript(scopeChain, evalCaller);
}
bool
@ -787,12 +776,9 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
if (!parser.checkOptions())
return false;
uint32_t staticLevel = lazy->staticLevel(cx);
Rooted<JSFunction*> fun(cx, lazy->functionNonDelazifying());
MOZ_ASSERT(!lazy->isLegacyGenerator());
ParseNode* pn = parser.standaloneLazyFunction(fun, staticLevel, lazy->strict(),
lazy->generatorKind());
ParseNode* pn = parser.standaloneLazyFunction(fun, lazy->strict(), lazy->generatorKind());
if (!pn)
return false;
@ -803,8 +789,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
RootedScriptSource sourceObject(cx, lazy->sourceObject());
MOZ_ASSERT(sourceObject);
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false,
options, staticLevel,
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options,
sourceObject, lazy->begin(), lazy->end()));
if (!script)
return false;

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

@ -27,7 +27,7 @@ CompileScript(ExclusiveContext* cx, LifoAlloc* alloc,
HandleObject scopeChain, Handle<ScopeObject*> enclosingStaticScope,
HandleScript evalCaller, const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf, JSString* source_ = nullptr,
unsigned staticLevel = 0, SourceCompressionTask* extraSct = nullptr);
SourceCompressionTask* extraSct = nullptr);
bool
CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const char16_t* chars, size_t length);

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

@ -5759,7 +5759,6 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
Rooted<JSObject*> enclosingScope(cx, innermostStaticScope());
Rooted<JSObject*> sourceObject(cx, script->sourceObject());
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options,
parent->staticLevel() + 1,
sourceObject,
funbox->bufStart, funbox->bufEnd));
if (!script)

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

@ -735,7 +735,7 @@ Parser<ParseHandler>::parse()
options().extraWarningsOption);
ParseContext<ParseHandler> globalpc(this, /* parent = */ nullptr, ParseHandler::null(),
&globalsc, /* newDirectives = */ nullptr,
/* staticLevel = */ 0, /* blockScopeDepth = */ 0);
/* blockScopeDepth = */ 0);
if (!globalpc.init(*this))
return null();
@ -824,7 +824,7 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun, const AutoN
handler.setFunctionBox(fn, funbox);
ParseContext<FullParseHandler> funpc(this, pc, fn, funbox, newDirectives,
/* staticLevel = */ 0, /* blockScopeDepth = */ 0);
/* blockScopeDepth = */ 0);
if (!funpc.init(*this))
return null();
@ -2445,7 +2445,7 @@ Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode*
return false;
ParseContext<SyntaxParseHandler> funpc(parser, outerpc, SyntaxParseHandler::null(),
funbox, newDirectives, outerpc->staticLevel + 1,
funbox, newDirectives,
/* blockScopeDepth = */ 0);
if (!funpc.init(*parser))
return false;
@ -2483,8 +2483,7 @@ Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode*
blockScopes.resize(oldBlockScopesLength);
// Continue doing a full parse for this inner function.
ParseContext<FullParseHandler> funpc(this, pc, pn, funbox,
newDirectives, outerpc->staticLevel + 1,
ParseContext<FullParseHandler> funpc(this, pc, pn, funbox, newDirectives,
/* blockScopeDepth = */ 0);
if (!funpc.init(*this))
return false;
@ -2523,8 +2522,7 @@ Parser<SyntaxParseHandler>::functionArgsAndBody(InHandling inHandling, Node pn,
return false;
// Initialize early for possible flags mutation via destructuringExpr.
ParseContext<SyntaxParseHandler> funpc(this, pc, handler.null(), funbox,
newDirectives, outerpc->staticLevel + 1,
ParseContext<SyntaxParseHandler> funpc(this, pc, handler.null(), funbox, newDirectives,
/* blockScopeDepth = */ 0);
if (!funpc.init(*this))
return false;
@ -2563,8 +2561,8 @@ Parser<ParseHandler>::appendToCallSiteObj(Node callSiteObj)
template <>
ParseNode*
Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, unsigned staticLevel,
bool strict, GeneratorKind generatorKind)
Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict,
GeneratorKind generatorKind)
{
MOZ_ASSERT(checkOptionsCalled);
@ -2589,7 +2587,7 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, unsigned st
Directives newDirectives = directives;
ParseContext<FullParseHandler> funpc(this, /* parent = */ nullptr, pn, funbox,
&newDirectives, staticLevel, /* blockScopeDepth = */ 0);
&newDirectives, /* blockScopeDepth = */ 0);
if (!funpc.init(*this))
return null();
@ -7537,7 +7535,6 @@ Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKi
ParseContext<ParseHandler> genpc(this, outerpc, genfn, genFunbox,
/* newDirectives = */ nullptr,
outerpc->staticLevel + 1,
/* blockScopeDepth = */ 0);
if (!genpc.init(*this))
return null();

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

@ -106,8 +106,6 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
Node maybeFunction; /* sc->isFunctionBox, the pn where pn->pn_funbox == sc */
const unsigned staticLevel; /* static compilation unit nesting level */
// lastYieldOffset stores the offset of the last yield that was parsed.
// NoYieldOffset is its initial value.
static const uint32_t NoYieldOffset = UINT32_MAX;
@ -251,12 +249,11 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
ParseContext(Parser<ParseHandler>* prs, GenericParseContext* parent,
Node maybeFunction, SharedContext* sc, Directives* newDirectives,
unsigned staticLevel, uint32_t blockScopeDepth)
uint32_t blockScopeDepth)
: GenericParseContext(parent, sc),
bodyid(0), // initialized in init()
stmtStack(prs->context),
maybeFunction(maybeFunction),
staticLevel(staticLevel),
lastYieldOffset(NoYieldOffset),
blockScopeDepth(blockScopeDepth),
blockNode(ParseHandler::null()),
@ -302,7 +299,7 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
// True if this is the ParseContext for the body of a function created by
// the Function constructor.
bool isFunctionConstructorBody() const {
return sc->isFunctionBox() && staticLevel == 0;
return sc->isFunctionBox() && !parent && sc->asFunctionBox()->function()->isLambda();
}
inline bool useAsmOrInsideUseAsm() const {
@ -554,8 +551,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
// Parse a function, given only its arguments and body. Used for lazily
// parsed functions.
Node standaloneLazyFunction(HandleFunction fun, unsigned staticLevel, bool strict,
GeneratorKind generatorKind);
Node standaloneLazyFunction(HandleFunction fun, bool strict, GeneratorKind generatorKind);
/*
* Parse a function body. Pass StatementListBody if the body is a list of

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

@ -1,43 +0,0 @@
// Debugger.Script.prototype.staticLevel returns the script's static level.
load(libdir + 'asserts.js');
var g = newGlobal();
var dbg = Debugger();
var gw = dbg.addDebuggee(g);
function test(expr, level) {
var log;
dbg.onDebuggerStatement = function (frame) {
log += 'd';
assertEq(frame.script.staticLevel, level);
};
print("Testing: " + expr);
log = '';
// The shell's 'evaluate' runs its argument as global code.
g.evaluate(expr);
assertEq(log, 'd');
}
test("debugger;", 0);
test("(function () { debugger; })()", 1);
test("(function () { (function () { debugger; })(); })()", 2);
test("(function () { (function () { (function () { debugger; })(); })(); })()", 3);
test("eval('debugger;');", 1);
test("eval('eval(\\\'debugger;\\\');');", 2);
test("evil = eval; eval('evil(\\\'debugger;\\\');');", 0); // I don't think it's evil at all!
test("(function () { eval('debugger;'); })();", 2);
test("evil = eval; (function () { evil('debugger;'); })();", 0);
// Generators' expressions are within a synthesized function's body.
test("((function () { debugger; })() for (x in [1])).next();", 2);
test("(x for (x in ((function () { debugger; })(), [1]))).next();", 2);
// The staticLevel accessor can't be assigned to.
g.eval('function f() {}');
var fw = gw.makeDebuggeeValue(g.f);
assertThrowsInstanceOf(function () { "use strict"; fw.script.staticLevel = 10; },
TypeError);

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

@ -5,7 +5,6 @@ var fscript = null;
dbg.onNewScript = function(script) {
dbg.onNewScript = undefined;
fscript = script.getChildScripts()[0];
assertEq(fscript.staticLevel, 1);
}
g.eval("function f(x) { arguments[0] = 3; return x }");

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

@ -86,6 +86,13 @@ BaselineFrame::trace(JSTracer* trc, JitFrameIterator& frameIterator)
}
}
bool
BaselineFrame::isDirectEvalFrame() const
{
return isEvalFrame() &&
script()->enclosingStaticScope()->as<StaticEvalObject>().isDirect();
}
bool
BaselineFrame::copyRawFrameSlots(AutoValueVector* vec) const
{

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

@ -408,9 +408,7 @@ class BaselineFrame
bool isNonStrictEvalFrame() const {
return isEvalFrame() && !script()->strict();
}
bool isDirectEvalFrame() const {
return isEvalFrame() && script()->staticLevel() > 0;
}
bool isDirectEvalFrame() const;
bool isNonStrictDirectEvalFrame() const {
return isNonStrictEvalFrame() && isDirectEvalFrame();
}

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

@ -4451,7 +4451,7 @@ Evaluate(JSContext* cx, HandleObject scope, Handle<ScopeObject*> staticScope,
RootedScript script(cx, frontend::CompileScript(cx, &cx->tempLifoAlloc(),
scope, staticScope,
/* evalCaller = */ nullptr, options,
srcBuf, /* source = */ nullptr, 0, &sct));
srcBuf, /* source = */ nullptr, &sct));
if (!script)
return false;

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

@ -772,7 +772,6 @@ CreateFunctionPrototype(JSContext* cx, JSProtoKey key)
/* enclosingScope = */ nullptr,
/* savedCallerFun = */ false,
options,
/* staticLevel = */ 0,
sourceObject,
0,
ss->length()));

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

@ -599,7 +599,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
HasNonSyntacticScope,
};
uint32_t length, lineno, column, nslots, staticLevel;
uint32_t length, lineno, column, nslots;
uint32_t natoms, nsrcnotes, i;
uint32_t nconsts, nobjects, nregexps, ntrynotes, nblockscopes, nyieldoffsets;
uint32_t prologueLength, version;
@ -672,7 +672,6 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
lineno = script->lineno();
column = script->column();
nslots = script->nslots();
staticLevel = script->staticLevel();
natoms = script->natoms();
nsrcnotes = script->numNotes();
@ -766,7 +765,6 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
JSVersion version_ = JSVersion(version);
MOZ_ASSERT((version_ & VersionFlags::MASK) == unsigned(version_));
// staticLevel is set below.
CompileOptions options(cx);
options.setVersion(version_)
.setNoScriptRval(!!(scriptBits & (1 << NoScriptRval)))
@ -808,7 +806,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
}
script = JSScript::Create(cx, enclosingScope, !!(scriptBits & (1 << SavedCallerFun)),
options, /* staticLevel = */ 0, sourceObject, 0, 0);
options, sourceObject, 0, 0);
if (!script)
return false;
@ -886,8 +884,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
if (!xdr->codeUint32(&lineno) ||
!xdr->codeUint32(&column) ||
!xdr->codeUint32(&nslots) ||
!xdr->codeUint32(&staticLevel))
!xdr->codeUint32(&nslots))
{
return false;
}
@ -896,7 +893,6 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
script->lineno_ = lineno;
script->column_ = column;
script->nslots_ = nslots;
script->staticLevel_ = staticLevel;
}
jsbytecode* code = script->code();
@ -2438,8 +2434,8 @@ JSScript::initCompartment(ExclusiveContext* cx)
/* static */ JSScript*
JSScript::Create(ExclusiveContext* cx, HandleObject enclosingScope, bool savedCallerFun,
const ReadOnlyCompileOptions& options, unsigned staticLevel,
HandleObject sourceObject, uint32_t bufStart, uint32_t bufEnd)
const ReadOnlyCompileOptions& options, HandleObject sourceObject,
uint32_t bufStart, uint32_t bufEnd)
{
MOZ_ASSERT(bufStart <= bufEnd);
@ -2467,19 +2463,6 @@ JSScript::Create(ExclusiveContext* cx, HandleObject enclosingScope, bool savedCa
script->version = options.version;
MOZ_ASSERT(script->getVersion() == options.version); // assert that no overflow occurred
// This is an unsigned-to-uint16_t conversion, test for too-high values.
// In practice, recursion in Parser and/or BytecodeEmitter will blow the
// stack if we nest functions more than a few hundred deep, so this will
// never trigger. Oh well.
if (staticLevel > UINT16_MAX) {
if (cx->isJSContext()) {
JS_ReportErrorNumber(cx->asJSContext(),
GetErrorMessage, nullptr, JSMSG_TOO_DEEP, js_function_str);
}
return nullptr;
}
script->staticLevel_ = uint16_t(staticLevel);
script->setSourceObject(sourceObject);
script->sourceStart_ = bufStart;
script->sourceEnd_ = bufEnd;
@ -3328,8 +3311,7 @@ CreateEmptyScriptForClone(JSContext* cx, HandleObject enclosingScope, HandleScri
.setVersion(src->getVersion());
return JSScript::Create(cx, enclosingScope, src->savedCallerFun(),
options, src->staticLevel(),
sourceObject, src->sourceStart(), src->sourceEnd());
options, sourceObject, src->sourceStart(), src->sourceEnd());
}
JSScript*
@ -4060,16 +4042,6 @@ LazyScript::hasUncompiledEnclosingScript() const
return !fun.hasScript() || fun.hasUncompiledScript() || !fun.nonLazyScript()->code();
}
uint32_t
LazyScript::staticLevel(JSContext* cx) const
{
for (StaticScopeIter<NoGC> ssi(enclosingScope()); !ssi.done(); ssi++) {
if (ssi.type() == StaticScopeIter<NoGC>::Function)
return ssi.funScript()->staticLevel() + 1;
}
return 1;
}
void
JSScript::updateBaselineOrIonRaw(JSContext* maybecx)
{

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

@ -1016,8 +1016,6 @@ class JSScript : public js::gc::TenuredCell
uint16_t nTypeSets_; /* number of type sets used in this script for
dynamic type monitoring */
uint16_t staticLevel_;/* static level for display maintenance */
// Bit fields.
public:
@ -1161,7 +1159,7 @@ class JSScript : public js::gc::TenuredCell
public:
static JSScript* Create(js::ExclusiveContext* cx,
js::HandleObject enclosingScope, bool savedCallerFun,
const JS::ReadOnlyCompileOptions& options, unsigned staticLevel,
const JS::ReadOnlyCompileOptions& options,
js::HandleObject sourceObject, uint32_t sourceStart,
uint32_t sourceEnd);
@ -1271,10 +1269,6 @@ class JSScript : public js::gc::TenuredCell
return nslots_;
}
size_t staticLevel() const {
return staticLevel_;
}
size_t nTypeSets() const {
return nTypeSets_;
}
@ -1767,7 +1761,7 @@ class JSScript : public js::gc::TenuredCell
return arr->vector[index];
}
// The following 3 functions find the static scope just before the
// The following 4 functions find the static scope just before the
// execution of the instruction pointed to by pc.
js::NestedScopeObject* getStaticBlockScope(jsbytecode* pc);
@ -1780,6 +1774,8 @@ class JSScript : public js::gc::TenuredCell
// if the innermost static scope falls without the extent of the script.
JSObject* innermostStaticScope(jsbytecode* pc);
JSObject* innermostStaticScope() { return innermostStaticScope(main()); }
/*
* The isEmpty method tells whether this script has code that computes any
* result (not return value, result AKA normal completion value) other than
@ -2276,7 +2272,6 @@ class LazyScript : public gc::TenuredCell
}
bool hasUncompiledEnclosingScript() const;
uint32_t staticLevel(JSContext* cx) const;
friend class GCMarker;
void traceChildren(JSTracer* trc);

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

@ -3869,8 +3869,11 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery
if (p) {
/* Is our newly found script deeper than the last one we found? */
JSScript* incumbent = p->value();
if (script->staticLevel() > incumbent->staticLevel())
if (StaticScopeChainLength(script->innermostStaticScope()) >
StaticScopeChainLength(incumbent->innermostStaticScope()))
{
p->value() = script;
}
} else {
/*
* This is the first matching script we've encountered for this
@ -4701,14 +4704,6 @@ DebuggerScript_getSourceLength(JSContext* cx, unsigned argc, Value* vp)
return true;
}
static bool
DebuggerScript_getStaticLevel(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get staticLevel)", args, obj, script);
args.rval().setNumber(uint32_t(script->staticLevel()));
return true;
}
static bool
DebuggerScript_getGlobal(JSContext* cx, unsigned argc, Value* vp)
{
@ -5492,7 +5487,6 @@ static const JSPropertySpec DebuggerScript_properties[] = {
JS_PSG("source", DebuggerScript_getSource, 0),
JS_PSG("sourceStart", DebuggerScript_getSourceStart, 0),
JS_PSG("sourceLength", DebuggerScript_getSourceLength, 0),
JS_PSG("staticLevel", DebuggerScript_getStaticLevel, 0),
JS_PSG("global", DebuggerScript_getGlobal, 0),
JS_PS_END
};
@ -6405,8 +6399,7 @@ EvaluateInEnv(JSContext* cx, Handle<Env*> env, HandleValue thisv, AbstractFrameP
SourceBufferHolder srcBuf(chars.start().get(), chars.length(), SourceBufferHolder::NoOwnership);
RootedScript script(cx, frontend::CompileScript(cx, &cx->tempLifoAlloc(), env, staticScope,
callerScript, options, srcBuf,
/* source = */ nullptr,
/* staticLevel = */ frame ? 1 : 0));
/* source = */ nullptr));
if (!script)
return false;

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

@ -2570,6 +2570,15 @@ js::HasNonSyntacticStaticScopeChain(JSObject* staticScope)
return false;
}
uint32_t
js::StaticScopeChainLength(JSObject* staticScope)
{
uint32_t length = 0;
for (StaticScopeIter<NoGC> ssi(staticScope); !ssi.done(); ssi++)
length++;
return length;
}
#ifdef DEBUG
void

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

@ -1234,6 +1234,7 @@ CreateScopeObjectsForScopeChain(JSContext* cx, AutoObjectVector& scopeChain,
MutableHandleObject dynamicScopeObj);
bool HasNonSyntacticStaticScopeChain(JSObject* staticScope);
uint32_t StaticScopeChainLength(JSObject* staticScope);
#ifdef DEBUG
void DumpStaticScopeChain(JSScript* script);

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

@ -107,6 +107,13 @@ InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractF
#endif
}
bool
InterpreterFrame::isDirectEvalFrame() const
{
return isEvalFrame() &&
script()->enclosingStaticScope()->as<StaticEvalObject>().isDirect();
}
bool
InterpreterFrame::copyRawFrameSlots(AutoValueVector* vec)
{

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

@ -508,9 +508,7 @@ class InterpreterFrame
return isEvalFrame() && !script()->strict();
}
bool isDirectEvalFrame() const {
return isEvalFrame() && script()->staticLevel() > 0;
}
bool isDirectEvalFrame() const;
bool isNonStrictDirectEvalFrame() const {
return isNonStrictEvalFrame() && isDirectEvalFrame();