• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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