X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/f9bf01c6616d5ddcf65b13b33cedf9e387ff7a63..81345200c95645a1b0d2635520f96ad55dfde63f:/runtime/LiteralParser.h diff --git a/runtime/LiteralParser.h b/runtime/LiteralParser.h index 0f8072b..f05f032 100644 --- a/runtime/LiteralParser.h +++ b/runtime/LiteralParser.h @@ -26,85 +26,142 @@ #ifndef LiteralParser_h #define LiteralParser_h +#include "Identifier.h" +#include "JSCJSValue.h" #include "JSGlobalObjectFunctions.h" -#include "JSValue.h" -#include "UString.h" +#include +#include namespace JSC { - class LiteralParser { +typedef enum { StrictJSON, NonStrictJSON, JSONP } ParserMode; + +enum JSONPPathEntryType { + JSONPPathEntryTypeDeclare, // var pathEntryName = JSON + JSONPPathEntryTypeDot, // .pathEntryName = JSON + JSONPPathEntryTypeLookup, // [pathIndex] = JSON + JSONPPathEntryTypeCall // (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 m_path; + Strong m_value; +}; + +template +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 +ALWAYS_INLINE void setParserTokenString(LiteralParserToken&, const CharType* string); + +template +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&, bool needsFullSourceInfo); + +private: + class Lexer { public: - typedef enum { StrictJSON, NonStrictJSON } ParserMode; - LiteralParser(ExecState* exec, const UString& s, ParserMode mode) - : m_exec(exec) - , m_lexer(s, 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& currentToken() { - m_lexer.next(); - JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement); - if (m_lexer.currentToken().type != TokEnd) - return JSValue(); - return result; + return m_currentToken; } - 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, TokError }; - - class Lexer { - public: - struct LiteralParserToken { - TokenType type; - const UChar* start; - const UChar* end; - UString stringToken; - double numberToken; - }; - Lexer(const UString& s, ParserMode mode) - : m_string(s) - , m_mode(mode) - , m_ptr(s.data()) - , m_end(s.data() + s.size()) - { - } - - TokenType next() - { - return lex(m_currentToken); - } - - const LiteralParserToken& currentToken() - { - return m_currentToken; - } - - private: - TokenType lex(LiteralParserToken&); - template TokenType lexString(LiteralParserToken&); - TokenType lexNumber(LiteralParserToken&); - LiteralParserToken m_currentToken; - UString m_string; - ParserMode m_mode; - const UChar* m_ptr; - const UChar* m_end; - }; - class StackGuard; - JSValue parse(ParserState); - - ExecState* m_exec; - LiteralParser::Lexer m_lexer; + String getErrorMessage() { return m_lexErrorMessage; } + + private: + String m_lexErrorMessage; + template TokenType lex(LiteralParserToken&); + ALWAYS_INLINE TokenType lexIdentifier(LiteralParserToken&); + template ALWAYS_INLINE TokenType lexString(LiteralParserToken&); + ALWAYS_INLINE TokenType lexNumber(LiteralParserToken&); + LiteralParserToken m_currentToken; ParserMode m_mode; + const CharType* m_ptr; + const CharType* m_end; }; + + class StackGuard; + JSValue parse(ParserState); + + ExecState* m_exec; + typename LiteralParser::Lexer m_lexer; + ParserMode m_mode; + String m_parseErrorMessage; + static unsigned const MaximumCachableCharacter = 128; + std::array m_shortIdentifiers; + std::array m_recentIdentifiers; + ALWAYS_INLINE const Identifier makeIdentifier(const LChar* characters, size_t length); + ALWAYS_INLINE const Identifier makeIdentifier(const UChar* characters, size_t length); + }; + } #endif