Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef frontend_SyntaxParseHandler_h
8 #define frontend_SyntaxParseHandler_h
10 #include "frontend/ParseNode.h"
11 #include "frontend/TokenStream.h"
13 namespace js {
14 namespace frontend {
16 template <typename ParseHandler>
17 class Parser;
19 // Parse handler used when processing the syntax in a block of code, to generate
20 // the minimal information which is required to detect syntax errors and allow
21 // bytecode to be emitted for outer functions.
22 //
23 // When parsing, we start at the top level with a full parse, and when possible
24 // only check the syntax for inner functions, so that they can be lazily parsed
25 // into bytecode when/if they first run. Checking the syntax of a function is
26 // several times faster than doing a full parse/emit, and lazy parsing improves
27 // both performance and memory usage significantly when pages contain large
28 // amounts of code that never executes (which happens often).
29 class SyntaxParseHandler
30 {
31 // Remember the last encountered name or string literal during syntax parses.
32 JSAtom *lastAtom;
33 TokenPos lastStringPos;
34 TokenStream &tokenStream;
36 public:
37 enum Node {
38 NodeFailure = 0,
39 NodeGeneric,
40 NodeName,
41 NodeGetProp,
42 NodeString,
43 NodeStringExprStatement,
44 NodeLValue
45 };
46 typedef Definition::Kind DefinitionNode;
48 SyntaxParseHandler(ExclusiveContext *cx, LifoAlloc &alloc,
49 TokenStream &tokenStream, bool foldConstants,
50 Parser<SyntaxParseHandler> *syntaxParser, LazyScript *lazyOuterFunction)
51 : lastAtom(nullptr),
52 tokenStream(tokenStream)
53 {}
55 static Node null() { return NodeFailure; }
57 void trace(JSTracer *trc) {}
59 Node newName(PropertyName *name, uint32_t blockid, const TokenPos &pos) {
60 lastAtom = name;
61 return NodeName;
62 }
64 DefinitionNode newPlaceholder(JSAtom *atom, uint32_t blockid, const TokenPos &pos) {
65 return Definition::PLACEHOLDER;
66 }
68 Node newIdentifier(JSAtom *atom, const TokenPos &pos) { return NodeString; }
69 Node newNumber(double value, DecimalPoint decimalPoint, const TokenPos &pos) { return NodeGeneric; }
70 Node newBooleanLiteral(bool cond, const TokenPos &pos) { return NodeGeneric; }
72 Node newStringLiteral(JSAtom *atom, const TokenPos &pos) {
73 lastAtom = atom;
74 lastStringPos = pos;
75 return NodeString;
76 }
78 Node newThisLiteral(const TokenPos &pos) { return NodeGeneric; }
79 Node newNullLiteral(const TokenPos &pos) { return NodeGeneric; }
81 template <class Boxer>
82 Node newRegExp(JSObject *reobj, const TokenPos &pos, Boxer &boxer) { return NodeGeneric; }
84 Node newConditional(Node cond, Node thenExpr, Node elseExpr) { return NodeGeneric; }
86 Node newElision() { return NodeGeneric; }
88 Node newDelete(uint32_t begin, Node expr) { return NodeGeneric; }
90 Node newUnary(ParseNodeKind kind, JSOp op, uint32_t begin, Node kid) {
91 return NodeGeneric;
92 }
94 Node newBinary(ParseNodeKind kind, JSOp op = JSOP_NOP) { return NodeGeneric; }
95 Node newBinary(ParseNodeKind kind, Node left, JSOp op = JSOP_NOP) { return NodeGeneric; }
96 Node newBinary(ParseNodeKind kind, Node left, Node right, JSOp op = JSOP_NOP) {
97 return NodeGeneric;
98 }
99 Node newBinaryOrAppend(ParseNodeKind kind, Node left, Node right,
100 ParseContext<SyntaxParseHandler> *pc, JSOp op = JSOP_NOP) {
101 return NodeGeneric;
102 }
104 Node newTernary(ParseNodeKind kind, Node first, Node second, Node third, JSOp op = JSOP_NOP) {
105 return NodeGeneric;
106 }
108 // Expressions
110 Node newArrayComprehension(Node body, unsigned blockid, const TokenPos &pos) {
111 return NodeGeneric;
112 }
113 Node newArrayLiteral(uint32_t begin, unsigned blockid) { return NodeGeneric; }
114 bool addElision(Node literal, const TokenPos &pos) { return true; }
115 bool addSpreadElement(Node literal, uint32_t begin, Node inner) { return true; }
116 bool addArrayElement(Node literal, Node element) { return true; }
118 Node newObjectLiteral(uint32_t begin) { return NodeGeneric; }
119 bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; }
120 bool addPropertyDefinition(Node literal, Node name, Node expr) { return true; }
121 bool addShorthandPropertyDefinition(Node literal, Node name) { return true; }
122 bool addAccessorPropertyDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
124 // Statements
126 Node newStatementList(unsigned blockid, const TokenPos &pos) { return NodeGeneric; }
127 void addStatementToList(Node list, Node stmt, ParseContext<SyntaxParseHandler> *pc) {}
128 Node newEmptyStatement(const TokenPos &pos) { return NodeGeneric; }
130 Node newExprStatement(Node expr, uint32_t end) {
131 return expr == NodeString ? NodeStringExprStatement : NodeGeneric;
132 }
134 Node newIfStatement(uint32_t begin, Node cond, Node then, Node else_) { return NodeGeneric; }
135 Node newDoWhileStatement(Node body, Node cond, const TokenPos &pos) { return NodeGeneric; }
136 Node newWhileStatement(uint32_t begin, Node cond, Node body) { return NodeGeneric; }
137 Node newSwitchStatement(uint32_t begin, Node discriminant, Node caseList) { return NodeGeneric; }
138 Node newCaseOrDefault(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
139 Node newContinueStatement(PropertyName *label, const TokenPos &pos) { return NodeGeneric; }
140 Node newBreakStatement(PropertyName *label, const TokenPos &pos) { return NodeGeneric; }
141 Node newReturnStatement(Node expr, const TokenPos &pos) { return NodeGeneric; }
143 Node newLabeledStatement(PropertyName *label, Node stmt, uint32_t begin) {
144 return NodeGeneric;
145 }
147 Node newThrowStatement(Node expr, const TokenPos &pos) { return NodeGeneric; }
148 Node newTryStatement(uint32_t begin, Node body, Node catchList, Node finallyBlock) {
149 return NodeGeneric;
150 }
151 Node newDebuggerStatement(const TokenPos &pos) { return NodeGeneric; }
153 Node newPropertyAccess(Node pn, PropertyName *name, uint32_t end) {
154 lastAtom = name;
155 return NodeGetProp;
156 }
158 Node newPropertyByValue(Node pn, Node kid, uint32_t end) { return NodeLValue; }
160 bool addCatchBlock(Node catchList, Node letBlock,
161 Node catchName, Node catchGuard, Node catchBody) { return true; }
163 void setLastFunctionArgumentDefault(Node funcpn, Node pn) {}
164 Node newFunctionDefinition() { return NodeGeneric; }
165 void setFunctionBody(Node pn, Node kid) {}
166 void setFunctionBox(Node pn, FunctionBox *funbox) {}
167 void addFunctionArgument(Node pn, Node argpn) {}
169 Node newForStatement(uint32_t begin, Node forHead, Node body, unsigned iflags) {
170 return NodeGeneric;
171 }
173 Node newForHead(ParseNodeKind kind, Node decls, Node lhs, Node rhs, const TokenPos &pos) {
174 return NodeGeneric;
175 }
177 Node newLexicalScope(ObjectBox *blockbox) { return NodeGeneric; }
178 void setLexicalScopeBody(Node block, Node body) {}
180 bool isOperationWithoutParens(Node pn, ParseNodeKind kind) {
181 // It is OK to return false here, callers should only use this method
182 // for reporting strict option warnings and parsing code which the
183 // syntax parser does not handle.
184 return false;
185 }
187 bool finishInitializerAssignment(Node pn, Node init, JSOp op) { return true; }
189 void setBeginPosition(Node pn, Node oth) {}
190 void setBeginPosition(Node pn, uint32_t begin) {}
192 void setEndPosition(Node pn, Node oth) {}
193 void setEndPosition(Node pn, uint32_t end) {}
196 void setPosition(Node pn, const TokenPos &pos) {}
197 TokenPos getPosition(Node pn) {
198 return tokenStream.currentToken().pos;
199 }
201 Node newList(ParseNodeKind kind, Node kid = NodeGeneric, JSOp op = JSOP_NOP) {
202 return NodeGeneric;
203 }
204 void addList(Node pn, Node kid) {}
205 bool isUnparenthesizedYield(Node pn) { return false; }
207 void setOp(Node pn, JSOp op) {}
208 void setBlockId(Node pn, unsigned blockid) {}
209 void setFlag(Node pn, unsigned flag) {}
210 void setListFlag(Node pn, unsigned flag) {}
211 Node setInParens(Node pn) {
212 // String literals enclosed by parentheses are ignored during
213 // strict mode parsing.
214 return NodeGeneric;
215 }
216 void setPrologue(Node pn) {}
218 bool isConstant(Node pn) { return false; }
219 PropertyName *isName(Node pn) {
220 return (pn == NodeName) ? lastAtom->asPropertyName() : nullptr;
221 }
222 PropertyName *isGetProp(Node pn) {
223 return (pn == NodeGetProp) ? lastAtom->asPropertyName() : nullptr;
224 }
225 JSAtom *isStringExprStatement(Node pn, TokenPos *pos) {
226 if (pn == NodeStringExprStatement) {
227 *pos = lastStringPos;
228 return lastAtom;
229 }
230 return nullptr;
231 }
233 Node makeAssignment(Node pn, Node rhs) { return NodeGeneric; }
235 static Node getDefinitionNode(DefinitionNode dn) { return NodeGeneric; }
236 static Definition::Kind getDefinitionKind(DefinitionNode dn) { return dn; }
237 void linkUseToDef(Node pn, DefinitionNode dn) {}
238 DefinitionNode resolve(DefinitionNode dn) { return dn; }
239 void deoptimizeUsesWithin(DefinitionNode dn, const TokenPos &pos) {}
240 bool dependencyCovered(Node pn, unsigned blockid, bool functionScope) {
241 // Only resolve lexical dependencies in cases where a definition covers
242 // the entire function. Not enough information is kept to compare the
243 // dependency location with blockid.
244 return functionScope;
245 }
247 static uintptr_t definitionToBits(DefinitionNode dn) {
248 // Use a shift, as DefinitionList tags the lower bit of its associated union.
249 return uintptr_t(dn << 1);
250 }
251 static DefinitionNode definitionFromBits(uintptr_t bits) {
252 return (DefinitionNode) (bits >> 1);
253 }
254 static DefinitionNode nullDefinition() {
255 return Definition::MISSING;
256 }
257 void disableSyntaxParser() {
258 }
259 };
261 } // namespace frontend
262 } // namespace js
264 #endif /* frontend_SyntaxParseHandler_h */