]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - parser/Lexer.cpp
JavaScriptCore-576.tar.gz
[apple/javascriptcore.git] / parser / Lexer.cpp
index 8e89c18a9ee9ff0f7ef90279ad0f4db5885aa73b..83f56bd244bb5f0e9c172efce957e99b8893787e 100644 (file)
@@ -39,19 +39,10 @@ using namespace Unicode;
 // We can't specify the namespace in yacc's C output, so do it here instead.
 using namespace JSC;
 
-#ifndef KDE_USE_FINAL
 #include "Grammar.h"
-#endif
-
 #include "Lookup.h"
 #include "Lexer.lut.h"
 
-// A bridge for yacc from the C world to the C++ world.
-int jscyylex(void* lvalp, void* llocp, void* globalData)
-{
-    return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp);
-}
-
 namespace JSC {
 
 static const UChar byteOrderMark = 0xFEFF;
@@ -141,8 +132,10 @@ ALWAYS_INLINE void Lexer::shift4()
     m_code += 4;
 }
 
-void Lexer::setCode(const SourceCode& source)
+void Lexer::setCode(const SourceCode& source, ParserArena& arena)
 {
+    m_arena = &arena.identifierArena();
+
     m_lineNumber = source.firstLine();
     m_delimited = false;
     m_lastToken = -1;
@@ -204,10 +197,9 @@ void Lexer::shiftLineTerminator()
     ++m_lineNumber;
 }
 
-ALWAYS_INLINE Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
+ALWAYS_INLINE const Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
 {
-    m_identifiers.append(Identifier(m_globalData, characters, length));
-    return &m_identifiers.last();
+    return &m_arena->makeIdentifier(m_globalData, characters, length);
 }
 
 inline bool Lexer::lastTokenWasRestrKeyword() const
@@ -647,6 +639,8 @@ inStringEscapeSequence:
         shiftLineTerminator();
         goto inString;
     }
+    if (m_current == -1)
+        goto returnError;
     record16(singleEscape(m_current));
     shift1();
     goto inString;
@@ -908,48 +902,110 @@ returnError:
     return -1;
 }
 
-bool Lexer::scanRegExp()
+bool Lexer::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix)
 {
     ASSERT(m_buffer16.isEmpty());
 
     bool lastWasEscape = false;
     bool inBrackets = false;
 
+    if (patternPrefix) {
+        ASSERT(!isLineTerminator(patternPrefix));
+        ASSERT(patternPrefix != '/');
+        ASSERT(patternPrefix != '[');
+        record16(patternPrefix);
+    }
+
     while (true) {
-        if (isLineTerminator(m_current) || m_current == -1)
-            return false;
-        if (m_current != '/' || lastWasEscape || inBrackets) {
-            // keep track of '[' and ']'
-            if (!lastWasEscape) {
-                if (m_current == '[' && !inBrackets)
-                    inBrackets = true;
-                if (m_current == ']' && inBrackets)
-                    inBrackets = false;
-            }
-            record16(m_current);
-            lastWasEscape = !lastWasEscape && m_current == '\\';
-        } else { // end of regexp
-            m_pattern = UString(m_buffer16);
+        int current = m_current;
+
+        if (isLineTerminator(current) || current == -1) {
             m_buffer16.resize(0);
-            shift1();
-            break;
+            return false;
         }
+
         shift1();
+
+        if (current == '/' && !lastWasEscape && !inBrackets)
+            break;
+
+        record16(current);
+
+        if (lastWasEscape) {
+            lastWasEscape = false;
+            continue;
+        }
+
+        switch (current) {
+        case '[':
+            inBrackets = true;
+            break;
+        case ']':
+            inBrackets = false;
+            break;
+        case '\\':
+            lastWasEscape = true;
+            break;
+        }
     }
 
+    pattern = makeIdentifier(m_buffer16.data(), m_buffer16.size());
+    m_buffer16.resize(0);
+
     while (isIdentPart(m_current)) {
         record16(m_current);
         shift1();
     }
-    m_flags = UString(m_buffer16);
+
+    flags = makeIdentifier(m_buffer16.data(), m_buffer16.size());
     m_buffer16.resize(0);
 
     return true;
 }
 
+bool Lexer::skipRegExp()
+{
+    bool lastWasEscape = false;
+    bool inBrackets = false;
+
+    while (true) {
+        int current = m_current;
+
+        if (isLineTerminator(current) || current == -1)
+            return false;
+
+        shift1();
+
+        if (current == '/' && !lastWasEscape && !inBrackets)
+            break;
+
+        if (lastWasEscape) {
+            lastWasEscape = false;
+            continue;
+        }
+
+        switch (current) {
+        case '[':
+            inBrackets = true;
+            break;
+        case ']':
+            inBrackets = false;
+            break;
+        case '\\':
+            lastWasEscape = true;
+            break;
+        }
+    }
+
+    while (isIdentPart(m_current))
+        shift1();
+
+    return true;
+}
+
 void Lexer::clear()
 {
-    m_identifiers.clear();
+    m_arena = 0;
     m_codeWithoutBOMs.clear();
 
     Vector<char> newBuffer8;
@@ -961,9 +1017,6 @@ void Lexer::clear()
     m_buffer16.swap(newBuffer16);
 
     m_isReparsing = false;
-
-    m_pattern = UString();
-    m_flags = UString();
 }
 
 SourceCode Lexer::sourceCode(int openBrace, int closeBrace, int firstLine)