]> git.saurik.com Git - apple/javascriptcore.git/commitdiff
JavaScriptCore-466.1.6.tar.gz iphone-221 v466.1.6
authorApple <opensource@apple.com>
Thu, 18 Dec 2008 00:04:33 +0000 (00:04 +0000)
committerApple <opensource@apple.com>
Thu, 18 Dec 2008 00:04:33 +0000 (00:04 +0000)
34 files changed:
API/JSBase.cpp
JavaScriptCore.exp
bindings/NP_jsobject.cpp
bindings/jni/jni_jsobject.cpp
bindings/make_testbindings [changed mode: 0644->0755]
kjs/Parser.cpp
kjs/Parser.h
kjs/SourceCode.h [new file with mode: 0644]
kjs/SourceProvider.h [new file with mode: 0644]
kjs/config.h
kjs/create_hash_table [changed mode: 0644->0755]
kjs/debugger.cpp
kjs/debugger.h
kjs/function.cpp
kjs/function_object.cpp
kjs/grammar.y
kjs/interpreter.cpp
kjs/interpreter.h
kjs/lexer.cpp
kjs/lexer.h
kjs/nodes.cpp
kjs/nodes.h
kjs/nodes2string.cpp
kjs/object.cpp
kjs/object.h
kjs/testkjs.cpp
kjs/ustring.cpp
kjs/ustring.h
make-generated-sources.sh [changed mode: 0644->0755]
pcre/dftables [changed mode: 0644->0755]
wtf/FastMalloc.cpp
wtf/OwnPtrWin.cpp [changed mode: 0644->0755]
wtf/TCSystemAlloc.cpp
wtf/Vector.h

index d8acc42d7c8e6686609a2f1a9ef03479d8ae212a..65f2128728e53286ceea50ade383072d188624ba 100644 (file)
@@ -28,6 +28,7 @@
 #include "JSBase.h"
 
 #include "APICast.h"
+#include "SourceCode.h"
 #include <kjs/ExecState.h>
 #include <kjs/JSGlobalObject.h>
 #include <kjs/JSLock.h>
@@ -43,8 +44,9 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
     JSObject* jsThisObject = toJS(thisObject);
     UString::Rep* scriptRep = toJS(script);
     UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
+    SourceCode source = makeSource(UString(scriptRep), UString(sourceURLRep), startingLineNumber);
     // Interpreter::evaluate sets "this" to the global object if it is NULL
-    Completion completion = Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), UString(sourceURLRep), startingLineNumber, UString(scriptRep), jsThisObject);
+    Completion completion = Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), source, jsThisObject);
 
     if (completion.complType() == Throw) {
         if (exception)
@@ -66,7 +68,8 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
     ExecState* exec = toJS(ctx);
     UString::Rep* scriptRep = toJS(script);
     UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
-    Completion completion = Interpreter::checkSyntax(exec->dynamicGlobalObject()->globalExec(), UString(sourceURLRep), startingLineNumber, UString(scriptRep));
+    SourceCode source = makeSource(UString(scriptRep), UString(sourceURLRep), startingLineNumber);
+    Completion completion = Interpreter::checkSyntax(exec->dynamicGlobalObject()->globalExec(), source);
     if (completion.complType() == Throw) {
         if (exception)
             *exception = toRef(completion.value());
index 3ee8f3b53324e0b22a82da0cfd721dbc7f46c575..123f80e922f57d3e62a088c878c54b68e01f0e8d 100644 (file)
@@ -102,15 +102,14 @@ __ZN3KJS10Identifier3addEPKc
 __ZN3KJS10Identifier5equalEPKNS_7UString3RepEPKc
 __ZN3KJS10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
 __ZN3KJS10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
-__ZN3KJS11Interpreter11checkSyntaxEPNS_9ExecStateERKNS_7UStringEiPKNS_5UCharEi
+__ZN3KJS11Interpreter11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
 __ZN3KJS11Interpreter21shouldPrintExceptionsEv
 __ZN3KJS11Interpreter24setShouldPrintExceptionsEb
-__ZN3KJS11Interpreter8evaluateEPNS_9ExecStateERKNS_7UStringEiPKNS_5UCharEiPNS_7JSValueE
-__ZN3KJS11Interpreter8evaluateEPNS_9ExecStateERKNS_7UStringEiS5_PNS_7JSValueE
+__ZN3KJS11Interpreter8evaluateEPNS_9ExecStateERKNS_10SourceCodeEPNS_7JSValueE
 __ZN3KJS11JSImmediate4typeEPKNS_7JSValueE
 __ZN3KJS11JSImmediate8toObjectEPKNS_7JSValueEPNS_9ExecStateE
 __ZN3KJS11JSImmediate8toStringEPKNS_7JSValueE
-__ZN3KJS11ProgramNode6createEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS4_IPNS_12FuncDeclNodeELm16EEE
+__ZN3KJS11ProgramNode6createERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS7_IPNS_12FuncDeclNodeELm16EEE
 __ZN3KJS11PropertyMap11getLocationERKNS_10IdentifierE
 __ZN3KJS11PropertyMap5clearEv
 __ZN3KJS11PropertyMap7restoreERKNS_15SavedPropertiesE
@@ -166,7 +165,7 @@ __ZN3KJS6JSLock4lockEv
 __ZN3KJS6JSLock6unlockEv
 __ZN3KJS6JSLock9lockCountEv
 __ZN3KJS6Lookup9findEntryEPKNS_9HashTableERKNS_10IdentifierE
-__ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE
+__ZN3KJS6Parser5parseEPiPNS_7UStringE
 __ZN3KJS6parserEv
 __ZN3KJS7CStringD1Ev
 __ZN3KJS7UString3Rep4nullE
@@ -192,9 +191,8 @@ __ZN3KJS8Bindings8Instance18didExecuteFunctionEv
 __ZN3KJS8Bindings8Instance19createRuntimeObjectEPS1_
 __ZN3KJS8Bindings8Instance21setDidExecuteFunctionEPFvPNS_9ExecStateEPNS_8JSObjectEE
 __ZN3KJS8Bindings8Instance32createBindingForLanguageInstanceENS1_15BindingLanguageEPvN3WTF10PassRefPtrINS0_10RootObjectEEE
-__ZN3KJS8Debugger12sourceUnusedEPNS_9ExecStateEi
 __ZN3KJS8Debugger6attachEPNS_14JSGlobalObjectE
-__ZN3KJS8Debugger9exceptionEPNS_9ExecStateEiiPNS_7JSValueE
+__ZN3KJS8Debugger12sourceUnusedEPNS_9ExecStateEl
 __ZN3KJS8DebuggerC2Ev
 __ZN3KJS8DebuggerD2Ev
 __ZN3KJS8JSObject11hasInstanceEPNS_9ExecStateEPNS_7JSValueE
@@ -243,7 +241,7 @@ __ZNK3KJS16JSVariableObject16saveLocalStorageERNS_15SavedPropertiesE
 __ZNK3KJS19InternalFunctionImp14implementsCallEv
 __ZNK3KJS19InternalFunctionImp21implementsHasInstanceEv
 __ZNK3KJS4List8getSliceEiRS0_
-__ZNK3KJS4Node8toStringEv
+__ZN3KJS4Node8toStringEv
 __ZNK3KJS6JSCell17getTruncatedInt32ERi
 __ZNK3KJS6JSCell18getTruncatedUInt32ERj
 __ZNK3KJS6JSCell9getNumberERd
@@ -259,6 +257,7 @@ __ZNK3KJS7UString10UTF8StringEb
 __ZNK3KJS7UString14toStrictUInt32EPb
 __ZNK3KJS7UString5asciiEv
 __ZNK3KJS7UString6is8BitEv
+__ZNK3KJS7UString6substrEii
 __ZNK3KJS7UString8toUInt32EPb
 __ZNK3KJS7UString8toUInt32EPbb
 __ZNK3KJS8Bindings10RootObject12globalObjectEv
index d68a8e69ecdce185a9468978103cce322f6e32fc..f334624df2f6fa190fe04b2fce0816434b5d4884 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "JSGlobalObject.h"
 #include "PropertyNameArray.h"
+#include "SourceCode.h"
 #include "c_utility.h"
 #include "interpreter.h"
 #include "npruntime_impl.h"
@@ -197,7 +198,9 @@ bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant)
         unsigned int UTF16Length;
         convertNPStringToUTF16(s, &scriptString, &UTF16Length); // requires free() of returned memory
         rootObject->globalObject()->startTimeoutCheck();
-        Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), UString(), 0, UString(reinterpret_cast<const UChar*>(scriptString), UTF16Length));
+
+        SourceCode source = makeSource(UString(reinterpret_cast<const UChar*>(scriptString), UTF16Length), UString());
+        Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), source);
         rootObject->globalObject()->stopTimeoutCheck();
         ComplType type = completion.complType();
         
index fe2e9e3e0c732bfb93d7c4e6c756ed147403edee..a16c640905ac01ce9050fa85baa5b611857d2da1 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(JAVA_BINDINGS)
 
+#include "SourceCode.h"
 #include "identifier.h"
 #include "internal.h"
 #include "interpreter.h"
@@ -202,7 +203,10 @@ jobject JavaJSObject::eval(jstring script) const
         return 0;
 
     rootObject->globalObject()->startTimeoutCheck();
-    Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), UString(), 0, JavaString(script).ustring(),thisObj);
+
+    SourceCode source = makeSource(JavaString(script).ustring(), UString());
+    Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), source, thisObj);
+
     rootObject->globalObject()->stopTimeoutCheck();
     ComplType type = completion.complType();
     
old mode 100644 (file)
new mode 100755 (executable)
index c6d7265af44c19ed28279a1e7bee8178cc56e6bc..7a63d8e2083e6cabb81aeab0644c45fe2bb819e5 100644 (file)
@@ -33,14 +33,7 @@ extern int kjsyyparse();
 
 namespace KJS {
 
-Parser::Parser()
-    : m_sourceId(0)
-{
-}
-
-void Parser::parse(int startingLineNumber,
-    const UChar* code, unsigned length,
-    int* sourceId, int* errLine, UString* errMsg)
+void Parser::parse(int* errLine, UString* errMsg)
 {
     ASSERT(!m_sourceElements);
 
@@ -50,11 +43,7 @@ void Parser::parse(int startingLineNumber,
         *errMsg = 0;
         
     Lexer& lexer = KJS::lexer();
-
-    lexer.setCode(startingLineNumber, code, length);
-    m_sourceId++;
-    if (sourceId)
-        *sourceId = m_sourceId;
+    lexer.setCode(*m_source);
 
     int parseError = kjsyyparse();
     bool lexError = lexer.sawError();
@@ -71,6 +60,23 @@ void Parser::parse(int startingLineNumber,
     }
 }
 
+void Parser::reparse(FunctionBodyNode* functionBodyNode)
+{
+    m_source = &functionBodyNode->source();
+    parse(0, 0);
+    ASSERT(m_sourceElements);
+
+    functionBodyNode->setData(m_sourceElements.get(),
+                              m_varDeclarations ? &m_varDeclarations->data : 0, 
+                              m_funcDeclarations ? &m_funcDeclarations->data : 0);
+    functionBodyNode->setLoc(m_source->firstLine(), m_lastLine);
+
+    m_source = 0;
+    m_sourceElements = 0;
+    m_varDeclarations = 0;
+    m_funcDeclarations = 0;
+}
+
 void Parser::didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack, 
                               ParserRefCountedData<DeclarationStacks::FunctionStack>* funcStack, int lastLine)
 {
index 92548fe2f0078bf249f366018637fb2b5cf8c438..88211866d39b9b360fad8ebc430e259872e62af3 100644 (file)
 #ifndef Parser_h
 #define Parser_h
 
+#include "SourceProvider.h"
+#include "nodes.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/RefPtr.h>
-#include "nodes.h"
 
 namespace KJS {
 
@@ -45,26 +46,20 @@ namespace KJS {
 
     class Parser : Noncopyable {
     public:
-        template <class ParsedNode>
-        PassRefPtr<ParsedNode> parse(const UString& sourceURL, int startingLineNumber,
-            const UChar* code, unsigned length,
-            int* sourceId = 0, int* errLine = 0, UString* errMsg = 0);
-
-        UString sourceURL() const { return m_sourceURL; }
-        int sourceId() const { return m_sourceId; }
+        template <class ParsedNode> PassRefPtr<ParsedNode> parse(PassRefPtr<SourceProvider>, int* errLine = 0, UString* errMsg = 0);
+        template <class ParsedNode> PassRefPtr<ParsedNode> parse(const SourceCode&, int* errLine = 0, UString* errMsg = 0);
 
         void didFinishParsing(SourceElements*, ParserRefCountedData<DeclarationStacks::VarStack>*, 
                               ParserRefCountedData<DeclarationStacks::FunctionStack>*, int lastLine);
 
+        void reparse(FunctionBodyNode*);
+
     private:
         friend Parser& parser();
 
-        Parser(); // Use parser() instead.
-        void parse(int startingLineNumber, const UChar* code, unsigned length,
-            int* sourceId, int* errLine, UString* errMsg);
+        void parse(int* errLine, UString* errMsg);
 
-        UString m_sourceURL;
-        int m_sourceId;
+        const SourceCode* m_source;
         RefPtr<SourceElements> m_sourceElements;
         RefPtr<ParserRefCountedData<DeclarationStacks::VarStack> > m_varDeclarations;
         RefPtr<ParserRefCountedData<DeclarationStacks::FunctionStack> > m_funcDeclarations;
@@ -73,25 +68,24 @@ namespace KJS {
     
     Parser& parser(); // Returns the singleton JavaScript parser.
 
-    template <class ParsedNode>
-    PassRefPtr<ParsedNode> Parser::parse(const UString& sourceURL, int startingLineNumber,
-        const UChar* code, unsigned length,
-        int* sourceId, int* errLine, UString* errMsg)
+    template <class ParsedNode> PassRefPtr<ParsedNode> Parser::parse(const SourceCode& source, int* errLine, UString* errMsg)
     {
-        m_sourceURL = sourceURL;
-        parse(startingLineNumber, code, length, sourceId, errLine, errMsg);
-        if (!m_sourceElements) {
-            m_sourceURL = UString();
-            return 0;
+        m_source = &source;
+        parse(errLine, errMsg);
+        RefPtr<ParsedNode> result;
+        if (m_sourceElements) {
+            result = ParsedNode::create(*m_source,
+                                        m_sourceElements.get(),
+                                        m_varDeclarations ? &m_varDeclarations->data : 0, 
+                                        m_funcDeclarations ? &m_funcDeclarations->data : 0);
+            result->setLoc(m_source->firstLine(), m_lastLine);
         }
-        RefPtr<ParsedNode> node = ParsedNode::create(m_sourceElements.release().get(),
-                                                     m_varDeclarations ? &m_varDeclarations->data : 0, 
-                                                     m_funcDeclarations ? &m_funcDeclarations->data : 0);
+
+        m_source = 0;
+        m_sourceElements = 0;
         m_varDeclarations = 0;
         m_funcDeclarations = 0;
-        m_sourceURL = UString();
-        node->setLoc(startingLineNumber, m_lastLine);
-        return node.release();
+        return result.release();
     }
 
 } // namespace KJS
diff --git a/kjs/SourceCode.h b/kjs/SourceCode.h
new file mode 100644 (file)
index 0000000..dba674f
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SourceCode_h
+#define SourceCode_h
+
+#include "SourceProvider.h"
+#include <wtf/RefPtr.h>
+
+namespace KJS {
+
+    class SourceCode {
+    public:
+        SourceCode()
+            : m_startChar(0)
+            , m_endChar(0)
+            , m_firstLine(0)
+        {
+        }
+
+        SourceCode(PassRefPtr<SourceProvider> provider, int firstLine = 0)
+            : m_provider(provider)
+            , m_startChar(0)
+            , m_endChar(m_provider->length())
+            , m_firstLine(firstLine + 1)
+        {
+        }
+
+        SourceCode(PassRefPtr<SourceProvider> provider, int start, int end, int firstLine)
+            : m_provider(provider)
+            , m_startChar(start)
+            , m_endChar(end)
+            , m_firstLine(firstLine + 1)
+        {
+        }
+
+        UString toString() const
+        {
+            if (!m_provider)
+                return UString();
+            return m_provider->getRange(m_startChar, m_endChar);
+        }
+        
+        SourceProvider* provider() const { return m_provider.get(); }
+        int firstLine() const { return m_firstLine; }
+        int startOffset() const { return m_startChar; }
+        const UChar* data() const { return m_provider->data() + m_startChar; }
+        int length() const { return m_endChar - m_startChar; }
+
+    private:
+        RefPtr<SourceProvider> m_provider;
+        int m_startChar;
+        int m_endChar;
+        int m_firstLine;
+    };
+
+    inline SourceCode makeSource(const UString& source, const UString& url = UString(), int firstLine = 0)
+    {
+        return SourceCode(UStringSourceProvider::create(source, url), firstLine);
+    }
+
+} // namespace KJS
+
+#endif // SourceCode_h
diff --git a/kjs/SourceProvider.h b/kjs/SourceProvider.h
new file mode 100644 (file)
index 0000000..65c8cb4
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SourceProvider_h
+#define SourceProvider_h
+
+#include "ustring.h"
+#include <wtf/RefCounted.h>
+
+namespace KJS {
+
+    class SourceProvider : public RefCounted<SourceProvider> {
+    public:
+        SourceProvider(const UString& url)
+            : m_url(url)
+        {
+        }
+        virtual ~SourceProvider() { }
+
+        virtual UString getRange(int start, int end) const = 0;
+        virtual const UChar* data() const = 0;
+        virtual int length() const = 0;
+        
+        const UString& url() { return m_url; }
+        intptr_t asID() { return reinterpret_cast<intptr_t>(this); }
+
+    private:
+        UString m_url;
+    };
+
+    class UStringSourceProvider : public SourceProvider {
+    public:
+        static PassRefPtr<UStringSourceProvider> create(const UString& source, const UString& url)
+        {
+            return new UStringSourceProvider(source, url);
+        }
+
+        UString getRange(int start, int end) const { return m_source.substr(start, end - start); }
+        const UChar* data() const { return m_source.data(); }
+        int length() const { return m_source.size(); }
+
+    private:
+        UStringSourceProvider(const UString& source, const UString& url)
+            : SourceProvider(url)
+            , m_source(source)
+        {
+        }
+
+        UString m_source;
+    };
+    
+} // namespace KJS
+
+#endif // SourceProvider_h
index f60561e16dd0c3e46b6229343c8853ee18ef79af..2545bf66d21a5352f255fdb2487ff8051697eab0 100644 (file)
@@ -25,6 +25,7 @@
 #if PLATFORM(DARWIN)
 
 #define HAVE_ERRNO_H 1
+#define HAVE_MADV_DONTNEED 1
 #define HAVE_MMAP 1
 #define HAVE_MERGESORT 1
 #define HAVE_SBRK 1
old mode 100644 (file)
new mode 100755 (executable)
index af9c5faaf4757d45d11a937d3c4e97f29ff2c813..9e69b2cfee7003ac61b71522ceacc0b5dc216f0a 100644 (file)
@@ -97,36 +97,35 @@ bool Debugger::hasHandledException(ExecState *exec, JSValue *exception)
     return false;
 }
 
-bool Debugger::sourceParsed(ExecState*, int /*sourceId*/, const UString &/*sourceURL*/, 
-                           const UString &/*source*/, int /*startingLineNumber*/, int /*errorLine*/, const UString & /*errorMsg*/)
+bool Debugger::sourceParsed(ExecState*, const SourceCode&, int /*errorLine*/, const UString& /*errorMsg*/)
 {
   return true;
 }
 
-bool Debugger::sourceUnused(ExecState*, int /*sourceId*/)
+bool Debugger::sourceUnused(ExecState*, intptr_t /*sourceID*/)
 {
   return true;
 }
 
-bool Debugger::exception(ExecState*, int /*sourceId*/, int /*lineno*/,
+bool Debugger::exception(ExecState*, intptr_t /*sourceID*/, int /*lineno*/,
                          JSValue* /*exception */)
 {
   return true;
 }
 
-bool Debugger::atStatement(ExecState*, int /*sourceId*/, int /*firstLine*/,
+bool Debugger::atStatement(ExecState*, intptr_t /*sourceID*/, int /*firstLine*/,
                            int /*lastLine*/)
 {
   return true;
 }
 
-bool Debugger::callEvent(ExecState*, int /*sourceId*/, int /*lineno*/,
+bool Debugger::callEvent(ExecState*, intptr_t /*sourceID*/, int /*lineno*/,
                          JSObject* /*function*/, const List &/*args*/)
 {
   return true;
 }
 
-bool Debugger::returnEvent(ExecState*, int /*sourceId*/, int /*lineno*/,
+bool Debugger::returnEvent(ExecState*, intptr_t /*sourceID*/, int /*lineno*/,
                            JSObject* /*function*/)
 {
   return true;
index 2d5cb6f5162d3493ac61d4967666bae5babf6170..6aa15e2436bff1040433420fca183e46ce011ad1 100644 (file)
@@ -33,6 +33,7 @@ namespace KJS {
   class JSGlobalObject;
   class JSObject;
   class JSValue;
+  class SourceCode;
   class UString;
   class List;
 
@@ -114,8 +115,7 @@ namespace KJS {
      * @return true if execution should be continue, false if it should
      * be aborted
      */
-    virtual bool sourceParsed(ExecState *exec, int sourceId, const UString &sourceURL,
-                              const UString &source, int startingLineNumber, int errorLine, const UString &errorMsg);
+    virtual bool sourceParsed(ExecState*, const SourceCode&, int errorLine, const UString& errorMsg) = 0;
 
     /**
      * Called when all functions/programs associated with a particular
@@ -131,7 +131,7 @@ namespace KJS {
      * @return true if execution should be continue, false if it should
      * be aborted
      */
-    virtual bool sourceUnused(ExecState *exec, int sourceId);
+    virtual bool sourceUnused(ExecState *exec, intptr_t sourceID);
 
     /**
      * Called when an exception is thrown during script execution.
@@ -146,7 +146,7 @@ namespace KJS {
      * @return true if execution should be continue, false if it should
      * be aborted
      */
-    virtual bool exception(ExecState *exec, int sourceId, int lineno,
+    virtual bool exception(ExecState *exec, intptr_t sourceID, int lineno,
                            JSValue *exception);
 
     bool hasHandledException(ExecState *, JSValue *);
@@ -166,7 +166,7 @@ namespace KJS {
      * @return true if execution should be continue, false if it should
      * be aborted
      */
-    virtual bool atStatement(ExecState *exec, int sourceId, int firstLine,
+    virtual bool atStatement(ExecState *exec, intptr_t sourceID, int firstLine,
                              int lastLine);
     /**
      * Called on each function call. Use together with @ref #returnEvent
@@ -188,7 +188,7 @@ namespace KJS {
      * @return true if execution should be continue, false if it should
      * be aborted
      */
-    virtual bool callEvent(ExecState *exec, int sourceId, int lineno,
+    virtual bool callEvent(ExecState *exec, intptr_t sourceID, int lineno,
                            JSObject *function, const List &args);
 
     /**
@@ -209,7 +209,7 @@ namespace KJS {
      * @return true if execution should be continue, false if it should
      * be aborted
      */
-    virtual bool returnEvent(ExecState *exec, int sourceId, int lineno,
+    virtual bool returnEvent(ExecState *exec, intptr_t sourceID, int lineno,
                              JSObject *function);
 
   private:
index 9f1b62c9f85d1b0da5a55aa3e9d498bea48cc2b7..92b3446c3b1826e7c83c99770be6fcc386690765 100644 (file)
@@ -698,21 +698,17 @@ JSValue* globalFuncEval(ExecState* exec, JSObject* thisObj, const List& args)
 
     UString s = x->toString(exec);
 
-    int sourceId;
     int errLine;
     UString errMsg;
-    RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg);
 
-    Debugger* dbg = exec->dynamicGlobalObject()->debugger();
-    if (dbg) {
-        bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg);
-        if (!cont)
-            return jsUndefined();
-    }
+    SourceCode source = makeSource(s); 
+    RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(source, &errLine, &errMsg);
+
+    // debugger code removed
 
     // No program node means a syntax occurred
     if (!evalNode)
-        return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
+        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL);
 
     bool switchGlobal = thisObj && thisObj != exec->dynamicGlobalObject() && thisObj->isGlobalObject();
 
index 5af2970367d1599858ef1d54e828dfbf9f9c8d55..38b72f29bc4cac39cebf1d11530902ab3a9a5274 100644 (file)
@@ -162,27 +162,18 @@ JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args, const
     }
 
     // parse the source code
-    int sourceId;
     int errLine;
     UString errMsg;
-    RefPtr<FunctionBodyNode> functionBody = parser().parse<FunctionBodyNode>(sourceURL, lineNumber, body.data(), body.size(), &sourceId, &errLine, &errMsg);
-
-    // notify debugger that source has been parsed
-    Debugger* dbg = exec->dynamicGlobalObject()->debugger();
-    if (dbg) {
-        // send empty sourceURL to indicate constructed code
-        bool cont = dbg->sourceParsed(exec, sourceId, UString(), body, lineNumber, errLine, errMsg);
-        if (!cont) {
-            dbg->imp()->abort();
-            return new JSObject();
-        }
-    }
+    SourceCode source = makeSource(body, sourceURL, lineNumber); 
+    RefPtr<FunctionBodyNode> functionBody = parser().parse<FunctionBodyNode>(source, &errLine, &errMsg);
+
+    // debugger code removed
 
     // No program node == syntax error - throw a syntax error
     if (!functionBody)
         // We can't return a Completion(Throw) here, so just set the exception
         // and return it
-        return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL);
+        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
 
     ScopeChain scopeChain;
     scopeChain.push(exec->lexicalGlobalObject());
index 658ae8948aaf0de612b0d0587c2feac7e4603e21..4252d02913681998ec1c68665e2232c604f6e394 100644 (file)
@@ -65,7 +65,7 @@ static LessNode* makeLessNode(ExpressionNode*, ExpressionNode*);
 static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr);
 static ExpressionNode* makePrefixNode(ExpressionNode* expr, Operator);
 static ExpressionNode* makePostfixNode(ExpressionNode* expr, Operator);
-static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*);
+static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&);
 static ExpressionNode* makeFunctionCallNode(ExpressionNode* func, ArgumentsNode*);
 static ExpressionNode* makeTypeOfNode(ExpressionNode*);
 static ExpressionNode* makeDeleteNode(ExpressionNode*);
@@ -198,6 +198,8 @@ static inline void appendToVarDeclarationList(ParserRefCountedData<DeclarationSt
 %token RSHIFTEQUAL URSHIFTEQUAL    /* >>= and >>>= */
 %token ANDEQUAL MODEQUAL           /* &= and %= */
 %token XOREQUAL OREQUAL            /* ^= and |= */
+%token <intValue> OPENBRACE        /* { (with char offset) */
+%token <intValue> CLOSEBRACE        /* { (with char offset) */
 
 /* terminal types */
 %token <doubleValue> NUMBER
@@ -287,9 +289,9 @@ Property:
     IDENT ':' AssignmentExpr            { $$ = new PropertyNode(*$1, $3, PropertyNode::Constant); }
   | STRING ':' AssignmentExpr           { $$ = new PropertyNode(Identifier(*$1), $3, PropertyNode::Constant); }
   | NUMBER ':' AssignmentExpr           { $$ = new PropertyNode(Identifier(UString::from($1)), $3, PropertyNode::Constant); }
-  | IDENT IDENT '(' ')' '{' FunctionBody '}'    { $$ = makeGetterOrSetterPropertyNode(*$1, *$2, 0, $6); DBG($6, @5, @7); if (!$$) YYABORT; }
-  | IDENT IDENT '(' FormalParameterList ')' '{' FunctionBody '}'
-                                        { $$ = makeGetterOrSetterPropertyNode(*$1, *$2, $4.head, $7); DBG($7, @6, @8); if (!$$) YYABORT; }
+  | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE    { $$ = makeGetterOrSetterPropertyNode(*$1, *$2, 0, $6, lexer().sourceCode($5, $7, @5.first_line)); DBG($6, @5, @7); if (!$$) YYABORT; }
+  | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
+                                        { $$ = makeGetterOrSetterPropertyNode(*$1, *$2, $4.head, $7, lexer().sourceCode($6, $8, @6.first_line)); DBG($7, @6, @8); if (!$$) YYABORT; }
 ;
 
 PropertyList:
@@ -301,10 +303,10 @@ PropertyList:
 
 PrimaryExpr:
     PrimaryExprNoBrace
-  | '{' '}'                             { $$ = new ObjectLiteralNode(); }
-  | '{' PropertyList '}'                { $$ = new ObjectLiteralNode($2.head); }
+  | OPENBRACE CLOSEBRACE                             { $$ = new ObjectLiteralNode(); }
+  | OPENBRACE PropertyList CLOSEBRACE                { $$ = new ObjectLiteralNode($2.head); }
   /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
-  | '{' PropertyList ',' '}'            { $$ = new ObjectLiteralNode($2.head); }
+  | OPENBRACE PropertyList ',' CLOSEBRACE            { $$ = new ObjectLiteralNode($2.head); }
 ;
 
 PrimaryExprNoBrace:
@@ -711,9 +713,9 @@ Statement:
 ;
 
 Block:
-    '{' '}'                             { $$ = createNodeInfo<StatementNode*>(new BlockNode(0), 0, 0);
+    OPENBRACE CLOSEBRACE                             { $$ = createNodeInfo<StatementNode*>(new BlockNode(0), 0, 0);
                                           DBG($$.m_node, @1, @2); }
-  | '{' SourceElements '}'              { $$ = createNodeInfo<StatementNode*>(new BlockNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations);
+  | OPENBRACE SourceElements CLOSEBRACE              { $$ = createNodeInfo<StatementNode*>(new BlockNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations);
                                           DBG($$.m_node, @1, @3); }
 ;
 
@@ -913,8 +915,8 @@ SwitchStatement:
 ;
 
 CaseBlock:
-    '{' CaseClausesOpt '}'              { $$ = createNodeInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations); }
-  | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}'
+    OPENBRACE CaseClausesOpt CLOSEBRACE              { $$ = createNodeInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations); }
+  | OPENBRACE CaseClausesOpt DefaultClause CaseClausesOpt CLOSEBRACE
                                         { $$ = createNodeInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, $3.m_node, $4.m_node.head),
                                                                               mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $3.m_varDeclarations), $4.m_varDeclarations),
                                                                               mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $3.m_funcDeclarations), $4.m_funcDeclarations)); }
@@ -981,16 +983,16 @@ DebuggerStatement:
 ;
 
 FunctionDeclaration:
-    FUNCTION IDENT '(' ')' '{' FunctionBody '}' { $$ = new FuncDeclNode(*$2, $6); DBG($6, @5, @7); }
-  | FUNCTION IDENT '(' FormalParameterList ')' '{' FunctionBody '}'
-                                        { $$ = new FuncDeclNode(*$2, $4.head, $7); DBG($7, @6, @8); }
+    FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = new FuncDeclNode(*$2, $6, lexer().sourceCode($5, $7, @5.first_line)); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
+                                        { $$ = new FuncDeclNode(*$2, $7, lexer().sourceCode($6, $8, @6.first_line), $4.head); DBG($7, @6, @8); }
 ;
 
 FunctionExpr:
-    FUNCTION '(' ')' '{' FunctionBody '}' { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5); DBG($5, @4, @6); }
-  | FUNCTION '(' FormalParameterList ')' '{' FunctionBody '}' { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $6, $3.head); DBG($6, @5, @7); }
-  | FUNCTION IDENT '(' ')' '{' FunctionBody '}' { $$ = new FuncExprNode(*$2, $6); DBG($6, @5, @7); }
-  | FUNCTION IDENT '(' FormalParameterList ')' '{' FunctionBody '}' { $$ = new FuncExprNode(*$2, $7, $4.head); DBG($7, @6, @8); }
+    FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5, lexer().sourceCode($4, $6, @4.first_line)); DBG($5, @4, @6); }
+  | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $6, lexer().sourceCode($5, $7, @5.first_line), $3.head); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = new FuncExprNode(*$2, $6, lexer().sourceCode($5, $7, @5.first_line)); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = new FuncExprNode(*$2, $7, lexer().sourceCode($6, $8, @6.first_line), $4.head); DBG($7, @6, @8); }
 ;
 
 FormalParameterList:
@@ -1001,20 +1003,8 @@ FormalParameterList:
 ;
 
 FunctionBody:
-    /* not in spec */           { $$ = FunctionBodyNode::create(0, 0, 0); }
-  | SourceElements              { $$ = FunctionBodyNode::create($1.m_node, $1.m_varDeclarations ? &$1.m_varDeclarations->data : 0, 
-                                                                $1.m_funcDeclarations ? &$1.m_funcDeclarations->data : 0);
-                                  // As in mergeDeclarationLists() we have to ref/deref to safely get rid of
-                                  // the declaration lists.
-                                  if ($1.m_varDeclarations) {
-                                      $1.m_varDeclarations->ref();
-                                      $1.m_varDeclarations->deref();
-                                  }
-                                  if ($1.m_funcDeclarations) {
-                                      $1.m_funcDeclarations->ref();
-                                      $1.m_funcDeclarations->deref();
-                                  }
-                                }
+    /* not in spec */                   { $$ = FunctionBodyNode::create(); }
+  | SourceElements_NoNode               { $$ = FunctionBodyNode::create(); }
 ;
 
 Program:
@@ -1038,7 +1028,600 @@ SourceElement:
     FunctionDeclaration                 { $$ = createNodeInfo<StatementNode*>($1, 0, new ParserRefCountedData<DeclarationStacks::FunctionStack>); $$.m_funcDeclarations->data.append($1); }
   | Statement                           { $$ = $1; }
 ;
+
+// Start NoNodes
+
+Literal_NoNode:
+    NULLTOKEN
+  | TRUETOKEN
+  | FALSETOKEN
+  | NUMBER { }
+  | STRING { }
+  | '/' /* regexp */ { Lexer& l = lexer(); if (!l.scanRegExp()) YYABORT; }
+  | DIVEQUAL /* regexp with /= */ { Lexer& l = lexer(); if (!l.scanRegExp()) YYABORT; }
+;
+
+Property_NoNode:
+    IDENT ':' AssignmentExpr_NoNode { }
+  | STRING ':' AssignmentExpr_NoNode { }
+  | NUMBER ':' AssignmentExpr_NoNode { }
+  | IDENT IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; }
+  | IDENT IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; }
+;
+
+PropertyList_NoNode:
+    Property_NoNode
+  | PropertyList_NoNode ',' Property_NoNode
+;
+
+PrimaryExpr_NoNode:
+    PrimaryExprNoBrace_NoNode
+  | OPENBRACE CLOSEBRACE { }
+  | OPENBRACE PropertyList_NoNode CLOSEBRACE { }
+  /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
+  | OPENBRACE PropertyList_NoNode ',' CLOSEBRACE { }
+;
+
+PrimaryExprNoBrace_NoNode:
+    THISTOKEN
+  | Literal_NoNode
+  | ArrayLiteral_NoNode
+  | IDENT { }
+  | '(' Expr_NoNode ')'
+;
+
+ArrayLiteral_NoNode:
+    '[' ElisionOpt_NoNode ']'
+  | '[' ElementList_NoNode ']'
+  | '[' ElementList_NoNode ',' ElisionOpt_NoNode ']'
+;
+
+ElementList_NoNode:
+    ElisionOpt_NoNode AssignmentExpr_NoNode
+  | ElementList_NoNode ',' ElisionOpt_NoNode AssignmentExpr_NoNode
+;
+
+ElisionOpt_NoNode:
+    /* nothing */
+  | Elision_NoNode
+;
+
+Elision_NoNode:
+    ','
+  | Elision_NoNode ','
+;
+
+MemberExpr_NoNode:
+    PrimaryExpr_NoNode
+  | FunctionExpr_NoNode
+  | MemberExpr_NoNode '[' Expr_NoNode ']'
+  | MemberExpr_NoNode '.' IDENT
+  | NEW MemberExpr_NoNode Arguments_NoNode
+;
+
+MemberExprNoBF_NoNode:
+    PrimaryExprNoBrace_NoNode
+  | MemberExprNoBF_NoNode '[' Expr_NoNode ']'
+  | MemberExprNoBF_NoNode '.' IDENT
+  | NEW MemberExpr_NoNode Arguments_NoNode
+;
+
+NewExpr_NoNode:
+    MemberExpr_NoNode
+  | NEW NewExpr_NoNode
+;
+
+NewExprNoBF_NoNode:
+    MemberExprNoBF_NoNode
+  | NEW NewExpr_NoNode
+;
+
+CallExpr_NoNode:
+    MemberExpr_NoNode Arguments_NoNode
+  | CallExpr_NoNode Arguments_NoNode
+  | CallExpr_NoNode '[' Expr_NoNode ']'
+  | CallExpr_NoNode '.' IDENT
+;
+
+CallExprNoBF_NoNode:
+    MemberExprNoBF_NoNode Arguments_NoNode
+  | CallExprNoBF_NoNode Arguments_NoNode
+  | CallExprNoBF_NoNode '[' Expr_NoNode ']'
+  | CallExprNoBF_NoNode '.' IDENT
+;
+
+Arguments_NoNode:
+    '(' ')'
+  | '(' ArgumentList_NoNode ')'
+;
+
+ArgumentList_NoNode:
+    AssignmentExpr_NoNode
+  | ArgumentList_NoNode ',' AssignmentExpr_NoNode
+;
+
+LeftHandSideExpr_NoNode:
+    NewExpr_NoNode
+  | CallExpr_NoNode
+;
+
+LeftHandSideExprNoBF_NoNode:
+    NewExprNoBF_NoNode
+  | CallExprNoBF_NoNode
+;
+
+PostfixExpr_NoNode:
+    LeftHandSideExpr_NoNode
+  | LeftHandSideExpr_NoNode PLUSPLUS
+  | LeftHandSideExpr_NoNode MINUSMINUS
+;
+
+PostfixExprNoBF_NoNode:
+    LeftHandSideExprNoBF_NoNode
+  | LeftHandSideExprNoBF_NoNode PLUSPLUS
+  | LeftHandSideExprNoBF_NoNode MINUSMINUS
+;
+
+UnaryExprCommon_NoNode:
+    DELETETOKEN UnaryExpr_NoNode
+  | VOIDTOKEN UnaryExpr_NoNode
+  | TYPEOF UnaryExpr_NoNode
+  | PLUSPLUS UnaryExpr_NoNode
+  | AUTOPLUSPLUS UnaryExpr_NoNode
+  | MINUSMINUS UnaryExpr_NoNode
+  | AUTOMINUSMINUS UnaryExpr_NoNode
+  | '+' UnaryExpr_NoNode
+  | '-' UnaryExpr_NoNode
+  | '~' UnaryExpr_NoNode
+  | '!' UnaryExpr_NoNode
+
+UnaryExpr_NoNode:
+    PostfixExpr_NoNode
+  | UnaryExprCommon_NoNode
+;
+
+UnaryExprNoBF_NoNode:
+    PostfixExprNoBF_NoNode
+  | UnaryExprCommon_NoNode
+;
+
+MultiplicativeExpr_NoNode:
+    UnaryExpr_NoNode
+  | MultiplicativeExpr_NoNode '*' UnaryExpr_NoNode
+  | MultiplicativeExpr_NoNode '/' UnaryExpr_NoNode
+  | MultiplicativeExpr_NoNode '%' UnaryExpr_NoNode
+;
+
+MultiplicativeExprNoBF_NoNode:
+    UnaryExprNoBF_NoNode
+  | MultiplicativeExprNoBF_NoNode '*' UnaryExpr_NoNode
+  | MultiplicativeExprNoBF_NoNode '/' UnaryExpr_NoNode
+  | MultiplicativeExprNoBF_NoNode '%' UnaryExpr_NoNode
+;
+
+AdditiveExpr_NoNode:
+    MultiplicativeExpr_NoNode
+  | AdditiveExpr_NoNode '+' MultiplicativeExpr_NoNode
+  | AdditiveExpr_NoNode '-' MultiplicativeExpr_NoNode
+;
+
+AdditiveExprNoBF_NoNode:
+    MultiplicativeExprNoBF_NoNode
+  | AdditiveExprNoBF_NoNode '+' MultiplicativeExpr_NoNode
+  | AdditiveExprNoBF_NoNode '-' MultiplicativeExpr_NoNode
+;
+
+ShiftExpr_NoNode:
+    AdditiveExpr_NoNode
+  | ShiftExpr_NoNode LSHIFT AdditiveExpr_NoNode
+  | ShiftExpr_NoNode RSHIFT AdditiveExpr_NoNode
+  | ShiftExpr_NoNode URSHIFT AdditiveExpr_NoNode
+;
+
+ShiftExprNoBF_NoNode:
+    AdditiveExprNoBF_NoNode
+  | ShiftExprNoBF_NoNode LSHIFT AdditiveExpr_NoNode
+  | ShiftExprNoBF_NoNode RSHIFT AdditiveExpr_NoNode
+  | ShiftExprNoBF_NoNode URSHIFT AdditiveExpr_NoNode
+;
+
+RelationalExpr_NoNode:
+    ShiftExpr_NoNode
+  | RelationalExpr_NoNode '<' ShiftExpr_NoNode
+  | RelationalExpr_NoNode '>' ShiftExpr_NoNode
+  | RelationalExpr_NoNode LE ShiftExpr_NoNode
+  | RelationalExpr_NoNode GE ShiftExpr_NoNode
+  | RelationalExpr_NoNode INSTANCEOF ShiftExpr_NoNode
+  | RelationalExpr_NoNode INTOKEN ShiftExpr_NoNode
+;
+
+RelationalExprNoIn_NoNode:
+    ShiftExpr_NoNode
+  | RelationalExprNoIn_NoNode '<' ShiftExpr_NoNode
+  | RelationalExprNoIn_NoNode '>' ShiftExpr_NoNode
+  | RelationalExprNoIn_NoNode LE ShiftExpr_NoNode
+  | RelationalExprNoIn_NoNode GE ShiftExpr_NoNode
+  | RelationalExprNoIn_NoNode INSTANCEOF ShiftExpr_NoNode
+;
+
+RelationalExprNoBF_NoNode:
+    ShiftExprNoBF_NoNode
+  | RelationalExprNoBF_NoNode '<' ShiftExpr_NoNode
+  | RelationalExprNoBF_NoNode '>' ShiftExpr_NoNode
+  | RelationalExprNoBF_NoNode LE ShiftExpr_NoNode
+  | RelationalExprNoBF_NoNode GE ShiftExpr_NoNode
+  | RelationalExprNoBF_NoNode INSTANCEOF ShiftExpr_NoNode
+  | RelationalExprNoBF_NoNode INTOKEN ShiftExpr_NoNode
+;
+
+EqualityExpr_NoNode:
+    RelationalExpr_NoNode
+  | EqualityExpr_NoNode EQEQ RelationalExpr_NoNode
+  | EqualityExpr_NoNode NE RelationalExpr_NoNode
+  | EqualityExpr_NoNode STREQ RelationalExpr_NoNode
+  | EqualityExpr_NoNode STRNEQ RelationalExpr_NoNode
+;
+
+EqualityExprNoIn_NoNode:
+    RelationalExprNoIn_NoNode
+  | EqualityExprNoIn_NoNode EQEQ RelationalExprNoIn_NoNode
+  | EqualityExprNoIn_NoNode NE RelationalExprNoIn_NoNode
+  | EqualityExprNoIn_NoNode STREQ RelationalExprNoIn_NoNode
+  | EqualityExprNoIn_NoNode STRNEQ RelationalExprNoIn_NoNode
+;
+
+EqualityExprNoBF_NoNode:
+    RelationalExprNoBF_NoNode
+  | EqualityExprNoBF_NoNode EQEQ RelationalExpr_NoNode
+  | EqualityExprNoBF_NoNode NE RelationalExpr_NoNode
+  | EqualityExprNoBF_NoNode STREQ RelationalExpr_NoNode
+  | EqualityExprNoBF_NoNode STRNEQ RelationalExpr_NoNode
+;
+
+BitwiseANDExpr_NoNode:
+    EqualityExpr_NoNode
+  | BitwiseANDExpr_NoNode '&' EqualityExpr_NoNode
+;
+
+BitwiseANDExprNoIn_NoNode:
+    EqualityExprNoIn_NoNode
+  | BitwiseANDExprNoIn_NoNode '&' EqualityExprNoIn_NoNode
+;
+
+BitwiseANDExprNoBF_NoNode:
+    EqualityExprNoBF_NoNode
+  | BitwiseANDExprNoBF_NoNode '&' EqualityExpr_NoNode
+;
+
+BitwiseXORExpr_NoNode:
+    BitwiseANDExpr_NoNode
+  | BitwiseXORExpr_NoNode '^' BitwiseANDExpr_NoNode
+;
+
+BitwiseXORExprNoIn_NoNode:
+    BitwiseANDExprNoIn_NoNode
+  | BitwiseXORExprNoIn_NoNode '^' BitwiseANDExprNoIn_NoNode
+;
+
+BitwiseXORExprNoBF_NoNode:
+    BitwiseANDExprNoBF_NoNode
+  | BitwiseXORExprNoBF_NoNode '^' BitwiseANDExpr_NoNode
+;
+
+BitwiseORExpr_NoNode:
+    BitwiseXORExpr_NoNode
+  | BitwiseORExpr_NoNode '|' BitwiseXORExpr_NoNode
+;
+
+BitwiseORExprNoIn_NoNode:
+    BitwiseXORExprNoIn_NoNode
+  | BitwiseORExprNoIn_NoNode '|' BitwiseXORExprNoIn_NoNode
+;
+
+BitwiseORExprNoBF_NoNode:
+    BitwiseXORExprNoBF_NoNode
+  | BitwiseORExprNoBF_NoNode '|' BitwiseXORExpr_NoNode
+;
+
+LogicalANDExpr_NoNode:
+    BitwiseORExpr_NoNode
+  | LogicalANDExpr_NoNode AND BitwiseORExpr_NoNode
+;
+
+LogicalANDExprNoIn_NoNode:
+    BitwiseORExprNoIn_NoNode
+  | LogicalANDExprNoIn_NoNode AND BitwiseORExprNoIn_NoNode
+;
+
+LogicalANDExprNoBF_NoNode:
+    BitwiseORExprNoBF_NoNode
+  | LogicalANDExprNoBF_NoNode AND BitwiseORExpr_NoNode
+;
+
+LogicalORExpr_NoNode:
+    LogicalANDExpr_NoNode
+  | LogicalORExpr_NoNode OR LogicalANDExpr_NoNode
+;
+
+LogicalORExprNoIn_NoNode:
+    LogicalANDExprNoIn_NoNode
+  | LogicalORExprNoIn_NoNode OR LogicalANDExprNoIn_NoNode
+;
+
+LogicalORExprNoBF_NoNode:
+    LogicalANDExprNoBF_NoNode
+  | LogicalORExprNoBF_NoNode OR LogicalANDExpr_NoNode
+;
+
+ConditionalExpr_NoNode:
+    LogicalORExpr_NoNode
+  | LogicalORExpr_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode
+;
+
+ConditionalExprNoIn_NoNode:
+    LogicalORExprNoIn_NoNode
+  | LogicalORExprNoIn_NoNode '?' AssignmentExprNoIn_NoNode ':' AssignmentExprNoIn_NoNode
+;
+
+ConditionalExprNoBF_NoNode:
+    LogicalORExprNoBF_NoNode
+  | LogicalORExprNoBF_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode
+;
+
+AssignmentExpr_NoNode:
+    ConditionalExpr_NoNode
+  | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode
+;
+
+AssignmentExprNoIn_NoNode:
+    ConditionalExprNoIn_NoNode
+  | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExprNoIn_NoNode
+;
+
+AssignmentExprNoBF_NoNode:
+    ConditionalExprNoBF_NoNode
+  | LeftHandSideExprNoBF_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode
+;
+
+AssignmentOperator_NoNode:
+    '='
+  | PLUSEQUAL
+  | MINUSEQUAL
+  | MULTEQUAL
+  | DIVEQUAL
+  | LSHIFTEQUAL
+  | RSHIFTEQUAL
+  | URSHIFTEQUAL
+  | ANDEQUAL
+  | XOREQUAL
+  | OREQUAL
+  | MODEQUAL
+;
+
+Expr_NoNode:
+    AssignmentExpr_NoNode
+  | Expr_NoNode ',' AssignmentExpr_NoNode
+;
+
+ExprNoIn_NoNode:
+    AssignmentExprNoIn_NoNode
+  | ExprNoIn_NoNode ',' AssignmentExprNoIn_NoNode
+;
+
+ExprNoBF_NoNode:
+    AssignmentExprNoBF_NoNode
+  | ExprNoBF_NoNode ',' AssignmentExpr_NoNode
+;
+
+Statement_NoNode:
+    Block_NoNode
+  | VariableStatement_NoNode
+  | ConstStatement_NoNode
+  | EmptyStatement_NoNode
+  | ExprStatement_NoNode
+  | IfStatement_NoNode
+  | IterationStatement_NoNode
+  | ContinueStatement_NoNode
+  | BreakStatement_NoNode
+  | ReturnStatement_NoNode
+  | WithStatement_NoNode
+  | SwitchStatement_NoNode
+  | LabelledStatement_NoNode
+  | ThrowStatement_NoNode
+  | TryStatement_NoNode
+  | DebuggerStatement_NoNode
+;
+
+Block_NoNode:
+    OPENBRACE CLOSEBRACE { }
+  | OPENBRACE SourceElements_NoNode CLOSEBRACE { }
+;
+
+VariableStatement_NoNode:
+    VAR VariableDeclarationList_NoNode ';'
+  | VAR VariableDeclarationList_NoNode error { AUTO_SEMICOLON; }
+;
+
+VariableDeclarationList_NoNode:
+    IDENT { }
+  | IDENT Initializer_NoNode { }
+  | VariableDeclarationList_NoNode ',' IDENT
+  | VariableDeclarationList_NoNode ',' IDENT Initializer_NoNode
+;
+
+VariableDeclarationListNoIn_NoNode:
+    IDENT { }
+  | IDENT InitializerNoIn_NoNode { }
+  | VariableDeclarationListNoIn_NoNode ',' IDENT
+  | VariableDeclarationListNoIn_NoNode ',' IDENT InitializerNoIn_NoNode
+;
+
+ConstStatement_NoNode:
+    CONSTTOKEN ConstDeclarationList_NoNode ';'
+  | CONSTTOKEN ConstDeclarationList_NoNode error { AUTO_SEMICOLON; }
+;
+
+ConstDeclarationList_NoNode:
+    ConstDeclaration_NoNode
+  | ConstDeclarationList_NoNode ',' ConstDeclaration_NoNode
+;
+
+ConstDeclaration_NoNode:
+    IDENT { }
+  | IDENT Initializer_NoNode { }
+;
+
+Initializer_NoNode:
+    '=' AssignmentExpr_NoNode
+;
+
+InitializerNoIn_NoNode:
+    '=' AssignmentExprNoIn_NoNode
+;
+
+EmptyStatement_NoNode:
+    ';'
+;
+
+ExprStatement_NoNode:
+    ExprNoBF_NoNode ';'
+  | ExprNoBF_NoNode error { AUTO_SEMICOLON; }
+;
+
+IfStatement_NoNode:
+    IF '(' Expr_NoNode ')' Statement_NoNode %prec IF_WITHOUT_ELSE
+  | IF '(' Expr_NoNode ')' Statement_NoNode ELSE Statement_NoNode
+;
+
+IterationStatement_NoNode:
+    DO Statement_NoNode WHILE '(' Expr_NoNode ')' ';'
+  | DO Statement_NoNode WHILE '(' Expr_NoNode ')' error // Always performs automatic semicolon insertion
+  | WHILE '(' Expr_NoNode ')' Statement_NoNode
+  | FOR '(' ExprNoInOpt_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode
+  | FOR '(' VAR VariableDeclarationListNoIn_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode
+  | FOR '(' LeftHandSideExpr_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode
+  | FOR '(' VAR IDENT INTOKEN Expr_NoNode ')' Statement_NoNode
+  | FOR '(' VAR IDENT InitializerNoIn_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode
+;
+
+ExprOpt_NoNode:
+    /* nothing */
+  | Expr_NoNode
+;
+
+ExprNoInOpt_NoNode:
+    /* nothing */
+  | ExprNoIn_NoNode
+;
+
+ContinueStatement_NoNode:
+    CONTINUE ';'
+  | CONTINUE error { AUTO_SEMICOLON; }
+  | CONTINUE IDENT ';'
+  | CONTINUE IDENT error { AUTO_SEMICOLON; }
+;
+
+BreakStatement_NoNode:
+    BREAK ';'
+  | BREAK error { AUTO_SEMICOLON; }
+  | BREAK IDENT ';'
+  | BREAK IDENT error { AUTO_SEMICOLON; }
+;
+
+ReturnStatement_NoNode:
+    RETURN ';'
+  | RETURN error { AUTO_SEMICOLON; }
+  | RETURN Expr_NoNode ';'
+  | RETURN Expr_NoNode error { AUTO_SEMICOLON; }
+;
+
+WithStatement_NoNode:
+    WITH '(' Expr_NoNode ')' Statement_NoNode
+;
+
+SwitchStatement_NoNode:
+    SWITCH '(' Expr_NoNode ')' CaseBlock_NoNode
+;
+
+CaseBlock_NoNode:
+    OPENBRACE CaseClausesOpt_NoNode CLOSEBRACE { }
+  | OPENBRACE CaseClausesOpt_NoNode DefaultClause_NoNode CaseClausesOpt_NoNode CLOSEBRACE { }
+;
+
+CaseClausesOpt_NoNode:
+    /* nothing */
+  | CaseClauses_NoNode
+;
+
+CaseClauses_NoNode:
+    CaseClause_NoNode
+  | CaseClauses_NoNode CaseClause_NoNode
+;
+
+CaseClause_NoNode:
+    CASE Expr_NoNode ':'
+  | CASE Expr_NoNode ':' SourceElements_NoNode
+;
+
+DefaultClause_NoNode:
+    DEFAULT ':'
+  | DEFAULT ':' SourceElements_NoNode
+;
+
+LabelledStatement_NoNode:
+    IDENT ':' Statement_NoNode { }
+;
+
+ThrowStatement_NoNode:
+    THROW Expr_NoNode ';'
+  | THROW Expr_NoNode error { AUTO_SEMICOLON; }
+;
+
+TryStatement_NoNode:
+    TRY Block_NoNode FINALLY Block_NoNode
+  | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode
+  | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode FINALLY Block_NoNode
+;
+
+DebuggerStatement_NoNode:
+    DEBUGGER ';'
+  | DEBUGGER error { AUTO_SEMICOLON; }
+;
+
+FunctionDeclaration_NoNode:
+    FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+  | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+;
+
+FunctionExpr_NoNode:
+    FUNCTION '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+  | FUNCTION '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+  | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+  | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+;
+
+FormalParameterList_NoNode:
+    IDENT { }
+  | FormalParameterList_NoNode ',' IDENT
+;
+
+FunctionBody_NoNode:
+    /* not in spec */
+  | SourceElements_NoNode
+;
+
+SourceElements_NoNode:
+    SourceElement_NoNode
+  | SourceElements_NoNode SourceElement_NoNode
+;
+
+SourceElement_NoNode:
+    FunctionDeclaration_NoNode
+  | Statement_NoNode
+;
+
+// End NoNodes
+
 %%
 
 static AddNode* makeAddNode(ExpressionNode* left, ExpressionNode* right)
@@ -1196,7 +1779,7 @@ static ExpressionNode* makeDeleteNode(ExpressionNode* expr)
     return new DeleteDotNode(dot->base(), dot->identifier());
 }
 
-static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body)
+static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source)
 {
     PropertyNode::Type type;
     if (getOrSet == "get")
@@ -1205,7 +1788,7 @@ static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier& getOrSet,
         type = PropertyNode::Setter;
     else
         return 0;
-    return new PropertyNode(name, new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, body, params), type);
+    return new PropertyNode(name, new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, body, source, params), type);
 }
 
 static ExpressionNode* makeNegateNode(ExpressionNode* n)
@@ -1239,7 +1822,7 @@ int yyerror(const char *)
 /* may we automatically insert a semicolon ? */
 static bool allowAutomaticSemicolon()
 {
-    return yychar == '}' || yychar == 0 || lexer().prevTerminator();
+    return yychar == CLOSEBRACE || yychar == 0 || lexer().prevTerminator();
 }
 
 static ExpressionNode* combineVarInitializers(ExpressionNode* list, AssignResolveNode* init)
index f7ea2c55a9abd40d3166e9c57a349db78b7fe214..1ef21cfbd577b1b2f97654a9700d6bcf17fbc7ad 100644 (file)
 
 namespace KJS {
 
-Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code)
-{
-    return checkSyntax(exec, sourceURL, startingLineNumber, code.data(), code.size());
-}
-
-Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength)
+Completion Interpreter::checkSyntax(ExecState* exec, const SourceCode& source)
 {
     JSLock lock;
 
     int errLine;
     UString errMsg;
-    RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
+    RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(source, &errLine, &errMsg);
     if (!progNode)
-        return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, 0, sourceURL));
+        return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
     return Completion(Normal);
 }
 
-Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
-{
-    return evaluate(exec, sourceURL, startingLineNumber, code.data(), code.size(), thisV);
-}
-
-Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
+Completion Interpreter::evaluate(ExecState* exec, const SourceCode& source, JSValue* thisV)
 {
     JSLock lock;
     
@@ -86,21 +76,15 @@ Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int
         return Completion(Throw, Error::create(exec, GeneralError, "Recursion too deep"));
     
     // parse the source code
-    int sourceId;
     int errLine;
     UString errMsg;
-    RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg);
+    RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(source, &errLine, &errMsg);
     
-    // notify debugger that source has been parsed
-    if (globalObject->debugger()) {
-        bool cont = globalObject->debugger()->sourceParsed(exec, sourceId, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
-        if (!cont)
-            return Completion(Break);
-    }
+    // removed debugger support
     
     // no program node means a syntax error occurred
     if (!progNode)
-        return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL));
+        return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
     
     exec->clearException();
     
@@ -128,7 +112,7 @@ Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int
     if (shouldPrintExceptions() && res.complType() == Throw) {
         JSLock lock;
         ExecState* exec = globalObject->globalExec();
-        CString f = sourceURL.UTF8String();
+        CString f = source.provider()->url().UTF8String();
         CString message = res.value()->toObject(exec)->toString(exec).UTF8String();
         int line = res.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
 #if PLATFORM(WIN_OS)
index 79b93988ef56a0d9c4d37ad8040035fde4fb2238..0e67c6f46e2428c3319ddcd53997830bae4f599e 100644 (file)
 #ifndef KJS_Interpreter_h
 #define KJS_Interpreter_h
 
+#include <wtf/PassRefPtr.h>
+
 namespace KJS {
 
   class Completion;
   class ExecState;
   class JSValue;
+  class SourceCode;
   class UString;
 
   struct UChar;
@@ -41,8 +44,7 @@ namespace KJS {
      * @return A normal completion if there were no syntax errors in the code, 
      * otherwise a throw completion with the syntax error as its value.
      */
-    static Completion checkSyntax(ExecState*, const UString& sourceURL, int startingLineNumber, const UString& code);
-    static Completion checkSyntax(ExecState*, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength);
+    static Completion checkSyntax(ExecState*, const SourceCode&);
 
     /**
      * Evaluates the supplied ECMAScript code.
@@ -59,8 +61,7 @@ namespace KJS {
      * execution. This should either be jsNull() or an Object.
      * @return A completion object representing the result of the execution.
      */
-    static Completion evaluate(ExecState*, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0);
-    static Completion evaluate(ExecState*, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV = 0);
+    static Completion evaluate(ExecState*, const SourceCode&, JSValue* thisV = 0);
     
     static bool shouldPrintExceptions();
     static void setShouldPrintExceptions(bool);
index dd4fcc4ca5c1a673c55493fe2189e315a4fc9f96..18a117ff9236fa64bdb533dc37fe2ae948f01ed4 100644 (file)
@@ -87,6 +87,10 @@ Lexer::Lexer()
     , next1(0)
     , next2(0)
     , next3(0)
+    , m_currentOffset(0)
+    , m_nextOffset1(0)
+    , m_nextOffset2(0)
+    , m_nextOffset3(0)
 {
     m_buffer8.reserveCapacity(initialReadBufferCapacity);
     m_buffer16.reserveCapacity(initialReadBufferCapacity);
@@ -94,17 +98,18 @@ Lexer::Lexer()
     m_identifiers.reserveCapacity(initialStringTableCapacity);
 }
 
-void Lexer::setCode(int startingLineNumber, const KJS::UChar *c, unsigned int len)
+void Lexer::setCode(const SourceCode& source)
 {
-    yylineno = 1 + startingLineNumber;
+    yylineno = source.firstLine();
     restrKeyword = false;
     delimited = false;
     eatNextIdentifier = false;
     stackToken = -1;
     lastToken = -1;
     pos = 0;
-    code = c;
-    length = len;
+    m_source = &source;
+    code = source.provider()->data() + source.startOffset();
+    length = source.length();
     skipLF = false;
     skipCR = false;
     error = false;
@@ -123,11 +128,17 @@ void Lexer::shift(unsigned p)
         current = next1;
         next1 = next2;
         next2 = next3;
+        m_currentOffset = m_nextOffset1;
+        m_nextOffset1 = m_nextOffset2;
+        m_nextOffset2 = m_nextOffset3;
         do {
             if (pos >= length) {
+                m_nextOffset3 = pos;
+                pos++;
                 next3 = -1;
                 break;
             }
+            m_nextOffset3 = pos;
             next3 = code[pos++].uc;
         } while (next3 == 0xFEFF);
     }
@@ -166,6 +177,7 @@ int Lexer::lex()
     stackToken = 0;
   }
 
+  int startOffset = m_currentOffset;
   while (!done) {
     if (skipLF && current != '\n') // found \r but not \n afterwards
         skipLF = false;
@@ -179,6 +191,7 @@ int Lexer::lex()
     }
     switch (state) {
     case Start:
+      startOffset = m_currentOffset;
       if (isWhiteSpace()) {
         // do nothing
       } else if (current == '/' && next1 == '/') {
@@ -229,7 +242,7 @@ int Lexer::lex()
         shift(2);
         state = InSingleLineComment;
       } else {
-        token = matchPunctuator(current, next1, next2, next3);
+        token = matchPunctuator(kjsyylval.intValue, current, next1, next2, next3);
         if (token != -1) {
           setDone(Other);
         } else {
@@ -636,7 +649,7 @@ bool Lexer::isOctalDigit(int c)
   return (c >= '0' && c <= '7');
 }
 
-int Lexer::matchPunctuator(int c1, int c2, int c3, int c4)
+int Lexer::matchPunctuator(int& charPos, int c1, int c2, int c3, int c4)
 {
   if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
     shift(4);
@@ -738,13 +751,19 @@ int Lexer::matchPunctuator(int c1, int c2, int c3, int c4)
     case '%':
     case '(':
     case ')':
-    case '{':
-    case '}':
     case '[':
     case ']':
     case ';':
       shift(1);
       return static_cast<int>(c1);
+    case '{':
+      charPos = pos - 4;
+      shift(1);
+      return OPENBRACE;
+    case '}':
+      charPos = pos - 4;
+      shift(1);
+      return CLOSEBRACE;
     default:
       return -1;
   }
index 1ce27af787e1d9d8c7806bf2052acbfdd03d7d84..69b68b8461f42d1a93d57cc665fd4b5864639db0 100644 (file)
@@ -24,6 +24,7 @@
 #ifndef Lexer_h
 #define Lexer_h
 
+#include "SourceCode.h"
 #include "ustring.h"
 #include <wtf/Vector.h>
 
@@ -34,7 +35,7 @@ namespace KJS {
 
   class Lexer : Noncopyable {
   public:
-    void setCode(int startingLineNumber, const UChar *c, unsigned int len);
+    void setCode(const SourceCode&);
     int lex();
 
     int lineNo() const { return yylineno; }
@@ -85,6 +86,13 @@ namespace KJS {
     bool sawError() const { return error; }
 
     void clear();
+    SourceCode sourceCode(int openBrace, int closeBrace, int firstLine)
+    {
+        // The SourceCode constructor adds 1 to the line number to account for
+        // all of the callers in WebCore that use zero-based line numbers, so
+        // we regrettably subtract 1 here to deal with that.
+        return SourceCode(m_source->provider(), m_source->startOffset() + openBrace + 1, m_source->startOffset() + closeBrace, firstLine - 1);
+    }
 
   private:
     friend Lexer& lexer();
@@ -115,7 +123,7 @@ namespace KJS {
     bool isLineTerminator();
     static bool isOctalDigit(int);
 
-    int matchPunctuator(int c1, int c2, int c3, int c4);
+    int matchPunctuator(int& charPos, int c1, int c2, int c3, int c4);
     static unsigned short singleEscape(unsigned short);
     static unsigned short convertOctal(int c1, int c2, int c3);
 
@@ -126,6 +134,7 @@ namespace KJS {
     KJS::Identifier* makeIdentifier(const Vector<UChar>& buffer);
     UString* makeUString(const Vector<UChar>& buffer);
 
+    const SourceCode* m_source;
     const UChar* code;
     unsigned int length;
     int yycolumn;
@@ -135,6 +144,11 @@ namespace KJS {
     // current and following unicode characters (int to allow for -1 for end-of-file marker)
     int current, next1, next2, next3;
 
+    int m_currentOffset;
+    int m_nextOffset1;
+    int m_nextOffset2;
+    int m_nextOffset3;
+
     Vector<UString*> m_strings;
     Vector<KJS::Identifier*> m_identifiers;
     
index 16e6b1edd6216339b99b3d94e39004030768c7d6..568e69feddf20eec2aaa2d72056d2ffaf725582a 100644 (file)
@@ -261,10 +261,10 @@ static void substitute(UString& string, const UString& substring)
     string = newString;
 }
 
-static inline int currentSourceId(ExecState* exec) KJS_FAST_CALL;
-static inline int currentSourceId(ExecState* exec)
+static inline int currentSourceID(ExecState* exec) KJS_FAST_CALL;
+static inline int currentSourceID(ExecState* exec)
 {
-    return exec->scopeNode()->sourceId();
+    return exec->scopeNode()->sourceID();
 }
 
 static inline const UString& currentSourceURL(ExecState* exec) KJS_FAST_CALL;
@@ -275,31 +275,31 @@ static inline const UString& currentSourceURL(ExecState* exec)
 
 JSValue* Node::setInterruptedCompletion(ExecState* exec)
 {
-    return exec->setInterruptedCompletion(Error::create(exec, TimeoutError, "JavaScript execution exceeded timeout.", lineNo(), currentSourceId(exec), currentSourceURL(exec)));
+    return exec->setInterruptedCompletion(Error::create(exec, TimeoutError, "JavaScript execution exceeded timeout.", lineNo(), currentSourceID(exec), currentSourceURL(exec)));
 }
 
 JSValue* Node::setErrorCompletion(ExecState* exec, ErrorType e, const char* msg)
 {
-    return exec->setThrowCompletion(Error::create(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
+    return exec->setThrowCompletion(Error::create(exec, e, msg, lineNo(), currentSourceID(exec), currentSourceURL(exec)));
 }
 
 JSValue* Node::setErrorCompletion(ExecState* exec, ErrorType e, const char* msg, const Identifier& ident)
 {
     UString message = msg;
     substitute(message, ident.ustring());
-    return exec->setThrowCompletion(Error::create(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
+    return exec->setThrowCompletion(Error::create(exec, e, message, lineNo(), currentSourceID(exec), currentSourceURL(exec)));
 }
 
 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg)
 {
-    return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
+    return KJS::throwError(exec, e, msg, lineNo(), currentSourceID(exec), currentSourceURL(exec));
 }
 
 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, const char* string)
 {
     UString message = msg;
     substitute(message, string);
-    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
+    return KJS::throwError(exec, e, message, lineNo(), currentSourceID(exec), currentSourceURL(exec));
 }
 
 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr)
@@ -307,14 +307,14 @@ JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue
     UString message = msg;
     substitute(message, v->toString(exec));
     substitute(message, expr->toString());
-    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
+    return KJS::throwError(exec, e, message, lineNo(), currentSourceID(exec), currentSourceURL(exec));
 }
 
 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, const Identifier& label)
 {
     UString message = msg;
     substitute(message, label.ustring());
-    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
+    return KJS::throwError(exec, e, message, lineNo(), currentSourceID(exec), currentSourceURL(exec));
 }
 
 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* e1, Node* e2)
@@ -323,7 +323,7 @@ JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue
     substitute(message, v->toString(exec));
     substitute(message, e1->toString());
     substitute(message, e2->toString());
-    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
+    return KJS::throwError(exec, e, message, lineNo(), currentSourceID(exec), currentSourceURL(exec));
 }
 
 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr, const Identifier& label)
@@ -332,7 +332,7 @@ JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue
     substitute(message, v->toString(exec));
     substitute(message, expr->toString());
     substitute(message, label.ustring());
-    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
+    return KJS::throwError(exec, e, message, lineNo(), currentSourceID(exec), currentSourceURL(exec));
 }
 
 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, const Identifier& label)
@@ -340,7 +340,7 @@ JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue
     UString message = msg;
     substitute(message, v->toString(exec));
     substitute(message, label.ustring());
-    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
+    return KJS::throwError(exec, e, message, lineNo(), currentSourceID(exec), currentSourceURL(exec));
 }
 
 JSValue* Node::throwUndefinedVariableError(ExecState* exec, const Identifier& ident)
@@ -364,7 +364,7 @@ void Node::handleException(ExecState* exec, JSValue* exceptionValue)
     }
     Debugger* dbg = exec->dynamicGlobalObject()->debugger();
     if (dbg && !dbg->hasHandledException(exec, exceptionValue)) {
-        bool cont = dbg->exception(exec, currentSourceId(exec), m_line, exceptionValue);
+        bool cont = dbg->exception(exec, currentSourceID(exec), m_line, exceptionValue);
         if (!cont)
             dbg->imp()->abort();
     }
@@ -416,12 +416,12 @@ BreakpointCheckStatement::BreakpointCheckStatement(PassRefPtr<StatementNode> sta
 JSValue* BreakpointCheckStatement::execute(ExecState* exec)
 {
     if (Debugger* debugger = exec->dynamicGlobalObject()->debugger())
-        if (!debugger->atStatement(exec, currentSourceId(exec), m_statement->firstLine(), m_statement->lastLine()))
+        if (!debugger->atStatement(exec, currentSourceID(exec), m_statement->firstLine(), m_statement->lastLine()))
             return exec->setNormalCompletion();
     return m_statement->execute(exec);
 }
 
-void BreakpointCheckStatement::streamTo(SourceStream& stream) const
+void BreakpointCheckStatement::streamTo(SourceStream& stream)
 {
     m_statement->streamTo(stream);
 }
@@ -3698,6 +3698,10 @@ static inline JSValue* statementListExecute(StatementVector& statements, ExecSta
 
 // ------------------------------ BlockNode ------------------------------------
 
+BlockNode::BlockNode()
+{
+}
+
 BlockNode::BlockNode(SourceElements* children)
 {
     if (children)
@@ -4329,11 +4333,25 @@ JSValue* TryNode::execute(ExecState* exec)
 
 // ------------------------------ FunctionBodyNode -----------------------------
 
-ScopeNode::ScopeNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
+ScopeNode::ScopeNode()
+    : BlockNode()
+{
+}
+
+ScopeNode::ScopeNode(const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
     : BlockNode(children)
-    , m_sourceURL(parser().sourceURL())
-    , m_sourceId(parser().sourceId())
+    , m_source(source)
+{
+    if (varStack)
+        m_varStack = *varStack;
+    if (funcStack)
+        m_functionStack = *funcStack;
+}
+
+void ScopeNode::setData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
 {
+    if (children)
+        children->releaseContentsIntoVector(m_children);
     if (varStack)
         m_varStack = *varStack;
     if (funcStack)
@@ -4342,41 +4360,57 @@ ScopeNode::ScopeNode(SourceElements* children, VarStack* varStack, FunctionStack
 
 // ------------------------------ ProgramNode -----------------------------
 
-ProgramNode::ProgramNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
-    : ScopeNode(children, varStack, funcStack)
+ProgramNode::ProgramNode(const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
+    : ScopeNode(source, children, varStack, funcStack)
 {
 }
 
-ProgramNode* ProgramNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
+ProgramNode* ProgramNode::create(const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
 {
-    return new ProgramNode(children, varStack, funcStack);
+    return new ProgramNode(source, children, varStack, funcStack);
 }
 
 // ------------------------------ EvalNode -----------------------------
 
-EvalNode::EvalNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
-    : ScopeNode(children, varStack, funcStack)
+EvalNode::EvalNode(const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
+    : ScopeNode(source, children, varStack, funcStack)
 {
 }
 
-EvalNode* EvalNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
+EvalNode* EvalNode::create(const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
 {
-    return new EvalNode(children, varStack, funcStack);
+    return new EvalNode(source, children, varStack, funcStack);
 }
 
 // ------------------------------ FunctionBodyNode -----------------------------
 
-FunctionBodyNode::FunctionBodyNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
-    : ScopeNode(children, varStack, funcStack)
+FunctionBodyNode::FunctionBodyNode()
+    : ScopeNode()
     , m_initialized(false)
 {
 }
 
+FunctionBodyNode::FunctionBodyNode(const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
+    : ScopeNode(source, children, varStack, funcStack)
+    , m_initialized(false)
+{
+}
+
+FunctionBodyNode* FunctionBodyNode::create()
+{
+    return new FunctionBodyNode();
+}
+
 FunctionBodyNode* FunctionBodyNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
 {
-    if (Debugger::debuggersPresent)
-        return new FunctionBodyNodeWithDebuggerHooks(children, varStack, funcStack);
-    return new FunctionBodyNode(children, varStack, funcStack);
+    // debugger code removed
+    return new FunctionBodyNode(SourceCode(), children, varStack, funcStack);
+}
+
+FunctionBodyNode* FunctionBodyNode::create(const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
+{
+    // debugger code removed
+    return new FunctionBodyNode(source, children, varStack, funcStack);
 }
 
 void FunctionBodyNode::initializeSymbolTable(ExecState* exec)
@@ -4627,6 +4661,8 @@ JSValue* EvalNode::execute(ExecState* exec)
 
 JSValue* FunctionBodyNode::execute(ExecState* exec)
 {
+    if (m_children.isEmpty())
+        parser().reparse(this);
     processDeclarations(exec);
     return ScopeNode::execute(exec);
 }
@@ -4634,14 +4670,14 @@ JSValue* FunctionBodyNode::execute(ExecState* exec)
 // ------------------------------ FunctionBodyNodeWithDebuggerHooks ---------------------------------
 
 FunctionBodyNodeWithDebuggerHooks::FunctionBodyNodeWithDebuggerHooks(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack)
-    : FunctionBodyNode(children, varStack, funcStack)
+    : FunctionBodyNode(SourceCode(), children, varStack, funcStack)
 {
 }
 
 JSValue* FunctionBodyNodeWithDebuggerHooks::execute(ExecState* exec)
 {
     if (Debugger* dbg = exec->dynamicGlobalObject()->debugger()) {
-        if (!dbg->callEvent(exec, sourceId(), lineNo(), exec->function(), *exec->arguments())) {
+        if (!dbg->callEvent(exec, sourceID(), lineNo(), exec->function(), *exec->arguments())) {
             dbg->imp()->abort();
             return exec->setInterruptedCompletion();
         }
@@ -4652,7 +4688,7 @@ JSValue* FunctionBodyNodeWithDebuggerHooks::execute(ExecState* exec)
     if (Debugger* dbg = exec->dynamicGlobalObject()->debugger()) {
         if (exec->completionType() == Throw)
             exec->setException(result);
-        if (!dbg->returnEvent(exec, sourceId(), lastLine(), exec->function())) {
+        if (!dbg->returnEvent(exec, sourceID(), lineNo(), exec->function())) {
             dbg->imp()->abort();
             return exec->setInterruptedCompletion();
         }
index c0fe50994f949091c36704695961cd176ad893cb..20a0a2ce445d1b1f933e33120054527c12cd5139 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "internal.h"
 #include "regexp.h"
+#include "SourceCode.h"
 #include "SymbolTable.h"
 #include <wtf/ListRefPtr.h>
 #include <wtf/MathExtras.h>
@@ -136,11 +137,11 @@ namespace KJS {
         {
         }
 
-        UString toString() const KJS_FAST_CALL;
+        UString toString() KJS_FAST_CALL;
         int lineNo() const KJS_FAST_CALL { return m_line; }
 
         // Serialization.
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL = 0;
         virtual Precedence precedence() const = 0;
         virtual bool needsParensIfLeftmost() const { return false; }
 
@@ -195,6 +196,7 @@ namespace KJS {
         virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
         virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
         virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
+        virtual bool isFuncExprNode() const KJS_FAST_CALL { return false; }
 
         JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
 
@@ -218,6 +220,7 @@ namespace KJS {
         void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); }
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
         virtual bool isEmptyStatement() const KJS_FAST_CALL { return false; }
+        virtual bool isExprStatement() const KJS_FAST_CALL { return false; } 
 
     protected:
         LabelStack m_labelStack;
@@ -230,7 +233,7 @@ namespace KJS {
     public:
         NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
 
@@ -243,7 +246,7 @@ namespace KJS {
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
 
@@ -256,7 +259,7 @@ namespace KJS {
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
 
@@ -268,7 +271,7 @@ namespace KJS {
         {
         }
 
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class NumberNode : public ExpressionNode {
@@ -284,7 +287,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
 
         virtual bool isNumber() const KJS_FAST_CALL { return true; }
@@ -325,7 +328,7 @@ namespace KJS {
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
     private:
@@ -340,7 +343,7 @@ namespace KJS {
         }
 
         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
     private:
@@ -354,7 +357,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
 
@@ -379,7 +382,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
         virtual bool isLocation() const KJS_FAST_CALL { return true; }
@@ -428,7 +431,7 @@ namespace KJS {
         }
 
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
 
         PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
@@ -466,7 +469,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
     private:
@@ -487,7 +490,7 @@ namespace KJS {
         }
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
@@ -514,7 +517,7 @@ namespace KJS {
         }
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
@@ -539,7 +542,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
         virtual bool needsParensIfLeftmost() const { return true; }
 
@@ -561,7 +564,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMember; }
 
         virtual bool isLocation() const KJS_FAST_CALL { return true; }
@@ -590,7 +593,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMember; }
 
         virtual bool isLocation() const KJS_FAST_CALL { return true; }
@@ -619,7 +622,7 @@ namespace KJS {
         }
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
         void evaluateList(ExecState*, List&) KJS_FAST_CALL;
@@ -643,7 +646,7 @@ namespace KJS {
         }
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
         void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (m_listNode) m_listNode->evaluateList(exec, list); }
@@ -671,7 +674,7 @@ namespace KJS {
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecLeftHandSide; }
 
     private:
@@ -691,7 +694,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
     private:
@@ -720,7 +723,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
     protected:
@@ -761,7 +764,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
     protected:
@@ -785,7 +788,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
     private:
@@ -829,7 +832,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
         virtual void optimizeForUnnecessaryResult();
     };
@@ -873,7 +876,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
         virtual void optimizeForUnnecessaryResult();
     };
@@ -934,7 +937,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class PostDecBracketNode : public PostfixBracketNode {
@@ -945,7 +948,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class PostfixDotNode : public ExpressionNode {
@@ -972,7 +975,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class PostDecDotNode : public PostfixDotNode {
@@ -983,7 +986,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class PostfixErrorNode : public ExpressionNode {
@@ -995,7 +998,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
 
     private:
@@ -1018,7 +1021,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1045,7 +1048,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1063,7 +1066,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1080,7 +1083,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1096,7 +1099,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1121,7 +1124,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
@@ -1154,7 +1157,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1176,7 +1179,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
     };
 
@@ -1219,7 +1222,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
     };
 
@@ -1271,7 +1274,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class PreDecBracketNode : public PrefixBracketNode {
@@ -1282,7 +1285,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class PrefixDotNode : public ExpressionNode {
@@ -1309,7 +1312,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class PreDecDotNode : public PrefixDotNode {
@@ -1320,7 +1323,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
     };
 
     class PrefixErrorNode : public ExpressionNode {
@@ -1332,7 +1335,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1354,7 +1357,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1372,7 +1375,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1393,7 +1396,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1413,7 +1416,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
@@ -1435,7 +1438,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMultiplicitave; }
 
     private:
@@ -1459,7 +1462,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMultiplicitave; }
 
     private:
@@ -1484,7 +1487,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMultiplicitave; }
 
     private:
@@ -1507,7 +1510,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAdditive; }
 
     protected:
@@ -1585,7 +1588,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAdditive; }
 
     private:
@@ -1609,7 +1612,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecShift; }
 
     private:
@@ -1633,7 +1636,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecShift; }
 
     private:
@@ -1657,7 +1660,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecShift; }
     private:
         ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(ExecState*);
@@ -1678,7 +1681,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
@@ -1728,7 +1731,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
@@ -1749,7 +1752,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
@@ -1770,7 +1773,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
@@ -1792,7 +1795,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
@@ -1811,7 +1814,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
@@ -1831,7 +1834,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecEquality; }
 
     private:
@@ -1853,7 +1856,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecEquality; }
 
     private:
@@ -1875,7 +1878,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecEquality; }
 
     private:
@@ -1897,7 +1900,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecEquality; }
 
     private:
@@ -1922,7 +1925,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecBitwiseAnd; }
 
     private:
@@ -1947,7 +1950,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecBitwiseOr; }
 
     private:
@@ -1972,7 +1975,7 @@ namespace KJS {
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecBitwiseXor; }
 
     private:
@@ -1997,7 +2000,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecLogicalAnd; }
 
     private:
@@ -2019,7 +2022,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecLogicalOr; }
 
     private:
@@ -2047,7 +2050,7 @@ namespace KJS {
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecConditional; }
 
     private:
@@ -2074,7 +2077,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
@@ -2125,7 +2128,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
@@ -2168,7 +2171,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
@@ -2189,7 +2192,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
@@ -2209,7 +2212,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
@@ -2230,7 +2233,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
@@ -2250,7 +2253,7 @@ namespace KJS {
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
@@ -2270,7 +2273,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecExpression; }
 
     private:
@@ -2294,7 +2297,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         void evaluateSingle(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
         PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
 
@@ -2315,7 +2318,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<ConstDeclNode> m_next;
@@ -2338,11 +2341,12 @@ namespace KJS {
 
     class BlockNode : public StatementNode {
     public:
+        BlockNode() KJS_FAST_CALL;
         BlockNode(SourceElements* children) KJS_FAST_CALL;
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     protected:
         StatementVector m_children;
@@ -2355,7 +2359,7 @@ namespace KJS {
         }
 
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; }
     };
 
@@ -2368,7 +2372,10 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
+        virtual bool isExprStatement() const KJS_FAST_CALL { return true; }
+
+        ExpressionNode* expr() const { return m_expr.get(); }
 
     private:
         RefPtr<ExpressionNode> m_expr;
@@ -2383,7 +2390,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<ExpressionNode> m_expr;
@@ -2399,7 +2406,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     protected:
         RefPtr<ExpressionNode> m_condition;
@@ -2416,7 +2423,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<StatementNode> m_elseBlock;
@@ -2432,7 +2439,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<StatementNode> m_statement;
@@ -2449,7 +2456,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<ExpressionNode> m_expr;
@@ -2476,7 +2483,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<ExpressionNode> m_expr1;
@@ -2493,7 +2500,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         Identifier m_ident;
@@ -2516,7 +2523,7 @@ namespace KJS {
         }
 
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         Identifier m_ident;
@@ -2534,7 +2541,7 @@ namespace KJS {
         }
 
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         Identifier m_ident;
@@ -2549,7 +2556,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<ExpressionNode> m_value;
@@ -2565,7 +2572,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<ExpressionNode> m_expr;
@@ -2582,7 +2589,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         Identifier m_label;
@@ -2598,7 +2605,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<ExpressionNode> m_expr;
@@ -2616,7 +2623,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<StatementNode> m_tryBlock;
@@ -2640,7 +2647,7 @@ namespace KJS {
 
         Identifier ident() KJS_FAST_CALL { return m_ident; }
         ParameterNode *nextParam() KJS_FAST_CALL { return m_next.get(); }
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
@@ -2653,11 +2660,17 @@ namespace KJS {
 
     class ScopeNode : public BlockNode {
     public:
-        ScopeNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
+        ScopeNode() KJS_FAST_CALL;
+        ScopeNode(const SourceCode&, SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
+
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
+
+        void setSource(const SourceCode& source) { m_source = source; }
+        const SourceCode& source() const { return m_source; }
+        const UString& sourceURL() const KJS_FAST_CALL { return m_source.provider()->url(); }
+        intptr_t sourceID() const { return m_source.provider()->asID(); }
 
-        int sourceId() const KJS_FAST_CALL { return m_sourceId; }
-        const UString& sourceURL() const KJS_FAST_CALL { return m_sourceURL; }
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        void setData(SourceElements*, VarStack*, FunctionStack*);
 
     protected:
         void optimizeVariableAccess(ExecState*) KJS_FAST_CALL;
@@ -2666,18 +2679,17 @@ namespace KJS {
         FunctionStack m_functionStack;
 
     private:
-        UString m_sourceURL;
-        int m_sourceId;
+        SourceCode m_source;
     };
 
     class ProgramNode : public ScopeNode {
     public:
-        static ProgramNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
+        static ProgramNode* create(const SourceCode&, SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
 
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
 
     private:
-        ProgramNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
+        ProgramNode(const SourceCode&, SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
 
         void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
         ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
@@ -2688,21 +2700,24 @@ namespace KJS {
 
     class EvalNode : public ScopeNode {
     public:
-        static EvalNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
+        static EvalNode* create(const SourceCode&, SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
 
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
 
     private:
-        EvalNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
+        EvalNode(const SourceCode&, SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
 
         ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
     };
 
     class FunctionBodyNode : public ScopeNode {
     public:
+        static FunctionBodyNode* create() KJS_FAST_CALL;
         static FunctionBodyNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
+        static FunctionBodyNode* create(const SourceCode&, SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
 
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
         SymbolTable& symbolTable() KJS_FAST_CALL { return m_symbolTable; }
 
@@ -2710,7 +2725,8 @@ namespace KJS {
         UString paramString() const KJS_FAST_CALL;
 
     protected:
-        FunctionBodyNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
+        FunctionBodyNode() KJS_FAST_CALL;
+        FunctionBodyNode(const SourceCode&, SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
 
     private:
         void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
@@ -2723,18 +2739,20 @@ namespace KJS {
 
     class FuncExprNode : public ExpressionNode {
     public:
-        FuncExprNode(const Identifier& ident, FunctionBodyNode* body, ParameterNode* parameter = 0) KJS_FAST_CALL
+        FuncExprNode(const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0) KJS_FAST_CALL
             : m_ident(ident)
             , m_parameter(parameter)
             , m_body(body)
         {
             addParams();
+            m_body->setSource(source);
         }
 
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMember; }
         virtual bool needsParensIfLeftmost() const { return true; }
+        virtual bool isFuncExprNode() const KJS_FAST_CALL { return true; }
 
     private:
         void addParams() KJS_FAST_CALL;
@@ -2748,23 +2766,17 @@ namespace KJS {
 
     class FuncDeclNode : public StatementNode {
     public:
-        FuncDeclNode(const Identifier& ident, FunctionBodyNode* body) KJS_FAST_CALL
-            : m_ident(ident)
-            , m_body(body)
-        {
-            addParams();
-        }
-
-        FuncDeclNode(const Identifier& ident, ParameterNode* parameter, FunctionBodyNode* body) KJS_FAST_CALL
+        FuncDeclNode(const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0) KJS_FAST_CALL
             : m_ident(ident)
             , m_parameter(parameter)
             , m_body(body)
         {
             addParams();
+            m_body->setSource(source);
         }
 
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
 
         Identifier m_ident;
@@ -2791,7 +2803,7 @@ namespace KJS {
         }
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
@@ -2818,7 +2830,7 @@ namespace KJS {
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); }
         ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); }
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
@@ -2834,7 +2846,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
     private:
@@ -2853,7 +2865,7 @@ namespace KJS {
 
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
 
     private:
         RefPtr<ExpressionNode> m_expr;
@@ -2865,7 +2877,7 @@ namespace KJS {
         BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL;
 
         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual void streamTo(SourceStream&) KJS_FAST_CALL;
         virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
 
     private:
index b10e180131160a36dcd794c2287d9999df20e298..24c2d9dd70fce0daec7e5132e07080a3105e8740 100644 (file)
@@ -60,7 +60,7 @@ public:
     SourceStream& operator<<(UnindentType);
     SourceStream& operator<<(DotExprType);
     SourceStream& operator<<(Precedence);
-    SourceStream& operator<<(const Node*);
+    SourceStream& operator<<(Node*);
     template <typename T> SourceStream& operator<<(const RefPtr<T>& n) { return *this << n.get(); }
 
 private:
@@ -203,7 +203,7 @@ SourceStream& SourceStream::operator<<(const Identifier& s)
     return *this;
 }
 
-SourceStream& SourceStream::operator<<(const Node* n)
+SourceStream& SourceStream::operator<<(Node* n)
 {
     bool needParens = (m_precedence != PrecExpression && n->precedence() > m_precedence) || (m_atStartOfStatement && n->needsParensIfLeftmost());
     m_precedence = PrecExpression;
@@ -257,7 +257,7 @@ inline SourceStream& SourceStream::operator<<(Precedence precedence)
 }
 
 static void streamLeftAssociativeBinaryOperator(SourceStream& s, Precedence precedence,
-    const char* operatorString, const Node* left, const Node* right)
+    const char* operatorString, Node* left, Node* right)
 {
     s << precedence << left
         << ' ' << operatorString << ' '
@@ -282,7 +282,7 @@ static inline void dotNodeStreamTo(SourceStream& s, const RefPtr<ExpressionNode>
 
 // --------
 
-UString Node::toString() const
+UString Node::toString()
 {
     SourceStream stream;
     streamTo(stream);
@@ -291,51 +291,51 @@ UString Node::toString() const
 
 // --------
 
-void NullNode::streamTo(SourceStream& s) const
+void NullNode::streamTo(SourceStream& s)
 {
     s << "null";
 }
 
-void FalseNode::streamTo(SourceStream& s) const
+void FalseNode::streamTo(SourceStream& s)
 {
     s << "false";
 }
 
-void TrueNode::streamTo(SourceStream& s) const
+void TrueNode::streamTo(SourceStream& s)
 {
     s << "true";
 }
 
-void PlaceholderTrueNode::streamTo(SourceStream&) const
+void PlaceholderTrueNode::streamTo(SourceStream&)
 {
 }
 
-void NumberNode::streamTo(SourceStream& s) const
+void NumberNode::streamTo(SourceStream& s)
 {
     s << value();
 }
 
-void StringNode::streamTo(SourceStream& s) const
+void StringNode::streamTo(SourceStream& s)
 {
     s << '"' << escapeStringForPrettyPrinting(m_value) << '"';
 }
 
-void RegExpNode::streamTo(SourceStream& s) const
+void RegExpNode::streamTo(SourceStream& s)
 {
     s << '/' <<  m_regExp->pattern() << '/' << m_regExp->flags();
 }
 
-void ThisNode::streamTo(SourceStream& s) const
+void ThisNode::streamTo(SourceStream& s)
 {
     s << "this";
 }
 
-void ResolveNode::streamTo(SourceStream& s) const
+void ResolveNode::streamTo(SourceStream& s)
 {
     s << m_ident;
 }
 
-void ElementNode::streamTo(SourceStream& s) const
+void ElementNode::streamTo(SourceStream& s)
 {
     for (const ElementNode* n = this; n; n = n->m_next.get()) {
         for (int i = 0; i < n->m_elision; i++)
@@ -346,7 +346,7 @@ void ElementNode::streamTo(SourceStream& s) const
     }
 }
 
-void ArrayNode::streamTo(SourceStream& s) const
+void ArrayNode::streamTo(SourceStream& s)
 {
     s << '[' << m_element;
     for (int i = 0; i < m_elision; i++)
@@ -358,7 +358,7 @@ void ArrayNode::streamTo(SourceStream& s) const
     s << ']';
 }
 
-void ObjectLiteralNode::streamTo(SourceStream& s) const
+void ObjectLiteralNode::streamTo(SourceStream& s)
 {
     if (m_list)
         s << "{ " << m_list << " }";
@@ -366,14 +366,14 @@ void ObjectLiteralNode::streamTo(SourceStream& s) const
         s << "{ }";
 }
 
-void PropertyListNode::streamTo(SourceStream& s) const
+void PropertyListNode::streamTo(SourceStream& s)
 {
     s << m_node;
     for (const PropertyListNode* n = m_next.get(); n; n = n->m_next.get())
         s << ", " << n->m_node;
 }
 
-void PropertyNode::streamTo(SourceStream& s) const
+void PropertyNode::streamTo(SourceStream& s)
 {
     switch (m_type) {
         case Constant: {
@@ -399,90 +399,90 @@ void PropertyNode::streamTo(SourceStream& s) const
     }
 }
 
-void BracketAccessorNode::streamTo(SourceStream& s) const
+void BracketAccessorNode::streamTo(SourceStream& s)
 {
     bracketNodeStreamTo(s, m_base, m_subscript);
 }
 
-void DotAccessorNode::streamTo(SourceStream& s) const
+void DotAccessorNode::streamTo(SourceStream& s)
 {
     dotNodeStreamTo(s, m_base, m_ident);
 }
 
-void ArgumentListNode::streamTo(SourceStream& s) const
+void ArgumentListNode::streamTo(SourceStream& s)
 {
     s << PrecAssignment << m_expr;
     for (ArgumentListNode* n = m_next.get(); n; n = n->m_next.get())
         s << ", " << PrecAssignment << n->m_expr;
 }
 
-void ArgumentsNode::streamTo(SourceStream& s) const
+void ArgumentsNode::streamTo(SourceStream& s)
 {
     s << '(' << m_listNode << ')';
 }
 
-void NewExprNode::streamTo(SourceStream& s) const
+void NewExprNode::streamTo(SourceStream& s)
 {
     s << "new " << PrecMember << m_expr << m_args;
 }
 
-void FunctionCallValueNode::streamTo(SourceStream& s) const
+void FunctionCallValueNode::streamTo(SourceStream& s)
 {
     s << PrecCall << m_expr << m_args;
 }
 
-void FunctionCallResolveNode::streamTo(SourceStream& s) const
+void FunctionCallResolveNode::streamTo(SourceStream& s)
 {
     s << m_ident << m_args;
 }
 
-void FunctionCallBracketNode::streamTo(SourceStream& s) const
+void FunctionCallBracketNode::streamTo(SourceStream& s)
 {
     bracketNodeStreamTo(s, m_base, m_subscript);
     s << m_args;
 }
 
-void FunctionCallDotNode::streamTo(SourceStream& s) const
+void FunctionCallDotNode::streamTo(SourceStream& s)
 {
     dotNodeStreamTo(s, m_base, m_ident);
     s << m_args;
 }
 
-void PostIncResolveNode::streamTo(SourceStream& s) const
+void PostIncResolveNode::streamTo(SourceStream& s)
 {
     s << m_ident << "++";
 }
 
-void PostDecResolveNode::streamTo(SourceStream& s) const
+void PostDecResolveNode::streamTo(SourceStream& s)
 {
     s << m_ident << "--";
 }
 
-void PostIncBracketNode::streamTo(SourceStream& s) const
+void PostIncBracketNode::streamTo(SourceStream& s)
 {
     bracketNodeStreamTo(s, m_base, m_subscript);
     s << "++";
 }
 
-void PostDecBracketNode::streamTo(SourceStream& s) const
+void PostDecBracketNode::streamTo(SourceStream& s)
 {
     bracketNodeStreamTo(s, m_base, m_subscript);
     s << "--";
 }
 
-void PostIncDotNode::streamTo(SourceStream& s) const
+void PostIncDotNode::streamTo(SourceStream& s)
 {
     dotNodeStreamTo(s, m_base, m_ident);
     s << "++";
 }
 
-void PostDecDotNode::streamTo(SourceStream& s) const
+void PostDecDotNode::streamTo(SourceStream& s)
 {
     dotNodeStreamTo(s, m_base, m_ident);
     s << "--";
 }
 
-void PostfixErrorNode::streamTo(SourceStream& s) const
+void PostfixErrorNode::streamTo(SourceStream& s)
 {
     s << PrecLeftHandSide << m_expr;
     if (m_operator == OpPlusPlus)
@@ -491,78 +491,78 @@ void PostfixErrorNode::streamTo(SourceStream& s) const
         s << "--";
 }
 
-void DeleteResolveNode::streamTo(SourceStream& s) const
+void DeleteResolveNode::streamTo(SourceStream& s)
 {
     s << "delete " << m_ident;
 }
 
-void DeleteBracketNode::streamTo(SourceStream& s) const
+void DeleteBracketNode::streamTo(SourceStream& s)
 {
     s << "delete ";
     bracketNodeStreamTo(s, m_base, m_subscript);
 }
 
-void DeleteDotNode::streamTo(SourceStream& s) const
+void DeleteDotNode::streamTo(SourceStream& s)
 {
     s << "delete ";
     dotNodeStreamTo(s, m_base, m_ident);
 }
 
-void DeleteValueNode::streamTo(SourceStream& s) const
+void DeleteValueNode::streamTo(SourceStream& s)
 {
     s << "delete " << PrecUnary << m_expr;
 }
 
-void VoidNode::streamTo(SourceStream& s) const
+void VoidNode::streamTo(SourceStream& s)
 {
     s << "void " << PrecUnary << m_expr;
 }
 
-void TypeOfValueNode::streamTo(SourceStream& s) const
+void TypeOfValueNode::streamTo(SourceStream& s)
 {
     s << "typeof " << PrecUnary << m_expr;
 }
 
-void TypeOfResolveNode::streamTo(SourceStream& s) const
+void TypeOfResolveNode::streamTo(SourceStream& s)
 {
     s << "typeof " << m_ident;
 }
 
-void PreIncResolveNode::streamTo(SourceStream& s) const
+void PreIncResolveNode::streamTo(SourceStream& s)
 {
     s << "++" << m_ident;
 }
 
-void PreDecResolveNode::streamTo(SourceStream& s) const
+void PreDecResolveNode::streamTo(SourceStream& s)
 {
     s << "--" << m_ident;
 }
 
-void PreIncBracketNode::streamTo(SourceStream& s) const
+void PreIncBracketNode::streamTo(SourceStream& s)
 {
     s << "++";
     bracketNodeStreamTo(s, m_base, m_subscript);
 }
 
-void PreDecBracketNode::streamTo(SourceStream& s) const
+void PreDecBracketNode::streamTo(SourceStream& s)
 {
     s << "--";
     bracketNodeStreamTo(s, m_base, m_subscript);
 }
 
-void PreIncDotNode::streamTo(SourceStream& s) const
+void PreIncDotNode::streamTo(SourceStream& s)
 {
     s << "++";
     dotNodeStreamTo(s, m_base, m_ident);
 }
 
-void PreDecDotNode::streamTo(SourceStream& s) const
+void PreDecDotNode::streamTo(SourceStream& s)
 {
     s << "--";
     dotNodeStreamTo(s, m_base, m_ident);
 }
 
-void PrefixErrorNode::streamTo(SourceStream& s) const
+void PrefixErrorNode::streamTo(SourceStream& s)
 {
     if (m_operator == OpPlusPlus)
         s << "++" << PrecUnary << m_expr;
@@ -570,194 +570,194 @@ void PrefixErrorNode::streamTo(SourceStream& s) const
         s << "--" << PrecUnary << m_expr;
 }
 
-void UnaryPlusNode::streamTo(SourceStream& s) const
+void UnaryPlusNode::streamTo(SourceStream& s)
 {
     s << "+ " << PrecUnary << m_expr;
 }
 
-void NegateNode::streamTo(SourceStream& s) const
+void NegateNode::streamTo(SourceStream& s)
 {
     s << "- " << PrecUnary << m_expr;
 }
 
-void BitwiseNotNode::streamTo(SourceStream& s) const
+void BitwiseNotNode::streamTo(SourceStream& s)
 {
     s << "~" << PrecUnary << m_expr;
 }
 
-void LogicalNotNode::streamTo(SourceStream& s) const
+void LogicalNotNode::streamTo(SourceStream& s)
 {
     s << "!" << PrecUnary << m_expr;
 }
 
-void MultNode::streamTo(SourceStream& s) const
+void MultNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "*", m_term1, m_term2);
 }
 
-void DivNode::streamTo(SourceStream& s) const
+void DivNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "/", m_term1, m_term2);
 }
 
-void ModNode::streamTo(SourceStream& s) const
+void ModNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "%", m_term1, m_term2);
 }
 
-void AddNode::streamTo(SourceStream& s) const
+void AddNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "+", m_term1, m_term2);
 }
 
-void SubNode::streamTo(SourceStream& s) const
+void SubNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "-", m_term1, m_term2);
 }
 
-void LeftShiftNode::streamTo(SourceStream& s) const
+void LeftShiftNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "<<", m_term1, m_term2);
 }
 
-void RightShiftNode::streamTo(SourceStream& s) const
+void RightShiftNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), ">>", m_term1, m_term2);
 }
 
-void UnsignedRightShiftNode::streamTo(SourceStream& s) const
+void UnsignedRightShiftNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), ">>>", m_term1, m_term2);
 }
 
-void LessNode::streamTo(SourceStream& s) const
+void LessNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "<", m_expr1, m_expr2);
 }
 
-void GreaterNode::streamTo(SourceStream& s) const
+void GreaterNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), ">", m_expr1, m_expr2);
 }
 
-void LessEqNode::streamTo(SourceStream& s) const
+void LessEqNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "<=", m_expr1, m_expr2);
 }
 
-void GreaterEqNode::streamTo(SourceStream& s) const
+void GreaterEqNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), ">=", m_expr1, m_expr2);
 }
 
-void InstanceOfNode::streamTo(SourceStream& s) const
+void InstanceOfNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "instanceof", m_expr1, m_expr2);
 }
 
-void InNode::streamTo(SourceStream& s) const
+void InNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "in", m_expr1, m_expr2);
 }
 
-void EqualNode::streamTo(SourceStream& s) const
+void EqualNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "==", m_expr1, m_expr2);
 }
 
-void NotEqualNode::streamTo(SourceStream& s) const
+void NotEqualNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "!=", m_expr1, m_expr2);
 }
 
-void StrictEqualNode::streamTo(SourceStream& s) const
+void StrictEqualNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "===", m_expr1, m_expr2);
 }
 
-void NotStrictEqualNode::streamTo(SourceStream& s) const
+void NotStrictEqualNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "!==", m_expr1, m_expr2);
 }
 
-void BitAndNode::streamTo(SourceStream& s) const
+void BitAndNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "&", m_expr1, m_expr2);
 }
 
-void BitXOrNode::streamTo(SourceStream& s) const
+void BitXOrNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "^", m_expr1, m_expr2);
 }
 
-void BitOrNode::streamTo(SourceStream& s) const
+void BitOrNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "|", m_expr1, m_expr2);
 }
 
-void LogicalAndNode::streamTo(SourceStream& s) const
+void LogicalAndNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "&&", m_expr1, m_expr2);
 }
 
-void LogicalOrNode::streamTo(SourceStream& s) const
+void LogicalOrNode::streamTo(SourceStream& s)
 {
     streamLeftAssociativeBinaryOperator(s, precedence(), "||", m_expr1, m_expr2);
 }
 
-void ConditionalNode::streamTo(SourceStream& s) const
+void ConditionalNode::streamTo(SourceStream& s)
 {
     s << PrecLogicalOr << m_logical
         << " ? " << PrecAssignment << m_expr1
         << " : " << PrecAssignment << m_expr2;
 }
 
-void ReadModifyResolveNode::streamTo(SourceStream& s) const
+void ReadModifyResolveNode::streamTo(SourceStream& s)
 {
     s << m_ident << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
 }
 
-void AssignResolveNode::streamTo(SourceStream& s) const
+void AssignResolveNode::streamTo(SourceStream& s)
 {
     s << m_ident << " = " << PrecAssignment << m_right;
 }
 
-void ReadModifyBracketNode::streamTo(SourceStream& s) const
+void ReadModifyBracketNode::streamTo(SourceStream& s)
 {
     bracketNodeStreamTo(s, m_base, m_subscript);
     s << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
 }
 
-void AssignBracketNode::streamTo(SourceStream& s) const
+void AssignBracketNode::streamTo(SourceStream& s)
 {
     bracketNodeStreamTo(s, m_base, m_subscript);
     s << " = " << PrecAssignment << m_right;
 }
 
-void ReadModifyDotNode::streamTo(SourceStream& s) const
+void ReadModifyDotNode::streamTo(SourceStream& s)
 {
     dotNodeStreamTo(s, m_base, m_ident);
     s << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
 }
 
-void AssignDotNode::streamTo(SourceStream& s) const
+void AssignDotNode::streamTo(SourceStream& s)
 {
     dotNodeStreamTo(s, m_base, m_ident);
     s << " = " << PrecAssignment << m_right;
 }
 
-void AssignErrorNode::streamTo(SourceStream& s) const
+void AssignErrorNode::streamTo(SourceStream& s)
 {
     s << PrecLeftHandSide << m_left << ' '
         << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
 }
 
-void CommaNode::streamTo(SourceStream& s) const
+void CommaNode::streamTo(SourceStream& s)
 {
     s << PrecAssignment << m_expr1 << ", " << PrecAssignment << m_expr2;
 }
 
-void ConstDeclNode::streamTo(SourceStream& s) const
+void ConstDeclNode::streamTo(SourceStream& s)
 {
     s << m_ident;
     if (m_init)
@@ -769,7 +769,7 @@ void ConstDeclNode::streamTo(SourceStream& s) const
     }
 }
 
-void ConstStatementNode::streamTo(SourceStream& s) const
+void ConstStatementNode::streamTo(SourceStream& s)
 {
     s << Endl << "const " << m_next << ';';
 }
@@ -780,14 +780,14 @@ static inline void statementListStreamTo(const Vector<RefPtr<StatementNode> >& n
         s << *ptr;
 }
 
-void BlockNode::streamTo(SourceStream& s) const
+void BlockNode::streamTo(SourceStream& s)
 {
     s << Endl << "{" << Indent;
     statementListStreamTo(m_children, s);
     s << Unindent << Endl << "}";
 }
 
-void ScopeNode::streamTo(SourceStream& s) const
+void ScopeNode::streamTo(SourceStream& s)
 {
     s << Endl << "{" << Indent;
 
@@ -809,44 +809,51 @@ void ScopeNode::streamTo(SourceStream& s) const
     s << Unindent << Endl << "}";
 }
 
-void EmptyStatementNode::streamTo(SourceStream& s) const
+void FunctionBodyNode::streamTo(SourceStream& s)
+{
+    if (m_children.isEmpty())
+        parser().reparse(this);
+    ScopeNode::streamTo(s);
+}
+
+void EmptyStatementNode::streamTo(SourceStream& s)
 {
     s << Endl << ';';
 }
 
-void ExprStatementNode::streamTo(SourceStream& s) const
+void ExprStatementNode::streamTo(SourceStream& s)
 {
     s << Endl << m_expr << ';';
 }
 
-void VarStatementNode::streamTo(SourceStream& s) const
+void VarStatementNode::streamTo(SourceStream& s)
 {
     s << Endl << "var " << m_expr << ';';
 }
 
-void IfNode::streamTo(SourceStream& s) const
+void IfNode::streamTo(SourceStream& s)
 {
     s << Endl << "if (" << m_condition << ')' << Indent << m_ifBlock << Unindent;
 }
 
-void IfElseNode::streamTo(SourceStream& s) const
+void IfElseNode::streamTo(SourceStream& s)
 {
     IfNode::streamTo(s);
     s << Endl << "else" << Indent << m_elseBlock << Unindent;
 }
 
-void DoWhileNode::streamTo(SourceStream& s) const
+void DoWhileNode::streamTo(SourceStream& s)
 {
     s << Endl << "do " << Indent << m_statement << Unindent << Endl
         << "while (" << m_expr << ");";
 }
 
-void WhileNode::streamTo(SourceStream& s) const
+void WhileNode::streamTo(SourceStream& s)
 {
     s << Endl << "while (" << m_expr << ')' << Indent << m_statement << Unindent;
 }
 
-void ForNode::streamTo(SourceStream& s) const
+void ForNode::streamTo(SourceStream& s)
 {
     s << Endl << "for ("
         << (m_expr1WasVarDecl ? "var " : "")
@@ -856,7 +863,7 @@ void ForNode::streamTo(SourceStream& s) const
         << ')' << Indent << m_statement << Unindent;
 }
 
-void ForInNode::streamTo(SourceStream& s) const
+void ForInNode::streamTo(SourceStream& s)
 {
     s << Endl << "for (";
     if (m_identIsVarDecl) {
@@ -871,7 +878,7 @@ void ForInNode::streamTo(SourceStream& s) const
     s << " in " << m_expr << ')' << Indent << m_statement << Unindent;
 }
 
-void ContinueNode::streamTo(SourceStream& s) const
+void ContinueNode::streamTo(SourceStream& s)
 {
     s << Endl << "continue";
     if (!m_ident.isNull())
@@ -879,7 +886,7 @@ void ContinueNode::streamTo(SourceStream& s) const
     s << ';';
 }
 
-void BreakNode::streamTo(SourceStream& s) const
+void BreakNode::streamTo(SourceStream& s)
 {
     s << Endl << "break";
     if (!m_ident.isNull())
@@ -887,7 +894,7 @@ void BreakNode::streamTo(SourceStream& s) const
     s << ';';
 }
 
-void ReturnNode::streamTo(SourceStream& s) const
+void ReturnNode::streamTo(SourceStream& s)
 {
     s << Endl << "return";
     if (m_value)
@@ -895,12 +902,12 @@ void ReturnNode::streamTo(SourceStream& s) const
     s << ';';
 }
 
-void WithNode::streamTo(SourceStream& s) const
+void WithNode::streamTo(SourceStream& s)
 {
     s << Endl << "with (" << m_expr << ") " << m_statement;
 }
 
-void CaseClauseNode::streamTo(SourceStream& s) const
+void CaseClauseNode::streamTo(SourceStream& s)
 {
     s << Endl;
     if (m_expr)
@@ -912,13 +919,13 @@ void CaseClauseNode::streamTo(SourceStream& s) const
     s << Unindent;
 }
 
-void ClauseListNode::streamTo(SourceStream& s) const
+void ClauseListNode::streamTo(SourceStream& s)
 {
     for (const ClauseListNode* n = this; n; n = n->getNext())
         s << n->getClause();
 }
 
-void CaseBlockNode::streamTo(SourceStream& s) const
+void CaseBlockNode::streamTo(SourceStream& s)
 {
     for (const ClauseListNode* n = m_list1.get(); n; n = n->getNext())
         s << n->getClause();
@@ -927,24 +934,24 @@ void CaseBlockNode::streamTo(SourceStream& s) const
         s << n->getClause();
 }
 
-void SwitchNode::streamTo(SourceStream& s) const
+void SwitchNode::streamTo(SourceStream& s)
 {
     s << Endl << "switch (" << m_expr << ") {"
         << Indent << m_block << Unindent
         << Endl << "}";
 }
 
-void LabelNode::streamTo(SourceStream& s) const
+void LabelNode::streamTo(SourceStream& s)
 {
     s << Endl << m_label << ":" << Indent << m_statement << Unindent;
 }
 
-void ThrowNode::streamTo(SourceStream& s) const
+void ThrowNode::streamTo(SourceStream& s)
 {
     s << Endl << "throw " << m_expr << ';';
 }
 
-void TryNode::streamTo(SourceStream& s) const
+void TryNode::streamTo(SourceStream& s)
 {
     s << Endl << "try " << m_tryBlock;
     if (m_catchBlock)
@@ -953,19 +960,19 @@ void TryNode::streamTo(SourceStream& s) const
         s << Endl << "finally " << m_finallyBlock;
 }
 
-void ParameterNode::streamTo(SourceStream& s) const
+void ParameterNode::streamTo(SourceStream& s)
 {
     s << m_ident;
     for (ParameterNode* n = m_next.get(); n; n = n->m_next.get())
         s << ", " << n->m_ident;
 }
 
-void FuncDeclNode::streamTo(SourceStream& s) const
+void FuncDeclNode::streamTo(SourceStream& s)
 {
     s << Endl << "function " << m_ident << '(' << m_parameter << ')' << m_body;
 }
 
-void FuncExprNode::streamTo(SourceStream& s) const
+void FuncExprNode::streamTo(SourceStream& s)
 {
     s << "function " << m_ident << '(' << m_parameter << ')' << m_body;
 }
index 8c6a154d018511f41780df7375e0a8bf52061581..d02af07ab857c454262e1d1b9b0b9427d40a8ffc 100644 (file)
@@ -600,7 +600,7 @@ const char * const errorNamesArr[] = {
 const char * const * const Error::errorNames = errorNamesArr;
 
 JSObject *Error::create(ExecState *exec, ErrorType errtype, const UString &message,
-                         int lineno, int sourceId, const UString &sourceURL)
+                         int lineno, intptr_t sourceID, const UString &sourceURL)
 {
   JSObject *cons;
   switch (errtype) {
@@ -636,8 +636,8 @@ JSObject *Error::create(ExecState *exec, ErrorType errtype, const UString &messa
 
   if (lineno != -1)
     err->put(exec, "line", jsNumber(lineno));
-  if (sourceId != -1)
-    err->put(exec, "sourceId", jsNumber(sourceId));
+  if (sourceID != -1)
+    err->put(exec, "sourceID", jsNumber(sourceID));
 
   if(!sourceURL.isNull())
     err->put(exec, "sourceURL", jsString(sourceURL));
@@ -671,9 +671,9 @@ JSObject *throwError(ExecState *exec, ErrorType type, const char *message)
     return error;
 }
 
-JSObject *throwError(ExecState *exec, ErrorType type, const UString &message, int line, int sourceId, const UString &sourceURL)
+JSObject *throwError(ExecState *exec, ErrorType type, const UString &message, int line, intptr_t sourceID, const UString &sourceURL)
 {
-    JSObject *error = Error::create(exec, type, message, line, sourceId, sourceURL);
+    JSObject *error = Error::create(exec, type, message, line, sourceID, sourceURL);
     exec->setException(error);
     return error;
 }
index 3807bed013f511adc55c5dd1a1bf0b41a012f37f..93cc0acc7b6802c6458e004ded84de68101c5273 100644 (file)
@@ -487,7 +487,7 @@ namespace KJS {
      * @param sourceId Optional source id.
      * @param sourceURL Optional source URL.
      */
-    static JSObject *create(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString &sourceURL);
+    static JSObject *create(ExecState *, ErrorType, const UString &message, int lineNumber, intptr_t sourceID, const UString &sourceURL);
     static JSObject *create(ExecState *, ErrorType, const char *message);
 
     /**
@@ -496,7 +496,7 @@ namespace KJS {
     static const char * const * const errorNames;
   };
 
-JSObject *throwError(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString &sourceURL);
+JSObject *throwError(ExecState *, ErrorType, const UString &message, int lineNumber, intptr_t sourceID, const UString &sourceURL);
 JSObject *throwError(ExecState *, ErrorType, const UString &message);
 JSObject *throwError(ExecState *, ErrorType, const char *message);
 JSObject *throwError(ExecState *, ErrorType);
index 25c807e6658ecb691e7449b5e76b7dbd94e420bb..6a7607c98af373ba3032a485cb5c1cf5f5f84672 100644 (file)
@@ -26,6 +26,7 @@
 #include "JSGlobalObject.h"
 #include "JSLock.h"
 #include "Parser.h"
+#include "SourceCode.h"
 #include "collector.h"
 #include "interpreter.h"
 #include "nodes.h"
@@ -165,7 +166,8 @@ JSValue* TestFunctionImp::callAsFunction(ExecState* exec, JSObject*, const List
         return throwError(exec, GeneralError, "Could not open file.");
 
       stopWatch.start();
-      Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), fileName, 0, script.data());
+      
+      Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), makeSource(script.data(), fileName));
       stopWatch.stop();
       
       return jsNumber(stopWatch.getElapsedMS());
@@ -177,7 +179,7 @@ JSValue* TestFunctionImp::callAsFunction(ExecState* exec, JSObject*, const List
       if (!fillBufferWithContentsOfFile(fileName, script))
         return throwError(exec, GeneralError, "Could not open file.");
 
-      Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), fileName, 0, script.data());
+      Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), makeSource(script.data(), fileName));
 
       return jsUndefined();
     }
@@ -247,8 +249,8 @@ static bool prettyPrintScript(const UString& fileName, const Vector<char>& scrip
 {
   int errLine = 0;
   UString errMsg;
-  UString scriptUString(script.data());
-  RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(fileName, 0, scriptUString.data(), scriptUString.size(), 0, &errLine, &errMsg);
+
+  RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(makeSource(script.data(), fileName), &errLine, &errMsg);
   if (!programNode) {
     fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
     return false;
@@ -274,7 +276,7 @@ static bool runWithScripts(const Vector<UString>& fileNames, bool prettyPrint)
     if (prettyPrint)
       prettyPrintScript(fileName, script);
     else {
-      Completion completion = Interpreter::evaluate(globalObject->globalExec(), fileName, 0, script.data());
+      Completion completion = Interpreter::evaluate(globalObject->globalExec(), makeSource(script.data(), fileName));
       success = success && completion.complType() != Throw;
     }
   }
index 888eb2d6bb70b6a2d7635b4231688c9391d5c6ab..6f6add81909ebc9ed4ee102ac546813bd70aa6c4 100644 (file)
@@ -172,8 +172,6 @@ static int statBufferSize = 0;
 
 PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar *d, int l)
 {
-  ASSERT(JSLock::lockCount() > 0);
-
   int sizeInBytes = l * sizeof(UChar);
   UChar *copyD = static_cast<UChar *>(fastMalloc(sizeInBytes));
   memcpy(copyD, d, sizeInBytes);
@@ -183,8 +181,6 @@ PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar *d, int l)
 
 PassRefPtr<UString::Rep> UString::Rep::create(UChar *d, int l)
 {
-  ASSERT(JSLock::lockCount() > 0);
-
   Rep* r = new Rep;
   r->offset = 0;
   r->len = l;
@@ -205,7 +201,6 @@ PassRefPtr<UString::Rep> UString::Rep::create(UChar *d, int l)
 
 PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length)
 {
-  ASSERT(JSLock::lockCount() > 0);
   ASSERT(base);
 
   int baseOffset = base->offset;
@@ -235,8 +230,6 @@ PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset,
 
 void UString::Rep::destroy()
 {
-  ASSERT(JSLock::lockCount() > 0);
-
   if (isIdentifier)
     Identifier::remove(this);
   if (baseString != this) {
index 7faa86a788de147cdb4179a7bf0d885e24b54268..dba58d731387139178acb6b6b6d3296e9256cd79 100644 (file)
@@ -155,8 +155,8 @@ namespace KJS {
       static unsigned computeHash(const UChar *, int length);
       static unsigned computeHash(const char *);
 
-      Rep* ref() { ASSERT(JSLock::lockCount() > 0); ++rc; return this; }
-      ALWAYS_INLINE void deref() { ASSERT(JSLock::lockCount() > 0); if (--rc == 0) destroy(); }
+      Rep* ref() { ++rc; return this; }
+      ALWAYS_INLINE void deref() { if (--rc == 0) destroy(); }
 
       // unshared data
       int offset;
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index f5f54f5b6533b10a6089b9816c7be2325e77f223..cae24adf63c5f1194cf747227485894b0d715879 100644 (file)
@@ -412,7 +412,7 @@ static const int kMaxFreeListLength = 256;
 
 // Lower and upper bounds on the per-thread cache sizes
 static const size_t kMinThreadCacheSize = kMaxSize * 2;
-static const size_t kMaxThreadCacheSize = 2 << 20;
+static const size_t kMaxThreadCacheSize = 512 * 1024;
 
 // Default bound on the total amount of thread caches
 static const size_t kDefaultOverallThreadCacheSize = 16 << 20;
@@ -3633,6 +3633,13 @@ void FastMallocZone::init()
 
 void releaseFastMallocFreeMemory()
 {
+    // Flush free pages in the current thread cache back to the page heap.
+    // Scavenging twice flushes everything
+    if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent()) {
+        threadCache->Scavenge();
+        threadCache->Scavenge();
+    }
+
     SpinLockHolder h(&pageheap_lock);
     pageheap->ReleaseFreePages();
 }
old mode 100644 (file)
new mode 100755 (executable)
index 8140fd3e7db0586ce314f521866a74c6d3b6f96f..18a9fe5b5710b6e4e166484291ab9ffeda7c6cba 100644 (file)
@@ -417,8 +417,10 @@ void TCMalloc_SystemRelease(void* start, size_t length)
   if (new_end > new_start) {
     // Note -- ignoring most return codes, because if this fails it
     // doesn't matter...
-    while (madvise(reinterpret_cast<char*>(new_start), new_end - new_start,
-                   MADV_DONTNEED) == -1 &&
+    // The msync call with MS_KILLPAGES on Leopard is equivalent to an
+    // madvise call with MADV_FREE on SnowLeopard
+    while (msync(reinterpret_cast<char*>(new_start), new_end - new_start,
+                   MS_KILLPAGES) == -1 &&
            errno == EAGAIN) {
       // NOP
     }
index cd6ecedbf8836b454cba07281ebc25e1ea44936c..d8c8e2ed51e2af89de0b7c6d9002041494ec403c 100644 (file)
@@ -1,4 +1,3 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
 /*
  *  Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  *
 #include <utility>
 
 namespace WTF {
-
+    
     using std::min;
     using std::max;
     
+    // WTF_ALIGN_OF / WTF_ALIGNED
+#if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(WINSCW)
+#define WTF_ALIGN_OF(type) __alignof__(type)
+#define WTF_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((__aligned__(n)))
+#elif COMPILER(MSVC)
+#define WTF_ALIGN_OF(type) __alignof(type)
+#define WTF_ALIGNED(variable_type, variable, n) __declspec(align(n)) variable_type variable
+#else
+#error WTF_ALIGN macros need alignment control.
+#endif
+    
+#if COMPILER(GCC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
+    typedef char __attribute__((__may_alias__)) AlignedBufferChar; 
+#else
+    typedef char AlignedBufferChar; 
+#endif
+    
+    template <size_t size, size_t alignment> struct AlignedBuffer;
+    template <size_t size> struct AlignedBuffer<size, 1> { AlignedBufferChar buffer[size]; };
+    template <size_t size> struct AlignedBuffer<size, 2> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2);  };
+    template <size_t size> struct AlignedBuffer<size, 4> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4);  };
+    template <size_t size> struct AlignedBuffer<size, 8> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8);  };
+    template <size_t size> struct AlignedBuffer<size, 16> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); };
+    template <size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); };
+    template <size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); };
+    
     template <bool needsDestruction, typename T>
     class VectorDestructor;
-
+    
     template<typename T>
     struct VectorDestructor<false, T>
     {
         static void destruct(T*, T*) {}
     };
-
+    
     template<typename T>
     struct VectorDestructor<true, T>
     {
@@ -54,16 +79,16 @@ namespace WTF {
                 cur->~T();
         }
     };
-
+    
     template <bool needsInitialization, bool canInitializeWithMemset, typename T>
     class VectorInitializer;
-
+    
     template<bool ignore, typename T>
     struct VectorInitializer<false, ignore, T>
     {
         static void initialize(T*, T*) {}
     };
-
+    
     template<typename T>
     struct VectorInitializer<true, false, T>
     {
@@ -73,7 +98,7 @@ namespace WTF {
                 new (cur) T;
         }
     };
-
+    
     template<typename T>
     struct VectorInitializer<true, true, T>
     {
@@ -82,10 +107,10 @@ namespace WTF {
             memset(begin, 0, reinterpret_cast<char*>(end) - reinterpret_cast<char*>(begin));
         }
     };
-
+    
     template <bool canMoveWithMemcpy, typename T>
     class VectorMover;
-
+    
     template<typename T>
     struct VectorMover<false, T>
     {
@@ -113,7 +138,7 @@ namespace WTF {
             }
         }
     };
-
+    
     template<typename T>
     struct VectorMover<true, T>
     {
@@ -126,10 +151,10 @@ namespace WTF {
             memmove(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src));
         }
     };
-
+    
     template <bool canCopyWithMemcpy, typename T>
     class VectorCopier;
-
+    
     template<typename T>
     struct VectorCopier<false, T>
     {
@@ -142,7 +167,7 @@ namespace WTF {
             }
         }
     };
-
+    
     template<typename T>
     struct VectorCopier<true, T>
     {
@@ -151,10 +176,10 @@ namespace WTF {
             memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src));
         }
     };
-
+    
     template <bool canFillWithMemset, typename T>
     class VectorFiller;
-
+    
     template<typename T>
     struct VectorFiller<false, T>
     {
@@ -166,7 +191,7 @@ namespace WTF {
             }
         }
     };
-
+    
     template<typename T>
     struct VectorFiller<true, T>
     {
@@ -191,7 +216,7 @@ namespace WTF {
             return true;
         }
     };
-
+    
     template<typename T>
     struct VectorComparer<true, T>
     {
@@ -208,27 +233,27 @@ namespace WTF {
         {
             VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, end);
         }
-
+        
         static void initialize(T* begin, T* end)
         {
             VectorInitializer<VectorTraits<T>::needsInitialization, VectorTraits<T>::canInitializeWithMemset, T>::initialize(begin, end);
         }
-
+        
         static void move(const T* src, const T* srcEnd, T* dst)
         {
             VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::move(src, srcEnd, dst);
         }
-
+        
         static void moveOverlapping(const T* src, const T* srcEnd, T* dst)
         {
             VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::moveOverlapping(src, srcEnd, dst);
         }
-
+        
         static void uninitializedCopy(const T* src, const T* srcEnd, T* dst)
         {
             VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(src, srcEnd, dst);
         }
-
+        
         static void uninitializedFill(T* dst, T* dstEnd, const T& val)
         {
             VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFill(dst, dstEnd, val);
@@ -239,28 +264,32 @@ namespace WTF {
             return VectorComparer<VectorTraits<T>::canCompareWithMemcmp, T>::compare(a, b, size);
         }
     };
-
+    
     template<typename T>
     class VectorBufferBase : Noncopyable {
     public:
         void allocateBuffer(size_t newCapacity)
         {
-            ASSERT(newCapacity >= m_capacity);
             m_capacity = newCapacity;
             if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
                 CRASH();
             m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T)));
         }
-
+        
         void deallocateBuffer(T* bufferToDeallocate)
         {
+            if (m_buffer == bufferToDeallocate) {
+                m_buffer = 0;
+                m_capacity = 0;
+            }
             fastFree(bufferToDeallocate);
         }
-
+        
         T* buffer() { return m_buffer; }
         const T* buffer() const { return m_buffer; }
+        T** bufferSlot() { return &m_buffer; }
         size_t capacity() const { return m_capacity; }
-
+        
         T* releaseBuffer()
         {
             T* buffer = m_buffer;
@@ -268,32 +297,32 @@ namespace WTF {
             m_capacity = 0;
             return buffer;
         }
-
+        
     protected:
         VectorBufferBase()
-            : m_buffer(0)
-            , m_capacity(0)
+        : m_buffer(0)
+        , m_capacity(0)
         {
         }
-
+        
         VectorBufferBase(T* buffer, size_t capacity)
-            : m_buffer(buffer)
-            , m_capacity(capacity)
+        : m_buffer(buffer)
+        , m_capacity(capacity)
         {
         }
-
+        
         ~VectorBufferBase()
         {
             // FIXME: It would be nice to find a way to ASSERT that m_buffer hasn't leaked here.
         }
-
+        
         T* m_buffer;
         size_t m_capacity;
     };
-
+    
     template<typename T, size_t inlineCapacity>
     class VectorBuffer;
-
+    
     template<typename T>
     class VectorBuffer<T, 0> : private VectorBufferBase<T> {
     private:
@@ -302,12 +331,12 @@ namespace WTF {
         VectorBuffer()
         {
         }
-
+        
         VectorBuffer(size_t capacity)
         {
             allocateBuffer(capacity);
         }
-
+        
         ~VectorBuffer()
         {
             deallocateBuffer(buffer());
@@ -318,514 +347,588 @@ namespace WTF {
             std::swap(m_buffer, other.m_buffer);
             std::swap(m_capacity, other.m_capacity);
         }
-
+        
+        void restoreInlineBufferIfNeeded() { }
+        
         using Base::allocateBuffer;
         using Base::deallocateBuffer;
-
+        
         using Base::buffer;
+        using Base::bufferSlot;
         using Base::capacity;
-
+        
         using Base::releaseBuffer;
     private:
         using Base::m_buffer;
         using Base::m_capacity;
     };
-
+    
     template<typename T, size_t inlineCapacity>
     class VectorBuffer : private VectorBufferBase<T> {
     private:
         typedef VectorBufferBase<T> Base;
     public:
         VectorBuffer()
-            : Base(inlineBuffer(), inlineCapacity)
+        : Base(inlineBuffer(), inlineCapacity)
         {
         }
-
+        
         VectorBuffer(size_t capacity)
-            : Base(inlineBuffer(), inlineCapacity)
+        : Base(inlineBuffer(), inlineCapacity)
         {
-            if (capacity > inlineCapacity)
-                allocateBuffer(capacity);
+            allocateBuffer(capacity);
         }
-
+        
         ~VectorBuffer()
         {
             deallocateBuffer(buffer());
         }
-
-        using Base::allocateBuffer;
-
+        
+        void allocateBuffer(size_t newCapacity)
+        {
+            if (newCapacity > inlineCapacity)
+                Base::allocateBuffer(newCapacity);
+        }
+        
         void deallocateBuffer(T* bufferToDeallocate)
         {
             if (bufferToDeallocate == inlineBuffer())
                 return;
             Base::deallocateBuffer(bufferToDeallocate);
         }
-
+        
+        void restoreInlineBufferIfNeeded()
+        {
+            if (m_buffer)
+                return;
+            m_buffer = inlineBuffer();
+            m_capacity = inlineCapacity;
+        }
+        
         using Base::buffer;
+        using Base::bufferSlot;
         using Base::capacity;
-
+        
         T* releaseBuffer()
         {
             if (buffer() == inlineBuffer())
                 return 0;
             return Base::releaseBuffer();
         }
-
+        
     private:
         using Base::m_buffer;
         using Base::m_capacity;
-
+        
         static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T);
-#if PLATFORM(ARM)
-        T *inlineBuffer() { return reinterpret_cast<T*>((void*)((&m_inlineBuffer))); }
-
-        __attribute__ ((aligned (4))) char m_inlineBuffer[m_inlineBufferSize];
-#else
-        T* inlineBuffer() { return reinterpret_cast<T*>(&m_inlineBuffer); }
-
-        // FIXME: Nothing guarantees this buffer is appropriately aligned to hold objects of type T.
-        char m_inlineBuffer[m_inlineBufferSize];
-#endif
+        T* inlineBuffer() { return reinterpret_cast<T*>(m_inlineBuffer.buffer); }
+        
+        AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer;
     };
-
+    
     template<typename T, size_t inlineCapacity = 0>
     class Vector {
-    private:
-        typedef VectorBuffer<T, inlineCapacity> Buffer;
-        typedef VectorTypeOperations<T> TypeOperations;
-
-    public:
-        typedef T ValueType;
-
-        typedef T* iterator;
-        typedef const T* const_iterator;
-
-        Vector() 
-            : m_size(0)
-        {
-        }
-        
-        explicit Vector(size_t size) 
-            : m_size(size)
-            , m_buffer(size)
-        {
-            TypeOperations::initialize(begin(), end());
-        }
-
-        ~Vector()
-        {
-            clear();
-        }
-
-        Vector(const Vector&);
-        template<size_t otherCapacity> 
-        Vector(const Vector<T, otherCapacity>&);
-
-        Vector& operator=(const Vector&);
-        template<size_t otherCapacity> 
-        Vector& operator=(const Vector<T, otherCapacity>&);
-
-        size_t size() const { return m_size; }
-        size_t capacity() const { return m_buffer.capacity(); }
-        bool isEmpty() const { return !size(); }
-
-        T& at(size_t i) 
-        { 
-            ASSERT(i < size());
-            return m_buffer.buffer()[i]; 
-        }
-        const T& at(size_t i) const 
-        {
-            ASSERT(i < size());
-            return m_buffer.buffer()[i]; 
-        }
-
-        T& operator[](size_t i) { return at(i); }
-        const T& operator[](size_t i) const { return at(i); }
-
-        T* data() { return m_buffer.buffer(); }
-        const T* data() const { return m_buffer.buffer(); }
-
-        iterator begin() { return data(); }
-        iterator end() { return begin() + m_size; }
-        const_iterator begin() const { return data(); }
-        const_iterator end() const { return begin() + m_size; }
-        
-        T& first() { return at(0); }
-        const T& first() const { return at(0); }
-        T& last() { return at(size() - 1); }
-        const T& last() const { return at(size() - 1); }
-
-        void shrink(size_t size);
-        void grow(size_t size);
-        void resize(size_t size);
-        void reserveCapacity(size_t newCapacity);
-
-        void clear() { if (m_size) shrink(0); }
-
-        template<typename U> void append(const U*, size_t);
-        template<typename U> void append(const U&);
-        template<typename U> void uncheckedAppend(const U& val);
-        template<typename U, size_t c> void append(const Vector<U, c>&);
-
-        template<typename U> void insert(size_t position, const U*, size_t);
-        template<typename U> void insert(size_t position, const U&);
-        template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&);
-
-        template<typename U> void prepend(const U*, size_t);
-        template<typename U> void prepend(const U&);
-        template<typename U, size_t c> void prepend(const Vector<U, c>&);
-
-        void remove(size_t position);
-
-        void removeLast() 
-        {
-            ASSERT(!isEmpty());
-            shrink(size() - 1); 
-        }
-
-        Vector(size_t size, const T& val)
-            : m_size(size)
-            , m_buffer(size)
-        {
-            TypeOperations::uninitializedFill(begin(), end(), val);
-        }
-
-        void fill(const T&, size_t);
-        void fill(const T& val) { fill(val, size()); }
-
-        template<typename Iterator> void appendRange(Iterator start, Iterator end);
-
-        T* releaseBuffer();
-
-        void swap(Vector<T, inlineCapacity>& other)
-        {
-            std::swap(m_size, other.m_size);
-            m_buffer.swap(other.m_buffer);
-        }
-
-    private:
-        void expandCapacity(size_t newMinCapacity);
-        const T* expandCapacity(size_t newMinCapacity, const T*);
-        template<typename U> U* expandCapacity(size_t newMinCapacity, U*); 
-
-        size_t m_size;
-        Buffer m_buffer;
-    };
-
-    template<typename T, size_t inlineCapacity>
-    Vector<T, inlineCapacity>::Vector(const Vector& other)
-        : m_size(other.size())
-        , m_buffer(other.capacity())
+private:
+    typedef VectorBuffer<T, inlineCapacity> Buffer;
+    typedef VectorTypeOperations<T> TypeOperations;
+    
+public:
+    typedef T ValueType;
+    
+    typedef T* iterator;
+    typedef const T* const_iterator;
+    
+    Vector() 
+    : m_size(0)
     {
-        TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
     }
-
-    template<typename T, size_t inlineCapacity>
-    template<size_t otherCapacity> 
-    Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other)
-        : m_size(other.size())
-        , m_buffer(other.capacity())
+    
+    explicit Vector(size_t size) 
+    : m_size(size)
+    , m_buffer(size)
     {
-        TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
+        if (begin())
+            TypeOperations::initialize(begin(), end());
     }
-
-    template<typename T, size_t inlineCapacity>
-    Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other)
+    
+    ~Vector()
     {
-        if (&other == this)
-            return *this;
-        
-        if (size() > other.size())
-            shrink(other.size());
-        else if (other.size() > capacity()) {
-            clear();
-            reserveCapacity(other.size());
-        }
-        
-        std::copy(other.begin(), other.begin() + size(), begin());
-        TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
-        m_size = other.size();
-
-        return *this;
+        if (m_size) shrink(0);
     }
-
-    template<typename T, size_t inlineCapacity>
+    
+    Vector(const Vector&);
     template<size_t otherCapacity> 
-    Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other)
-    {
-        if (&other == this)
-            return *this;
-        
-        if (size() > other.size())
-            shrink(other.size());
-        else if (other.size() > capacity()) {
-            clear();
-            reserveCapacity(other.size());
-        }
-        
-        std::copy(other.begin(), other.begin() + size(), begin());
-        TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
-        m_size = other.size();
-
-        return *this;
+    Vector(const Vector<T, otherCapacity>&);
+    
+    Vector& operator=(const Vector&);
+    template<size_t otherCapacity> 
+    Vector& operator=(const Vector<T, otherCapacity>&);
+    
+    size_t size() const { return m_size; }
+    size_t capacity() const { return m_buffer.capacity(); }
+    bool isEmpty() const { return !size(); }
+    
+    T& at(size_t i) 
+    { 
+        ASSERT(i < size());
+        return m_buffer.buffer()[i]; 
     }
-
-    template<typename T, size_t inlineCapacity>
-    void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize)
+    const T& at(size_t i) const 
     {
-        if (size() > newSize)
-            shrink(newSize);
-        else if (newSize > capacity()) {
-            clear();
-            reserveCapacity(newSize);
-        }
-        
-        std::fill(begin(), end(), val);
-        TypeOperations::uninitializedFill(end(), begin() + newSize, val);
-        m_size = newSize;
+        ASSERT(i < size());
+        return m_buffer.buffer()[i]; 
     }
-
-    template<typename T, size_t inlineCapacity>
-    template<typename Iterator>
-    void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end)
+    
+    T& operator[](size_t i) { return at(i); }
+    const T& operator[](size_t i) const { return at(i); }
+    
+    T* data() { return m_buffer.buffer(); }
+    const T* data() const { return m_buffer.buffer(); }
+    T** dataSlot() { return m_buffer.bufferSlot(); }
+    
+    iterator begin() { return data(); }
+    iterator end() { return begin() + m_size; }
+    const_iterator begin() const { return data(); }
+    const_iterator end() const { return begin() + m_size; }
+    
+    T& first() { return at(0); }
+    const T& first() const { return at(0); }
+    T& last() { return at(size() - 1); }
+    const T& last() const { return at(size() - 1); }
+    
+    template<typename U> size_t find(const U&) const;
+    
+    void shrink(size_t size);
+    void grow(size_t size);
+    void resize(size_t size);
+    void reserveCapacity(size_t newCapacity);
+    void shrinkCapacity(size_t newCapacity);
+    void shrinkToFit() { shrinkCapacity(size()); }
+    
+    void clear() { shrinkCapacity(0); }
+    
+    template<typename U> void append(const U*, size_t);
+    template<typename U> void append(const U&);
+    template<typename U> void uncheckedAppend(const U& val);
+    template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&);
+    
+    template<typename U> void insert(size_t position, const U*, size_t);
+    template<typename U> void insert(size_t position, const U&);
+    template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&);
+    
+    template<typename U> void prepend(const U*, size_t);
+    template<typename U> void prepend(const U&);
+    template<typename U, size_t c> void prepend(const Vector<U, c>&);
+    
+    void remove(size_t position);
+    void remove(size_t position, size_t length);
+    
+    void removeLast() 
     {
-        for (Iterator it = start; it != end; ++it)
-            append(*it);
+        ASSERT(!isEmpty());
+        shrink(size() - 1); 
     }
-
-    template<typename T, size_t inlineCapacity>
-    void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
+    
+    Vector(size_t size, const T& val)
+    : m_size(size)
+    , m_buffer(size)
     {
-        reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
+        if (begin())
+            TypeOperations::uninitializedFill(begin(), end(), val);
     }
     
-    template<typename T, size_t inlineCapacity>
-    const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr)
+    void fill(const T&, size_t);
+    void fill(const T& val) { fill(val, size()); }
+    
+    template<typename Iterator> void appendRange(Iterator start, Iterator end);
+    
+    T* releaseBuffer();
+    
+    void swap(Vector<T, inlineCapacity>& other)
     {
-        if (ptr < begin() || ptr >= end()) {
-            expandCapacity(newMinCapacity);
-            return ptr;
-        }
-        size_t index = ptr - begin();
-        expandCapacity(newMinCapacity);
-        return begin() + index;
+        std::swap(m_size, other.m_size);
+        m_buffer.swap(other.m_buffer);
     }
+    
+private:
+    void expandCapacity(size_t newMinCapacity);
+    const T* expandCapacity(size_t newMinCapacity, const T*);
+    template<typename U> U* expandCapacity(size_t newMinCapacity, U*); 
+    
+    size_t m_size;
+    Buffer m_buffer;
+};
+
+template<typename T, size_t inlineCapacity>
+Vector<T, inlineCapacity>::Vector(const Vector& other)
+: m_size(other.size())
+, m_buffer(other.capacity())
+{
+    if (begin())
+        TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
+}
+
+template<typename T, size_t inlineCapacity>
+template<size_t otherCapacity> 
+Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other)
+: m_size(other.size())
+, m_buffer(other.capacity())
+{
+    if (begin())
+        TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
+}
 
-    template<typename T, size_t inlineCapacity> template<typename U>
-    inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
-    {
+template<typename T, size_t inlineCapacity>
+Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other)
+{
+    if (&other == this)
+        return *this;
+    
+    if (size() > other.size())
+        shrink(other.size());
+    else if (other.size() > capacity()) {
+        clear();
+        reserveCapacity(other.size());
+        if (!begin())
+            return *this;
+    }
+    
+    std::copy(other.begin(), other.begin() + size(), begin());
+    TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
+    m_size = other.size();
+    
+    return *this;
+}
+
+template<typename T, size_t inlineCapacity>
+template<size_t otherCapacity> 
+Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other)
+{
+    if (&other == this)
+        return *this;
+    
+    if (size() > other.size())
+        shrink(other.size());
+    else if (other.size() > capacity()) {
+        clear();
+        reserveCapacity(other.size());
+        if (!begin())
+            return *this;
+    }
+    
+    std::copy(other.begin(), other.begin() + size(), begin());
+    TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
+    m_size = other.size();
+    
+    return *this;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize)
+{
+    if (size() > newSize)
+        shrink(newSize);
+    else if (newSize > capacity()) {
+        clear();
+        reserveCapacity(newSize);
+        if (!begin())
+            return;
+    }
+    
+    std::fill(begin(), end(), val);
+    TypeOperations::uninitializedFill(end(), begin() + newSize, val);
+    m_size = newSize;
+}
+
+template<typename T, size_t inlineCapacity>
+template<typename Iterator>
+void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end)
+{
+    for (Iterator it = start; it != end; ++it)
+        append(*it);
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
+{
+    reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
+}
+
+template<typename T, size_t inlineCapacity>
+const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr)
+{
+    if (ptr < begin() || ptr >= end()) {
         expandCapacity(newMinCapacity);
         return ptr;
     }
-
-    template<typename T, size_t inlineCapacity>
-    void Vector<T, inlineCapacity>::resize(size_t size)
-    {
-        if (size <= m_size)
-            TypeOperations::destruct(begin() + size, end());
-        else {
-            if (size > capacity())
-                expandCapacity(size);
-            TypeOperations::initialize(end(), begin() + size);
-        }
-        
-        m_size = size;
-    }
-
-    template<typename T, size_t inlineCapacity>
-    void Vector<T, inlineCapacity>::shrink(size_t size)
-    {
-        ASSERT(size <= m_size);
+    size_t index = ptr - begin();
+    expandCapacity(newMinCapacity);
+    return begin() + index;
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
+{
+    expandCapacity(newMinCapacity);
+    return ptr;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::resize(size_t size)
+{
+    if (size <= m_size)
         TypeOperations::destruct(begin() + size, end());
-        m_size = size;
-    }
-
-    template<typename T, size_t inlineCapacity>
-    void Vector<T, inlineCapacity>::grow(size_t size)
-    {
-        ASSERT(size >= m_size);
+    else {
         if (size > capacity())
             expandCapacity(size);
-        TypeOperations::initialize(end(), begin() + size);
-        m_size = size;
+        if (begin())
+            TypeOperations::initialize(end(), begin() + size);
     }
-
-    template<typename T, size_t inlineCapacity>
-    void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity)
-    {
-        if (newCapacity <= capacity())
-            return;
-        T* oldBuffer = begin();
+    
+    m_size = size;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::shrink(size_t size)
+{
+    ASSERT(size <= m_size);
+    TypeOperations::destruct(begin() + size, end());
+    m_size = size;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::grow(size_t size)
+{
+    ASSERT(size >= m_size);
+    if (size > capacity())
+        expandCapacity(size);
+    if (begin())
+        TypeOperations::initialize(end(), begin() + size);
+    m_size = size;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity)
+{
+    if (newCapacity <= capacity())
+        return;
+    T* oldBuffer = begin();
+    T* oldEnd = end();
+    m_buffer.allocateBuffer(newCapacity);
+    if (begin())
+        TypeOperations::move(oldBuffer, oldEnd, begin());
+    m_buffer.deallocateBuffer(oldBuffer);
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity)
+{
+    if (newCapacity >= capacity())
+        return;
+    
+    if (newCapacity < size()) 
+        shrink(newCapacity);
+    
+    T* oldBuffer = begin();
+    if (newCapacity > 0) {
         T* oldEnd = end();
         m_buffer.allocateBuffer(newCapacity);
-        TypeOperations::move(oldBuffer, oldEnd, begin());
-        m_buffer.deallocateBuffer(oldBuffer);
+        if (begin() != oldBuffer)
+            TypeOperations::move(oldBuffer, oldEnd, begin());
     }
-
-    // Templatizing these is better than just letting the conversion happen implicitly,
-    // because for instance it allows a PassRefPtr to be appended to a RefPtr vector
-    // without refcount thrash.
-
-    template<typename T, size_t inlineCapacity> template<typename U>
-    void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize)
-    {
-        size_t newSize = m_size + dataSize;
-        if (newSize > capacity())
-            data = expandCapacity(newSize, data);
-        T* dest = end();
-        for (size_t i = 0; i < dataSize; ++i)
-            new (&dest[i]) T(data[i]);
-        m_size = newSize;
+    
+    m_buffer.deallocateBuffer(oldBuffer);
+    m_buffer.restoreInlineBufferIfNeeded();
+}
+
+// Templatizing these is better than just letting the conversion happen implicitly,
+// because for instance it allows a PassRefPtr to be appended to a RefPtr vector
+// without refcount thrash.
+
+template<typename T, size_t inlineCapacity> template<typename U>
+void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize)
+{
+    size_t newSize = m_size + dataSize;
+    if (newSize > capacity()) {
+        data = expandCapacity(newSize, data);
+        if (!begin())
+            return;
     }
-
-    template<typename T, size_t inlineCapacity> template<typename U>
-    inline void Vector<T, inlineCapacity>::append(const U& val)
-    {
-        const U* ptr = &val;
-        if (size() == capacity())
-            ptr = expandCapacity(size() + 1, ptr);
-            
+    T* dest = end();
+    for (size_t i = 0; i < dataSize; ++i)
+        new (&dest[i]) T(data[i]);
+    m_size = newSize;
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline void Vector<T, inlineCapacity>::append(const U& val)
+{
+    const U* ptr = &val;
+    if (size() == capacity()) {
+        ptr = expandCapacity(size() + 1, ptr);
+        if (!begin())
+            return;
+    }
+    
 #if COMPILER(MSVC7)
-        // FIXME: MSVC7 generates compilation errors when trying to assign
-        // a pointer to a Vector of its base class (i.e. can't downcast). So far
-        // I've been unable to determine any logical reason for this, so I can
-        // only assume it is a bug with the compiler. Casting is a bad solution,
-        // however, because it subverts implicit conversions, so a better 
-        // one is needed. 
-        new (end()) T(static_cast<T>(*ptr));
+    // FIXME: MSVC7 generates compilation errors when trying to assign
+    // a pointer to a Vector of its base class (i.e. can't downcast). So far
+    // I've been unable to determine any logical reason for this, so I can
+    // only assume it is a bug with the compiler. Casting is a bad solution,
+    // however, because it subverts implicit conversions, so a better 
+    // one is needed. 
+    new (end()) T(static_cast<T>(*ptr));
 #else
-        new (end()) T(*ptr);
+    new (end()) T(*ptr);
 #endif
-        ++m_size;
-    }
-
-    // This version of append saves a branch in the case where you know that the
-    // vector's capacity is large enough for the append to succeed.
-
-    template<typename T, size_t inlineCapacity> template<typename U>
-    inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val)
-    {
-        ASSERT(size() < capacity());
-        const U* ptr = &val;
-        new (end()) T(*ptr);
-        ++m_size;
-    }
-
-    template<typename T, size_t inlineCapacity> template<typename U, size_t c>
-    inline void Vector<T, inlineCapacity>::append(const Vector<U, c>& val)
-    {
-        append(val.begin(), val.size());
-    }
-
-    template<typename T, size_t inlineCapacity> template<typename U>
-    void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize)
-    {
-        ASSERT(position <= size());
-        size_t newSize = m_size + dataSize;
-        if (newSize > capacity())
-            data = expandCapacity(newSize, data);
-        T* spot = begin() + position;
-        TypeOperations::moveOverlapping(spot, end(), spot + dataSize);
-        for (size_t i = 0; i < dataSize; ++i)
-            new (&spot[i]) T(data[i]);
-        m_size = newSize;
-    }
-     
-    template<typename T, size_t inlineCapacity> template<typename U>
-    inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val)
-    {
-        ASSERT(position <= size());
-        const U* data = &val;
-        if (size() == capacity())
-            data = expandCapacity(size() + 1, data);
-        T* spot = begin() + position;
-        TypeOperations::moveOverlapping(spot, end(), spot + 1);
-        new (spot) T(*data);
-        ++m_size;
-    }
-   
-    template<typename T, size_t inlineCapacity> template<typename U, size_t c>
-    inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val)
-    {
-        insert(position, val.begin(), val.size());
-    }
-
-    template<typename T, size_t inlineCapacity> template<typename U>
-    void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize)
-    {
-        insert(0, data, dataSize);
+    ++m_size;
+}
+
+// This version of append saves a branch in the case where you know that the
+// vector's capacity is large enough for the append to succeed.
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val)
+{
+    ASSERT(size() < capacity());
+    const U* ptr = &val;
+    new (end()) T(*ptr);
+    ++m_size;
+}
+
+// This method should not be called append, a better name would be appendElements.
+// It could also be eliminated entirely, and call sites could just use
+// appendRange(val.begin(), val.end()).
+template<typename T, size_t inlineCapacity> template<size_t otherCapacity>
+inline void Vector<T, inlineCapacity>::append(const Vector<T, otherCapacity>& val)
+{
+    append(val.begin(), val.size());
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize)
+{
+    ASSERT(position <= size());
+    size_t newSize = m_size + dataSize;
+    if (newSize > capacity()) {
+        data = expandCapacity(newSize, data);
+        if (!begin())
+            return;
     }
-
-    template<typename T, size_t inlineCapacity> template<typename U>
-    inline void Vector<T, inlineCapacity>::prepend(const U& val)
-    {
-        insert(0, val);
+    T* spot = begin() + position;
+    TypeOperations::moveOverlapping(spot, end(), spot + dataSize);
+    for (size_t i = 0; i < dataSize; ++i)
+        new (&spot[i]) T(data[i]);
+    m_size = newSize;
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val)
+{
+    ASSERT(position <= size());
+    const U* data = &val;
+    if (size() == capacity()) {
+        data = expandCapacity(size() + 1, data);
+        if (!begin())
+            return;
     }
-   
-    template<typename T, size_t inlineCapacity> template<typename U, size_t c>
-    inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val)
-    {
-        insert(0, val.begin(), val.size());
+    T* spot = begin() + position;
+    TypeOperations::moveOverlapping(spot, end(), spot + 1);
+    new (spot) T(*data);
+    ++m_size;
+}
+
+template<typename T, size_t inlineCapacity> template<typename U, size_t c>
+inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val)
+{
+    insert(position, val.begin(), val.size());
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize)
+{
+    insert(0, data, dataSize);
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline void Vector<T, inlineCapacity>::prepend(const U& val)
+{
+    insert(0, val);
+}
+
+template<typename T, size_t inlineCapacity> template<typename U, size_t c>
+inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val)
+{
+    insert(0, val.begin(), val.size());
+}
+
+template<typename T, size_t inlineCapacity>
+inline void Vector<T, inlineCapacity>::remove(size_t position)
+{
+    ASSERT(position < size());
+    T* spot = begin() + position;
+    spot->~T();
+    TypeOperations::moveOverlapping(spot + 1, end(), spot);
+    --m_size;
+}
+
+template<typename T, size_t inlineCapacity>
+inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length)
+{
+    ASSERT(position < size());
+    ASSERT(position + length < size());
+    T* beginSpot = begin() + position;
+    T* endSpot = beginSpot + length;
+    TypeOperations::destruct(beginSpot, endSpot); 
+    TypeOperations::moveOverlapping(endSpot, end(), beginSpot);
+    m_size -= length;
+}
+
+template<typename T, size_t inlineCapacity>
+inline T* Vector<T, inlineCapacity>::releaseBuffer()
+{
+    T* buffer = m_buffer.releaseBuffer();
+    if (inlineCapacity && !buffer && m_size) {
+        // If the vector had some data, but no buffer to release,
+        // that means it was using the inline buffer. In that case,
+        // we create a brand new buffer so the caller always gets one.
+        size_t bytes = m_size * sizeof(T);
+        buffer = static_cast<T*>(fastMalloc(bytes));
+        memcpy(buffer, data(), bytes);
     }
+    m_size = 0;
+    return buffer;
+}
+
+template<typename T, size_t inlineCapacity>
+void deleteAllValues(const Vector<T, inlineCapacity>& collection)
+{
+    typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
+    iterator end = collection.end();
+    for (iterator it = collection.begin(); it != end; ++it)
+        delete *it;
+}
+
+template<typename T, size_t inlineCapacity>
+inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b)
+{
+    a.swap(b);
+}
+
+template<typename T, size_t inlineCapacity>
+bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
+{
+    if (a.size() != b.size())
+        return false;
     
-    template<typename T, size_t inlineCapacity>
-    inline void Vector<T, inlineCapacity>::remove(size_t position)
-    {
-        ASSERT(position < size());
-        T* spot = begin() + position;
-        spot->~T();
-        TypeOperations::moveOverlapping(spot + 1, end(), spot);
-        --m_size;
-    }
-
-    template<typename T, size_t inlineCapacity>
-    inline T* Vector<T, inlineCapacity>::releaseBuffer()
-    {
-        T* buffer = m_buffer.releaseBuffer();
-        if (inlineCapacity && !buffer && m_size) {
-            // If the vector had some data, but no buffer to release,
-            // that means it was using the inline buffer. In that case,
-            // we create a brand new buffer so the caller always gets one.
-            size_t bytes = m_size * sizeof(T);
-            buffer = static_cast<T*>(fastMalloc(bytes));
-            memcpy(buffer, data(), bytes);
-        }
-        ASSERT(buffer);
-        m_size = 0;
-        return buffer;
-    }
-
-    template<typename T, size_t inlineCapacity>
-    void deleteAllValues(const Vector<T, inlineCapacity>& collection)
-    {
-        typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
-        iterator end = collection.end();
-        for (iterator it = collection.begin(); it != end; ++it)
-            delete *it;
-    }
-
-    template<typename T, size_t inlineCapacity>
-    inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b)
-    {
-        a.swap(b);
-    }
-
-    template<typename T, size_t inlineCapacity>
-    bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
-    {
-        if (a.size() != b.size())
-            return false;
-
-        return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size());
-    }
-
-    template<typename T, size_t inlineCapacity>
-    inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
-    {
-        return !(a == b);
-    }
+    return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size());
+}
+
+template<typename T, size_t inlineCapacity>
+inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
+{
+    return !(a == b);
+}
 
 
 } // namespace WTF