]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/LiteralParser.h
40c3d586f59ae64c627fbf3aa5f15b788c360bbb
[apple/javascriptcore.git] / 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 #ifndef LiteralParser_h
27 #define LiteralParser_h
28
29 #include "Identifier.h"
30 #include "JSGlobalObjectFunctions.h"
31 #include "JSValue.h"
32 #include "UString.h"
33
34 namespace JSC {
35
36 class LiteralParser {
37 public:
38 typedef enum { StrictJSON, NonStrictJSON, JSONP } ParserMode;
39 LiteralParser(ExecState* exec, const UChar* characters, unsigned length, ParserMode mode)
40 : m_exec(exec)
41 , m_lexer(characters, length, mode)
42 , m_mode(mode)
43 {
44 }
45
46 JSValue tryLiteralParse()
47 {
48 m_lexer.next();
49 JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
50 if (m_lexer.currentToken().type == TokSemi)
51 m_lexer.next();
52 if (m_lexer.currentToken().type != TokEnd)
53 return JSValue();
54 return result;
55 }
56
57 enum JSONPPathEntryType {
58 JSONPPathEntryTypeDeclare, // var pathEntryName = JSON
59 JSONPPathEntryTypeDot, // <prior entries>.pathEntryName = JSON
60 JSONPPathEntryTypeLookup, // <prior entries>[pathIndex] = JSON
61 JSONPPathEntryTypeCall // <prior entries>(JSON)
62 };
63
64 struct JSONPPathEntry {
65 JSONPPathEntryType m_type;
66 Identifier m_pathEntryName;
67 int m_pathIndex;
68 };
69
70 struct JSONPData {
71 Vector<JSONPPathEntry> m_path;
72 Strong<Unknown> m_value;
73 };
74
75 bool tryJSONPParse(Vector<JSONPData>&, bool needsFullSourceInfo);
76
77 private:
78 enum ParserState { StartParseObject, StartParseArray, StartParseExpression,
79 StartParseStatement, StartParseStatementEndStatement,
80 DoParseObjectStartExpression, DoParseObjectEndExpression,
81 DoParseArrayStartExpression, DoParseArrayEndExpression };
82 enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace,
83 TokString, TokIdentifier, TokNumber, TokColon,
84 TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
85 TokNull, TokEnd, TokDot, TokAssign, TokSemi, TokError };
86
87 class Lexer {
88 public:
89 struct LiteralParserToken {
90 TokenType type;
91 const UChar* start;
92 const UChar* end;
93 UString stringBuffer;
94 union {
95 double numberToken;
96 struct {
97 const UChar* stringToken;
98 int stringLength;
99 };
100 };
101 };
102 Lexer(const UChar* characters, unsigned length, ParserMode mode)
103 : m_mode(mode)
104 , m_ptr(characters)
105 , m_end(characters + length)
106 {
107 }
108
109 TokenType next();
110
111 const LiteralParserToken& currentToken()
112 {
113 return m_currentToken;
114 }
115
116 private:
117 template <ParserMode mode> TokenType lex(LiteralParserToken&);
118 template <ParserMode mode, UChar terminator> ALWAYS_INLINE TokenType lexString(LiteralParserToken&);
119 ALWAYS_INLINE TokenType lexNumber(LiteralParserToken&);
120 LiteralParserToken m_currentToken;
121 UString m_string;
122 ParserMode m_mode;
123 const UChar* m_ptr;
124 const UChar* m_end;
125 };
126
127 class StackGuard;
128 JSValue parse(ParserState);
129
130 ExecState* m_exec;
131 LiteralParser::Lexer m_lexer;
132 ParserMode m_mode;
133 static unsigned const MaximumCachableCharacter = 128;
134 FixedArray<Identifier, MaximumCachableCharacter> m_shortIdentifiers;
135 FixedArray<Identifier, MaximumCachableCharacter> m_recentIdentifiers;
136 ALWAYS_INLINE const Identifier makeIdentifier(const UChar* characters, size_t length);
137 };
138
139 }
140
141 #endif