From: Apple Date: Thu, 18 Dec 2008 00:04:33 +0000 (+0000) Subject: JavaScriptCore-466.1.6.tar.gz X-Git-Tag: iphone-221^0 X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/commitdiff_plain/b5422865f473faf3977f31b96a635c4c8c4ede09 JavaScriptCore-466.1.6.tar.gz --- diff --git a/API/JSBase.cpp b/API/JSBase.cpp index d8acc42..65f2128 100644 --- a/API/JSBase.cpp +++ b/API/JSBase.cpp @@ -28,6 +28,7 @@ #include "JSBase.h" #include "APICast.h" +#include "SourceCode.h" #include #include #include @@ -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()); diff --git a/JavaScriptCore.exp b/JavaScriptCore.exp index 3ee8f3b..123f80e 100644 --- a/JavaScriptCore.exp +++ b/JavaScriptCore.exp @@ -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 diff --git a/bindings/NP_jsobject.cpp b/bindings/NP_jsobject.cpp index d68a8e6..f334624 100644 --- a/bindings/NP_jsobject.cpp +++ b/bindings/NP_jsobject.cpp @@ -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(scriptString), UTF16Length)); + + SourceCode source = makeSource(UString(reinterpret_cast(scriptString), UTF16Length), UString()); + Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), source); rootObject->globalObject()->stopTimeoutCheck(); ComplType type = completion.complType(); diff --git a/bindings/jni/jni_jsobject.cpp b/bindings/jni/jni_jsobject.cpp index fe2e9e3..a16c640 100644 --- a/bindings/jni/jni_jsobject.cpp +++ b/bindings/jni/jni_jsobject.cpp @@ -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(); diff --git a/bindings/make_testbindings b/bindings/make_testbindings old mode 100644 new mode 100755 diff --git a/kjs/Parser.cpp b/kjs/Parser.cpp index c6d7265..7a63d8e 100644 --- a/kjs/Parser.cpp +++ b/kjs/Parser.cpp @@ -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* varStack, ParserRefCountedData* funcStack, int lastLine) { diff --git a/kjs/Parser.h b/kjs/Parser.h index 92548fe..8821186 100644 --- a/kjs/Parser.h +++ b/kjs/Parser.h @@ -25,11 +25,12 @@ #ifndef Parser_h #define Parser_h +#include "SourceProvider.h" +#include "nodes.h" #include #include #include #include -#include "nodes.h" namespace KJS { @@ -45,26 +46,20 @@ namespace KJS { class Parser : Noncopyable { public: - template - PassRefPtr 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 PassRefPtr parse(PassRefPtr, int* errLine = 0, UString* errMsg = 0); + template PassRefPtr parse(const SourceCode&, int* errLine = 0, UString* errMsg = 0); void didFinishParsing(SourceElements*, ParserRefCountedData*, ParserRefCountedData*, 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 m_sourceElements; RefPtr > m_varDeclarations; RefPtr > m_funcDeclarations; @@ -73,25 +68,24 @@ namespace KJS { Parser& parser(); // Returns the singleton JavaScript parser. - template - PassRefPtr Parser::parse(const UString& sourceURL, int startingLineNumber, - const UChar* code, unsigned length, - int* sourceId, int* errLine, UString* errMsg) + template PassRefPtr 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 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 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 index 0000000..dba674f --- /dev/null +++ b/kjs/SourceCode.h @@ -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 + +namespace KJS { + + class SourceCode { + public: + SourceCode() + : m_startChar(0) + , m_endChar(0) + , m_firstLine(0) + { + } + + SourceCode(PassRefPtr provider, int firstLine = 0) + : m_provider(provider) + , m_startChar(0) + , m_endChar(m_provider->length()) + , m_firstLine(firstLine + 1) + { + } + + SourceCode(PassRefPtr 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 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 index 0000000..65c8cb4 --- /dev/null +++ b/kjs/SourceProvider.h @@ -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 + +namespace KJS { + + class SourceProvider : public RefCounted { + 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(this); } + + private: + UString m_url; + }; + + class UStringSourceProvider : public SourceProvider { + public: + static PassRefPtr 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 diff --git a/kjs/config.h b/kjs/config.h index f60561e..2545bf6 100644 --- a/kjs/config.h +++ b/kjs/config.h @@ -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 diff --git a/kjs/create_hash_table b/kjs/create_hash_table old mode 100644 new mode 100755 diff --git a/kjs/debugger.cpp b/kjs/debugger.cpp index af9c5fa..9e69b2c 100644 --- a/kjs/debugger.cpp +++ b/kjs/debugger.cpp @@ -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; diff --git a/kjs/debugger.h b/kjs/debugger.h index 2d5cb6f..6aa15e2 100644 --- a/kjs/debugger.h +++ b/kjs/debugger.h @@ -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: diff --git a/kjs/function.cpp b/kjs/function.cpp index 9f1b62c..92b3446 100644 --- a/kjs/function.cpp +++ b/kjs/function.cpp @@ -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 = parser().parse(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 = parser().parse(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(); diff --git a/kjs/function_object.cpp b/kjs/function_object.cpp index 5af2970..38b72f2 100644 --- a/kjs/function_object.cpp +++ b/kjs/function_object.cpp @@ -162,27 +162,18 @@ JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args, const } // parse the source code - int sourceId; int errLine; UString errMsg; - RefPtr functionBody = parser().parse(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 functionBody = parser().parse(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()); diff --git a/kjs/grammar.y b/kjs/grammar.y index 658ae89..4252d02 100644 --- a/kjs/grammar.y +++ b/kjs/grammar.y @@ -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>= and >>>= */ %token ANDEQUAL MODEQUAL /* &= and %= */ %token XOREQUAL OREQUAL /* ^= and |= */ +%token OPENBRACE /* { (with char offset) */ +%token CLOSEBRACE /* { (with char offset) */ /* terminal types */ %token 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(new BlockNode(0), 0, 0); + OPENBRACE CLOSEBRACE { $$ = createNodeInfo(new BlockNode(0), 0, 0); DBG($$.m_node, @1, @2); } - | '{' SourceElements '}' { $$ = createNodeInfo(new BlockNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations); + | OPENBRACE SourceElements CLOSEBRACE { $$ = createNodeInfo(new BlockNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations); DBG($$.m_node, @1, @3); } ; @@ -913,8 +915,8 @@ SwitchStatement: ; CaseBlock: - '{' CaseClausesOpt '}' { $$ = createNodeInfo(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations); } - | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}' + OPENBRACE CaseClausesOpt CLOSEBRACE { $$ = createNodeInfo(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations); } + | OPENBRACE CaseClausesOpt DefaultClause CaseClausesOpt CLOSEBRACE { $$ = createNodeInfo(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($1, 0, new ParserRefCountedData); $$.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) diff --git a/kjs/interpreter.cpp b/kjs/interpreter.cpp index f7ea2c5..1ef21cf 100644 --- a/kjs/interpreter.cpp +++ b/kjs/interpreter.cpp @@ -54,29 +54,19 @@ 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 progNode = parser().parse(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg); + RefPtr progNode = parser().parse(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 progNode = parser().parse(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg); + RefPtr progNode = parser().parse(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) diff --git a/kjs/interpreter.h b/kjs/interpreter.h index 79b9398..0e67c6f 100644 --- a/kjs/interpreter.h +++ b/kjs/interpreter.h @@ -23,11 +23,14 @@ #ifndef KJS_Interpreter_h #define KJS_Interpreter_h +#include + 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); diff --git a/kjs/lexer.cpp b/kjs/lexer.cpp index dd4fcc4..18a117f 100644 --- a/kjs/lexer.cpp +++ b/kjs/lexer.cpp @@ -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(c1); + case '{': + charPos = pos - 4; + shift(1); + return OPENBRACE; + case '}': + charPos = pos - 4; + shift(1); + return CLOSEBRACE; default: return -1; } diff --git a/kjs/lexer.h b/kjs/lexer.h index 1ce27af..69b68b8 100644 --- a/kjs/lexer.h +++ b/kjs/lexer.h @@ -24,6 +24,7 @@ #ifndef Lexer_h #define Lexer_h +#include "SourceCode.h" #include "ustring.h" #include @@ -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& buffer); UString* makeUString(const Vector& 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 m_strings; Vector m_identifiers; diff --git a/kjs/nodes.cpp b/kjs/nodes.cpp index 16e6b1e..568e69f 100644 --- a/kjs/nodes.cpp +++ b/kjs/nodes.cpp @@ -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 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(); } diff --git a/kjs/nodes.h b/kjs/nodes.h index c0fe509..20a0a2c 100644 --- a/kjs/nodes.h +++ b/kjs/nodes.h @@ -28,6 +28,7 @@ #include "internal.h" #include "regexp.h" +#include "SourceCode.h" #include "SymbolTable.h" #include #include @@ -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(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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 m_expr; @@ -2865,7 +2877,7 @@ namespace KJS { BreakpointCheckStatement(PassRefPtr) 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: diff --git a/kjs/nodes2string.cpp b/kjs/nodes2string.cpp index b10e180..24c2d9d 100644 --- a/kjs/nodes2string.cpp +++ b/kjs/nodes2string.cpp @@ -60,7 +60,7 @@ public: SourceStream& operator<<(UnindentType); SourceStream& operator<<(DotExprType); SourceStream& operator<<(Precedence); - SourceStream& operator<<(const Node*); + SourceStream& operator<<(Node*); template SourceStream& operator<<(const RefPtr& 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 // -------- -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 >& 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; } diff --git a/kjs/object.cpp b/kjs/object.cpp index 8c6a154..d02af07 100644 --- a/kjs/object.cpp +++ b/kjs/object.cpp @@ -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; } diff --git a/kjs/object.h b/kjs/object.h index 3807bed..93cc0ac 100644 --- a/kjs/object.h +++ b/kjs/object.h @@ -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); diff --git a/kjs/testkjs.cpp b/kjs/testkjs.cpp index 25c807e..6a7607c 100644 --- a/kjs/testkjs.cpp +++ b/kjs/testkjs.cpp @@ -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& scrip { int errLine = 0; UString errMsg; - UString scriptUString(script.data()); - RefPtr programNode = parser().parse(fileName, 0, scriptUString.data(), scriptUString.size(), 0, &errLine, &errMsg); + + RefPtr programNode = parser().parse(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& 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; } } diff --git a/kjs/ustring.cpp b/kjs/ustring.cpp index 888eb2d..6f6add8 100644 --- a/kjs/ustring.cpp +++ b/kjs/ustring.cpp @@ -172,8 +172,6 @@ static int statBufferSize = 0; PassRefPtr UString::Rep::createCopying(const UChar *d, int l) { - ASSERT(JSLock::lockCount() > 0); - int sizeInBytes = l * sizeof(UChar); UChar *copyD = static_cast(fastMalloc(sizeInBytes)); memcpy(copyD, d, sizeInBytes); @@ -183,8 +181,6 @@ PassRefPtr UString::Rep::createCopying(const UChar *d, int l) PassRefPtr 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::create(UChar *d, int l) PassRefPtr UString::Rep::create(PassRefPtr base, int offset, int length) { - ASSERT(JSLock::lockCount() > 0); ASSERT(base); int baseOffset = base->offset; @@ -235,8 +230,6 @@ PassRefPtr UString::Rep::create(PassRefPtr base, int offset, void UString::Rep::destroy() { - ASSERT(JSLock::lockCount() > 0); - if (isIdentifier) Identifier::remove(this); if (baseString != this) { diff --git a/kjs/ustring.h b/kjs/ustring.h index 7faa86a..dba58d7 100644 --- a/kjs/ustring.h +++ b/kjs/ustring.h @@ -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; diff --git a/make-generated-sources.sh b/make-generated-sources.sh old mode 100644 new mode 100755 diff --git a/pcre/dftables b/pcre/dftables old mode 100644 new mode 100755 diff --git a/wtf/FastMalloc.cpp b/wtf/FastMalloc.cpp index f5f54f5..cae24ad 100644 --- a/wtf/FastMalloc.cpp +++ b/wtf/FastMalloc.cpp @@ -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(); } diff --git a/wtf/OwnPtrWin.cpp b/wtf/OwnPtrWin.cpp old mode 100644 new mode 100755 diff --git a/wtf/TCSystemAlloc.cpp b/wtf/TCSystemAlloc.cpp index 8140fd3..18a9fe5 100644 --- a/wtf/TCSystemAlloc.cpp +++ b/wtf/TCSystemAlloc.cpp @@ -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(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(new_start), new_end - new_start, + MS_KILLPAGES) == -1 && errno == EAGAIN) { // NOP } diff --git a/wtf/Vector.h b/wtf/Vector.h index cd6eced..d8c8e2e 100644 --- a/wtf/Vector.h +++ b/wtf/Vector.h @@ -1,4 +1,3 @@ -// -*- mode: c++; c-basic-offset: 4 -*- /* * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * @@ -32,19 +31,45 @@ #include 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 struct AlignedBuffer; + template struct AlignedBuffer { AlignedBufferChar buffer[size]; }; + template struct AlignedBuffer { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2); }; + template struct AlignedBuffer { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4); }; + template struct AlignedBuffer { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8); }; + template struct AlignedBuffer { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); }; + template struct AlignedBuffer { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); }; + template struct AlignedBuffer { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); }; + template class VectorDestructor; - + template struct VectorDestructor { static void destruct(T*, T*) {} }; - + template struct VectorDestructor { @@ -54,16 +79,16 @@ namespace WTF { cur->~T(); } }; - + template class VectorInitializer; - + template struct VectorInitializer { static void initialize(T*, T*) {} }; - + template struct VectorInitializer { @@ -73,7 +98,7 @@ namespace WTF { new (cur) T; } }; - + template struct VectorInitializer { @@ -82,10 +107,10 @@ namespace WTF { memset(begin, 0, reinterpret_cast(end) - reinterpret_cast(begin)); } }; - + template class VectorMover; - + template struct VectorMover { @@ -113,7 +138,7 @@ namespace WTF { } } }; - + template struct VectorMover { @@ -126,10 +151,10 @@ namespace WTF { memmove(dst, src, reinterpret_cast(srcEnd) - reinterpret_cast(src)); } }; - + template class VectorCopier; - + template struct VectorCopier { @@ -142,7 +167,7 @@ namespace WTF { } } }; - + template struct VectorCopier { @@ -151,10 +176,10 @@ namespace WTF { memcpy(dst, src, reinterpret_cast(srcEnd) - reinterpret_cast(src)); } }; - + template class VectorFiller; - + template struct VectorFiller { @@ -166,7 +191,7 @@ namespace WTF { } } }; - + template struct VectorFiller { @@ -191,7 +216,7 @@ namespace WTF { return true; } }; - + template struct VectorComparer { @@ -208,27 +233,27 @@ namespace WTF { { VectorDestructor::needsDestruction, T>::destruct(begin, end); } - + static void initialize(T* begin, T* end) { VectorInitializer::needsInitialization, VectorTraits::canInitializeWithMemset, T>::initialize(begin, end); } - + static void move(const T* src, const T* srcEnd, T* dst) { VectorMover::canMoveWithMemcpy, T>::move(src, srcEnd, dst); } - + static void moveOverlapping(const T* src, const T* srcEnd, T* dst) { VectorMover::canMoveWithMemcpy, T>::moveOverlapping(src, srcEnd, dst); } - + static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) { VectorCopier::canCopyWithMemcpy, T>::uninitializedCopy(src, srcEnd, dst); } - + static void uninitializedFill(T* dst, T* dstEnd, const T& val) { VectorFiller::canFillWithMemset, T>::uninitializedFill(dst, dstEnd, val); @@ -239,28 +264,32 @@ namespace WTF { return VectorComparer::canCompareWithMemcmp, T>::compare(a, b, size); } }; - + template class VectorBufferBase : Noncopyable { public: void allocateBuffer(size_t newCapacity) { - ASSERT(newCapacity >= m_capacity); m_capacity = newCapacity; if (newCapacity > std::numeric_limits::max() / sizeof(T)) CRASH(); m_buffer = static_cast(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 class VectorBuffer; - + template class VectorBuffer : private VectorBufferBase { 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 class VectorBuffer : private VectorBufferBase { private: typedef VectorBufferBase 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((void*)((&m_inlineBuffer))); } - - __attribute__ ((aligned (4))) char m_inlineBuffer[m_inlineBufferSize]; -#else - T* inlineBuffer() { return reinterpret_cast(&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(m_inlineBuffer.buffer); } + + AlignedBuffer m_inlineBuffer; }; - + template class Vector { - private: - typedef VectorBuffer Buffer; - typedef VectorTypeOperations 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 - Vector(const Vector&); - - Vector& operator=(const Vector&); - template - Vector& operator=(const Vector&); - - 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 void append(const U*, size_t); - template void append(const U&); - template void uncheckedAppend(const U& val); - template void append(const Vector&); - - template void insert(size_t position, const U*, size_t); - template void insert(size_t position, const U&); - template void insert(size_t position, const Vector&); - - template void prepend(const U*, size_t); - template void prepend(const U&); - template void prepend(const Vector&); - - 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 void appendRange(Iterator start, Iterator end); - - T* releaseBuffer(); - - void swap(Vector& 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 U* expandCapacity(size_t newMinCapacity, U*); - - size_t m_size; - Buffer m_buffer; - }; - - template - Vector::Vector(const Vector& other) - : m_size(other.size()) - , m_buffer(other.capacity()) +private: + typedef VectorBuffer Buffer; + typedef VectorTypeOperations 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 - template - Vector::Vector(const Vector& 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 - Vector& Vector::operator=(const Vector& 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 + + Vector(const Vector&); template - Vector& Vector::operator=(const Vector& 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&); + + Vector& operator=(const Vector&); + template + Vector& operator=(const Vector&); + + 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 - void Vector::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 - template - void Vector::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 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 void append(const U*, size_t); + template void append(const U&); + template void uncheckedAppend(const U& val); + template void append(const Vector&); + + template void insert(size_t position, const U*, size_t); + template void insert(size_t position, const U&); + template void insert(size_t position, const Vector&); + + template void prepend(const U*, size_t); + template void prepend(const U&); + template void prepend(const Vector&); + + 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 - void Vector::expandCapacity(size_t newMinCapacity) + + Vector(size_t size, const T& val) + : m_size(size) + , m_buffer(size) { - reserveCapacity(max(newMinCapacity, max(static_cast(16), capacity() + capacity() / 4 + 1))); + if (begin()) + TypeOperations::uninitializedFill(begin(), end(), val); } - template - const T* Vector::expandCapacity(size_t newMinCapacity, const T* ptr) + void fill(const T&, size_t); + void fill(const T& val) { fill(val, size()); } + + template void appendRange(Iterator start, Iterator end); + + T* releaseBuffer(); + + void swap(Vector& 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 U* expandCapacity(size_t newMinCapacity, U*); + + size_t m_size; + Buffer m_buffer; +}; + +template +Vector::Vector(const Vector& other) +: m_size(other.size()) +, m_buffer(other.capacity()) +{ + if (begin()) + TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); +} + +template +template +Vector::Vector(const Vector& other) +: m_size(other.size()) +, m_buffer(other.capacity()) +{ + if (begin()) + TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); +} - template template - inline U* Vector::expandCapacity(size_t newMinCapacity, U* ptr) - { +template +Vector& Vector::operator=(const Vector& 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 +template +Vector& Vector::operator=(const Vector& 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 +void Vector::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 +template +void Vector::appendRange(Iterator start, Iterator end) +{ + for (Iterator it = start; it != end; ++it) + append(*it); +} + +template +void Vector::expandCapacity(size_t newMinCapacity) +{ + reserveCapacity(max(newMinCapacity, max(static_cast(16), capacity() + capacity() / 4 + 1))); +} + +template +const T* Vector::expandCapacity(size_t newMinCapacity, const T* ptr) +{ + if (ptr < begin() || ptr >= end()) { expandCapacity(newMinCapacity); return ptr; } - - template - void Vector::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 - void Vector::shrink(size_t size) - { - ASSERT(size <= m_size); + size_t index = ptr - begin(); + expandCapacity(newMinCapacity); + return begin() + index; +} + +template template +inline U* Vector::expandCapacity(size_t newMinCapacity, U* ptr) +{ + expandCapacity(newMinCapacity); + return ptr; +} + +template +void Vector::resize(size_t size) +{ + if (size <= m_size) TypeOperations::destruct(begin() + size, end()); - m_size = size; - } - - template - void Vector::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 - void Vector::reserveCapacity(size_t newCapacity) - { - if (newCapacity <= capacity()) - return; - T* oldBuffer = begin(); + + m_size = size; +} + +template +void Vector::shrink(size_t size) +{ + ASSERT(size <= m_size); + TypeOperations::destruct(begin() + size, end()); + m_size = size; +} + +template +void Vector::grow(size_t size) +{ + ASSERT(size >= m_size); + if (size > capacity()) + expandCapacity(size); + if (begin()) + TypeOperations::initialize(end(), begin() + size); + m_size = size; +} + +template +void Vector::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 +void Vector::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 template - void Vector::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 template +void Vector::append(const U* data, size_t dataSize) +{ + size_t newSize = m_size + dataSize; + if (newSize > capacity()) { + data = expandCapacity(newSize, data); + if (!begin()) + return; } - - template template - inline void Vector::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 template +inline void Vector::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(*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(*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 template - inline void Vector::uncheckedAppend(const U& val) - { - ASSERT(size() < capacity()); - const U* ptr = &val; - new (end()) T(*ptr); - ++m_size; - } - - template template - inline void Vector::append(const Vector& val) - { - append(val.begin(), val.size()); - } - - template template - void Vector::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 template - inline void Vector::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 template - inline void Vector::insert(size_t position, const Vector& val) - { - insert(position, val.begin(), val.size()); - } - - template template - void Vector::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 template +inline void Vector::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 template +inline void Vector::append(const Vector& val) +{ + append(val.begin(), val.size()); +} + +template template +void Vector::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 template - inline void Vector::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 template +inline void Vector::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 template - inline void Vector::prepend(const Vector& val) - { - insert(0, val.begin(), val.size()); + T* spot = begin() + position; + TypeOperations::moveOverlapping(spot, end(), spot + 1); + new (spot) T(*data); + ++m_size; +} + +template template +inline void Vector::insert(size_t position, const Vector& val) +{ + insert(position, val.begin(), val.size()); +} + +template template +void Vector::prepend(const U* data, size_t dataSize) +{ + insert(0, data, dataSize); +} + +template template +inline void Vector::prepend(const U& val) +{ + insert(0, val); +} + +template template +inline void Vector::prepend(const Vector& val) +{ + insert(0, val.begin(), val.size()); +} + +template +inline void Vector::remove(size_t position) +{ + ASSERT(position < size()); + T* spot = begin() + position; + spot->~T(); + TypeOperations::moveOverlapping(spot + 1, end(), spot); + --m_size; +} + +template +inline void Vector::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 +inline T* Vector::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(fastMalloc(bytes)); + memcpy(buffer, data(), bytes); } + m_size = 0; + return buffer; +} + +template +void deleteAllValues(const Vector& collection) +{ + typedef typename Vector::const_iterator iterator; + iterator end = collection.end(); + for (iterator it = collection.begin(); it != end; ++it) + delete *it; +} + +template +inline void swap(Vector& a, Vector& b) +{ + a.swap(b); +} + +template +bool operator==(const Vector& a, const Vector& b) +{ + if (a.size() != b.size()) + return false; - template - inline void Vector::remove(size_t position) - { - ASSERT(position < size()); - T* spot = begin() + position; - spot->~T(); - TypeOperations::moveOverlapping(spot + 1, end(), spot); - --m_size; - } - - template - inline T* Vector::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(fastMalloc(bytes)); - memcpy(buffer, data(), bytes); - } - ASSERT(buffer); - m_size = 0; - return buffer; - } - - template - void deleteAllValues(const Vector& collection) - { - typedef typename Vector::const_iterator iterator; - iterator end = collection.end(); - for (iterator it = collection.begin(); it != end; ++it) - delete *it; - } - - template - inline void swap(Vector& a, Vector& b) - { - a.swap(b); - } - - template - bool operator==(const Vector& a, const Vector& b) - { - if (a.size() != b.size()) - return false; - - return VectorTypeOperations::compare(a.data(), b.data(), a.size()); - } - - template - inline bool operator!=(const Vector& a, const Vector& b) - { - return !(a == b); - } + return VectorTypeOperations::compare(a.data(), b.data(), a.size()); +} + +template +inline bool operator!=(const Vector& a, const Vector& b) +{ + return !(a == b); +} } // namespace WTF