LiteralParser.h 6.0 KB

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