mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 14:45:29 +00:00
Bug 917996 - XDR Lazy Scripts. r=till
This commit is contained in:
parent
022c86a654
commit
3557e5f96f
@ -2069,9 +2069,9 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox *funbo
|
||||
size_t numInnerFunctions = pc->innerFunctions.length();
|
||||
|
||||
RootedFunction fun(context, funbox->function());
|
||||
LazyScript *lazy = LazyScript::Create(context, fun, numFreeVariables, numInnerFunctions, versionNumber(),
|
||||
funbox->bufStart, funbox->bufEnd,
|
||||
funbox->startLine, funbox->startColumn);
|
||||
LazyScript *lazy = LazyScript::CreateRaw(context, fun, numFreeVariables, numInnerFunctions,
|
||||
versionNumber(), funbox->bufStart, funbox->bufEnd,
|
||||
funbox->startLine, funbox->startColumn);
|
||||
if (!lazy)
|
||||
return false;
|
||||
|
||||
|
@ -357,8 +357,9 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
|
||||
MutableHandleObject objp)
|
||||
{
|
||||
enum FirstWordFlag {
|
||||
HasAtom = 0x1,
|
||||
IsStarGenerator = 0x2
|
||||
HasAtom = 0x1,
|
||||
IsStarGenerator = 0x2,
|
||||
IsLazy = 0x4
|
||||
};
|
||||
|
||||
/* NB: Keep this in sync with CloneFunctionAndScript. */
|
||||
@ -369,6 +370,8 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
|
||||
JSContext *cx = xdr->cx();
|
||||
RootedFunction fun(cx);
|
||||
RootedScript script(cx);
|
||||
Rooted<LazyScript *> lazy(cx);
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
fun = &objp->as<JSFunction>();
|
||||
if (!fun->isInterpreted()) {
|
||||
@ -379,13 +382,27 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fun->atom() || fun->hasGuessedAtom())
|
||||
firstword |= HasAtom;
|
||||
|
||||
if (fun->isStarGenerator())
|
||||
firstword |= IsStarGenerator;
|
||||
script = fun->getOrCreateScript(cx);
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
if (fun->isInterpretedLazy()) {
|
||||
// This can only happen for re-lazified cloned functions, so this
|
||||
// does not apply to any JSFunction produced by the parser, only to
|
||||
// JSFunction created by the runtime.
|
||||
JS_ASSERT(!fun->lazyScript()->maybeScript());
|
||||
|
||||
// Encode a lazy script.
|
||||
firstword |= IsLazy;
|
||||
lazy = fun->lazyScript();
|
||||
} else {
|
||||
// Encode the script.
|
||||
script = fun->nonLazyScript();
|
||||
}
|
||||
|
||||
atom = fun->displayAtom();
|
||||
flagsword = (fun->nargs() << 16) | fun->flags();
|
||||
}
|
||||
@ -414,18 +431,29 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
|
||||
if (!xdr->codeUint32(&flagsword))
|
||||
return false;
|
||||
|
||||
if (!XDRScript(xdr, enclosingScope, enclosingScript, fun, &script))
|
||||
return false;
|
||||
if (firstword & IsLazy) {
|
||||
if (!XDRLazyScript(xdr, enclosingScope, enclosingScript, fun, &lazy))
|
||||
return false;
|
||||
} else {
|
||||
if (!XDRScript(xdr, enclosingScope, enclosingScript, fun, &script))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
fun->setArgCount(flagsword >> 16);
|
||||
fun->setFlags(uint16_t(flagsword));
|
||||
fun->initAtom(atom);
|
||||
fun->initScript(script);
|
||||
script->setFunction(fun);
|
||||
if (firstword & IsLazy) {
|
||||
fun->initLazyScript(lazy);
|
||||
} else {
|
||||
fun->initScript(script);
|
||||
script->setFunction(fun);
|
||||
JS_ASSERT(fun->nargs() == script->bindings.numArgs());
|
||||
}
|
||||
|
||||
|
||||
if (!JSFunction::setTypeForScriptedFunction(cx, fun))
|
||||
return false;
|
||||
JS_ASSERT(fun->nargs() == fun->nonLazyScript()->bindings.numArgs());
|
||||
objp.set(fun);
|
||||
}
|
||||
|
||||
|
@ -414,6 +414,75 @@ js::XDRScriptConst(XDRState<XDR_ENCODE> *, MutableHandleValue);
|
||||
template bool
|
||||
js::XDRScriptConst(XDRState<XDR_DECODE> *, MutableHandleValue);
|
||||
|
||||
// Code LazyScript's free variables.
|
||||
template<XDRMode mode>
|
||||
static bool
|
||||
XDRLazyFreeVariables(XDRState<mode> *xdr, MutableHandle<LazyScript *> lazy)
|
||||
{
|
||||
JSContext *cx = xdr->cx();
|
||||
RootedAtom atom(cx);
|
||||
HeapPtrAtom *freeVariables = lazy->freeVariables();
|
||||
size_t numFreeVariables = lazy->numFreeVariables();
|
||||
for (size_t i = 0; i < numFreeVariables; i++) {
|
||||
if (mode == XDR_ENCODE)
|
||||
atom = freeVariables[i];
|
||||
|
||||
if (!XDRAtom(xdr, &atom))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE)
|
||||
freeVariables[i] = atom;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Code the missing part needed to re-create a LazyScript from a JSScript.
|
||||
template<XDRMode mode>
|
||||
static bool
|
||||
XDRRelazificationInfo(XDRState<mode> *xdr, HandleFunction fun, HandleScript script,
|
||||
MutableHandle<LazyScript *> lazy)
|
||||
{
|
||||
MOZ_ASSERT_IF(mode == XDR_ENCODE, script->isRelazifiable() && script->maybeLazyScript());
|
||||
MOZ_ASSERT_IF(mode == XDR_ENCODE, !lazy->numInnerFunctions());
|
||||
|
||||
JSContext *cx = xdr->cx();
|
||||
|
||||
uint64_t packedFields;
|
||||
{
|
||||
uint32_t begin = script->sourceStart();
|
||||
uint32_t end = script->sourceEnd();
|
||||
uint32_t lineno = script->lineno();
|
||||
uint32_t column = script->column();
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
packedFields = lazy->packedFields();
|
||||
MOZ_ASSERT(begin == lazy->begin());
|
||||
MOZ_ASSERT(end == lazy->end());
|
||||
MOZ_ASSERT(lineno == lazy->lineno());
|
||||
MOZ_ASSERT(column == lazy->column());
|
||||
}
|
||||
|
||||
if (!xdr->codeUint64(&packedFields))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
lazy.set(LazyScript::Create(cx, fun, packedFields, begin, end, lineno, column));
|
||||
|
||||
// As opposed to XDRLazyScript, we need to restore the runtime bits
|
||||
// of the script, as we are trying to match the fact this function
|
||||
// has already been parsed and that it would need to be re-lazified.
|
||||
lazy->initRuntimeFields(packedFields);
|
||||
}
|
||||
}
|
||||
|
||||
// Code free variables.
|
||||
if (!XDRLazyFreeVariables(xdr, lazy))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
FindScopeObjectIndex(JSScript *script, NestedScopeObject &scope)
|
||||
{
|
||||
@ -463,7 +532,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
SelfHosted,
|
||||
IsCompileAndGo,
|
||||
HasSingleton,
|
||||
TreatAsRunOnce
|
||||
TreatAsRunOnce,
|
||||
HasLazyScript
|
||||
};
|
||||
|
||||
uint32_t length, lineno, column, nslots;
|
||||
@ -561,6 +631,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
scriptBits |= (1 << HasSingleton);
|
||||
if (script->treatAsRunOnce())
|
||||
scriptBits |= (1 << TreatAsRunOnce);
|
||||
if (script->isRelazifiable())
|
||||
scriptBits |= (1 << HasLazyScript);
|
||||
}
|
||||
|
||||
if (!xdr->codeUint32(&prologLength))
|
||||
@ -821,12 +893,16 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
case CK_JSFunction: {
|
||||
/* Code the nested function's enclosing scope. */
|
||||
uint32_t funEnclosingScopeIndex = 0;
|
||||
RootedObject funEnclosingScope(cx);
|
||||
if (mode == XDR_ENCODE) {
|
||||
JSScript *innerScript = (*objp)->as<JSFunction>().getOrCreateScript(cx);
|
||||
if (!innerScript)
|
||||
return false;
|
||||
RootedObject staticScope(cx, innerScript->enclosingStaticScope());
|
||||
StaticScopeIter<NoGC> ssi(staticScope);
|
||||
RootedFunction function(cx, &(*objp)->as<JSFunction>());
|
||||
|
||||
if (function->isInterpretedLazy())
|
||||
funEnclosingScope = function->lazyScript()->enclosingScope();
|
||||
else
|
||||
funEnclosingScope = function->nonLazyScript()->enclosingStaticScope();
|
||||
|
||||
StaticScopeIter<NoGC> ssi(funEnclosingScope);
|
||||
if (ssi.done() || ssi.type() == StaticScopeIter<NoGC>::FUNCTION) {
|
||||
JS_ASSERT(ssi.done() == !fun);
|
||||
funEnclosingScopeIndex = UINT32_MAX;
|
||||
@ -835,9 +911,10 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
JS_ASSERT(funEnclosingScopeIndex < i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!xdr->codeUint32(&funEnclosingScopeIndex))
|
||||
return false;
|
||||
Rooted<JSObject*> funEnclosingScope(cx);
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
if (funEnclosingScopeIndex == UINT32_MAX) {
|
||||
funEnclosingScope = fun;
|
||||
@ -847,6 +924,7 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
}
|
||||
}
|
||||
|
||||
// Code nested function and script.
|
||||
RootedObject tmp(cx, *objp);
|
||||
if (!XDRInterpretedFunction(xdr, funEnclosingScope, script, &tmp))
|
||||
return false;
|
||||
@ -901,6 +979,18 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptBits & (1 << HasLazyScript)) {
|
||||
Rooted<LazyScript *> lazy(cx);
|
||||
if (mode == XDR_ENCODE)
|
||||
lazy = script->maybeLazyScript();
|
||||
|
||||
if (!XDRRelazificationInfo(xdr, fun, script, &lazy))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE)
|
||||
script->setLazyScript(lazy);
|
||||
}
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
scriptp.set(script);
|
||||
|
||||
@ -923,6 +1013,83 @@ template bool
|
||||
js::XDRScript(XDRState<XDR_DECODE> *, HandleObject, HandleScript, HandleFunction,
|
||||
MutableHandleScript);
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
js::XDRLazyScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript,
|
||||
HandleFunction fun, MutableHandle<LazyScript *> lazy)
|
||||
{
|
||||
JSContext *cx = xdr->cx();
|
||||
|
||||
{
|
||||
uint32_t begin;
|
||||
uint32_t end;
|
||||
uint32_t lineno;
|
||||
uint32_t column;
|
||||
uint64_t packedFields;
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
MOZ_ASSERT(!lazy->maybeScript());
|
||||
MOZ_ASSERT(fun == lazy->functionNonDelazifying());
|
||||
|
||||
begin = lazy->begin();
|
||||
end = lazy->end();
|
||||
lineno = lazy->lineno();
|
||||
column = lazy->column();
|
||||
packedFields = lazy->packedFields();
|
||||
}
|
||||
|
||||
if (!xdr->codeUint32(&begin) || !xdr->codeUint32(&end) ||
|
||||
!xdr->codeUint32(&lineno) || !xdr->codeUint32(&column) ||
|
||||
!xdr->codeUint64(&packedFields))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode == XDR_DECODE)
|
||||
lazy.set(LazyScript::Create(cx, fun, packedFields, begin, end, lineno, column));
|
||||
}
|
||||
|
||||
// Code free variables.
|
||||
if (!XDRLazyFreeVariables(xdr, lazy))
|
||||
return false;
|
||||
|
||||
// Code inner functions.
|
||||
{
|
||||
RootedObject func(cx);
|
||||
HeapPtrFunction *innerFunctions = lazy->innerFunctions();
|
||||
size_t numInnerFunctions = lazy->numInnerFunctions();
|
||||
for (size_t i = 0; i < numInnerFunctions; i++) {
|
||||
if (mode == XDR_ENCODE)
|
||||
func = innerFunctions[i];
|
||||
|
||||
if (!XDRInterpretedFunction(xdr, fun, enclosingScript, &func))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE)
|
||||
innerFunctions[i] = &func->as<JSFunction>();
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
JS_ASSERT(!lazy->sourceObject());
|
||||
ScriptSourceObject *sourceObject = &enclosingScript->scriptSourceUnwrap();
|
||||
|
||||
// Set the enclosing scope of the lazy function, this would later be
|
||||
// used to define the environment when the function would be used.
|
||||
lazy->setParent(enclosingScope, sourceObject);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template bool
|
||||
js::XDRLazyScript(XDRState<XDR_ENCODE> *, HandleObject, HandleScript,
|
||||
HandleFunction, MutableHandle<LazyScript *>);
|
||||
|
||||
template bool
|
||||
js::XDRLazyScript(XDRState<XDR_DECODE> *, HandleObject, HandleScript,
|
||||
HandleFunction, MutableHandle<LazyScript *>);
|
||||
|
||||
void
|
||||
JSScript::setSourceObject(JSObject *object)
|
||||
{
|
||||
@ -930,9 +1097,14 @@ JSScript::setSourceObject(JSObject *object)
|
||||
sourceObject_ = object;
|
||||
}
|
||||
|
||||
js::ScriptSourceObject &
|
||||
JSScript::scriptSourceUnwrap() const {
|
||||
return UncheckedUnwrap(sourceObject())->as<ScriptSourceObject>();
|
||||
}
|
||||
|
||||
js::ScriptSource *
|
||||
JSScript::scriptSource() const {
|
||||
return UncheckedUnwrap(sourceObject())->as<ScriptSourceObject>().source();
|
||||
return scriptSourceUnwrap().source();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -3242,30 +3414,18 @@ JSScript::formalLivesInArgumentsObject(unsigned argSlot)
|
||||
return argsObjAliasesFormals() && !formalIsAliased(argSlot);
|
||||
}
|
||||
|
||||
LazyScript::LazyScript(JSFunction *fun, void *table, uint32_t numFreeVariables, uint32_t numInnerFunctions,
|
||||
JSVersion version, uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
|
||||
LazyScript::LazyScript(JSFunction *fun, void *table, uint64_t packedFields, uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
|
||||
: script_(nullptr),
|
||||
function_(fun),
|
||||
enclosingScope_(nullptr),
|
||||
sourceObject_(nullptr),
|
||||
table_(table),
|
||||
version_(version),
|
||||
numFreeVariables_(numFreeVariables),
|
||||
numInnerFunctions_(numInnerFunctions),
|
||||
generatorKindBits_(GeneratorKindAsBits(NotGenerator)),
|
||||
strict_(false),
|
||||
bindingsAccessedDynamically_(false),
|
||||
hasDebuggerStatement_(false),
|
||||
directlyInsideEval_(false),
|
||||
usesArgumentsAndApply_(false),
|
||||
hasBeenCloned_(false),
|
||||
treatAsRunOnce_(false),
|
||||
packedFields_(packedFields),
|
||||
begin_(begin),
|
||||
end_(end),
|
||||
lineno_(lineno),
|
||||
column_(column)
|
||||
{
|
||||
JS_ASSERT(this->version() == version);
|
||||
JS_ASSERT(begin <= end);
|
||||
}
|
||||
|
||||
@ -3301,14 +3461,23 @@ LazyScript::sourceObject() const
|
||||
}
|
||||
|
||||
/* static */ LazyScript *
|
||||
LazyScript::Create(ExclusiveContext *cx, HandleFunction fun,
|
||||
uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
|
||||
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
|
||||
LazyScript::CreateRaw(ExclusiveContext *cx, HandleFunction fun,
|
||||
uint64_t packedFields, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column)
|
||||
{
|
||||
JS_ASSERT(begin <= end);
|
||||
union {
|
||||
PackedView p;
|
||||
uint64_t packed;
|
||||
};
|
||||
|
||||
size_t bytes = (numFreeVariables * sizeof(HeapPtrAtom))
|
||||
+ (numInnerFunctions * sizeof(HeapPtrFunction));
|
||||
packed = packedFields;
|
||||
|
||||
// Reset runtime flags to obtain a fresh LazyScript.
|
||||
p.hasBeenCloned = false;
|
||||
p.treatAsRunOnce = false;
|
||||
|
||||
size_t bytes = (p.numFreeVariables * sizeof(HeapPtrAtom))
|
||||
+ (p.numInnerFunctions * sizeof(HeapPtrFunction));
|
||||
|
||||
void *table = nullptr;
|
||||
if (bytes) {
|
||||
@ -3323,8 +3492,75 @@ LazyScript::Create(ExclusiveContext *cx, HandleFunction fun,
|
||||
|
||||
cx->compartment()->scheduleDelazificationForDebugMode();
|
||||
|
||||
return new (res) LazyScript(fun, table, numFreeVariables, numInnerFunctions, version,
|
||||
begin, end, lineno, column);
|
||||
return new (res) LazyScript(fun, table, packed, begin, end, lineno, column);
|
||||
}
|
||||
|
||||
/* static */ LazyScript *
|
||||
LazyScript::CreateRaw(ExclusiveContext *cx, HandleFunction fun,
|
||||
uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
|
||||
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
|
||||
{
|
||||
union {
|
||||
PackedView p;
|
||||
uint64_t packedFields;
|
||||
};
|
||||
|
||||
p.version = version;
|
||||
p.numFreeVariables = numFreeVariables;
|
||||
p.numInnerFunctions = numInnerFunctions;
|
||||
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
|
||||
p.strict = false;
|
||||
p.bindingsAccessedDynamically = false;
|
||||
p.hasDebuggerStatement = false;
|
||||
p.directlyInsideEval = false;
|
||||
p.usesArgumentsAndApply = false;
|
||||
|
||||
LazyScript *res = LazyScript::CreateRaw(cx, fun, packedFields, begin, end, lineno, column);
|
||||
JS_ASSERT(res->version() == version);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* static */ LazyScript *
|
||||
LazyScript::Create(ExclusiveContext *cx, HandleFunction fun,
|
||||
uint64_t packedFields, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column)
|
||||
{
|
||||
// Dummy atom which is not a valid property name.
|
||||
RootedAtom dummyAtom(cx, cx->names().comma);
|
||||
|
||||
// Dummy function which is not a valid function as this is the one which is
|
||||
// holding this lazy script.
|
||||
HandleFunction dummyFun = fun;
|
||||
|
||||
LazyScript *res = LazyScript::CreateRaw(cx, fun, packedFields, begin, end, lineno, column);
|
||||
if (!res)
|
||||
return nullptr;
|
||||
|
||||
// Fill with dummies, to be GC-safe after the initialization of the free
|
||||
// variables and inner functions.
|
||||
size_t i, num;
|
||||
HeapPtrAtom *variables = res->freeVariables();
|
||||
for (i = 0, num = res->numFreeVariables(); i < num; i++)
|
||||
variables[i].init(dummyAtom);
|
||||
|
||||
HeapPtrFunction *functions = res->innerFunctions();
|
||||
for (i = 0, num = res->numInnerFunctions(); i < num; i++)
|
||||
functions[i].init(dummyFun);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
LazyScript::initRuntimeFields(uint64_t packedFields)
|
||||
{
|
||||
union {
|
||||
PackedView p;
|
||||
uint64_t packed;
|
||||
};
|
||||
|
||||
packed = packedFields;
|
||||
p_.hasBeenCloned = p.hasBeenCloned;
|
||||
p_.treatAsRunOnce = p.treatAsRunOnce;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -595,6 +595,11 @@ JSScript *
|
||||
CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, HandleScript script,
|
||||
NewObjectKind newKind = GenericObject);
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRLazyScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript,
|
||||
HandleFunction fun, MutableHandle<LazyScript *> lazy);
|
||||
|
||||
/*
|
||||
* Code any constant value.
|
||||
*/
|
||||
@ -1240,6 +1245,7 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
|
||||
JSObject *sourceObject() const {
|
||||
return sourceObject_;
|
||||
}
|
||||
js::ScriptSourceObject &scriptSourceUnwrap() const;
|
||||
js::ScriptSource *scriptSource() const;
|
||||
JSPrincipals *originPrincipals() const { return scriptSource()->originPrincipals(); }
|
||||
const char *filename() const { return scriptSource()->filename(); }
|
||||
@ -1607,22 +1613,29 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
|
||||
uint32_t padding;
|
||||
#endif
|
||||
|
||||
// Assorted bits that should really be in ScriptSourceObject.
|
||||
uint32_t version_ : 8;
|
||||
struct PackedView {
|
||||
// Assorted bits that should really be in ScriptSourceObject.
|
||||
uint32_t version : 8;
|
||||
|
||||
uint32_t numFreeVariables_ : 24;
|
||||
uint32_t numInnerFunctions_ : 23;
|
||||
uint32_t numFreeVariables : 24;
|
||||
uint32_t numInnerFunctions : 23;
|
||||
|
||||
uint32_t generatorKindBits_:2;
|
||||
uint32_t generatorKindBits : 2;
|
||||
|
||||
// N.B. These are booleans but need to be uint32_t to pack correctly on MSVC.
|
||||
uint32_t strict_ : 1;
|
||||
uint32_t bindingsAccessedDynamically_ : 1;
|
||||
uint32_t hasDebuggerStatement_ : 1;
|
||||
uint32_t directlyInsideEval_:1;
|
||||
uint32_t usesArgumentsAndApply_:1;
|
||||
uint32_t hasBeenCloned_:1;
|
||||
uint32_t treatAsRunOnce_:1;
|
||||
// N.B. These are booleans but need to be uint32_t to pack correctly on MSVC.
|
||||
uint32_t strict : 1;
|
||||
uint32_t bindingsAccessedDynamically : 1;
|
||||
uint32_t hasDebuggerStatement : 1;
|
||||
uint32_t directlyInsideEval : 1;
|
||||
uint32_t usesArgumentsAndApply : 1;
|
||||
uint32_t hasBeenCloned : 1;
|
||||
uint32_t treatAsRunOnce : 1;
|
||||
};
|
||||
|
||||
union {
|
||||
PackedView p_;
|
||||
uint64_t packedFields_;
|
||||
};
|
||||
|
||||
// Source location for the script.
|
||||
uint32_t begin_;
|
||||
@ -1630,16 +1643,34 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
|
||||
uint32_t lineno_;
|
||||
uint32_t column_;
|
||||
|
||||
LazyScript(JSFunction *fun, void *table,
|
||||
uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
|
||||
LazyScript(JSFunction *fun, void *table, uint64_t packedFields,
|
||||
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column);
|
||||
|
||||
// Create a LazyScript without initializing the freeVariables and the
|
||||
// innerFunctions. To be GC-safe, the caller must initialize both vectors
|
||||
// with valid atoms and functions.
|
||||
static LazyScript *CreateRaw(ExclusiveContext *cx, HandleFunction fun,
|
||||
uint64_t packedData, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column);
|
||||
|
||||
public:
|
||||
// Create a LazyScript without initializing the freeVariables and the
|
||||
// innerFunctions. To be GC-safe, the caller must initialize both vectors
|
||||
// with valid atoms and functions.
|
||||
static LazyScript *CreateRaw(ExclusiveContext *cx, HandleFunction fun,
|
||||
uint32_t numFreeVariables, uint32_t numInnerFunctions,
|
||||
JSVersion version, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column);
|
||||
|
||||
// Create a LazyScript and initialize the freeVariables and the
|
||||
// innerFunctions with dummy values to be replaced in a later initialization
|
||||
// phase.
|
||||
static LazyScript *Create(ExclusiveContext *cx, HandleFunction fun,
|
||||
uint32_t numFreeVariables, uint32_t numInnerFunctions,
|
||||
JSVersion version, uint32_t begin, uint32_t end,
|
||||
uint64_t packedData, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column);
|
||||
|
||||
void initRuntimeFields(uint64_t packedFields);
|
||||
|
||||
inline JSFunction *functionDelazifying(JSContext *cx) const;
|
||||
JSFunction *functionNonDelazifying() const {
|
||||
return function_;
|
||||
@ -1663,26 +1694,26 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
|
||||
}
|
||||
JSVersion version() const {
|
||||
JS_STATIC_ASSERT(JSVERSION_UNKNOWN == -1);
|
||||
return (version_ == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(version_);
|
||||
return (p_.version == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(p_.version);
|
||||
}
|
||||
|
||||
void setParent(JSObject *enclosingScope, ScriptSourceObject *sourceObject);
|
||||
|
||||
uint32_t numFreeVariables() const {
|
||||
return numFreeVariables_;
|
||||
return p_.numFreeVariables;
|
||||
}
|
||||
HeapPtrAtom *freeVariables() {
|
||||
return (HeapPtrAtom *)table_;
|
||||
}
|
||||
|
||||
uint32_t numInnerFunctions() const {
|
||||
return numInnerFunctions_;
|
||||
return p_.numInnerFunctions;
|
||||
}
|
||||
HeapPtrFunction *innerFunctions() {
|
||||
return (HeapPtrFunction *)&freeVariables()[numFreeVariables()];
|
||||
}
|
||||
|
||||
GeneratorKind generatorKind() const { return GeneratorKindFromBits(generatorKindBits_); }
|
||||
GeneratorKind generatorKind() const { return GeneratorKindFromBits(p_.generatorKindBits); }
|
||||
|
||||
bool isGenerator() const { return generatorKind() != NotGenerator; }
|
||||
|
||||
@ -1696,56 +1727,56 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
|
||||
JS_ASSERT(!isGenerator());
|
||||
// Legacy generators cannot currently be lazy.
|
||||
JS_ASSERT(kind != LegacyGenerator);
|
||||
generatorKindBits_ = GeneratorKindAsBits(kind);
|
||||
p_.generatorKindBits = GeneratorKindAsBits(kind);
|
||||
}
|
||||
|
||||
bool strict() const {
|
||||
return strict_;
|
||||
return p_.strict;
|
||||
}
|
||||
void setStrict() {
|
||||
strict_ = true;
|
||||
p_.strict = true;
|
||||
}
|
||||
|
||||
bool bindingsAccessedDynamically() const {
|
||||
return bindingsAccessedDynamically_;
|
||||
return p_.bindingsAccessedDynamically;
|
||||
}
|
||||
void setBindingsAccessedDynamically() {
|
||||
bindingsAccessedDynamically_ = true;
|
||||
p_.bindingsAccessedDynamically = true;
|
||||
}
|
||||
|
||||
bool hasDebuggerStatement() const {
|
||||
return hasDebuggerStatement_;
|
||||
return p_.hasDebuggerStatement;
|
||||
}
|
||||
void setHasDebuggerStatement() {
|
||||
hasDebuggerStatement_ = true;
|
||||
p_.hasDebuggerStatement = true;
|
||||
}
|
||||
|
||||
bool directlyInsideEval() const {
|
||||
return directlyInsideEval_;
|
||||
return p_.directlyInsideEval;
|
||||
}
|
||||
void setDirectlyInsideEval() {
|
||||
directlyInsideEval_ = true;
|
||||
p_.directlyInsideEval = true;
|
||||
}
|
||||
|
||||
bool usesArgumentsAndApply() const {
|
||||
return usesArgumentsAndApply_;
|
||||
return p_.usesArgumentsAndApply;
|
||||
}
|
||||
void setUsesArgumentsAndApply() {
|
||||
usesArgumentsAndApply_ = true;
|
||||
p_.usesArgumentsAndApply = true;
|
||||
}
|
||||
|
||||
bool hasBeenCloned() const {
|
||||
return hasBeenCloned_;
|
||||
return p_.hasBeenCloned;
|
||||
}
|
||||
void setHasBeenCloned() {
|
||||
hasBeenCloned_ = true;
|
||||
p_.hasBeenCloned = true;
|
||||
}
|
||||
|
||||
bool treatAsRunOnce() const {
|
||||
return treatAsRunOnce_;
|
||||
return p_.treatAsRunOnce;
|
||||
}
|
||||
void setTreatAsRunOnce() {
|
||||
treatAsRunOnce_ = true;
|
||||
p_.treatAsRunOnce = true;
|
||||
}
|
||||
|
||||
ScriptSource *source() const {
|
||||
@ -1775,6 +1806,10 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
|
||||
{
|
||||
return mallocSizeOf(table_);
|
||||
}
|
||||
|
||||
uint64_t packedFields() const {
|
||||
return packedFields_;
|
||||
}
|
||||
};
|
||||
|
||||
/* If this fails, add/remove padding within LazyScript. */
|
||||
|
Loading…
Reference in New Issue
Block a user