js/src/frontend/SyntaxParseHandler.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial