]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/LiteralParser.h
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / runtime / LiteralParser.h
index 40c3d586f59ae64c627fbf3aa5f15b788c360bbb..f05f032043d34562aa644bf894ff9d0d368d2954 100644 (file)
 #define LiteralParser_h
 
 #include "Identifier.h"
+#include "JSCJSValue.h"
 #include "JSGlobalObjectFunctions.h"
-#include "JSValue.h"
-#include "UString.h"
+#include <array>
+#include <wtf/text/WTFString.h>
 
 namespace JSC {
 
-    class LiteralParser {
+typedef enum { StrictJSON, NonStrictJSON, JSONP } ParserMode;
+
+enum JSONPPathEntryType {
+    JSONPPathEntryTypeDeclare, // var pathEntryName = JSON
+    JSONPPathEntryTypeDot, // <prior entries>.pathEntryName = JSON
+    JSONPPathEntryTypeLookup, // <prior entries>[pathIndex] = JSON
+    JSONPPathEntryTypeCall // <prior entries>(JSON)
+};
+
+enum ParserState { StartParseObject, StartParseArray, StartParseExpression, 
+                   StartParseStatement, StartParseStatementEndStatement, 
+                   DoParseObjectStartExpression, DoParseObjectEndExpression,
+                   DoParseArrayStartExpression, DoParseArrayEndExpression };
+enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace, 
+                 TokString, TokIdentifier, TokNumber, TokColon, 
+                 TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
+                 TokNull, TokEnd, TokDot, TokAssign, TokSemi, TokError };
+    
+struct JSONPPathEntry {
+    JSONPPathEntryType m_type;
+    Identifier m_pathEntryName;
+    int m_pathIndex;
+};
+
+struct JSONPData {
+    Vector<JSONPPathEntry> m_path;
+    Strong<Unknown> m_value;
+};
+
+template <typename CharType>
+struct LiteralParserToken {
+    TokenType type;
+    const CharType* start;
+    const CharType* end;
+    String stringBuffer;
+    union {
+        double numberToken;
+        struct {
+            union {
+                const LChar* stringToken8;
+                const UChar* stringToken16;
+            };
+            unsigned stringIs8Bit : 1;
+            unsigned stringLength : 31;
+        };
+    };
+};
+
+template <typename CharType>
+ALWAYS_INLINE void setParserTokenString(LiteralParserToken<CharType>&, const CharType* string);
+
+template <typename CharType>
+class LiteralParser {
+public:
+    LiteralParser(ExecState* exec, const CharType* characters, unsigned length, ParserMode mode)
+        : m_exec(exec)
+        , m_lexer(characters, length, mode)
+        , m_mode(mode)
+    {
+    }
+    
+    String getErrorMessage()
+    { 
+        if (!m_lexer.getErrorMessage().isEmpty())
+            return String::format("JSON Parse error: %s", m_lexer.getErrorMessage().ascii().data()).impl();
+        if (!m_parseErrorMessage.isEmpty())
+            return String::format("JSON Parse error: %s", m_parseErrorMessage.ascii().data()).impl();
+        return ASCIILiteral("JSON Parse error: Unable to parse JSON string");
+    }
+    
+    JSValue tryLiteralParse()
+    {
+        m_lexer.next();
+        JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
+        if (m_lexer.currentToken().type == TokSemi)
+            m_lexer.next();
+        if (m_lexer.currentToken().type != TokEnd)
+            return JSValue();
+        return result;
+    }
+    
+    bool tryJSONPParse(Vector<JSONPData>&, bool needsFullSourceInfo);
+
+private:
+    class Lexer {
     public:
-        typedef enum { StrictJSON, NonStrictJSON, JSONP } ParserMode;
-        LiteralParser(ExecState* exec, const UChar* characters, unsigned length, ParserMode mode)
-            : m_exec(exec)
-            , m_lexer(characters, length, mode)
-            , m_mode(mode)
+        Lexer(const CharType* characters, unsigned length, ParserMode mode)
+            : m_mode(mode)
+            , m_ptr(characters)
+            , m_end(characters + length)
         {
         }
         
-        JSValue tryLiteralParse()
+        TokenType next();
+        
+        const LiteralParserToken<CharType>& currentToken()
         {
-            m_lexer.next();
-            JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
-            if (m_lexer.currentToken().type == TokSemi)
-                m_lexer.next();
-            if (m_lexer.currentToken().type != TokEnd)
-                return JSValue();
-            return result;
+            return m_currentToken;
         }
         
-        enum JSONPPathEntryType {
-            JSONPPathEntryTypeDeclare, // var pathEntryName = JSON
-            JSONPPathEntryTypeDot, // <prior entries>.pathEntryName = JSON
-            JSONPPathEntryTypeLookup, // <prior entries>[pathIndex] = JSON
-            JSONPPathEntryTypeCall // <prior entries>(JSON)
-        };
-
-        struct JSONPPathEntry {
-            JSONPPathEntryType m_type;
-            Identifier m_pathEntryName;
-            int m_pathIndex;
-        };
-
-        struct JSONPData {
-            Vector<JSONPPathEntry> m_path;
-            Strong<Unknown> m_value;
-        };
-
-        bool tryJSONPParse(Vector<JSONPData>&, bool needsFullSourceInfo);
-
-    private:
-        enum ParserState { StartParseObject, StartParseArray, StartParseExpression, 
-                           StartParseStatement, StartParseStatementEndStatement, 
-                           DoParseObjectStartExpression, DoParseObjectEndExpression,
-                           DoParseArrayStartExpression, DoParseArrayEndExpression };
-        enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace, 
-                         TokString, TokIdentifier, TokNumber, TokColon, 
-                         TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
-                         TokNull, TokEnd, TokDot, TokAssign, TokSemi, TokError };
-        
-        class Lexer {
-        public:
-            struct LiteralParserToken {
-                TokenType type;
-                const UChar* start;
-                const UChar* end;
-                UString stringBuffer;
-                union {
-                    double numberToken;
-                    struct {
-                        const UChar* stringToken;
-                        int stringLength;
-                    };
-                };
-            };
-            Lexer(const UChar* characters, unsigned length, ParserMode mode)
-                : m_mode(mode)
-                , m_ptr(characters)
-                , m_end(characters + length)
-            {
-            }
-            
-            TokenType next();
-            
-            const LiteralParserToken& currentToken()
-            {
-                return m_currentToken;
-            }
-            
-        private:
-            template <ParserMode mode> TokenType lex(LiteralParserToken&);
-            template <ParserMode mode, UChar terminator> ALWAYS_INLINE TokenType lexString(LiteralParserToken&);
-            ALWAYS_INLINE TokenType lexNumber(LiteralParserToken&);
-            LiteralParserToken m_currentToken;
-            UString m_string;
-            ParserMode m_mode;
-            const UChar* m_ptr;
-            const UChar* m_end;
-        };
+        String getErrorMessage() { return m_lexErrorMessage; }
         
-        class StackGuard;
-        JSValue parse(ParserState);
-
-        ExecState* m_exec;
-        LiteralParser::Lexer m_lexer;
+    private:
+        String m_lexErrorMessage;
+        template <ParserMode mode> TokenType lex(LiteralParserToken<CharType>&);
+        ALWAYS_INLINE TokenType lexIdentifier(LiteralParserToken<CharType>&);
+        template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType lexString(LiteralParserToken<CharType>&);
+        ALWAYS_INLINE TokenType lexNumber(LiteralParserToken<CharType>&);
+        LiteralParserToken<CharType> m_currentToken;
         ParserMode m_mode;
-        static unsigned const MaximumCachableCharacter = 128;
-        FixedArray<Identifier, MaximumCachableCharacter> m_shortIdentifiers;
-        FixedArray<Identifier, MaximumCachableCharacter> m_recentIdentifiers;
-        ALWAYS_INLINE const Identifier makeIdentifier(const UChar* characters, size_t length);
+        const CharType* m_ptr;
+        const CharType* m_end;
+    };
+    
+    class StackGuard;
+    JSValue parse(ParserState);
+
+    ExecState* m_exec;
+    typename LiteralParser<CharType>::Lexer m_lexer;
+    ParserMode m_mode;
+    String m_parseErrorMessage;
+    static unsigned const MaximumCachableCharacter = 128;
+    std::array<Identifier, MaximumCachableCharacter> m_shortIdentifiers;
+    std::array<Identifier, MaximumCachableCharacter> m_recentIdentifiers;
+    ALWAYS_INLINE const Identifier makeIdentifier(const LChar* characters, size_t length);
+    ALWAYS_INLINE const Identifier makeIdentifier(const UChar* characters, size_t length);
     };
 
 }