--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -60,17 +60,17 @@ using namespace js::frontend;
static bool
NewTryNote(JSContext *cx, BytecodeEmitter *bce, JSTryNoteKind kind, unsigned stackDepth,
size_t start, size_t end);
static bool
SetSrcNoteOffset(JSContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which, ptrdiff_t offset);
-struct js::StmtInfoBCE : public js::StmtInfoBase
+struct frontend::StmtInfoBCE : public StmtInfoBase
{
StmtInfoBCE *down; /* info for enclosing statement */
StmtInfoBCE *downScope; /* next enclosing lexical scope */
ptrdiff_t update; /* loop update offset (top if none) */
ptrdiff_t breaks; /* offset of last break in loop */
ptrdiff_t continues; /* offset of last continue in loop */
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -20,16 +20,17 @@
#include "frontend/Parser.h"
#include "frontend/ParseMaps.h"
#include "frontend/TreeContext.h"
#include "vm/ScopeObject.h"
namespace js {
+namespace frontend {
struct TryNode {
JSTryNote note;
TryNode *prev;
};
struct CGObjectList {
uint32_t length; /* number of emitted so far objects */
@@ -179,18 +180,16 @@ struct BytecodeEmitter
inline ptrdiff_t countFinalSourceNotes();
bool reportError(ParseNode *pn, unsigned errorNumber, ...);
bool reportStrictWarning(ParseNode *pn, unsigned errorNumber, ...);
bool reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...);
};
-namespace frontend {
-
/*
* Emit one bytecode.
*/
ptrdiff_t
Emit1(JSContext *cx, BytecodeEmitter *bce, JSOp op);
/*
* Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1).
@@ -405,18 +404,16 @@ jssrcnote *
AddToSrcNoteDelta(JSContext *cx, BytecodeEmitter *bce, jssrcnote *sn, ptrdiff_t delta);
bool
FinishTakingSrcNotes(JSContext *cx, BytecodeEmitter *bce, jssrcnote *notes);
void
FinishTakingTryNotes(BytecodeEmitter *bce, TryNoteArray *array);
-} /* namespace frontend */
-
/*
* Finish taking source notes in cx's notePool, copying final notes to the new
* stable store allocated by the caller and passed in via notes. Return false
* on malloc failure, which means this function reported an error.
*
* Use this to compute the number of jssrcnotes to allocate and pass in via
* notes. This method knows a lot about details of FinishTakingSrcNotes, so
* DON'T CHANGE js::frontend::FinishTakingSrcNotes WITHOUT CHECKING WHETHER
@@ -461,16 +458,17 @@ inline size_t LetDataToOffset(ptrdiff_t
return size_t(w) >> 1;
}
inline bool LetDataToGroupAssign(ptrdiff_t w)
{
return size_t(w) & 1;
}
+} /* namespace frontend */
} /* namespace js */
struct JSSrcNoteSpec {
const char *name; /* name for disassembly/debugging output */
int8_t arity; /* number of offset operands */
};
extern JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[];
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -19,16 +19,17 @@
#include "vm/NumericConversions.h"
#include "jsatominlines.h"
#include "frontend/TreeContext-inl.h"
#include "vm/String-inl.h"
using namespace js;
+using namespace js::frontend;
static ParseNode *
ContainsVarOrConst(ParseNode *pn)
{
if (!pn)
return NULL;
if (pn->isKind(PNK_VAR) || pn->isKind(PNK_CONST))
return pn;
@@ -396,17 +397,18 @@ Boolish(ParseNode *pn)
return Falsy;
default:
return Unknown;
}
}
bool
-js::FoldConstants(JSContext *cx, ParseNode *pn, Parser *parser, bool inGenexpLambda, bool inCond)
+frontend::FoldConstants(JSContext *cx, ParseNode *pn, Parser *parser, bool inGenexpLambda,
+ bool inCond)
{
ParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
JS_CHECK_RECURSION(cx, return false);
switch (pn->getArity()) {
case PN_FUNC:
if (!FoldConstants(cx, pn->pn_body, parser, pn->pn_funbox->inGenexpLambda))
--- a/js/src/frontend/FoldConstants.h
+++ b/js/src/frontend/FoldConstants.h
@@ -6,16 +6,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef FoldConstants_h__
#define FoldConstants_h__
#include "jsprvtd.h"
namespace js {
+namespace frontend {
bool
FoldConstants(JSContext *cx, ParseNode *pn, Parser *parser, bool inGenexpLambda = false,
bool inCond = false);
+} /* namespace frontend */
} /* namespace js */
#endif /* FoldConstants_h__ */
--- a/js/src/frontend/ParseMaps-inl.h
+++ b/js/src/frontend/ParseMaps-inl.h
@@ -6,20 +6,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ParseMapPool_inl_h__
#define ParseMapPool_inl_h__
#include "jscntxt.h"
#include "frontend/ParseNode.h" /* Need sizeof(js::Definition). */
-
-#include "ParseMaps.h"
+#include "frontend/ParseMaps.h"
namespace js {
+namespace frontend {
template <>
inline AtomDefnMap *
ParseMapPool::acquire<AtomDefnMap>()
{
return reinterpret_cast<AtomDefnMap *>(allocate());
}
@@ -108,11 +108,12 @@ AtomDecls::init()
inline
AtomDecls::~AtomDecls()
{
if (map)
cx->parseMapPool().release(map);
}
+} /* namespace frontend */
} /* namespace js */
#endif
--- a/js/src/frontend/ParseMaps.cpp
+++ b/js/src/frontend/ParseMaps.cpp
@@ -5,16 +5,17 @@
* 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 "ParseMaps-inl.h"
#include "jscntxt.h"
#include "jscompartment.h"
using namespace js;
+using namespace js::frontend;
void
ParseMapPool::checkInvariants()
{
/*
* Having all values be of the same size permits us to easily reuse the
* allocated space for each of the map types.
*/
@@ -148,8 +149,32 @@ AtomDecls::addShadow(JSAtom *atom, Defin
bool
AtomDecls::addHoist(JSAtom *atom, Definition *defn)
{
AtomDefnListAddPtr p = map->lookupForAdd(atom);
if (p)
return p.value().pushBack(cx, defn);
return map->add(p, atom, DefinitionList(defn));
}
+
+void
+frontend::InitAtomMap(JSContext *cx, frontend::AtomIndexMap *indices, HeapPtrAtom *atoms)
+{
+ if (indices->isMap()) {
+ typedef AtomIndexMap::WordMap WordMap;
+ const WordMap &wm = indices->asMap();
+ for (WordMap::Range r = wm.all(); !r.empty(); r.popFront()) {
+ JSAtom *atom = r.front().key;
+ jsatomid index = r.front().value;
+ JS_ASSERT(index < indices->count());
+ atoms[index].init(atom);
+ }
+ } else {
+ for (const AtomIndexMap::InlineElem *it = indices->asInline(), *end = indices->inlineEnd();
+ it != end; ++it) {
+ JSAtom *atom = it->key;
+ if (!atom)
+ continue;
+ JS_ASSERT(it->value < indices->count());
+ atoms[it->value].init(atom);
+ }
+ }
+}
--- a/js/src/frontend/ParseMaps.h
+++ b/js/src/frontend/ParseMaps.h
@@ -10,22 +10,34 @@
#include "mozilla/Attributes.h"
#include "ds/InlineMap.h"
#include "js/HashTable.h"
#include "js/Vector.h"
namespace js {
+namespace frontend {
struct Definition;
+class DefinitionList;
+typedef InlineMap<JSAtom *, jsatomid, 24> AtomIndexMap;
+typedef InlineMap<JSAtom *, Definition *, 24> AtomDefnMap;
typedef InlineMap<JSAtom *, DefinitionList, 24> AtomDefnListMap;
/*
+ * For all unmapped atoms recorded in al, add a mapping from the atom's index
+ * to its address. map->length must already be set to the number of atoms in
+ * the list and map->vector must point to pre-allocated memory.
+ */
+void
+InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtr<JSAtom> *atoms);
+
+/*
* A pool that permits the reuse of the backing storage for the defn, index, or
* defn-or-header (multi) maps.
*
* The pool owns all the maps that are given out, and is responsible for
* relinquishing all resources when |purgeAll| is triggered.
*/
class ParseMapPool
{
@@ -305,24 +317,16 @@ class DefinitionList
Range all() const { return Range(*this); }
#ifdef DEBUG
void dump();
#endif
};
-namespace tl {
-
-template <> struct IsPodType<DefinitionList> {
- static const bool result = true;
-};
-
-} /* namespace tl */
-
/*
* Multimap for function-scope atom declarations.
*
* Wraps an internal DefinitionList map with multi-map functionality.
*
* In the common case, no block scoping is used, and atoms have a single
* associated definition. In the uncommon (block scoping) case, we map the atom
* to a chain of definition nodes.
@@ -396,11 +400,21 @@ typedef AtomDefnMap::Range AtomDefn
typedef AtomDefnMap::AddPtr AtomDefnAddPtr;
typedef AtomDefnMap::Ptr AtomDefnPtr;
typedef AtomIndexMap::AddPtr AtomIndexAddPtr;
typedef AtomIndexMap::Ptr AtomIndexPtr;
typedef AtomDefnListMap::Ptr AtomDefnListPtr;
typedef AtomDefnListMap::AddPtr AtomDefnListAddPtr;
typedef AtomDefnListMap::Range AtomDefnListRange;
+} /* namespace frontend */
+
+namespace tl {
+
+template <> struct IsPodType<frontend::DefinitionList> {
+ static const bool result = true;
+};
+
+} /* namespace tl */
+
} /* namepsace js */
#endif
--- a/js/src/frontend/ParseNode-inl.h
+++ b/js/src/frontend/ParseNode-inl.h
@@ -9,16 +9,17 @@
#include "frontend/ParseNode.h"
#include "frontend/TokenStream.h"
#include "frontend/TreeContext.h"
#include "frontend/TreeContext-inl.h"
namespace js {
+namespace frontend {
inline bool
UpvarCookie::set(JSContext *cx, unsigned newLevel, uint16_t newSlot)
{
// This is an unsigned-to-uint16_t conversion, test for too-high values.
// In practice, recursion in Parser and/or BytecodeEmitter will blow the
// stack if we nest functions more than a few hundred deep, so this will
// never trigger. Oh well.
@@ -188,11 +189,12 @@ NameNode::initCommon(TreeContext *tc)
pn_expr = NULL;
pn_cookie.makeFree();
pn_dflags = (!tc->topStmt || tc->topStmt->type == STMT_BLOCK)
? PND_BLOCKCHILD
: 0;
pn_blockid = tc->blockid();
}
+} /* namespace frontend */
} /* namespace js */
#endif /* ParseNode_inl_h__ */
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -9,16 +9,17 @@
#include "frontend/Parser.h"
#include "jsscriptinlines.h"
#include "frontend/ParseMaps-inl.h"
#include "frontend/ParseNode-inl.h"
using namespace js;
+using namespace js::frontend;
/*
* Asserts to verify assumptions behind pn_ macros.
*/
#define pn_offsetof(m) offsetof(ParseNode, m)
JS_STATIC_ASSERT(pn_offsetof(pn_link) == pn_offsetof(dn_uses));
@@ -565,17 +566,17 @@ CloneParseTree(ParseNode *opn, Parser *p
*
* opn must be the pn_head of a node produced by Parser::variables, so its form
* is known to be LHS = NAME | [LHS] | {id:LHS}.
*
* The cloned tree is for use only in the same statement and binding context as
* the original tree.
*/
ParseNode *
-js::CloneLeftHandSide(ParseNode *opn, Parser *parser)
+frontend::CloneLeftHandSide(ParseNode *opn, Parser *parser)
{
ParseNode *pn = parser->new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
opn->pn_pos);
if (!pn)
return NULL;
pn->setInParens(opn->isInParens());
pn->setDefn(opn->isDefn());
pn->setUsed(opn->isUsed());
@@ -636,16 +637,16 @@ js::CloneLeftHandSide(ParseNode *opn, Pa
LinkUseToDef(pn, (Definition *) opn);
}
}
return pn;
}
#ifdef DEBUG
void
-js::DumpParseTree(ParseNode *pn, int indent)
+frontend::DumpParseTree(ParseNode *pn, int indent)
{
if (pn == NULL)
fprintf(stderr, "()");
else
pn->dump(indent);
}
#endif
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -12,16 +12,17 @@
#include "jsscript.h"
#include "frontend/ParseMaps.h"
#include "frontend/TokenStream.h"
#include "frontend/TreeContext.h"
namespace js {
+namespace frontend {
/*
* Indicates a location in the stack that an upvar value can be retrieved from
* as a two tuple of (level, slot).
*
* Some existing client code uses the level value as a delta, or level "skip"
* quantity. We could probably document that through use of more types at some
* point in the future.
@@ -1532,11 +1533,12 @@ struct FunctionBox : public ObjectBox
/*
* True if this function is inside the scope of a with-statement, an E4X
* filter-expression, or a function that uses direct eval.
*/
bool inAnyDynamicScope() const;
};
+} /* namespace frontend */
} /* namespace js */
#endif /* ParseNode_h__ */
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -885,17 +885,17 @@ MakeDefIntoUse(Definition *dn, ParseNode
dn->setUsed(true);
dn->pn_lexdef = (Definition *) pn;
dn->pn_cookie.makeFree();
dn->pn_dflags &= ~PND_BOUND;
return dn;
}
bool
-js::DefineArg(ParseNode *pn, JSAtom *atom, unsigned i, Parser *parser)
+frontend::DefineArg(ParseNode *pn, JSAtom *atom, unsigned i, Parser *parser)
{
/*
* Make an argument definition node, distinguished by being in
* parser->tc->decls but having PNK_NAME kind and JSOP_NOP op. Insert it in
* a PNK_ARGSBODY list node returned via pn->pn_body.
*/
ParseNode *argpn = NameNode::create(PNK_NAME, atom, parser, parser->tc);
if (!argpn)
@@ -928,17 +928,17 @@ typedef bool
(*Binder)(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
static bool
BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
static bool
BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
-struct BindData {
+struct frontend::BindData {
BindData(JSContext *cx) : let(cx), fresh(true) {}
ParseNode *pn; /* name node for definition processing and
error source coordinates */
JSOp op; /* prolog bytecode or nop */
Binder binder; /* binder, discriminates u */
struct LetData {
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -17,21 +17,20 @@
#include "jsatom.h"
#include "jsscript.h"
#include "jswin.h"
#include "frontend/ParseMaps.h"
#include "frontend/ParseNode.h"
#include "frontend/TreeContext.h"
-typedef struct BindData BindData;
+namespace js {
+namespace frontend {
-namespace js {
-
-class StaticBlockObject;
+struct BindData;
enum FunctionSyntaxKind { Expression, Statement };
enum LetContext { LetExpresion, LetStatement };
enum VarContext { HoistVars, DontHoistVars };
struct Parser : private AutoGCRooter
{
JSContext *const context; /* FIXME Bug 551291: use AutoGCRooter::context? */
@@ -100,17 +99,17 @@ struct Parser : private AutoGCRooter
/*
* Report a parse (compile) error.
*/
inline bool reportError(ParseNode *pn, unsigned errorNumber, ...);
inline bool reportUcError(ParseNode *pn, unsigned errorNumber, ...);
inline bool reportWarning(ParseNode *pn, unsigned errorNumber, ...);
inline bool reportStrictWarning(ParseNode *pn, unsigned errorNumber, ...);
inline bool reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...);
- typedef bool (js::Parser::*Reporter)(ParseNode *pn, unsigned errorNumber, ...);
+ typedef bool (Parser::*Reporter)(ParseNode *pn, unsigned errorNumber, ...);
private:
ParseNode *allocParseNode(size_t size) {
JS_ASSERT(size == sizeof(ParseNode));
return static_cast<ParseNode *>(allocator.allocNode());
}
/*
@@ -303,16 +302,17 @@ Parser::reportStrictModeError(ParseNode
bool result = tokenStream.reportStrictModeErrorNumberVA(pn, errorNumber, args);
va_end(args);
return result;
}
bool
DefineArg(ParseNode *pn, JSAtom *atom, unsigned i, Parser *parser);
+} /* namespace frontend */
} /* namespace js */
/*
* Convenience macro to access Parser.tokenStream as a pointer.
*/
#define TS(p) (&(p)->tokenStream)
#endif /* Parser_h__ */
--- a/js/src/frontend/SemanticAnalysis.h
+++ b/js/src/frontend/SemanticAnalysis.h
@@ -5,25 +5,26 @@
* 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/. */
#ifndef SemanticAnalysis_h__
#define SemanticAnalysis_h__
namespace js {
-struct Parser;
class StackFrame;
namespace frontend {
+class Parser;
+
/*
- * For each function in the compilation unit given by tc, decide whether the
- * function is a full closure or a null closure and set JSFunction flags
- * accordingly.
+ * For each function in the compilation unit given by sc and functionList,
+ * decide whether the function is a full closure or a null closure and set
+ * JSFunction flags accordingly.
*/
bool
AnalyzeFunctions(Parser *parser, StackFrame *callerFrame);
} /* namespace frontend */
} /* namespace js */
#endif /* SemanticAnalysis_h__ */
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -38,32 +38,33 @@
#include "jsscriptinlines.h"
#if JS_HAS_XML_SUPPORT
#include "jsxml.h"
#endif
using namespace js;
+using namespace js::frontend;
using namespace js::unicode;
#define JS_KEYWORD(keyword, type, op, version) \
const char js_##keyword##_str[] = #keyword;
#include "jskeyword.tbl"
#undef JS_KEYWORD
static const KeywordInfo keywords[] = {
#define JS_KEYWORD(keyword, type, op, version) \
{js_##keyword##_str, type, op, version},
#include "jskeyword.tbl"
#undef JS_KEYWORD
};
const KeywordInfo *
-js::FindKeyword(const jschar *s, size_t length)
+frontend::FindKeyword(const jschar *s, size_t length)
{
JS_ASSERT(length != 0);
register size_t i;
const struct KeywordInfo *kw;
const char *chars;
#define JSKW_LENGTH() length
@@ -90,17 +91,17 @@ js::FindKeyword(const jschar *s, size_t
} while (--length != 0);
return kw;
no_match:
return NULL;
}
bool
-js::IsIdentifier(JSLinearString *str)
+frontend::IsIdentifier(JSLinearString *str)
{
const jschar *chars = str->chars();
size_t length = str->length();
if (length == 0)
return false;
jschar c = *chars;
if (!IsIdentifierStart(c))
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -22,16 +22,17 @@
#include "js/Vector.h"
#define JS_KEYWORD(keyword, type, op, version) \
extern const char js_##keyword##_str[];
#include "jskeyword.tbl"
#undef JS_KEYWORD
namespace js {
+namespace frontend {
enum TokenKind {
TOK_ERROR = -1, /* well-known as the only code < EOF */
TOK_EOF, /* end of file */
TOK_EOL, /* end of line; only returned by peekTokenSameLine() */
TOK_SEMI, /* semicolon */
TOK_COMMA, /* comma operator */
TOK_HOOK, TOK_COLON, /* conditional (?:) */
@@ -833,19 +834,20 @@ bool
IsIdentifier(JSLinearString *str);
/*
* Steal one JSREPORT_* bit (see jsapi.h) to tell that arguments to the error
* message have const jschar* type, not const char*.
*/
#define JSREPORT_UC 0x100
+} /* namespace frontend */
} /* namespace js */
extern JS_FRIEND_API(int)
js_fgets(char *buf, int size, FILE *file);
#ifdef DEBUG
extern const char *
-TokenKindToString(js::TokenKind tt);
+TokenKindToString(js::frontend::TokenKind tt);
#endif
#endif /* TokenStream_h__ */
--- a/js/src/frontend/TreeContext-inl.h
+++ b/js/src/frontend/TreeContext-inl.h
@@ -9,48 +9,49 @@
#define TreeContext_inl_h__
#include "frontend/Parser.h"
#include "frontend/TreeContext.h"
#include "frontend/ParseMaps-inl.h"
namespace js {
+namespace frontend {
inline
SharedContext::SharedContext(JSContext *cx, JSObject *scopeChain, JSFunction *fun,
FunctionBox *funbox)
: context(cx),
fun_(cx, fun),
funbox_(funbox),
scopeChain_(cx, scopeChain),
bindings(),
bindingsRoot(cx, &bindings),
cxFlags(cx)
{
JS_ASSERT((fun && !scopeChain_) || (!fun && !funbox));
}
+inline bool
+SharedContext::needStrictChecks() {
+ return context->hasStrictOption() || inStrictMode();
+}
+
inline unsigned
TreeContext::blockid()
{
return topStmt ? topStmt->blockid : bodyid;
}
inline bool
TreeContext::atBodyLevel()
{
return !topStmt || topStmt->isFunctionBodyBlock;
}
-inline bool
-SharedContext::needStrictChecks() {
- return context->hasStrictOption() || inStrictMode();
-}
-
inline
TreeContext::TreeContext(Parser *prs, SharedContext *sc, unsigned staticLevel, uint32_t bodyid)
: sc(sc),
bodyid(0), // initialized in init()
blockidGen(bodyid), // used to set |bodyid| and subsequently incremented in init()
topStmt(NULL),
topScopeStmt(NULL),
blockChain(prs->context),
@@ -91,16 +92,18 @@ TreeContext::~TreeContext()
{
// |*parserTC| pointed to this object. Now that this object is about to
// die, make |*parserTC| point to this object's parent.
JS_ASSERT(*parserTC == this);
*parserTC = this->parent;
sc->context->delete_(funcStmts);
}
+} /* namespace frontend */
+
template <class ContextT>
void
frontend::PushStatement(ContextT *ct, typename ContextT::StmtInfo *stmt, StmtType type)
{
stmt->type = type;
stmt->isBlockScope = false;
stmt->isForLetBlock = false;
stmt->label = NULL;
--- a/js/src/frontend/TreeContext.h
+++ b/js/src/frontend/TreeContext.h
@@ -14,19 +14,18 @@
#include "jsscript.h"
#include "jsprvtd.h"
#include "jspubtd.h"
#include "frontend/ParseMaps.h"
#include "vm/ScopeObject.h"
-typedef struct BindData BindData;
-
namespace js {
+namespace frontend {
class ContextFlags {
// This class's data is all private and so only visible to these friends.
friend struct SharedContext;
friend struct FunctionBox;
// This function/global/eval code body contained a Use Strict Directive.
@@ -370,18 +369,16 @@ struct StmtInfoTC : public StmtInfoBase
uint32_t blockid; /* for simplified dominance computation */
/* True if type == STMT_BLOCK and this block is a function body. */
bool isFunctionBodyBlock;
StmtInfoTC(JSContext *cx) : StmtInfoBase(cx), isFunctionBodyBlock(false) {}
};
-namespace frontend {
-
bool
GenerateBlockId(TreeContext *tc, uint32_t &blockid);
// Push the C-stack-allocated struct at stmt onto the StmtInfoTC stack.
template <class ContextT>
void
PushStatement(ContextT *ct, typename ContextT::StmtInfo *stmt, StmtType type);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -82,16 +82,17 @@
#if ENABLE_YARR_JIT
#include "assembler/jit/ExecutableAllocator.h"
#include "methodjit/Logging.h"
#endif
using namespace js;
using namespace js::gc;
using namespace js::types;
+using js::frontend::Parser;
/*
* This class is a version-establishing barrier at the head of a VM entry or
* re-entry. It ensures that:
*
* - |newVersion| is the starting (default) version used for the context.
* - The starting version state is not an override.
* - Overrides in the VM session are not propagated to the caller.
@@ -6713,17 +6714,17 @@ JS_PUBLIC_API(JSBool)
JS_IsIdentifier(JSContext *cx, JSString *str, JSBool *isIdentifier)
{
assertSameCompartment(cx, str);
JSLinearString* linearStr = str->ensureLinear(cx);
if (!linearStr)
return false;
- *isIdentifier = js::IsIdentifier(linearStr);
+ *isIdentifier = js::frontend::IsIdentifier(linearStr);
return true;
}
JS_PUBLIC_API(JSBool)
JS_DescribeScriptedCaller(JSContext *cx, JSScript **script, unsigned *lineno)
{
if (script)
*script = NULL;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -906,17 +906,17 @@ class JS_PUBLIC_API(AutoGCRooter) {
* below. Any other negative value indicates some deeper problem such as
* memory corruption.
*/
ptrdiff_t tag;
enum {
JSVAL = -1, /* js::AutoValueRooter */
VALARRAY = -2, /* js::AutoValueArrayRooter */
- PARSER = -3, /* js::Parser */
+ PARSER = -3, /* js::frontend::Parser */
SHAPEVECTOR = -4, /* js::AutoShapeVector */
ENUMERATOR = -5, /* js::AutoEnumStateRooter */
IDARRAY = -6, /* js::AutoIdArray */
DESCRIPTORS = -7, /* js::AutoPropDescArrayRooter */
NAMESPACES = -8, /* js::AutoNamespaceArray */
XML = -9, /* js::AutoXMLRooter */
OBJECT = -10, /* js::AutoObjectRooter */
ID = -11, /* js::AutoIdRooter */
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -449,40 +449,16 @@ js_DumpAtoms(JSContext *cx, FILE *fp)
putc('\n', fp);
}
putc('\n', fp);
}
#endif
namespace js {
-void
-InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtrAtom *atoms)
-{
- if (indices->isMap()) {
- typedef AtomIndexMap::WordMap WordMap;
- const WordMap &wm = indices->asMap();
- for (WordMap::Range r = wm.all(); !r.empty(); r.popFront()) {
- JSAtom *atom = r.front().key;
- jsatomid index = r.front().value;
- JS_ASSERT(index < indices->count());
- atoms[index].init(atom);
- }
- } else {
- for (const AtomIndexMap::InlineElem *it = indices->asInline(), *end = indices->inlineEnd();
- it != end; ++it) {
- JSAtom *atom = it->key;
- if (!atom)
- continue;
- JS_ASSERT(it->value < indices->count());
- atoms[it->value].init(atom);
- }
- }
-}
-
bool
IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp)
{
JS_ASSERT(index > JSID_INT_MAX);
jschar buf[UINT32_CHAR_BUFFER_LENGTH];
RangedPtr<jschar> end(ArrayEnd(buf), buf, ArrayEnd(buf));
RangedPtr<jschar> start = BackfillIndexInCharBuffer(index, end);
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -421,23 +421,15 @@ InternNonIntElementId(JSContext *cx, JSO
inline bool
InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid *idp)
{
Value dummy;
return InternNonIntElementId(cx, obj, idval, idp, &dummy);
}
-/*
- * For all unmapped atoms recorded in al, add a mapping from the atom's index
- * to its address. map->length must already be set to the number of atoms in
- * the list and map->vector must point to pre-allocated memory.
- */
-extern void
-InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtr<JSAtom> *atoms);
-
template<XDRMode mode>
bool
XDRAtom(XDRState<mode> *xdr, JSAtom **atomp);
} /* namespace js */
#endif /* jsatom_h___ */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1020,17 +1020,17 @@ JSContext::JSContext(JSRuntime *rt)
#endif
#endif
}
JSContext::~JSContext()
{
/* Free the stuff hanging off of cx. */
if (parseMapPool_)
- Foreground::delete_<ParseMapPool>(parseMapPool_);
+ Foreground::delete_(parseMapPool_);
if (lastMessage)
Foreground::free_(lastMessage);
/* Remove any argument formatters. */
JSArgumentFormatMap *map = argumentFormatMap;
while (map) {
JSArgumentFormatMap *temp = map;
@@ -1187,17 +1187,17 @@ JSRuntime::onOutOfMemory(void *p, size_t
js_ReportOutOfMemory(cx);
return NULL;
}
void
JSContext::purge()
{
if (!activeCompilations) {
- Foreground::delete_<ParseMapPool>(parseMapPool_);
+ Foreground::delete_(parseMapPool_);
parseMapPool_ = NULL;
}
}
#if defined(JS_METHODJIT)
static bool
ComputeIsJITBroken()
{
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1107,17 +1107,17 @@ struct JSContext : js::ContextFriendFiel
/* Set cx->compartment based on the current scope chain. */
void resetCompartment();
/* Wrap cx->exception for the current compartment. */
void wrapPendingException();
private:
/* Lazily initialized pool of maps used during parse/emit. */
- js::ParseMapPool *parseMapPool_;
+ js::frontend::ParseMapPool *parseMapPool_;
public:
/* Top-level object and pointer to top stack frame's scope chain. */
JSObject *globalObject;
/* State for object and array toSource conversion. */
JSSharpObjectMap sharpObjectMap;
js::BusyArraysSet busyArrays;
@@ -1136,17 +1136,17 @@ struct JSContext : js::ContextFriendFiel
/* Client opaque pointers. */
void *data;
void *data2;
inline js::RegExpStatics *regExpStatics();
public:
- js::ParseMapPool &parseMapPool() {
+ js::frontend::ParseMapPool &parseMapPool() {
JS_ASSERT(parseMapPool_);
return *parseMapPool_;
}
inline bool ensureParseMapPool();
/*
* The default script compilation version can be set iff there is no code running.
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -555,17 +555,17 @@ JSContext::setPendingException(js::Value
js::assertSameCompartment(this, v);
}
inline bool
JSContext::ensureParseMapPool()
{
if (parseMapPool_)
return true;
- parseMapPool_ = js::OffTheBooks::new_<js::ParseMapPool>(this);
+ parseMapPool_ = js::OffTheBooks::new_<js::frontend::ParseMapPool>(this);
return parseMapPool_;
}
inline js::PropertyTree&
JSContext::propertyTree()
{
return compartment->propertyTree;
}
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -56,16 +56,17 @@
#include "vm/ArgumentsObject-inl.h"
#include "vm/ScopeObject-inl.h"
#include "vm/Stack-inl.h"
using namespace mozilla;
using namespace js;
using namespace js::gc;
using namespace js::types;
+using namespace js::frontend;
static JSBool
fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, Value *vp)
{
JSObject *obj = obj_;
while (!obj->isFunction()) {
obj = obj->getProto();
if (!obj)
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2081,17 +2081,17 @@ inline void
AutoGCRooter::trace(JSTracer *trc)
{
switch (tag) {
case JSVAL:
MarkValueRoot(trc, &static_cast<AutoValueRooter *>(this)->val, "JS::AutoValueRooter.val");
return;
case PARSER:
- static_cast<Parser *>(this)->trace(trc);
+ static_cast<frontend::Parser *>(this)->trace(trc);
return;
case ENUMERATOR:
static_cast<AutoEnumStateRooter *>(this)->trace(trc);
return;
case IDARRAY: {
JSIdArray *ida = static_cast<AutoIdArray *>(this)->idArray;
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -63,16 +63,17 @@
#include "vm/MethodGuard-inl.h"
#include "jsautooplen.h"
using namespace mozilla;
using namespace js;
using namespace js::gc;
using namespace js::types;
+using js::frontend::IsIdentifier;
JS_STATIC_ASSERT(int32_t((JSObject::NELEMENTS_LIMIT - 1) * sizeof(Value)) == int64_t((JSObject::NELEMENTS_LIMIT - 1) * sizeof(Value)));
Class js::ObjectClass = {
js_Object_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
JS_PropertyStub, /* addProperty */
JS_PropertyStub, /* delProperty */
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -50,16 +50,19 @@
#include "jsautooplen.h"
#include "vm/RegExpObject-inl.h"
using namespace mozilla;
using namespace js;
using namespace js::gc;
+using js::frontend::IsIdentifier;
+using js::frontend::LetDataToGroupAssign;
+using js::frontend::LetDataToOffset;
/*
* Index limit must stay within 32 bits.
*/
JS_STATIC_ASSERT(sizeof(uint32_t) * JS_BITS_PER_BYTE >= INDEX_LIMIT_LOG2 + 1);
/* Verify JSOP_XXX_LENGTH constant definitions. */
#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -126,30 +126,16 @@ class StringBuffer;
class FrameRegs;
class StackFrame;
class StackSegment;
class StackSpace;
class ContextStack;
class ScriptFrameIter;
-struct BytecodeEmitter;
-struct Definition;
-struct FunctionBox;
-struct ObjectBox;
-struct ParseNode;
-struct Parser;
-struct SharedContext;
-class TokenStream;
-struct Token;
-struct TokenPos;
-struct TokenPtr;
-struct TreeContext;
-class UpvarCookie;
-
class Proxy;
class BaseProxyHandler;
class DirectWrapper;
class CrossCompartmentWrapper;
class TempAllocPolicy;
class RuntimeAllocPolicy;
@@ -167,23 +153,16 @@ class UnownedBaseShape;
struct Shape;
struct EmptyShape;
class ShapeKindArray;
class Bindings;
struct StackBaseShape;
struct StackShape;
-class MultiDeclRange;
-class ParseMapPool;
-class DefinitionList;
-typedef InlineMap<JSAtom *, Definition *, 24> AtomDefnMap;
-typedef InlineMap<JSAtom *, jsatomid, 24> AtomIndexMap;
-typedef Vector<UpvarCookie, 8> UpvarCookies;
-
class Breakpoint;
class BreakpointSite;
class Debugger;
class WatchpointMap;
/*
* Env is the type of what ES5 calls "lexical environments" (runtime
* activations of lexical scopes). This is currently just JSObject, and is
@@ -192,16 +171,32 @@ class WatchpointMap;
*/
typedef JSObject Env;
typedef JSNative Native;
typedef JSPropertyOp PropertyOp;
typedef JSStrictPropertyOp StrictPropertyOp;
typedef JSPropertyDescriptor PropertyDescriptor;
+namespace frontend {
+
+struct BytecodeEmitter;
+struct Definition;
+struct FunctionBox;
+struct ObjectBox;
+struct Token;
+struct TokenPos;
+struct TokenPtr;
+class TokenStream;
+struct Parser;
+class ParseMapPool;
+struct ParseNode;
+
+} /* namespace frontend */
+
namespace analyze {
struct LifetimeVariable;
class LoopAnalysis;
class ScriptAnalysis;
class SlotValue;
class SSAValue;
class SSAUseChain;
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -29,16 +29,17 @@
#include "frontend/TokenStream.h"
#include "frontend/TreeContext.h"
#include "vm/RegExpObject.h"
#include "jsscriptinlines.h"
using namespace mozilla;
using namespace js;
+using namespace js::frontend;
namespace js {
char const *aopNames[] = {
"=", /* AOP_ASSIGN */
"+=", /* AOP_PLUS */
"-=", /* AOP_MINUS */
"*=", /* AOP_STAR */
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -551,17 +551,17 @@ struct JSScript : public js::gc::Cell
// Three ways ways to initialize a JSScript. Callers of partiallyInit()
// and fullyInitTrivial() are responsible for notifying the debugger after
// successfully creating any kind (function or other) of new JSScript.
// However, callers of fullyInitFromEmitter() do not need to do this.
bool partiallyInit(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
uint32_t nobjects, uint32_t nregexps, uint32_t ntrynotes, uint32_t nconsts,
uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets);
bool fullyInitTrivial(JSContext *cx); // inits a JSOP_STOP-only script
- bool fullyInitFromEmitter(JSContext *cx, js::BytecodeEmitter *bce);
+ bool fullyInitFromEmitter(JSContext *cx, js::frontend::BytecodeEmitter *bce);
void setVersion(JSVersion v) { version = v; }
/* See ContextFlags::funArgumentsHasLocalBinding comment. */
bool argumentsHasVarBinding() const { return argsHasVarBinding_; }
jsbytecode *argumentsBytecode() const { JS_ASSERT(code[0] == JSOP_ARGUMENTS); return code; }
void setArgumentsHasVarBinding();
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -54,16 +54,17 @@ size_t sE4XObjectsCreated = 0;
#ifdef DEBUG
#include <string.h> /* for #ifdef DEBUG memset calls */
#endif
using namespace mozilla;
using namespace js;
using namespace js::gc;
using namespace js::types;
+using namespace js::frontend;
template<class T, class U>
struct IdentityOp
{
typedef JSBool (* compare)(const T *a, const U *b);
};
template<class T>
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -3190,33 +3190,35 @@ Compile(JSContext *cx, unsigned argc, js
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return ok;
}
static JSBool
Parse(JSContext *cx, unsigned argc, jsval *vp)
{
+ using namespace js::frontend;
+
if (argc < 1) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
"compile", "0", "s");
return false;
}
jsval arg0 = JS_ARGV(cx, vp)[0];
if (!JSVAL_IS_STRING(arg0)) {
const char *typeName = JS_GetTypeName(cx, JS_TypeOfValue(cx, arg0));
JS_ReportError(cx, "expected string to parse, got %s", typeName);
return false;
}
JSString *scriptContents = JSVAL_TO_STRING(arg0);
- js::Parser parser(cx, /* prin = */ NULL, /* originPrin = */ NULL,
- JS_GetStringCharsZ(cx, scriptContents), JS_GetStringLength(scriptContents),
- "<string>", /* lineno = */ 1, cx->findVersion(),
- /* foldConstants = */ true, /* compileAndGo = */ false);
+ Parser parser(cx, /* prin = */ NULL, /* originPrin = */ NULL,
+ JS_GetStringCharsZ(cx, scriptContents), JS_GetStringLength(scriptContents),
+ "<string>", /* lineno = */ 1, cx->findVersion(),
+ /* foldConstants = */ true, /* compileAndGo = */ false);
if (!parser.init())
return false;
ParseNode *pn = parser.parse(NULL);
if (!pn)
return false;
#ifdef DEBUG
DumpParseTree(pn);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -21,16 +21,17 @@
#include "frontend/BytecodeEmitter.h"
#include "gc/Marking.h"
#include "methodjit/Retcon.h"
#include "js/Vector.h"
#include "vm/Stack-inl.h"
using namespace js;
+using js::frontend::IsIdentifier;
/*** Forward declarations ************************************************************************/
extern Class DebuggerFrame_class;
enum {
JSSLOT_DEBUGFRAME_OWNER,
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -13,16 +13,17 @@
#include "jsobjinlines.h"
#include "vm/RegExpObject-inl.h"
#include "vm/RegExpStatics-inl.h"
using namespace js;
using js::detail::RegExpCode;
+using js::frontend::TokenStream;
JS_STATIC_ASSERT(IgnoreCaseFlag == JSREG_FOLD);
JS_STATIC_ASSERT(GlobalFlag == JSREG_GLOB);
JS_STATIC_ASSERT(MultilineFlag == JSREG_MULTILINE);
JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY);
/* RegExpObjectBuilder */
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -102,29 +102,32 @@ class RegExpCode
~RegExpCode() {
#if ENABLE_YARR_JIT
codeBlock.release();
#endif
if (byteCode)
Foreground::delete_<BytecodePattern>(byteCode);
}
- static bool checkSyntax(JSContext *cx, TokenStream *tokenStream, JSLinearString *source) {
+ static bool checkSyntax(JSContext *cx, frontend::TokenStream *tokenStream,
+ JSLinearString *source)
+ {
ErrorCode error = JSC::Yarr::checkSyntax(*source);
if (error == JSC::Yarr::NoError)
return true;
reportYarrError(cx, tokenStream, error);
return false;
}
#if ENABLE_YARR_JIT
static inline bool isJITRuntimeEnabled(JSContext *cx);
#endif
- static void reportYarrError(JSContext *cx, TokenStream *ts, JSC::Yarr::ErrorCode error);
+ static void reportYarrError(JSContext *cx, frontend::TokenStream *ts,
+ JSC::Yarr::ErrorCode error);
static size_t getOutputSize(size_t pairCount) {
return pairCount * 2;
}
bool compile(JSContext *cx, JSLinearString &pattern, unsigned *parenCount, RegExpFlag flags);
@@ -307,24 +310,24 @@ class RegExpObject : public JSObject
/*
* Note: The regexp statics flags are OR'd into the provided flags,
* so this function is really meant for object creation during code
* execution, as opposed to during something like XDR.
*/
static RegExpObject *
create(JSContext *cx, RegExpStatics *res, const jschar *chars, size_t length,
- RegExpFlag flags, TokenStream *ts);
+ RegExpFlag flags, frontend::TokenStream *ts);
static RegExpObject *
createNoStatics(JSContext *cx, const jschar *chars, size_t length, RegExpFlag flags,
- TokenStream *ts);
+ frontend::TokenStream *ts);
static RegExpObject *
- createNoStatics(JSContext *cx, HandleAtom atom, RegExpFlag flags, TokenStream *ts);
+ createNoStatics(JSContext *cx, HandleAtom atom, RegExpFlag flags, frontend::TokenStream *ts);
/*
* Run the regular expression over the input text.
*
* Results are placed in |output| as integer pairs. For eaxmple,
* |output[0]| and |output[1]| represent the text indices that make
* up the "0" (whole match) pair. Capturing parens will result in
* more output.
--- a/js/src/vm/ScopeObject-inl.h
+++ b/js/src/vm/ScopeObject-inl.h
@@ -187,27 +187,27 @@ StaticBlockObject::setEnclosingBlock(Sta
inline void
StaticBlockObject::setStackDepth(uint32_t depth)
{
JS_ASSERT(getReservedSlot(DEPTH_SLOT).isUndefined());
initReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth));
}
inline void
-StaticBlockObject::setDefinitionParseNode(unsigned i, Definition *def)
+StaticBlockObject::setDefinitionParseNode(unsigned i, frontend::Definition *def)
{
JS_ASSERT(slotValue(i).isUndefined());
setSlotValue(i, PrivateValue(def));
}
-inline Definition *
+inline frontend::Definition *
StaticBlockObject::maybeDefinitionParseNode(unsigned i)
{
Value v = slotValue(i);
- return v.isUndefined() ? NULL : reinterpret_cast<Definition *>(v.toPrivate());
+ return v.isUndefined() ? NULL : reinterpret_cast<frontend::Definition *>(v.toPrivate());
}
inline void
StaticBlockObject::setAliased(unsigned i, bool aliased)
{
JS_ASSERT_IF(i > 0, slotValue(i-1).isBoolean());
setSlotValue(i, BooleanValue(aliased));
if (aliased && !needsClone()) {
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -241,18 +241,18 @@ class StaticBlockObject : public BlockOb
void setStackDepth(uint32_t depth);
bool containsVarAtDepth(uint32_t depth);
/*
* Frontend compilation temporarily uses the object's slots to link
* a let var to its associated Definition parse node.
*/
- void setDefinitionParseNode(unsigned i, Definition *def);
- Definition *maybeDefinitionParseNode(unsigned i);
+ void setDefinitionParseNode(unsigned i, frontend::Definition *def);
+ frontend::Definition *maybeDefinitionParseNode(unsigned i);
/*
* A let binding is aliased is accessed lexically by nested functions or
* dynamically through dynamic name lookup (eval, with, function::, etc).
*/
void setAliased(unsigned i, bool aliased);
bool isAliased(unsigned i);