зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1179063 - Hook up FunctionBox directly to the JSFunction being parsed to avoid allocating extra static scopes. (r=efaust)
This commit is contained in:
Родитель
885fc65599
Коммит
9cbf164447
|
@ -107,16 +107,6 @@ struct frontend::LoopStmtInfo : public StmtInfoBCE
|
|||
}
|
||||
};
|
||||
|
||||
void
|
||||
FunctionBox::switchStaticScopeToFunction()
|
||||
{
|
||||
if (staticScope_->is<StaticFunctionBoxScopeObject>()) {
|
||||
MOZ_ASSERT(staticScope_->as<StaticFunctionBoxScopeObject>().functionBox() == this);
|
||||
staticScope_ = function();
|
||||
}
|
||||
MOZ_ASSERT(staticScope_ == function());
|
||||
}
|
||||
|
||||
BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent,
|
||||
Parser<FullParseHandler>* parser, SharedContext* sc,
|
||||
HandleScript script, Handle<LazyScript*> lazyScript,
|
||||
|
|
|
@ -1160,8 +1160,8 @@ ObjectBox::trace(JSTracer* trc)
|
|||
if (box->isFunctionBox()) {
|
||||
FunctionBox* funbox = box->asFunctionBox();
|
||||
funbox->bindings.trace(trc);
|
||||
if (funbox->staticScope_)
|
||||
TraceRoot(trc, &funbox->staticScope_, "funbox-staticScope");
|
||||
if (funbox->enclosingStaticScope_)
|
||||
TraceRoot(trc, &funbox->enclosingStaticScope_, "funbox-enclosingStaticScope");
|
||||
}
|
||||
box = box->traceLink;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,22 @@ using mozilla::Maybe;
|
|||
|
||||
using JS::AutoGCRooter;
|
||||
|
||||
JSFunction::AutoParseUsingFunctionBox::AutoParseUsingFunctionBox(ExclusiveContext* cx,
|
||||
frontend::FunctionBox* funbox)
|
||||
: fun_(cx, funbox->function()),
|
||||
oldEnv_(cx, fun_->environment())
|
||||
{
|
||||
fun_->setFunctionBox(funbox);
|
||||
funbox->computeAllowSyntax(fun_);
|
||||
funbox->computeInWith(fun_);
|
||||
}
|
||||
|
||||
JSFunction::AutoParseUsingFunctionBox::~AutoParseUsingFunctionBox()
|
||||
{
|
||||
fun_->unsetFunctionBox();
|
||||
fun_->setEnvironment(oldEnv_);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
namespace frontend {
|
||||
|
||||
|
@ -613,12 +629,12 @@ Parser<ParseHandler>::newObjectBox(JSObject* obj)
|
|||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
|
||||
JSObject* staticScope, ParseContext<ParseHandler>* outerpc,
|
||||
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* outerpc,
|
||||
Directives directives, bool extraWarnings, GeneratorKind generatorKind)
|
||||
: ObjectBox(fun, traceListHead),
|
||||
SharedContext(cx, directives, extraWarnings),
|
||||
bindings(),
|
||||
staticScope_(staticScope),
|
||||
enclosingStaticScope_(enclosingStaticScope),
|
||||
bufStart(0),
|
||||
bufEnd(0),
|
||||
length(0),
|
||||
|
@ -636,22 +652,17 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
|
|||
// baked into JIT code, so they must be allocated tenured. They are held by
|
||||
// the JSScript so cannot be collected during a minor GC anyway.
|
||||
MOZ_ASSERT(fun->isTenured());
|
||||
|
||||
if (staticScope->is<StaticFunctionBoxScopeObject>())
|
||||
staticScope->as<StaticFunctionBoxScopeObject>().setFunctionBox(this);
|
||||
|
||||
computeAllowSyntax(staticScope);
|
||||
computeInWith(staticScope);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox*
|
||||
Parser<ParseHandler>::newFunctionBoxWithScope(Node fn, JSFunction* fun,
|
||||
ParseContext<ParseHandler>* outerpc,
|
||||
Directives inheritedDirectives,
|
||||
GeneratorKind generatorKind,
|
||||
JSObject* staticScope)
|
||||
Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
|
||||
ParseContext<ParseHandler>* outerpc,
|
||||
Directives inheritedDirectives,
|
||||
GeneratorKind generatorKind,
|
||||
JSObject* enclosingStaticScope)
|
||||
{
|
||||
MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
|
||||
MOZ_ASSERT(fun);
|
||||
|
||||
/*
|
||||
|
@ -662,9 +673,8 @@ Parser<ParseHandler>::newFunctionBoxWithScope(Node fn, JSFunction* fun,
|
|||
* function.
|
||||
*/
|
||||
FunctionBox* funbox =
|
||||
alloc.new_<FunctionBox>(context, traceListHead, fun, staticScope, outerpc,
|
||||
inheritedDirectives,
|
||||
options().extraWarningsOption,
|
||||
alloc.new_<FunctionBox>(context, traceListHead, fun, enclosingStaticScope, outerpc,
|
||||
inheritedDirectives, options().extraWarningsOption,
|
||||
generatorKind);
|
||||
if (!funbox) {
|
||||
ReportOutOfMemory(context);
|
||||
|
@ -678,29 +688,6 @@ Parser<ParseHandler>::newFunctionBoxWithScope(Node fn, JSFunction* fun,
|
|||
return funbox;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox*
|
||||
Parser<ParseHandler>::newFunctionBox(Node fn, HandleFunction fun,
|
||||
ParseContext<ParseHandler>* outerpc,
|
||||
Directives inheritedDirectives,
|
||||
GeneratorKind generatorKind,
|
||||
HandleObject enclosingStaticScope)
|
||||
{
|
||||
MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
|
||||
|
||||
StaticFunctionBoxScopeObject* scope =
|
||||
StaticFunctionBoxScopeObject::create(context, enclosingStaticScope);
|
||||
if (!scope)
|
||||
return nullptr;
|
||||
|
||||
FunctionBox* funbox = newFunctionBoxWithScope(fn, fun, outerpc, inheritedDirectives,
|
||||
generatorKind, scope);
|
||||
if (!funbox)
|
||||
return nullptr;
|
||||
|
||||
return funbox;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
void
|
||||
Parser<ParseHandler>::trace(JSTracer* trc)
|
||||
|
|
|
@ -106,6 +106,11 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
|
|||
|
||||
Node maybeFunction; /* sc->isFunctionBox, the pn where pn->pn_funbox == sc */
|
||||
|
||||
// If sc->isFunctionBox(), this is used to temporarily link up the
|
||||
// FunctionBox with the JSFunction so the static scope chain may be walked
|
||||
// without a JSScript.
|
||||
mozilla::Maybe<JSFunction::AutoParseUsingFunctionBox> parseUsingFunctionBox;
|
||||
|
||||
// lastYieldOffset stores the offset of the last yield that was parsed.
|
||||
// NoYieldOffset is its initial value.
|
||||
static const uint32_t NoYieldOffset = UINT32_MAX;
|
||||
|
@ -270,6 +275,8 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
|
|||
inDeclDestructuring(false)
|
||||
{
|
||||
prs->pc = this;
|
||||
if (sc->isFunctionBox())
|
||||
parseUsingFunctionBox.emplace(prs->context, sc->asFunctionBox());
|
||||
}
|
||||
|
||||
~ParseContext();
|
||||
|
@ -463,17 +470,10 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
* cx->tempLifoAlloc.
|
||||
*/
|
||||
ObjectBox* newObjectBox(JSObject* obj);
|
||||
FunctionBox* newFunctionBoxWithScope(Node fn, JSFunction* fun,
|
||||
ParseContext<ParseHandler>* outerpc,
|
||||
Directives directives, GeneratorKind generatorKind,
|
||||
JSObject* staticScope);
|
||||
|
||||
private:
|
||||
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, ParseContext<ParseHandler>* outerpc,
|
||||
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, ParseContext<ParseHandler>* outerpc,
|
||||
Directives directives, GeneratorKind generatorKind,
|
||||
HandleObject enclosingStaticScope);
|
||||
JSObject* enclosingStaticScope);
|
||||
|
||||
public:
|
||||
// Use when the funbox is the outermost.
|
||||
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, Directives directives,
|
||||
GeneratorKind generatorKind, HandleObject enclosingStaticScope)
|
||||
|
|
|
@ -191,10 +191,6 @@ class SharedContext
|
|||
bool inWith_;
|
||||
bool superScopeAlreadyNeedsHomeObject_;
|
||||
|
||||
protected:
|
||||
void computeAllowSyntax(JSObject* staticScope);
|
||||
void computeInWith(JSObject* staticScope);
|
||||
|
||||
public:
|
||||
SharedContext(ExclusiveContext* cx, Directives directives,
|
||||
bool extraWarnings)
|
||||
|
@ -215,6 +211,8 @@ class SharedContext
|
|||
// for the static scope. FunctionBoxes are LifoAlloc'd and need to
|
||||
// manually trace their static scope.
|
||||
virtual JSObject* staticScope() const = 0;
|
||||
void computeAllowSyntax(JSObject* staticScope);
|
||||
void computeInWith(JSObject* staticScope);
|
||||
|
||||
virtual ObjectBox* toObjectBox() { return nullptr; }
|
||||
inline bool isFunctionBox() { return toObjectBox() && toObjectBox()->isFunctionBox(); }
|
||||
|
@ -277,7 +275,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
{
|
||||
public:
|
||||
Bindings bindings; /* bindings for this function */
|
||||
JSObject* staticScope_;
|
||||
JSObject* enclosingStaticScope_;
|
||||
uint32_t bufStart;
|
||||
uint32_t bufEnd;
|
||||
uint32_t startLine;
|
||||
|
@ -285,7 +283,6 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
uint16_t length;
|
||||
|
||||
uint8_t generatorKindBits_; /* The GeneratorKind of this function. */
|
||||
bool inWith_:1; /* some enclosing scope is a with-statement */
|
||||
bool inGenexpLambda:1; /* lambda from generator expression */
|
||||
bool hasDestructuringArgs:1; /* arguments list contains destructuring expression */
|
||||
bool useAsm:1; /* see useAsmOrInsideUseAsm */
|
||||
|
@ -300,13 +297,13 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
|
||||
JSObject* staticScope, ParseContext<ParseHandler>* pc,
|
||||
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* pc,
|
||||
Directives directives, bool extraWarnings, GeneratorKind generatorKind);
|
||||
|
||||
ObjectBox* toObjectBox() override { return this; }
|
||||
JSFunction* function() const { return &object->as<JSFunction>(); }
|
||||
JSObject* staticScope() const override { return staticScope_; }
|
||||
void switchStaticScopeToFunction();
|
||||
JSObject* staticScope() const override { return function(); }
|
||||
JSObject* enclosingStaticScope() const { return enclosingStaticScope_; }
|
||||
|
||||
GeneratorKind generatorKind() const { return GeneratorKindFromBits(generatorKindBits_); }
|
||||
bool isGenerator() const { return generatorKind() != NotGenerator; }
|
||||
|
|
|
@ -687,12 +687,12 @@ JSFunction::trace(JSTracer* trc)
|
|||
// Functions can be be marked as interpreted despite having no script
|
||||
// yet at some points when parsing, and can be lazy with no lazy script
|
||||
// for self-hosted code.
|
||||
if (hasScript() && u.i.s.script_)
|
||||
if (hasScript() && !hasUncompiledScript())
|
||||
TraceManuallyBarrieredEdge(trc, &u.i.s.script_, "script");
|
||||
else if (isInterpretedLazy() && u.i.s.lazy_)
|
||||
TraceManuallyBarrieredEdge(trc, &u.i.s.lazy_, "lazyScript");
|
||||
|
||||
if (u.i.env_)
|
||||
if (!isBeingParsed() && u.i.env_)
|
||||
TraceManuallyBarrieredEdge(trc, &u.i.env_, "fun_environment");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
#include "jstypes.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
namespace frontend {
|
||||
class FunctionBox;
|
||||
}
|
||||
|
||||
class FunctionExtended;
|
||||
|
||||
typedef JSNative Native;
|
||||
|
@ -57,9 +62,11 @@ class JSFunction : public js::NativeObject
|
|||
INTERPRETED_LAZY = 0x0200, /* function is interpreted but doesn't have a script yet */
|
||||
RESOLVED_LENGTH = 0x0400, /* f.length has been resolved (see fun_resolve). */
|
||||
RESOLVED_NAME = 0x0800, /* f.name has been resolved (see fun_resolve). */
|
||||
BEING_PARSED = 0x1000, /* function is currently being parsed; has
|
||||
a funbox in place of an environment */
|
||||
|
||||
FUNCTION_KIND_SHIFT = 12,
|
||||
FUNCTION_KIND_MASK = 0xf << FUNCTION_KIND_SHIFT,
|
||||
FUNCTION_KIND_SHIFT = 13,
|
||||
FUNCTION_KIND_MASK = 0x7 << FUNCTION_KIND_SHIFT,
|
||||
|
||||
ASMJS_KIND = AsmJS << FUNCTION_KIND_SHIFT,
|
||||
ARROW_KIND = Arrow << FUNCTION_KIND_SHIFT,
|
||||
|
@ -92,6 +99,18 @@ class JSFunction : public js::NativeObject
|
|||
static_assert(((FunctionKindLimit - 1) << FUNCTION_KIND_SHIFT) <= FUNCTION_KIND_MASK,
|
||||
"FunctionKind doesn't fit into flags_");
|
||||
|
||||
// Implemented in Parser.cpp. Used so the static scope chain may be walked
|
||||
// in Parser without a JSScript.
|
||||
class MOZ_STACK_CLASS AutoParseUsingFunctionBox
|
||||
{
|
||||
js::RootedFunction fun_;
|
||||
js::RootedObject oldEnv_;
|
||||
|
||||
public:
|
||||
AutoParseUsingFunctionBox(js::ExclusiveContext* cx, js::frontend::FunctionBox* funbox);
|
||||
~AutoParseUsingFunctionBox();
|
||||
};
|
||||
|
||||
private:
|
||||
uint16_t nargs_; /* number of formal arguments
|
||||
(including defaults and the rest parameter unlike f.length) */
|
||||
|
@ -110,8 +129,11 @@ class JSFunction : public js::NativeObject
|
|||
use the accessor! */
|
||||
js::LazyScript* lazy_; /* lazily compiled script, or nullptr */
|
||||
} s;
|
||||
JSObject* env_; /* environment for new activations;
|
||||
use the accessor! */
|
||||
union {
|
||||
JSObject* env_; /* environment for new activations;
|
||||
use the accessor! */
|
||||
js::frontend::FunctionBox* funbox_; /* the function box when parsing */
|
||||
};
|
||||
} i;
|
||||
void* nativeOrScript;
|
||||
} u;
|
||||
|
@ -122,6 +144,7 @@ class JSFunction : public js::NativeObject
|
|||
/* Call objects must be created for each invocation of a heavyweight function. */
|
||||
bool isHeavyweight() const {
|
||||
MOZ_ASSERT(!isInterpretedLazy());
|
||||
MOZ_ASSERT(!isBeingParsed());
|
||||
|
||||
if (isNative())
|
||||
return false;
|
||||
|
@ -164,6 +187,7 @@ class JSFunction : public js::NativeObject
|
|||
bool hasRest() const { return flags() & HAS_REST; }
|
||||
bool isInterpretedLazy() const { return flags() & INTERPRETED_LAZY; }
|
||||
bool hasScript() const { return flags() & INTERPRETED; }
|
||||
bool isBeingParsed() const { return flags() & BEING_PARSED; }
|
||||
|
||||
// Arrow functions store their lexical |this| in the first extended slot.
|
||||
bool isArrow() const { return kind() == Arrow; }
|
||||
|
@ -287,20 +311,34 @@ class JSFunction : public js::NativeObject
|
|||
* activations (stack frames) of the function.
|
||||
*/
|
||||
JSObject* environment() const {
|
||||
MOZ_ASSERT(isInterpreted());
|
||||
MOZ_ASSERT(isInterpreted() && !isBeingParsed());
|
||||
return u.i.env_;
|
||||
}
|
||||
|
||||
void setEnvironment(JSObject* obj) {
|
||||
MOZ_ASSERT(isInterpreted());
|
||||
MOZ_ASSERT(isInterpreted() && !isBeingParsed());
|
||||
*(js::HeapPtrObject*)&u.i.env_ = obj;
|
||||
}
|
||||
|
||||
void initEnvironment(JSObject* obj) {
|
||||
MOZ_ASSERT(isInterpreted());
|
||||
MOZ_ASSERT(isInterpreted() && !isBeingParsed());
|
||||
((js::HeapPtrObject*)&u.i.env_)->init(obj);
|
||||
}
|
||||
|
||||
private:
|
||||
void setFunctionBox(js::frontend::FunctionBox* funbox) {
|
||||
MOZ_ASSERT(isInterpreted());
|
||||
flags_ |= BEING_PARSED;
|
||||
u.i.funbox_ = funbox;
|
||||
}
|
||||
|
||||
void unsetFunctionBox() {
|
||||
MOZ_ASSERT(isBeingParsed());
|
||||
flags_ &= ~BEING_PARSED;
|
||||
u.i.funbox_ = nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
static inline size_t offsetOfNargs() { return offsetof(JSFunction, nargs_); }
|
||||
static inline size_t offsetOfFlags() { return offsetof(JSFunction, flags_); }
|
||||
static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
|
||||
|
@ -398,6 +436,11 @@ class JSFunction : public js::NativeObject
|
|||
return u.i.s.lazy_;
|
||||
}
|
||||
|
||||
js::frontend::FunctionBox* functionBox() const {
|
||||
MOZ_ASSERT(isBeingParsed());
|
||||
return u.i.funbox_;
|
||||
}
|
||||
|
||||
js::GeneratorKind generatorKind() const {
|
||||
if (!isInterpreted())
|
||||
return js::NotGenerator;
|
||||
|
|
|
@ -2650,10 +2650,6 @@ JSScript::linkToFunctionFromEmitter(js::ExclusiveContext* cx, JS::Handle<JSScrip
|
|||
fun->setUnlazifiedScript(script);
|
||||
else
|
||||
fun->setScript(script);
|
||||
|
||||
// Switch the static scope over to the JSFunction now that we have a
|
||||
// JSScript.
|
||||
funbox->switchStaticScopeToFunction();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
|
|
@ -87,11 +87,13 @@ StaticScopeIter<allowGC>::operator++(int)
|
|||
obj = obj->template as<StaticEvalObject>().enclosingScopeForStaticScopeIter();
|
||||
} else if (obj->template is<StaticNonSyntacticScopeObjects>()) {
|
||||
obj = obj->template as<StaticNonSyntacticScopeObjects>().enclosingScopeForStaticScopeIter();
|
||||
} else if (obj->template is<StaticFunctionBoxScopeObject>()) {
|
||||
obj = obj->template as<StaticFunctionBoxScopeObject>().enclosingScopeForStaticScopeIter();
|
||||
} else if (onNamedLambda || !obj->template as<JSFunction>().isNamedLambda()) {
|
||||
onNamedLambda = false;
|
||||
obj = obj->template as<JSFunction>().nonLazyScript()->enclosingStaticScope();
|
||||
JSFunction& fun = obj->template as<JSFunction>();
|
||||
if (fun.isBeingParsed())
|
||||
obj = fun.functionBox()->enclosingStaticScope();
|
||||
else
|
||||
obj = fun.nonLazyScript()->enclosingStaticScope();
|
||||
} else {
|
||||
onNamedLambda = true;
|
||||
}
|
||||
|
@ -103,10 +105,12 @@ template <AllowGC allowGC>
|
|||
inline bool
|
||||
StaticScopeIter<allowGC>::hasSyntacticDynamicScopeObject() const
|
||||
{
|
||||
if (obj->template is<JSFunction>())
|
||||
return obj->template as<JSFunction>().isHeavyweight();
|
||||
if (obj->template is<StaticFunctionBoxScopeObject>())
|
||||
return obj->template as<StaticFunctionBoxScopeObject>().functionBox()->isHeavyweight();
|
||||
if (obj->template is<JSFunction>()) {
|
||||
JSFunction& fun = obj->template as<JSFunction>();
|
||||
if (fun.isBeingParsed())
|
||||
return fun.functionBox()->isHeavyweight();
|
||||
return fun.isHeavyweight();
|
||||
}
|
||||
if (obj->template is<StaticBlockObject>())
|
||||
return obj->template as<StaticBlockObject>().needsClone();
|
||||
if (obj->template is<StaticWithObject>())
|
||||
|
@ -190,8 +194,6 @@ inline JSFunction&
|
|||
StaticScopeIter<allowGC>::fun() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Function);
|
||||
if (maybeFunctionBox())
|
||||
return *maybeFunctionBox()->function();
|
||||
return obj->template as<JSFunction>();
|
||||
}
|
||||
|
||||
|
@ -200,8 +202,8 @@ inline frontend::FunctionBox*
|
|||
StaticScopeIter<allowGC>::maybeFunctionBox() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Function);
|
||||
if (obj->template is<StaticFunctionBoxScopeObject>())
|
||||
return obj->template as<StaticFunctionBoxScopeObject>().functionBox();
|
||||
if (fun().isBeingParsed())
|
||||
return fun().functionBox();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -593,25 +593,6 @@ const Class NonSyntacticVariablesObject::class_ = {
|
|||
JSCLASS_IS_ANONYMOUS
|
||||
};
|
||||
|
||||
/* static */ StaticFunctionBoxScopeObject*
|
||||
StaticFunctionBoxScopeObject::create(ExclusiveContext* cx, HandleObject enclosing)
|
||||
{
|
||||
StaticFunctionBoxScopeObject* obj =
|
||||
NewObjectWithNullTaggedProto<StaticFunctionBoxScopeObject>(cx, GenericObject,
|
||||
BaseShape::DELEGATE);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
obj->setReservedSlot(SCOPE_CHAIN_SLOT, ObjectOrNullValue(enclosing));
|
||||
return obj;
|
||||
}
|
||||
|
||||
const Class StaticFunctionBoxScopeObject::class_ = {
|
||||
"StaticFunctionBoxScopeObject",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(StaticFunctionBoxScopeObject::RESERVED_SLOTS) |
|
||||
JSCLASS_IS_ANONYMOUS
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* static */ ClonedBlockObject*
|
||||
|
@ -2599,7 +2580,7 @@ js::DumpStaticScopeChain(JSObject* staticScope)
|
|||
for (StaticScopeIter<NoGC> ssi(staticScope); !ssi.done(); ssi++) {
|
||||
switch (ssi.type()) {
|
||||
case StaticScopeIter<NoGC>::Function:
|
||||
if (ssi.maybeFunctionBox())
|
||||
if (ssi.fun().isBeingParsed())
|
||||
fprintf(stdout, "funbox [%p fun=%p]", ssi.maybeFunctionBox(), &ssi.fun());
|
||||
else
|
||||
fprintf(stdout, "function [%p]", &ssi.fun());
|
||||
|
|
|
@ -26,7 +26,6 @@ class FunctionBox;
|
|||
class StaticWithObject;
|
||||
class StaticEvalObject;
|
||||
class StaticNonSyntacticScopeObjects;
|
||||
class StaticFunctionBoxScopeObject;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -59,10 +58,6 @@ class StaticFunctionBoxScopeObject;
|
|||
* StaticNonSyntacticScopeObjects
|
||||
* Signals presence of "polluting" scope objects. Used by Gecko.
|
||||
*
|
||||
* StaticFunctionBoxScopeObject
|
||||
* Stands in for JSFunctions in the Parser, before their JSScripts
|
||||
* are compiled.
|
||||
*
|
||||
* There is an additional scope for named lambdas without a static scope
|
||||
* object. E.g., in:
|
||||
*
|
||||
|
@ -83,7 +78,6 @@ class StaticScopeIter
|
|||
obj->is<StaticWithObject>() ||
|
||||
obj->is<StaticEvalObject>() ||
|
||||
obj->is<StaticNonSyntacticScopeObjects>() ||
|
||||
obj->is<StaticFunctionBoxScopeObject>() ||
|
||||
obj->is<JSFunction>();
|
||||
}
|
||||
|
||||
|
@ -459,33 +453,6 @@ class NonSyntacticVariablesObject : public ScopeObject
|
|||
static NonSyntacticVariablesObject* create(JSContext* cx, Handle<GlobalObject*> global);
|
||||
};
|
||||
|
||||
// Function static scopes that wrap around FunctionBoxes used in the Parser,
|
||||
// before a JSScript has been created.
|
||||
class StaticFunctionBoxScopeObject : public ScopeObject
|
||||
{
|
||||
static const unsigned FUNCTION_BOX_SLOT = 1;
|
||||
|
||||
public:
|
||||
static const unsigned RESERVED_SLOTS = 2;
|
||||
static const Class class_;
|
||||
|
||||
static StaticFunctionBoxScopeObject* create(ExclusiveContext* cx,
|
||||
HandleObject enclosing);
|
||||
|
||||
void setFunctionBox(frontend::FunctionBox* funbox) {
|
||||
setReservedSlot(FUNCTION_BOX_SLOT, PrivateValue(funbox));
|
||||
}
|
||||
|
||||
frontend::FunctionBox* functionBox() {
|
||||
return reinterpret_cast<frontend::FunctionBox*>(
|
||||
getReservedSlot(FUNCTION_BOX_SLOT).toPrivate());
|
||||
}
|
||||
|
||||
JSObject* enclosingScopeForStaticScopeIter() {
|
||||
return getReservedSlot(SCOPE_CHAIN_SLOT).toObjectOrNull();
|
||||
}
|
||||
};
|
||||
|
||||
class NestedScopeObject : public ScopeObject
|
||||
{
|
||||
public:
|
||||
|
|
Загрузка…
Ссылка в новой задаче