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 { BinaryExprContextBinaryExprContext35 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 } ~BinaryExprContextBinaryExprContext41 ~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 { UnaryExprContextUnaryExprContext50 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 } ~UnaryExprContextUnaryExprContext56 ~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 SyntaxChecker(JSGlobalData *,Lexer *)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 } PropertyProperty88 ALWAYS_INLINE Property(const Identifier* ident, PropertyNode::Type ty) 89 : name(ident) 90 , type(ty) 91 { 92 } PropertyProperty93 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 createSourceElements()117 int createSourceElements() { return 1; } makeFunctionCallNode(int,int,int,int,int)118 ExpressionType makeFunctionCallNode(int, int, int, int, int) { return CallExpr; } appendToComma(ExpressionType & base,ExpressionType right)119 void appendToComma(ExpressionType& base, ExpressionType right) { base = right; } createCommaExpr(ExpressionType,ExpressionType right)120 ExpressionType createCommaExpr(ExpressionType, ExpressionType right) { return right; } makeAssignNode(ExpressionType,Operator,ExpressionType,bool,bool,int,int,int)121 ExpressionType makeAssignNode(ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; } makePrefixNode(ExpressionType,Operator,int,int,int)122 ExpressionType makePrefixNode(ExpressionType, Operator, int, int, int) { return PreExpr; } makePostfixNode(ExpressionType,Operator,int,int,int)123 ExpressionType makePostfixNode(ExpressionType, Operator, int, int, int) { return PostExpr; } makeTypeOfNode(ExpressionType)124 ExpressionType makeTypeOfNode(ExpressionType) { return TypeofExpr; } makeDeleteNode(ExpressionType,int,int,int)125 ExpressionType makeDeleteNode(ExpressionType, int, int, int) { return DeleteExpr; } makeNegateNode(ExpressionType)126 ExpressionType makeNegateNode(ExpressionType) { return UnaryExpr; } makeBitwiseNotNode(ExpressionType)127 ExpressionType makeBitwiseNotNode(ExpressionType) { return UnaryExpr; } createLogicalNot(ExpressionType)128 ExpressionType createLogicalNot(ExpressionType) { return UnaryExpr; } createUnaryPlus(ExpressionType)129 ExpressionType createUnaryPlus(ExpressionType) { return UnaryExpr; } createVoid(ExpressionType)130 ExpressionType createVoid(ExpressionType) { return UnaryExpr; } thisExpr()131 ExpressionType thisExpr() { return ThisExpr; } createResolve(const Identifier *,int)132 ExpressionType createResolve(const Identifier*, int) { return ResolveExpr; } createObjectLiteral()133 ExpressionType createObjectLiteral() { return ObjectLiteralExpr; } createObjectLiteral(int)134 ExpressionType createObjectLiteral(int) { return ObjectLiteralExpr; } createArray(int)135 ExpressionType createArray(int) { return ArrayLiteralExpr; } createArray(int,int)136 ExpressionType createArray(int, int) { return ArrayLiteralExpr; } createNumberExpr(double)137 ExpressionType createNumberExpr(double) { return NumberExpr; } createString(const Identifier *)138 ExpressionType createString(const Identifier*) { return StringExpr; } createBoolean(bool)139 ExpressionType createBoolean(bool) { return BoolExpr; } createNull()140 ExpressionType createNull() { return NullExpr; } createBracketAccess(ExpressionType,ExpressionType,bool,int,int,int)141 ExpressionType createBracketAccess(ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; } createDotAccess(ExpressionType,const Identifier &,int,int,int)142 ExpressionType createDotAccess(ExpressionType, const Identifier&, int, int, int) { return DotExpr; } createRegExp(const Identifier & pattern,const Identifier &,int)143 ExpressionType createRegExp(const Identifier& pattern, const Identifier&, int) { return Yarr::checkSyntax(pattern.ustring()) ? 0 : RegExpExpr; } createNewExpr(ExpressionType,int,int,int,int)144 ExpressionType createNewExpr(ExpressionType, int, int, int, int) { return NewExpr; } createNewExpr(ExpressionType,int,int)145 ExpressionType createNewExpr(ExpressionType, int, int) { return NewExpr; } createConditionalExpr(ExpressionType,ExpressionType,ExpressionType)146 ExpressionType createConditionalExpr(ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; } createAssignResolve(const Identifier &,ExpressionType,bool,int,int,int)147 ExpressionType createAssignResolve(const Identifier&, ExpressionType, bool, int, int, int) { return AssignmentExpr; } createFunctionExpr(const Identifier *,int,int,int,int,int,int)148 ExpressionType createFunctionExpr(const Identifier*, int, int, int, int, int, int) { return FunctionExpr; } createFunctionBody(bool)149 int createFunctionBody(bool) { return 1; } createArguments()150 int createArguments() { return 1; } createArguments(int)151 int createArguments(int) { return 1; } createArgumentsList(int)152 int createArgumentsList(int) { return 1; } createArgumentsList(int,int)153 int createArgumentsList(int, int) { return 1; } createProperty(const Identifier * name,int,PropertyNode::Type type)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 } createProperty(JSGlobalData * globalData,double name,int,PropertyNode::Type type)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 } createPropertyList(Property)167 int createPropertyList(Property) { return 1; } createPropertyList(Property,int)168 int createPropertyList(Property, int) { return 1; } createElementList(int,int)169 int createElementList(int, int) { return 1; } createElementList(int,int,int)170 int createElementList(int, int, int) { return 1; } createFormalParameterList(const Identifier &)171 int createFormalParameterList(const Identifier&) { return 1; } createFormalParameterList(int,const Identifier &)172 int createFormalParameterList(int, const Identifier&) { return 1; } createClause(int,int)173 int createClause(int, int) { return 1; } createClauseList(int)174 int createClauseList(int) { return 1; } createClauseList(int,int)175 int createClauseList(int, int) { return 1; } setUsesArguments(int)176 void setUsesArguments(int) { } createFuncDeclStatement(const Identifier *,int,int,int,int,int,int)177 int createFuncDeclStatement(const Identifier*, int, int, int, int, int, int) { return 1; } createBlockStatement(int,int,int)178 int createBlockStatement(int, int, int) { return 1; } createExprStatement(int,int,int)179 int createExprStatement(int, int, int) { return 1; } createIfStatement(int,int,int,int)180 int createIfStatement(int, int, int, int) { return 1; } createIfStatement(int,int,int,int,int)181 int createIfStatement(int, int, int, int, int) { return 1; } createForLoop(int,int,int,int,bool,int,int)182 int createForLoop(int, int, int, int, bool, int, int) { return 1; } createForInLoop(const Identifier *,int,int,int,int,int,int,int,int,int,int)183 int createForInLoop(const Identifier*, int, int, int, int, int, int, int, int, int, int) { return 1; } createForInLoop(int,int,int,int,int,int,int,int)184 int createForInLoop(int, int, int, int, int, int, int, int) { return 1; } createEmptyStatement()185 int createEmptyStatement() { return 1; } createVarStatement(int,int,int)186 int createVarStatement(int, int, int) { return 1; } createReturnStatement(int,int,int,int,int)187 int createReturnStatement(int, int, int, int, int) { return 1; } createBreakStatement(int,int,int,int)188 int createBreakStatement(int, int, int, int) { return 1; } createBreakStatement(const Identifier *,int,int,int,int)189 int createBreakStatement(const Identifier*, int, int, int, int) { return 1; } createContinueStatement(int,int,int,int)190 int createContinueStatement(int, int, int, int) { return 1; } createContinueStatement(const Identifier *,int,int,int,int)191 int createContinueStatement(const Identifier*, int, int, int, int) { return 1; } createTryStatement(int,const Identifier *,bool,int,int,int,int)192 int createTryStatement(int, const Identifier*, bool, int, int, int, int) { return 1; } createSwitchStatement(int,int,int,int,int,int)193 int createSwitchStatement(int, int, int, int, int, int) { return 1; } createWhileStatement(int,int,int,int)194 int createWhileStatement(int, int, int, int) { return 1; } createWithStatement(int,int,int,int,int,int)195 int createWithStatement(int, int, int, int, int, int) { return 1; } createDoWhileStatement(int,int,int,int)196 int createDoWhileStatement(int, int, int, int) { return 1; } createLabelStatement(const Identifier *,int,int,int)197 int createLabelStatement(const Identifier*, int, int, int) { return 1; } createThrowStatement(int,int,int,int,int)198 int createThrowStatement(int, int, int, int, int) { return 1; } createDebugger(int,int)199 int createDebugger(int, int) { return 1; } createConstStatement(int,int,int)200 int createConstStatement(int, int, int) { return 1; } appendConstDecl(int,const Identifier *,int)201 int appendConstDecl(int, const Identifier*, int) { return 1; } createGetterOrSetterProperty(PropertyNode::Type type,const Identifier * name,int,int,int,int,int,int)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 appendStatement(int,int)210 void appendStatement(int, int) { } addVar(const Identifier *,bool)211 void addVar(const Identifier*, bool) { } combineCommaNodes(int,int)212 int combineCommaNodes(int, int) { return 1; } evalCount()213 int evalCount() const { return 0; } appendBinaryExpressionInfo(int & operandStackDepth,int expr,int,int,int,bool)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 operatorStackPop(int & operatorStackDepth)224 void operatorStackPop(int& operatorStackDepth) { operatorStackDepth--; } operatorStackHasHigherPrecedence(int &,int)225 bool operatorStackHasHigherPrecedence(int&, int) { return true; } getFromOperandStack(int)226 BinaryOperand getFromOperandStack(int) { return m_topBinaryExpr; } shrinkOperandStackBy(int & operandStackDepth,int amount)227 void shrinkOperandStackBy(int& operandStackDepth, int amount) { operandStackDepth -= amount; } appendBinaryOperation(int & operandStackDepth,int &,BinaryOperand,BinaryOperand)228 void appendBinaryOperation(int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; } operatorStackAppend(int & operatorStackDepth,int,int)229 void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; } popOperandStack(int &)230 int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; } 231 appendUnaryToken(int & stackDepth,int tok,int)232 void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; } unaryTokenStackLastType(int &)233 int unaryTokenStackLastType(int&) { return m_topUnaryToken; } unaryTokenStackLastStart(int &)234 int unaryTokenStackLastStart(int&) { return 0; } unaryTokenStackRemoveLast(int & stackDepth)235 void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; } 236 assignmentStackAppend(int,int,int,int,int,Operator)237 void assignmentStackAppend(int, int, int, int, int, Operator) { } createAssignment(int,int,int,int,int)238 int createAssignment(int, int, int, int, int) { ASSERT_NOT_REACHED(); return 1; } getName(const Property & property)239 const Identifier& getName(const Property& property) const { ASSERT(property.name); return *property.name; } getType(const Property & property)240 PropertyNode::Type getType(const Property& property) const { return property.type; } isResolve(ExpressionType expr)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