Ignore:
Timestamp:
Nov 9, 2011, 8:49:01 PM (14 years ago)
Author:
[email protected]
Message:

Towards 8 Bit Strings: Templatize JSC::LiteralParser class by character type
https://bugs.webkit.org/show_bug.cgi?id=71862

Changed LiteralParser to be templatized of character type.

Moved five enums out of class definition to work around a clang compiler defect.

Added lexIdentifier templated method to break out character specific versions.
Added static setParserTokenString templated method to handle setting approriately
sized string pointer.

To keep code in LiteralParser.cpp and keep LiteralParser.h small, the two
flavors of LiteralParser are explicitly instantiated at the end of
LiteralParser.cpp.

Reviewed by Oliver Hunt.

  • API/JSValueRef.cpp:

(JSValueMakeFromJSONString):

(JSC::Interpreter::callEval):
(JSC::Interpreter::execute):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncEval):

  • runtime/JSONObject.cpp:

(JSC::JSONProtoFuncParse):

  • runtime/LiteralParser.cpp:

(JSC::isJSONWhiteSpace):
(JSC::::tryJSONPParse):
(JSC::::makeIdentifier):
(JSC::::Lexer::lex):
(JSC::::Lexer::lexIdentifier):
(JSC::::Lexer::next):
(JSC::LChar):
(JSC::UChar):
(JSC::isSafeStringCharacter):
(JSC::::Lexer::lexString):
(JSC::::Lexer::lexNumber):
(JSC::::parse):

  • runtime/LiteralParser.h:

(JSC::LiteralParser::LiteralParser):
(JSC::LiteralParser::getErrorMessage):
(JSC::LiteralParser::tryLiteralParse):
(JSC::LiteralParser::Lexer::Lexer):
(JSC::LiteralParser::Lexer::currentToken):
(JSC::LiteralParser::Lexer::getErrorMessage):

  • runtime/UString.h:

(JSC::LChar):
(JSC::UChar):

  • wtf/text/StringBuilder.cpp:

(WTF::StringBuilder::append):

  • wtf/text/StringBuilder.h:

(WTF::StringBuilder::append):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/LiteralParser.h

    r95901 r99812  
    3434namespace JSC {
    3535
    36     class LiteralParser {
     36typedef enum { StrictJSON, NonStrictJSON, JSONP } ParserMode;
     37
     38enum 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
     45enum ParserState { StartParseObject, StartParseArray, StartParseExpression,
     46                   StartParseStatement, StartParseStatementEndStatement,
     47                   DoParseObjectStartExpression, DoParseObjectEndExpression,
     48                   DoParseArrayStartExpression, DoParseArrayEndExpression };
     49enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace,
     50                 TokString, TokIdentifier, TokNumber, TokColon,
     51                 TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
     52                 TokNull, TokEnd, TokDot, TokAssign, TokSemi, TokError };
     53   
     54struct JSONPPathEntry {
     55    JSONPPathEntryType m_type;
     56    Identifier m_pathEntryName;
     57    int m_pathIndex;
     58};
     59
     60struct JSONPData {
     61    Vector<JSONPPathEntry> m_path;
     62    Strong<Unknown> m_value;
     63};
     64
     65template <typename CharType>
     66struct LiteralParserToken {
     67    TokenType type;
     68    const CharType* start;
     69    const CharType* end;
     70    UString stringBuffer;
     71    union {
     72        double numberToken;
     73        struct {
     74            union {
     75                const LChar* stringToken8;
     76                const UChar* stringToken16;
     77            };
     78            unsigned stringIs8Bit : 1;
     79            unsigned stringLength : 31;
     80        };
     81    };
     82};
     83
     84template <typename CharType>
     85ALWAYS_INLINE void setParserTokenString(LiteralParserToken<CharType>&, const CharType* string);
     86
     87template <typename CharType>
     88class LiteralParser {
     89public:
     90    LiteralParser(ExecState* exec, const CharType* characters, unsigned length, ParserMode mode)
     91        : m_exec(exec)
     92        , m_lexer(characters, length, mode)
     93        , m_mode(mode)
     94    {
     95    }
     96   
     97    UString getErrorMessage()
     98    {
     99        if (!m_lexer.getErrorMessage().isEmpty())
     100            return String::format("JSON Parse error: %s", m_lexer.getErrorMessage().ascii().data()).impl();
     101        if (!m_parseErrorMessage.isEmpty())
     102            return String::format("JSON Parse error: %s", m_parseErrorMessage.ascii().data()).impl();
     103        return "JSON Parse error: Unable to parse JSON string";
     104    }
     105   
     106    JSValue tryLiteralParse()
     107    {
     108        m_lexer.next();
     109        JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
     110        if (m_lexer.currentToken().type == TokSemi)
     111            m_lexer.next();
     112        if (m_lexer.currentToken().type != TokEnd)
     113            return JSValue();
     114        return result;
     115    }
     116   
     117    bool tryJSONPParse(Vector<JSONPData>&, bool needsFullSourceInfo);
     118
     119private:
     120    class Lexer {
    37121    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)
     122        Lexer(const CharType* characters, unsigned length, ParserMode mode)
     123            : m_mode(mode)
     124            , m_ptr(characters)
     125            , m_end(characters + length)
    43126        {
    44127        }
    45128       
    46         UString getErrorMessage()
    47         {
    48             if (!m_lexer.getErrorMessage().isEmpty())
    49                 return String::format("JSON Parse error: %s", m_lexer.getErrorMessage().ascii().data()).impl();
    50             if (!m_parseErrorMessage.isEmpty())
    51                 return String::format("JSON Parse error: %s", m_parseErrorMessage.ascii().data()).impl();
    52             return "JSON Parse error: Unable to parse JSON string";
     129        TokenType next();
     130       
     131        const LiteralParserToken<CharType>& currentToken()
     132        {
     133            return m_currentToken;
    53134        }
    54135       
    55         JSValue tryLiteralParse()
    56         {
    57             m_lexer.next();
    58             JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
    59             if (m_lexer.currentToken().type == TokSemi)
    60                 m_lexer.next();
    61             if (m_lexer.currentToken().type != TokEnd)
    62                 return JSValue();
    63             return result;
    64         }
     136        UString getErrorMessage() { return m_lexErrorMessage; }
    65137       
    66         enum JSONPPathEntryType {
    67             JSONPPathEntryTypeDeclare, // var pathEntryName = JSON
    68             JSONPPathEntryTypeDot, // <prior entries>.pathEntryName = JSON
    69             JSONPPathEntryTypeLookup, // <prior entries>[pathIndex] = JSON
    70             JSONPPathEntryTypeCall // <prior entries>(JSON)
    71         };
     138    private:
     139        UString m_lexErrorMessage;
     140        template <ParserMode mode> TokenType lex(LiteralParserToken<CharType>&);
     141        ALWAYS_INLINE TokenType lexIdentifier(LiteralParserToken<CharType>&);
     142        template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType lexString(LiteralParserToken<CharType>&);
     143        ALWAYS_INLINE TokenType lexNumber(LiteralParserToken<CharType>&);
     144        LiteralParserToken<CharType> m_currentToken;
     145        UString m_string;
     146        ParserMode m_mode;
     147        const CharType* m_ptr;
     148        const CharType* m_end;
     149    };
     150   
     151    class StackGuard;
     152    JSValue parse(ParserState);
    72153
    73         struct JSONPPathEntry {
    74             JSONPPathEntryType m_type;
    75             Identifier m_pathEntryName;
    76             int m_pathIndex;
    77         };
    78 
    79         struct JSONPData {
    80             Vector<JSONPPathEntry> m_path;
    81             Strong<Unknown> m_value;
    82         };
    83 
    84         bool tryJSONPParse(Vector<JSONPData>&, bool needsFullSourceInfo);
    85 
    86     private:
    87         enum ParserState { StartParseObject, StartParseArray, StartParseExpression,
    88                            StartParseStatement, StartParseStatementEndStatement,
    89                            DoParseObjectStartExpression, DoParseObjectEndExpression,
    90                            DoParseArrayStartExpression, DoParseArrayEndExpression };
    91         enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace,
    92                          TokString, TokIdentifier, TokNumber, TokColon,
    93                          TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
    94                          TokNull, TokEnd, TokDot, TokAssign, TokSemi, TokError };
    95        
    96         class Lexer {
    97         public:
    98             struct LiteralParserToken {
    99                 TokenType type;
    100                 const UChar* start;
    101                 const UChar* end;
    102                 UString stringBuffer;
    103                 union {
    104                     double numberToken;
    105                     struct {
    106                         const UChar* stringToken;
    107                         int stringLength;
    108                     };
    109                 };
    110             };
    111             Lexer(const UChar* characters, unsigned length, ParserMode mode)
    112                 : m_mode(mode)
    113                 , m_ptr(characters)
    114                 , m_end(characters + length)
    115             {
    116             }
    117            
    118             TokenType next();
    119            
    120             const LiteralParserToken& currentToken()
    121             {
    122                 return m_currentToken;
    123             }
    124            
    125             UString getErrorMessage() { return m_lexErrorMessage; }
    126            
    127         private:
    128             UString m_lexErrorMessage;
    129             template <ParserMode mode> TokenType lex(LiteralParserToken&);
    130             template <ParserMode mode, UChar terminator> ALWAYS_INLINE TokenType lexString(LiteralParserToken&);
    131             ALWAYS_INLINE TokenType lexNumber(LiteralParserToken&);
    132             LiteralParserToken m_currentToken;
    133             UString m_string;
    134             ParserMode m_mode;
    135             const UChar* m_ptr;
    136             const UChar* m_end;
    137         };
    138        
    139         class StackGuard;
    140         JSValue parse(ParserState);
    141 
    142         ExecState* m_exec;
    143         LiteralParser::Lexer m_lexer;
    144         ParserMode m_mode;
    145         UString m_parseErrorMessage;
    146         static unsigned const MaximumCachableCharacter = 128;
    147         FixedArray<Identifier, MaximumCachableCharacter> m_shortIdentifiers;
    148         FixedArray<Identifier, MaximumCachableCharacter> m_recentIdentifiers;
    149         ALWAYS_INLINE const Identifier makeIdentifier(const UChar* characters, size_t length);
     154    ExecState* m_exec;
     155    typename LiteralParser<CharType>::Lexer m_lexer;
     156    ParserMode m_mode;
     157    UString m_parseErrorMessage;
     158    static unsigned const MaximumCachableCharacter = 128;
     159    FixedArray<Identifier, MaximumCachableCharacter> m_shortIdentifiers;
     160    FixedArray<Identifier, MaximumCachableCharacter> m_recentIdentifiers;
     161    ALWAYS_INLINE const Identifier makeIdentifier(const LChar* characters, size_t length);
     162    ALWAYS_INLINE const Identifier makeIdentifier(const UChar* characters, size_t length);
    150163    };
    151164
Note: See TracChangeset for help on using the changeset viewer.