Bug 788957 (part 1) - Change FunctionBox so it has an ObjectBox rather than is an ObjectBox. r=benjamin.

--HG--
extra : rebase_source : b7f2465bddce85a641be03c7120be8b949653bd2
This commit is contained in:
Nicholas Nethercote 2012-09-10 17:58:32 -07:00
parent 88360f0511
commit 1d3a09e9e5
7 changed files with 31 additions and 21 deletions

View File

@ -4880,7 +4880,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
/* Make the function object a literal in the outer script's pool. */
unsigned index = bce->objectList.add(pn->pn_funbox);
unsigned index = bce->objectList.add(&pn->pn_funbox->objbox);
/* Non-hoisted functions simply emit their respective op. */
if (!pn->functionIsHoisted()) {

View File

@ -445,7 +445,7 @@ CloneParseTree(ParseNode *opn, Parser *parser)
case PN_FUNC:
NULLCHECK(pn->pn_funbox =
parser->newFunctionBox(opn->pn_funbox->object, pc, opn->pn_funbox->strictModeState));
parser->newFunctionBox(opn->pn_funbox->fun(), pc, opn->pn_funbox->strictModeState));
NULLCHECK(pn->pn_body = CloneParseTree(opn->pn_body, parser));
pn->pn_cookie = opn->pn_cookie;
pn->pn_dflags = opn->pn_dflags;

View File

@ -1465,9 +1465,14 @@ struct ObjectBox {
ObjectBox *traceLink;
ObjectBox *emitLink;
JSObject *object;
bool isFunctionBox;
// An ObjectBox can hold a JSObject or a JSFunction. In the latter case,
// the ObjectBox will be embedded within a FunctionBox; |funbox| points to
// that FunctionBox.
FunctionBox *const funbox;
ObjectBox(ObjectBox *traceLink, JSObject *obj);
ObjectBox(ObjectBox *traceLink, JSFunction *fun, FunctionBox *funbox);
};
} /* namespace frontend */

View File

@ -362,7 +362,15 @@ ObjectBox::ObjectBox(ObjectBox* traceLink, JSObject *obj)
: traceLink(traceLink),
emitLink(NULL),
object(obj),
isFunctionBox(false)
funbox(NULL)
{
}
ObjectBox::ObjectBox(ObjectBox* traceLink, JSFunction *fun, FunctionBox *funbox)
: traceLink(traceLink),
emitLink(NULL),
object(fun),
funbox(funbox)
{
}
@ -390,9 +398,9 @@ Parser::newObjectBox(JSObject *obj)
return objbox;
}
FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *outerpc,
FunctionBox::FunctionBox(ObjectBox *traceListHead, JSFunction *fun, ParseContext *outerpc,
StrictMode sms)
: ObjectBox(traceListHead, obj),
: objbox(traceListHead, fun, this),
siblings(outerpc ? outerpc->functionList : NULL),
kids(NULL),
bindings(),
@ -404,8 +412,6 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *
inGenexpLambda(false),
cxFlags() // the cxFlags are set in LeaveFunction
{
isFunctionBox = true;
if (!outerpc) {
inWith = false;
@ -450,10 +456,9 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *
}
FunctionBox *
Parser::newFunctionBox(JSObject *obj, ParseContext *outerpc, StrictMode sms)
Parser::newFunctionBox(JSFunction *fun, ParseContext *outerpc, StrictMode sms)
{
JS_ASSERT(obj && !IsPoisonedPtr(obj));
JS_ASSERT(obj->isFunction());
JS_ASSERT(fun && !IsPoisonedPtr(fun));
/*
* We use JSContext.tempLifoAlloc to allocate parsed objects and place them
@ -463,7 +468,7 @@ Parser::newFunctionBox(JSObject *obj, ParseContext *outerpc, StrictMode sms)
* function.
*/
FunctionBox *funbox =
context->tempLifoAlloc().new_<FunctionBox>(traceListHead, obj, outerpc, sms);
context->tempLifoAlloc().new_<FunctionBox>(traceListHead, fun, outerpc, sms);
if (!funbox) {
js_ReportOutOfMemory(context);
return NULL;
@ -471,7 +476,7 @@ Parser::newFunctionBox(JSObject *obj, ParseContext *outerpc, StrictMode sms)
if (outerpc)
outerpc->functionList = funbox;
traceListHead = funbox;
traceListHead = &funbox->objbox;
return funbox;
}
@ -482,8 +487,8 @@ Parser::trace(JSTracer *trc)
ObjectBox *objbox = traceListHead;
while (objbox) {
MarkObjectRoot(trc, &objbox->object, "parser.object");
if (objbox->isFunctionBox)
static_cast<FunctionBox *>(objbox)->bindings.trace(trc);
if (objbox->funbox)
objbox->funbox->bindings.trace(trc);
objbox = objbox->traceLink;
}
}

View File

@ -303,7 +303,7 @@ struct Parser : private AutoGCRooter
*/
ObjectBox *newObjectBox(JSObject *obj);
FunctionBox *newFunctionBox(JSObject *obj, ParseContext *pc, StrictMode sms);
FunctionBox *newFunctionBox(JSFunction *fun, ParseContext *pc, StrictMode sms);
/*
* Create a new function object given parse context (pc) and a name (which

View File

@ -283,8 +283,9 @@ struct StmtInfoBase {
}
};
struct FunctionBox : public ObjectBox
struct FunctionBox
{
ObjectBox objbox;
FunctionBox *siblings;
FunctionBox *kids;
Bindings bindings; /* bindings for this function */
@ -298,12 +299,11 @@ struct FunctionBox : public ObjectBox
ContextFlags cxFlags;
FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseContext *pc,
StrictMode sms);
FunctionBox(ObjectBox *traceListHead, JSFunction *fun, ParseContext *pc, StrictMode sms);
bool funIsGenerator() const { return cxFlags.funIsGenerator; }
JSFunction *fun() const { return (JSFunction *) object; }
JSFunction *fun() const { return objbox.object->toFunction(); }
void recursivelySetStrictMode(StrictMode strictness);
};

View File

@ -3100,7 +3100,7 @@ ASTSerializer::identifier(ParseNode *pn, Value *dst)
bool
ASTSerializer::function(ParseNode *pn, ASTType type, Value *dst)
{
JSFunction *func = (JSFunction *)pn->pn_funbox->object;
JSFunction *func = pn->pn_funbox->fun();
bool isGenerator =
#if JS_HAS_GENERATORS