Remove excessive headers from JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / runtime / LiteralParser.h
1 /*
2  * Copyright (C) 2009 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #pragma once
27
28 #include "Identifier.h"
29 #include "JSCJSValue.h"
30 #include <array>
31 #include <wtf/text/StringBuilder.h>
32 #include <wtf/text/WTFString.h>
33
34 namespace JSC {
35
36 typedef enum { StrictJSON, NonStrictJSON, JSONP } ParserMode;
37
38 enum JSONPPathEntryType {
39     JSONPPathEntryTypeDeclare, // var pathEntryName = JSON
40     JSONPPathEntryTypeDot, // <prior entries>.pathEntryName = JSON
41     JSONPPathEntryTypeLookup, // <prior entries>[pathIndex] = JSON
42     JSONPPathEntryTypeCall // <prior entries>(JSON)
43 };
44
45 enum ParserState { StartParseObject, StartParseArray, StartParseExpression, 
46                    StartParseStatement, StartParseStatementEndStatement, 
47                    DoParseObjectStartExpression, DoParseObjectEndExpression,
48                    DoParseArrayStartExpression, DoParseArrayEndExpression };
49 enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace, 
50                  TokString, TokIdentifier, TokNumber, TokColon, 
51                  TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
52                  TokNull, TokEnd, TokDot, TokAssign, TokSemi, TokError };
53     
54 struct JSONPPathEntry {
55     JSONPPathEntryType m_type;
56     Identifier m_pathEntryName;
57     int m_pathIndex;
58 };
59
60 struct JSONPData {
61     Vector<JSONPPathEntry> m_path;
62     Strong<Unknown> m_value;
63 };
64
65 template <typename CharType>
66 struct LiteralParserToken {
67 private:
68 WTF_MAKE_NONCOPYABLE(LiteralParserToken<CharType>);
69
70 public:
71     LiteralParserToken() = default;
72
73     TokenType type;
74     const CharType* start;
75     const CharType* end;
76     union {
77         double numberToken;
78         struct {
79             union {
80                 const LChar* stringToken8;
81                 const UChar* stringToken16;
82             };
83             unsigned stringIs8Bit : 1;
84             unsigned stringLength : 31;
85         };
86     };
87 };
88
89 template <typename CharType>
90 ALWAYS_INLINE void setParserTokenString(LiteralParserToken<CharType>&, const CharType* string);
91
92 template <typename CharType>
93 class LiteralParser {
94 public:
95     LiteralParser(ExecState* exec, const CharType* characters, unsigned length, ParserMode mode)
96         : m_exec(exec)
97         , m_lexer(characters, length, mode)
98         , m_mode(mode)
99     {
100     }
101     
102     String getErrorMessage()
103     { 
104         if (!m_lexer.getErrorMessage().isEmpty())
105             return String::format("JSON Parse error: %s", m_lexer.getErrorMessage().ascii().data());
106         if (!m_parseErrorMessage.isEmpty())
107             return String::format("JSON Parse error: %s", m_parseErrorMessage.ascii().data());
108         return ASCIILiteral("JSON Parse error: Unable to parse JSON string");
109     }
110     
111     JSValue tryLiteralParse()
112     {
113         m_lexer.next();
114         JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
115         if (m_lexer.currentToken()->type == TokSemi)
116             m_lexer.next();
117         if (m_lexer.currentToken()->type != TokEnd)
118             return JSValue();
119         return result;
120     }
121     
122     bool tryJSONPParse(Vector<JSONPData>&, bool needsFullSourceInfo);
123
124 private:
125     class Lexer {
126     public:
127         Lexer(const CharType* characters, unsigned length, ParserMode mode)
128             : m_mode(mode)
129             , m_ptr(characters)
130             , m_end(characters + length)
131         {
132         }
133         
134         TokenType next();
135         
136 #if ASSERT_DISABLED
137         typedef const LiteralParserToken<CharType>* LiteralParserTokenPtr;
138
139         LiteralParserTokenPtr currentToken()
140         {
141             return &m_currentToken;
142         }
143 #else
144         class LiteralParserTokenPtr;
145         friend class LiteralParserTokenPtr;
146         class LiteralParserTokenPtr {
147         public:
148             LiteralParserTokenPtr(Lexer& lexer)
149                 : m_lexer(lexer)
150                 , m_tokenID(lexer.m_currentTokenID)
151             {
152             }
153
154             ALWAYS_INLINE const LiteralParserToken<CharType>* operator->() const
155             {
156                 ASSERT(m_tokenID == m_lexer.m_currentTokenID);
157                 return &m_lexer.m_currentToken;
158             }
159
160         private:
161             Lexer& m_lexer;
162             unsigned m_tokenID;
163         };
164
165         LiteralParserTokenPtr currentToken()
166         {
167             return LiteralParserTokenPtr(*this);
168         }
169 #endif
170         
171         String getErrorMessage() { return m_lexErrorMessage; }
172         
173     private:
174         String m_lexErrorMessage;
175         template <ParserMode mode> TokenType lex(LiteralParserToken<CharType>&);
176         ALWAYS_INLINE TokenType lexIdentifier(LiteralParserToken<CharType>&);
177         template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType lexString(LiteralParserToken<CharType>&);
178         template <ParserMode mode, char terminator> TokenType lexStringSlow(LiteralParserToken<CharType>&, const CharType* runStart);
179         ALWAYS_INLINE TokenType lexNumber(LiteralParserToken<CharType>&);
180         LiteralParserToken<CharType> m_currentToken;
181         ParserMode m_mode;
182         const CharType* m_ptr;
183         const CharType* m_end;
184         StringBuilder m_builder;
185 #if !ASSERT_DISABLED
186         unsigned m_currentTokenID { 0 };
187 #endif
188     };
189     
190     class StackGuard;
191     JSValue parse(ParserState);
192
193     ExecState* m_exec;
194     typename LiteralParser<CharType>::Lexer m_lexer;
195     ParserMode m_mode;
196     String m_parseErrorMessage;
197     static unsigned const MaximumCachableCharacter = 128;
198     std::array<Identifier, MaximumCachableCharacter> m_shortIdentifiers;
199     std::array<Identifier, MaximumCachableCharacter> m_recentIdentifiers;
200     ALWAYS_INLINE const Identifier makeIdentifier(const LChar* characters, size_t length);
201     ALWAYS_INLINE const Identifier makeIdentifier(const UChar* characters, size_t length);
202 };
203
204 } // namespace JSC