mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 885522 - Move function heavyweight info to JSScript, r=luke.
This commit is contained in:
parent
f80974aecb
commit
9beb9a61fc
@ -853,10 +853,10 @@ EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce)
|
||||
*/
|
||||
for (unsigned i = pn->pn_cookie.level(); i; i--) {
|
||||
skippedScopes += ClonedBlockDepth(bceOfDef);
|
||||
JSFunction *funOfDef = bceOfDef->sc->asFunctionBox()->function();
|
||||
if (funOfDef->isHeavyweight()) {
|
||||
FunctionBox *funbox = bceOfDef->sc->asFunctionBox();
|
||||
if (funbox->isHeavyweight()) {
|
||||
skippedScopes++;
|
||||
if (funOfDef->isNamedLambda())
|
||||
if (funbox->function()->isNamedLambda())
|
||||
skippedScopes++;
|
||||
}
|
||||
bceOfDef = bceOfDef->parent;
|
||||
@ -1136,7 +1136,7 @@ TryConvertFreeName(BytecodeEmitter *bce, ParseNode *pn)
|
||||
return false;
|
||||
if (funbox->function()->isNamedLambda() && funbox->function()->atom() == pn->pn_atom)
|
||||
return false;
|
||||
if (funbox->function()->isHeavyweight()) {
|
||||
if (funbox->isHeavyweight()) {
|
||||
hops++;
|
||||
if (funbox->function()->isNamedLambda())
|
||||
hops++;
|
||||
@ -1389,7 +1389,7 @@ BindNameToSlotHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (dn->pn_cookie.level() != bce->script->staticLevel)
|
||||
return true;
|
||||
|
||||
RootedFunction fun(cx, bce->sc->asFunctionBox()->function());
|
||||
DebugOnly<JSFunction *> fun = bce->sc->asFunctionBox()->function();
|
||||
JS_ASSERT(fun->isLambda());
|
||||
JS_ASSERT(pn->pn_atom == fun->atom());
|
||||
|
||||
@ -1417,7 +1417,7 @@ BindNameToSlotHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* heavyweight, ensuring that the function name is represented in
|
||||
* the scope chain so that assignment will throw a TypeError.
|
||||
*/
|
||||
if (!fun->isHeavyweight()) {
|
||||
if (!bce->sc->asFunctionBox()->isHeavyweight()) {
|
||||
op = JSOP_CALLEE;
|
||||
pn->pn_dflags |= PND_CONST;
|
||||
}
|
||||
@ -2624,7 +2624,7 @@ MaybeEmitVarDecl(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *
|
||||
}
|
||||
|
||||
if (JOF_OPTYPE(pn->getOp()) == JOF_ATOM &&
|
||||
(!bce->sc->isFunctionBox() || bce->sc->asFunctionBox()->function()->isHeavyweight()))
|
||||
(!bce->sc->isFunctionBox() || bce->sc->asFunctionBox()->isHeavyweight()))
|
||||
{
|
||||
bce->switchToProlog();
|
||||
if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
|
||||
|
@ -311,17 +311,8 @@ ParseContext<ParseHandler>::generateFunctionBindings(JSContext *cx, InternalHand
|
||||
AppendPackedBindings(this, args_, packedBindings);
|
||||
AppendPackedBindings(this, vars_, packedBindings + args_.length());
|
||||
|
||||
if (!Bindings::initWithTemporaryStorage(cx, bindings, args_.length(), vars_.length(),
|
||||
packedBindings))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FunctionBox *funbox = sc->asFunctionBox();
|
||||
if (bindings->hasAnyAliasedBindings() || funbox->hasExtensibleScope())
|
||||
funbox->function()->setIsHeavyweight();
|
||||
|
||||
return true;
|
||||
return Bindings::initWithTemporaryStorage(cx, bindings, args_.length(), vars_.length(),
|
||||
packedBindings);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
@ -1279,7 +1270,7 @@ ConvertDefinitionToNamedLambdaUse(JSContext *cx, ParseContext<FullParseHandler>
|
||||
* produce an error (in strict mode).
|
||||
*/
|
||||
if (dn->isClosed() || dn->isAssigned())
|
||||
funbox->function()->setIsHeavyweight();
|
||||
funbox->setNeedsDeclEnvObject();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -74,11 +74,11 @@ class FunctionContextFlags
|
||||
friend class FunctionBox;
|
||||
|
||||
// We parsed a yield statement in the function.
|
||||
bool isGenerator:1;
|
||||
bool isGenerator:1;
|
||||
|
||||
// The function or a function that encloses it may define new local names
|
||||
// at runtime through means other than calling eval.
|
||||
bool mightAliasLocals:1;
|
||||
bool mightAliasLocals:1;
|
||||
|
||||
// This function does something that can extend the set of bindings in its
|
||||
// call objects --- it does a direct eval in non-strict code, or includes a
|
||||
@ -87,7 +87,11 @@ class FunctionContextFlags
|
||||
// This flag is *not* inherited by enclosed or enclosing functions; it
|
||||
// applies only to the function in whose flags it appears.
|
||||
//
|
||||
bool hasExtensibleScope:1;
|
||||
bool hasExtensibleScope:1;
|
||||
|
||||
// This function refers directly to its name in a way which requires the
|
||||
// name to be a separate object on the scope chain.
|
||||
bool needsDeclEnvObject:1;
|
||||
|
||||
// Technically, every function has a binding named 'arguments'. Internally,
|
||||
// this binding is only added when 'arguments' is mentioned by the function
|
||||
@ -110,7 +114,7 @@ class FunctionContextFlags
|
||||
// have no special semantics: the initial value is unconditionally the
|
||||
// actual argument (or undefined if nactual < nformal).
|
||||
//
|
||||
bool argumentsHasLocalBinding:1;
|
||||
bool argumentsHasLocalBinding:1;
|
||||
|
||||
// In many cases where 'arguments' has a local binding (as described above)
|
||||
// we do not need to actually create an arguments object in the function
|
||||
@ -121,13 +125,14 @@ class FunctionContextFlags
|
||||
// be unsound in several cases. The frontend filters out such cases by
|
||||
// setting this flag which eagerly sets script->needsArgsObj to true.
|
||||
//
|
||||
bool definitelyNeedsArgsObj:1;
|
||||
bool definitelyNeedsArgsObj:1;
|
||||
|
||||
public:
|
||||
FunctionContextFlags()
|
||||
: isGenerator(false),
|
||||
mightAliasLocals(false),
|
||||
hasExtensibleScope(false),
|
||||
needsDeclEnvObject(false),
|
||||
argumentsHasLocalBinding(false),
|
||||
definitelyNeedsArgsObj(false)
|
||||
{ }
|
||||
@ -226,12 +231,14 @@ class FunctionBox : public ObjectBox, public SharedContext
|
||||
bool isGenerator() const { return funCxFlags.isGenerator; }
|
||||
bool mightAliasLocals() const { return funCxFlags.mightAliasLocals; }
|
||||
bool hasExtensibleScope() const { return funCxFlags.hasExtensibleScope; }
|
||||
bool needsDeclEnvObject() const { return funCxFlags.needsDeclEnvObject; }
|
||||
bool argumentsHasLocalBinding() const { return funCxFlags.argumentsHasLocalBinding; }
|
||||
bool definitelyNeedsArgsObj() const { return funCxFlags.definitelyNeedsArgsObj; }
|
||||
|
||||
void setIsGenerator() { funCxFlags.isGenerator = true; }
|
||||
void setMightAliasLocals() { funCxFlags.mightAliasLocals = true; }
|
||||
void setHasExtensibleScope() { funCxFlags.hasExtensibleScope = true; }
|
||||
void setNeedsDeclEnvObject() { funCxFlags.needsDeclEnvObject = true; }
|
||||
void setArgumentsHasLocalBinding() { funCxFlags.argumentsHasLocalBinding = true; }
|
||||
void setDefinitelyNeedsArgsObj() { JS_ASSERT(funCxFlags.argumentsHasLocalBinding);
|
||||
funCxFlags.definitelyNeedsArgsObj = true; }
|
||||
@ -247,6 +254,14 @@ class FunctionBox : public ObjectBox, public SharedContext
|
||||
startLine = tokenStream.getLineno();
|
||||
startColumn = tokenStream.getColumn();
|
||||
}
|
||||
|
||||
bool isHeavyweight()
|
||||
{
|
||||
// Note: this should be kept in sync with JSFunction::isHeavyweight().
|
||||
return bindings.hasAnyAliasedBindings() ||
|
||||
hasExtensibleScope() ||
|
||||
needsDeclEnvObject();
|
||||
}
|
||||
};
|
||||
|
||||
inline FunctionBox *
|
||||
|
@ -1063,14 +1063,6 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti
|
||||
|
||||
if (JSScript *script = lazy->maybeScript()) {
|
||||
fun->initScript(script);
|
||||
|
||||
/*
|
||||
* Set some bits that are normally filled in by the Parser after
|
||||
* the full parse tree has been produced.
|
||||
*/
|
||||
if (script->function()->isHeavyweight())
|
||||
fun->setIsHeavyweight();
|
||||
fun->nargs = script->function()->nargs;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ class JSFunction : public JSObject
|
||||
INTERPRETED = 0x0001, /* function has a JSScript and environment. */
|
||||
NATIVE_CTOR = 0x0002, /* native that can be called as a constructor */
|
||||
EXTENDED = 0x0004, /* structure is FunctionExtended */
|
||||
HEAVYWEIGHT = 0x0008, /* activation requires a Call object */
|
||||
IS_FUN_PROTO = 0x0010, /* function is Function.prototype for some global object */
|
||||
EXPR_CLOSURE = 0x0020, /* expression closure: function(x) x*x */
|
||||
HAS_GUESSED_ATOM = 0x0040, /* function had no explicit name, but a
|
||||
@ -80,11 +79,8 @@ class JSFunction : public JSObject
|
||||
|
||||
public:
|
||||
|
||||
bool isHeavyweight() {
|
||||
/* The heavyweight flag is not set until the script is parsed. */
|
||||
JS_ASSERT(!isInterpretedLazy());
|
||||
return flags & HEAVYWEIGHT;
|
||||
}
|
||||
/* Call objects must be created for each invocation of a heavyweight function. */
|
||||
inline bool isHeavyweight() const;
|
||||
|
||||
/* A function can be classified as either native (C++) or interpreted (JS): */
|
||||
bool isInterpreted() const { return flags & (INTERPRETED | INTERPRETED_LAZY); }
|
||||
@ -173,10 +169,6 @@ class JSFunction : public JSObject
|
||||
flags |= IS_FUN_PROTO;
|
||||
}
|
||||
|
||||
void setIsHeavyweight() {
|
||||
flags |= HEAVYWEIGHT;
|
||||
}
|
||||
|
||||
// Can be called multiple times by the parser.
|
||||
void setIsExprClosure() {
|
||||
flags |= EXPR_CLOSURE;
|
||||
|
@ -223,6 +223,20 @@ CloneFunctionObjectIfNotSingleton(JSContext *cx, HandleFunction fun, HandleObjec
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
inline bool
|
||||
JSFunction::isHeavyweight() const
|
||||
{
|
||||
JS_ASSERT(!isInterpretedLazy());
|
||||
|
||||
if (isNative())
|
||||
return false;
|
||||
|
||||
// Note: this should be kept in sync with FunctionBox::isHeavyweight().
|
||||
return nonLazyScript()->bindings.hasAnyAliasedBindings() ||
|
||||
nonLazyScript()->funHasExtensibleScope ||
|
||||
nonLazyScript()->funNeedsDeclEnvObject;
|
||||
}
|
||||
|
||||
inline JSScript *
|
||||
JSFunction::existingScript()
|
||||
{
|
||||
@ -238,10 +252,6 @@ JSFunction::existingScript()
|
||||
flags &= ~INTERPRETED_LAZY;
|
||||
flags |= INTERPRETED;
|
||||
initScript(script);
|
||||
|
||||
if (script->function()->isHeavyweight())
|
||||
setIsHeavyweight();
|
||||
nargs = script->function()->nargs;
|
||||
}
|
||||
JS_ASSERT(hasScript());
|
||||
return u.i.s.script_;
|
||||
|
@ -396,6 +396,7 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
Strict,
|
||||
ContainsDynamicNameAccess,
|
||||
FunHasExtensibleScope,
|
||||
FunNeedsDeclEnvObject,
|
||||
FunHasAnyAliasedFormal,
|
||||
ArgumentsHasVarBinding,
|
||||
NeedsArgsObj,
|
||||
@ -477,6 +478,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
scriptBits |= (1 << ContainsDynamicNameAccess);
|
||||
if (script->funHasExtensibleScope)
|
||||
scriptBits |= (1 << FunHasExtensibleScope);
|
||||
if (script->funNeedsDeclEnvObject)
|
||||
scriptBits |= (1 << FunNeedsDeclEnvObject);
|
||||
if (script->funHasAnyAliasedFormal)
|
||||
scriptBits |= (1 << FunHasAnyAliasedFormal);
|
||||
if (script->argumentsHasVarBinding())
|
||||
@ -576,6 +579,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
script->bindingsAccessedDynamically = true;
|
||||
if (scriptBits & (1 << FunHasExtensibleScope))
|
||||
script->funHasExtensibleScope = true;
|
||||
if (scriptBits & (1 << FunNeedsDeclEnvObject))
|
||||
script->funNeedsDeclEnvObject = true;
|
||||
if (scriptBits & (1 << FunHasAnyAliasedFormal))
|
||||
script->funHasAnyAliasedFormal = true;
|
||||
if (scriptBits & (1 << ArgumentsHasVarBinding))
|
||||
@ -1894,6 +1899,7 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
|
||||
script->explicitUseStrict = bce->sc->hasExplicitUseStrict();
|
||||
script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
|
||||
script->funHasExtensibleScope = funbox ? funbox->hasExtensibleScope() : false;
|
||||
script->funNeedsDeclEnvObject = funbox ? funbox->needsDeclEnvObject() : false;
|
||||
script->hasSingletons = bce->hasSingletons;
|
||||
|
||||
if (funbox) {
|
||||
@ -2408,6 +2414,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
|
||||
dst->explicitUseStrict = src->explicitUseStrict;
|
||||
dst->bindingsAccessedDynamically = src->bindingsAccessedDynamically;
|
||||
dst->funHasExtensibleScope = src->funHasExtensibleScope;
|
||||
dst->funNeedsDeclEnvObject = src->funNeedsDeclEnvObject;
|
||||
dst->funHasAnyAliasedFormal = src->funHasAnyAliasedFormal;
|
||||
dst->hasSingletons = src->hasSingletons;
|
||||
dst->isGenerator = src->isGenerator;
|
||||
|
@ -205,7 +205,7 @@ class Bindings
|
||||
bool bindingIsAliased(unsigned bindingIndex);
|
||||
|
||||
/* Return whether this scope has any aliased bindings. */
|
||||
bool hasAnyAliasedBindings() const { return !callObjShape_->isEmptyShape(); }
|
||||
bool hasAnyAliasedBindings() const { return callObjShape_ && !callObjShape_->isEmptyShape(); }
|
||||
|
||||
void trace(JSTracer *trc);
|
||||
};
|
||||
@ -525,8 +525,9 @@ class JSScript : public js::gc::Cell
|
||||
bool explicitUseStrict:1; /* code has "use strict"; explicitly */
|
||||
bool compileAndGo:1; /* see Parser::compileAndGo */
|
||||
bool selfHosted:1; /* see Parser::selfHostingMode */
|
||||
bool bindingsAccessedDynamically:1; /* see ContextFlags' field of the same name */
|
||||
bool funHasExtensibleScope:1; /* see ContextFlags' field of the same name */
|
||||
bool bindingsAccessedDynamically:1; /* see FunctionContextFlags */
|
||||
bool funHasExtensibleScope:1; /* see FunctionContextFlags */
|
||||
bool funNeedsDeclEnvObject:1; /* see FunctionContextFlags */
|
||||
bool funHasAnyAliasedFormal:1; /* true if any formalIsAliased(i) */
|
||||
bool warnedAboutTwoArgumentEval:1; /* have warned about use of
|
||||
obsolete eval(s, o) in
|
||||
|
@ -26,7 +26,7 @@ namespace js {
|
||||
* and saved versions. If deserialization fails, the data should be
|
||||
* invalidated if possible.
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 147);
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 148);
|
||||
|
||||
class XDRBuffer {
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user