Bug 568953 - Implement ModuleBox; r=jorendorff

This commit is contained in:
Eddy Bruel 2013-01-18 14:24:09 +01:00
parent 14cd5d771b
commit 934df64ff5
6 changed files with 58 additions and 4 deletions

View File

@ -1673,7 +1673,10 @@ BytecodeEmitter::needsImplicitThis()
if (!script->compileAndGo)
return true;
if (sc->isFunctionBox()) {
if (sc->isModuleBox()) {
/* Modules can never occur inside a with-statement */
return false;
} if (sc->isFunctionBox()) {
if (sc->asFunctionBox()->inWith)
return true;
} else {

View File

@ -4,7 +4,7 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "builtin/Module.h"
#include "frontend/ParseNode.h"
#include "frontend/Parser.h"
@ -808,6 +808,13 @@ ObjectBox::ObjectBox(JSFunction *function, ObjectBox* traceLink)
JS_ASSERT(asFunctionBox()->function() == function);
}
ModuleBox *
ObjectBox::asModuleBox()
{
JS_ASSERT(isModuleBox());
return static_cast<ModuleBox *>(this);
}
FunctionBox *
ObjectBox::asFunctionBox()
{
@ -815,12 +822,22 @@ ObjectBox::asFunctionBox()
return static_cast<FunctionBox *>(this);
}
ObjectBox::ObjectBox(Module *module, ObjectBox* traceLink)
: object(module),
traceLink(traceLink),
emitLink(NULL)
{
JS_ASSERT(object->isModule());
}
void
ObjectBox::trace(JSTracer *trc)
{
ObjectBox *box = this;
while (box) {
MarkObjectRoot(trc, &box->object, "parser.object");
if (box->isModuleBox())
box->asModuleBox()->bindings.trace(trc);
if (box->isFunctionBox())
box->asFunctionBox()->bindings.trace(trc);
box = box->traceLink;

View File

@ -604,8 +604,8 @@ struct ParseNode {
struct { /* name, labeled statement, etc. */
union {
JSAtom *atom; /* lexical name or label atom */
FunctionBox *funbox; /* function object */
ObjectBox *objbox; /* block or regexp object */
FunctionBox *funbox; /* function object */
};
union {
ParseNode *expr; /* function body, var initializer, argument default,
@ -1497,12 +1497,16 @@ LinkUseToDef(ParseNode *pn, Definition *dn)
pn->pn_lexdef = dn;
}
class ModuleBox;
class ObjectBox {
public:
JSObject *object;
ObjectBox(JSObject *object, ObjectBox *traceLink);
bool isModuleBox() { return object->isModule(); }
bool isFunctionBox() { return object->isFunction(); }
ModuleBox *asModuleBox();
FunctionBox *asFunctionBox();
void trace(JSTracer *trc);
@ -1513,6 +1517,7 @@ class ObjectBox {
ObjectBox *emitLink;
ObjectBox(JSFunction *function, ObjectBox *traceLink);
ObjectBox(Module *module, ObjectBox *traceLink);
};
} /* namespace frontend */

View File

@ -394,7 +394,7 @@ FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fu
// outerpc->parsingWith is true.
inWith = true;
} else if (!outerpc->sc->isFunctionBox()) {
} else if (outerpc->sc->isGlobalSharedContext()) {
// This covers the case where a function is nested within an eval()
// within a |with| statement.
//
@ -449,6 +449,13 @@ Parser::newFunctionBox(JSFunction *fun, ParseContext *outerpc, bool strict)
return funbox;
}
ModuleBox::ModuleBox(JSContext *cx, ParseContext *pc, Module *module,
ObjectBox *traceListHead)
: ObjectBox(module, traceListHead),
SharedContext(cx, true)
{
}
void
Parser::trace(JSTracer *trc)
{

View File

@ -35,6 +35,13 @@ SharedContext::asGlobalSharedContext()
return static_cast<GlobalSharedContext*>(this);
}
inline ModuleBox *
SharedContext::asModuleBox()
{
JS_ASSERT(isModuleBox());
return static_cast<ModuleBox*>(this);
}
inline FunctionBox *
SharedContext::asFunctionBox()
{

View File

@ -147,8 +147,10 @@ class SharedContext
virtual ObjectBox *toObjectBox() = 0;
inline bool isGlobalSharedContext() { return toObjectBox() == NULL; }
inline bool isModuleBox() { return toObjectBox() && toObjectBox()->isModuleBox(); }
inline bool isFunctionBox() { return toObjectBox() && toObjectBox()->isFunctionBox(); }
inline GlobalSharedContext *asGlobalSharedContext();
inline ModuleBox *asModuleBox();
inline FunctionBox *asFunctionBox();
bool hasExplicitUseStrict() const { return anyCxFlags.hasExplicitUseStrict; }
@ -173,6 +175,19 @@ class GlobalSharedContext : public SharedContext
JSObject *scopeChain() const { return scopeChain_; }
};
class ModuleBox : public ObjectBox, public SharedContext {
public:
size_t bufStart;
size_t bufEnd;
Bindings bindings;
ModuleBox(JSContext *cx, ParseContext *pc, Module *module,
ObjectBox *traceListHead);
ObjectBox *toObjectBox() { return this; }
Module *module() const { return &object->asModule(); }
};
class FunctionBox : public ObjectBox, public SharedContext
{
public: