1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef SyntaxChecker_h 27 #define SyntaxChecker_h 28 29 #include <yarr/YarrSyntaxChecker.h> 30 31 namespace JSC { 32 class SyntaxChecker { 33 public: 34 struct BinaryExprContext { 35 BinaryExprContext(SyntaxChecker& context) 36 : m_context(&context) 37 { 38 m_context->m_topBinaryExprs.append(m_context->m_topBinaryExpr); 39 m_context->m_topBinaryExpr = 0; 40 } 41 ~BinaryExprContext() 42 { 43 m_context->m_topBinaryExpr = m_context->m_topBinaryExprs.last(); 44 m_context->m_topBinaryExprs.removeLast(); 45 } 46 private: 47 SyntaxChecker* m_context; 48 }; 49 struct UnaryExprContext { 50 UnaryExprContext(SyntaxChecker& context) 51 : m_context(&context) 52 { 53 m_context->m_topUnaryTokens.append(m_context->m_topUnaryToken); 54 m_context->m_topUnaryToken = 0; 55 } 56 ~UnaryExprContext() 57 { 58 m_context->m_topUnaryToken = m_context->m_topUnaryTokens.last(); 59 m_context->m_topUnaryTokens.removeLast(); 60 } 61 private: 62 SyntaxChecker* m_context; 63 }; 64 65 SyntaxChecker(JSGlobalData* , Lexer*) 66 { 67 } 68 69 typedef SyntaxChecker FunctionBodyBuilder; 70 enum { NoneExpr = 0, 71 ResolveEvalExpr, ResolveExpr, NumberExpr, StringExpr, 72 ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr, 73 FunctionExpr, BracketExpr, DotExpr, CallExpr, 74 NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr, 75 ConditionalExpr, AssignmentExpr, TypeofExpr, 76 DeleteExpr, ArrayLiteralExpr }; 77 typedef int ExpressionType; 78 79 typedef ExpressionType Expression; 80 typedef int SourceElements; 81 typedef int Arguments; 82 typedef ExpressionType Comma; 83 struct Property { 84 ALWAYS_INLINE Property(void* = 0) 85 : type((PropertyNode::Type)0) 86 { 87 } 88 ALWAYS_INLINE Property(const Identifier* ident, PropertyNode::Type ty) 89 : name(ident) 90 , type(ty) 91 { 92 } 93 ALWAYS_INLINE Property(PropertyNode::Type ty) 94 : name(0) 95 , type(ty) 96 { 97 } 98 ALWAYS_INLINE bool operator!() { return !type; } 99 const Identifier* name; 100 PropertyNode::Type type; 101 }; 102 typedef int PropertyList; 103 typedef int ElementList; 104 typedef int ArgumentsList; 105 typedef int FormalParameterList; 106 typedef int FunctionBody; 107 typedef int Statement; 108 typedef int ClauseList; 109 typedef int Clause; 110 typedef int ConstDeclList; 111 typedef int BinaryOperand; 112 113 static const bool CreatesAST = false; 114 static const bool NeedsFreeVariableInfo = false; 115 static const bool CanUseFunctionCache = true; 116 117 int createSourceElements() { return 1; } 118 ExpressionType makeFunctionCallNode(int, int, int, int, int) { return CallExpr; } 119 void appendToComma(ExpressionType& base, ExpressionType right) { base = right; } 120 ExpressionType createCommaExpr(ExpressionType, ExpressionType right) { return right; } 121 ExpressionType makeAssignNode(ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; } 122 ExpressionType makePrefixNode(ExpressionType, Operator, int, int, int) { return PreExpr; } 123 ExpressionType makePostfixNode(ExpressionType, Operator, int, int, int) { return PostExpr; } 124 ExpressionType makeTypeOfNode(ExpressionType) { return TypeofExpr; } 125 ExpressionType makeDeleteNode(ExpressionType, int, int, int) { return DeleteExpr; } 126 ExpressionType makeNegateNode(ExpressionType) { return UnaryExpr; } 127 ExpressionType makeBitwiseNotNode(ExpressionType) { return UnaryExpr; } 128 ExpressionType createLogicalNot(ExpressionType) { return UnaryExpr; } 129 ExpressionType createUnaryPlus(ExpressionType) { return UnaryExpr; } 130 ExpressionType createVoid(ExpressionType) { return UnaryExpr; } 131 ExpressionType thisExpr() { return ThisExpr; } 132 ExpressionType createResolve(const Identifier*, int) { return ResolveExpr; } 133 ExpressionType createObjectLiteral() { return ObjectLiteralExpr; } 134 ExpressionType createObjectLiteral(int) { return ObjectLiteralExpr; } 135 ExpressionType createArray(int) { return ArrayLiteralExpr; } 136 ExpressionType createArray(int, int) { return ArrayLiteralExpr; } 137 ExpressionType createNumberExpr(double) { return NumberExpr; } 138 ExpressionType createString(const Identifier*) { return StringExpr; } 139 ExpressionType createBoolean(bool) { return BoolExpr; } 140 ExpressionType createNull() { return NullExpr; } 141 ExpressionType createBracketAccess(ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; } 142 ExpressionType createDotAccess(ExpressionType, const Identifier&, int, int, int) { return DotExpr; } 143 ExpressionType createRegExp(const Identifier& pattern, const Identifier&, int) { return Yarr::checkSyntax(pattern.ustring()) ? 0 : RegExpExpr; } 144 ExpressionType createNewExpr(ExpressionType, int, int, int, int) { return NewExpr; } 145 ExpressionType createNewExpr(ExpressionType, int, int) { return NewExpr; } 146 ExpressionType createConditionalExpr(ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; } 147 ExpressionType createAssignResolve(const Identifier&, ExpressionType, bool, int, int, int) { return AssignmentExpr; } 148 ExpressionType createFunctionExpr(const Identifier*, int, int, int, int, int, int) { return FunctionExpr; } 149 int createFunctionBody(bool) { return 1; } 150 int createArguments() { return 1; } 151 int createArguments(int) { return 1; } 152 int createArgumentsList(int) { return 1; } 153 int createArgumentsList(int, int) { return 1; } 154 template <bool complete> Property createProperty(const Identifier* name, int, PropertyNode::Type type) 155 { 156 ASSERT(name); 157 if (!complete) 158 return Property(type); 159 return Property(name, type); 160 } 161 template <bool complete> Property createProperty(JSGlobalData* globalData, double name, int, PropertyNode::Type type) 162 { 163 if (!complete) 164 return Property(type); 165 return Property(&globalData->parser->arena().identifierArena().makeNumericIdentifier(globalData, name), type); 166 } 167 int createPropertyList(Property) { return 1; } 168 int createPropertyList(Property, int) { return 1; } 169 int createElementList(int, int) { return 1; } 170 int createElementList(int, int, int) { return 1; } 171 int createFormalParameterList(const Identifier&) { return 1; } 172 int createFormalParameterList(int, const Identifier&) { return 1; } 173 int createClause(int, int) { return 1; } 174 int createClauseList(int) { return 1; } 175 int createClauseList(int, int) { return 1; } 176 void setUsesArguments(int) { } 177 int createFuncDeclStatement(const Identifier*, int, int, int, int, int, int) { return 1; } 178 int createBlockStatement(int, int, int) { return 1; } 179 int createExprStatement(int, int, int) { return 1; } 180 int createIfStatement(int, int, int, int) { return 1; } 181 int createIfStatement(int, int, int, int, int) { return 1; } 182 int createForLoop(int, int, int, int, bool, int, int) { return 1; } 183 int createForInLoop(const Identifier*, int, int, int, int, int, int, int, int, int, int) { return 1; } 184 int createForInLoop(int, int, int, int, int, int, int, int) { return 1; } 185 int createEmptyStatement() { return 1; } 186 int createVarStatement(int, int, int) { return 1; } 187 int createReturnStatement(int, int, int, int, int) { return 1; } 188 int createBreakStatement(int, int, int, int) { return 1; } 189 int createBreakStatement(const Identifier*, int, int, int, int) { return 1; } 190 int createContinueStatement(int, int, int, int) { return 1; } 191 int createContinueStatement(const Identifier*, int, int, int, int) { return 1; } 192 int createTryStatement(int, const Identifier*, bool, int, int, int, int) { return 1; } 193 int createSwitchStatement(int, int, int, int, int, int) { return 1; } 194 int createWhileStatement(int, int, int, int) { return 1; } 195 int createWithStatement(int, int, int, int, int, int) { return 1; } 196 int createDoWhileStatement(int, int, int, int) { return 1; } 197 int createLabelStatement(const Identifier*, int, int, int) { return 1; } 198 int createThrowStatement(int, int, int, int, int) { return 1; } 199 int createDebugger(int, int) { return 1; } 200 int createConstStatement(int, int, int) { return 1; } 201 int appendConstDecl(int, const Identifier*, int) { return 1; } 202 template <bool strict> Property createGetterOrSetterProperty(PropertyNode::Type type, const Identifier* name, int, int, int, int, int, int) 203 { 204 ASSERT(name); 205 if (!strict) 206 return Property(type); 207 return Property(name, type); 208 } 209 210 void appendStatement(int, int) { } 211 void addVar(const Identifier*, bool) { } 212 int combineCommaNodes(int, int) { return 1; } 213 int evalCount() const { return 0; } 214 void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool) 215 { 216 if (!m_topBinaryExpr) 217 m_topBinaryExpr = expr; 218 else 219 m_topBinaryExpr = BinaryExpr; 220 operandStackDepth++; 221 } 222 223 // Logic to handle datastructures used during parsing of binary expressions 224 void operatorStackPop(int& operatorStackDepth) { operatorStackDepth--; } 225 bool operatorStackHasHigherPrecedence(int&, int) { return true; } 226 BinaryOperand getFromOperandStack(int) { return m_topBinaryExpr; } 227 void shrinkOperandStackBy(int& operandStackDepth, int amount) { operandStackDepth -= amount; } 228 void appendBinaryOperation(int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; } 229 void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; } 230 int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; } 231 232 void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; } 233 int unaryTokenStackLastType(int&) { return m_topUnaryToken; } 234 int unaryTokenStackLastStart(int&) { return 0; } 235 void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; } 236 237 void assignmentStackAppend(int, int, int, int, int, Operator) { } 238 int createAssignment(int, int, int, int, int) { ASSERT_NOT_REACHED(); return 1; } 239 const Identifier& getName(const Property& property) const { ASSERT(property.name); return *property.name; } 240 PropertyNode::Type getType(const Property& property) const { return property.type; } 241 bool isResolve(ExpressionType expr) const { return expr == ResolveExpr || expr == ResolveEvalExpr; } 242 243 private: 244 int m_topBinaryExpr; 245 int m_topUnaryToken; 246 Vector<int, 8> m_topBinaryExprs; 247 Vector<int, 8> m_topUnaryTokens; 248 }; 249 250 } 251 252 #endif 253