#include "JSBase.h"
#include "APICast.h"
+#include "SourceCode.h"
#include <kjs/ExecState.h>
#include <kjs/JSGlobalObject.h>
#include <kjs/JSLock.h>
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)
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());
__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
__ZN3KJS6JSLock6unlockEv
__ZN3KJS6JSLock9lockCountEv
__ZN3KJS6Lookup9findEntryEPKNS_9HashTableERKNS_10IdentifierE
-__ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE
+__ZN3KJS6Parser5parseEPiPNS_7UStringE
__ZN3KJS6parserEv
__ZN3KJS7CStringD1Ev
__ZN3KJS7UString3Rep4nullE
__ZN3KJS8Bindings8Instance19createRuntimeObjectEPS1_
__ZN3KJS8Bindings8Instance21setDidExecuteFunctionEPFvPNS_9ExecStateEPNS_8JSObjectEE
__ZN3KJS8Bindings8Instance32createBindingForLanguageInstanceENS1_15BindingLanguageEPvN3WTF10PassRefPtrINS0_10RootObjectEEE
-__ZN3KJS8Debugger12sourceUnusedEPNS_9ExecStateEi
__ZN3KJS8Debugger6attachEPNS_14JSGlobalObjectE
-__ZN3KJS8Debugger9exceptionEPNS_9ExecStateEiiPNS_7JSValueE
+__ZN3KJS8Debugger12sourceUnusedEPNS_9ExecStateEl
__ZN3KJS8DebuggerC2Ev
__ZN3KJS8DebuggerD2Ev
__ZN3KJS8JSObject11hasInstanceEPNS_9ExecStateEPNS_7JSValueE
__ZNK3KJS19InternalFunctionImp14implementsCallEv
__ZNK3KJS19InternalFunctionImp21implementsHasInstanceEv
__ZNK3KJS4List8getSliceEiRS0_
-__ZNK3KJS4Node8toStringEv
+__ZN3KJS4Node8toStringEv
__ZNK3KJS6JSCell17getTruncatedInt32ERi
__ZNK3KJS6JSCell18getTruncatedUInt32ERj
__ZNK3KJS6JSCell9getNumberERd
__ZNK3KJS7UString14toStrictUInt32EPb
__ZNK3KJS7UString5asciiEv
__ZNK3KJS7UString6is8BitEv
+__ZNK3KJS7UString6substrEii
__ZNK3KJS7UString8toUInt32EPb
__ZNK3KJS7UString8toUInt32EPbb
__ZNK3KJS8Bindings10RootObject12globalObjectEv
#include "JSGlobalObject.h"
#include "PropertyNameArray.h"
+#include "SourceCode.h"
#include "c_utility.h"
#include "interpreter.h"
#include "npruntime_impl.h"
unsigned int UTF16Length;
convertNPStringToUTF16(s, &scriptString, &UTF16Length); // requires free() of returned memory
rootObject->globalObject()->startTimeoutCheck();
- Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), UString(), 0, UString(reinterpret_cast<const UChar*>(scriptString), UTF16Length));
+
+ SourceCode source = makeSource(UString(reinterpret_cast<const UChar*>(scriptString), UTF16Length), UString());
+ Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), source);
rootObject->globalObject()->stopTimeoutCheck();
ComplType type = completion.complType();
#if ENABLE(JAVA_BINDINGS)
+#include "SourceCode.h"
#include "identifier.h"
#include "internal.h"
#include "interpreter.h"
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();
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);
*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();
}
}
+void Parser::reparse(FunctionBodyNode* functionBodyNode)
+{
+ m_source = &functionBodyNode->source();
+ parse(0, 0);
+ ASSERT(m_sourceElements);
+
+ functionBodyNode->setData(m_sourceElements.get(),
+ m_varDeclarations ? &m_varDeclarations->data : 0,
+ m_funcDeclarations ? &m_funcDeclarations->data : 0);
+ functionBodyNode->setLoc(m_source->firstLine(), m_lastLine);
+
+ m_source = 0;
+ m_sourceElements = 0;
+ m_varDeclarations = 0;
+ m_funcDeclarations = 0;
+}
+
void Parser::didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack,
ParserRefCountedData<DeclarationStacks::FunctionStack>* funcStack, int lastLine)
{
#ifndef Parser_h
#define Parser_h
+#include "SourceProvider.h"
+#include "nodes.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
-#include "nodes.h"
namespace KJS {
class Parser : Noncopyable {
public:
- template <class ParsedNode>
- PassRefPtr<ParsedNode> parse(const UString& sourceURL, int startingLineNumber,
- const UChar* code, unsigned length,
- int* sourceId = 0, int* errLine = 0, UString* errMsg = 0);
-
- UString sourceURL() const { return m_sourceURL; }
- int sourceId() const { return m_sourceId; }
+ template <class ParsedNode> PassRefPtr<ParsedNode> parse(PassRefPtr<SourceProvider>, int* errLine = 0, UString* errMsg = 0);
+ template <class ParsedNode> PassRefPtr<ParsedNode> parse(const SourceCode&, int* errLine = 0, UString* errMsg = 0);
void didFinishParsing(SourceElements*, ParserRefCountedData<DeclarationStacks::VarStack>*,
ParserRefCountedData<DeclarationStacks::FunctionStack>*, int lastLine);
+ void reparse(FunctionBodyNode*);
+
private:
friend Parser& parser();
- Parser(); // Use parser() instead.
- void parse(int startingLineNumber, const UChar* code, unsigned length,
- int* sourceId, int* errLine, UString* errMsg);
+ void parse(int* errLine, UString* errMsg);
- UString m_sourceURL;
- int m_sourceId;
+ const SourceCode* m_source;
RefPtr<SourceElements> m_sourceElements;
RefPtr<ParserRefCountedData<DeclarationStacks::VarStack> > m_varDeclarations;
RefPtr<ParserRefCountedData<DeclarationStacks::FunctionStack> > m_funcDeclarations;
Parser& parser(); // Returns the singleton JavaScript parser.
- template <class ParsedNode>
- PassRefPtr<ParsedNode> Parser::parse(const UString& sourceURL, int startingLineNumber,
- const UChar* code, unsigned length,
- int* sourceId, int* errLine, UString* errMsg)
+ template <class ParsedNode> PassRefPtr<ParsedNode> Parser::parse(const SourceCode& source, int* errLine, UString* errMsg)
{
- m_sourceURL = sourceURL;
- parse(startingLineNumber, code, length, sourceId, errLine, errMsg);
- if (!m_sourceElements) {
- m_sourceURL = UString();
- return 0;
+ m_source = &source;
+ parse(errLine, errMsg);
+ RefPtr<ParsedNode> result;
+ if (m_sourceElements) {
+ result = ParsedNode::create(*m_source,
+ m_sourceElements.get(),
+ m_varDeclarations ? &m_varDeclarations->data : 0,
+ m_funcDeclarations ? &m_funcDeclarations->data : 0);
+ result->setLoc(m_source->firstLine(), m_lastLine);
}
- RefPtr<ParsedNode> node = ParsedNode::create(m_sourceElements.release().get(),
- m_varDeclarations ? &m_varDeclarations->data : 0,
- m_funcDeclarations ? &m_funcDeclarations->data : 0);
+
+ m_source = 0;
+ m_sourceElements = 0;
m_varDeclarations = 0;
m_funcDeclarations = 0;
- m_sourceURL = UString();
- node->setLoc(startingLineNumber, m_lastLine);
- return node.release();
+ return result.release();
}
} // namespace KJS
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SourceCode_h
+#define SourceCode_h
+
+#include "SourceProvider.h"
+#include <wtf/RefPtr.h>
+
+namespace KJS {
+
+ class SourceCode {
+ public:
+ SourceCode()
+ : m_startChar(0)
+ , m_endChar(0)
+ , m_firstLine(0)
+ {
+ }
+
+ SourceCode(PassRefPtr<SourceProvider> provider, int firstLine = 0)
+ : m_provider(provider)
+ , m_startChar(0)
+ , m_endChar(m_provider->length())
+ , m_firstLine(firstLine + 1)
+ {
+ }
+
+ SourceCode(PassRefPtr<SourceProvider> provider, int start, int end, int firstLine)
+ : m_provider(provider)
+ , m_startChar(start)
+ , m_endChar(end)
+ , m_firstLine(firstLine + 1)
+ {
+ }
+
+ UString toString() const
+ {
+ if (!m_provider)
+ return UString();
+ return m_provider->getRange(m_startChar, m_endChar);
+ }
+
+ SourceProvider* provider() const { return m_provider.get(); }
+ int firstLine() const { return m_firstLine; }
+ int startOffset() const { return m_startChar; }
+ const UChar* data() const { return m_provider->data() + m_startChar; }
+ int length() const { return m_endChar - m_startChar; }
+
+ private:
+ RefPtr<SourceProvider> m_provider;
+ int m_startChar;
+ int m_endChar;
+ int m_firstLine;
+ };
+
+ inline SourceCode makeSource(const UString& source, const UString& url = UString(), int firstLine = 0)
+ {
+ return SourceCode(UStringSourceProvider::create(source, url), firstLine);
+ }
+
+} // namespace KJS
+
+#endif // SourceCode_h
--- /dev/null
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SourceProvider_h
+#define SourceProvider_h
+
+#include "ustring.h"
+#include <wtf/RefCounted.h>
+
+namespace KJS {
+
+ class SourceProvider : public RefCounted<SourceProvider> {
+ public:
+ SourceProvider(const UString& url)
+ : m_url(url)
+ {
+ }
+ virtual ~SourceProvider() { }
+
+ virtual UString getRange(int start, int end) const = 0;
+ virtual const UChar* data() const = 0;
+ virtual int length() const = 0;
+
+ const UString& url() { return m_url; }
+ intptr_t asID() { return reinterpret_cast<intptr_t>(this); }
+
+ private:
+ UString m_url;
+ };
+
+ class UStringSourceProvider : public SourceProvider {
+ public:
+ static PassRefPtr<UStringSourceProvider> create(const UString& source, const UString& url)
+ {
+ return new UStringSourceProvider(source, url);
+ }
+
+ UString getRange(int start, int end) const { return m_source.substr(start, end - start); }
+ const UChar* data() const { return m_source.data(); }
+ int length() const { return m_source.size(); }
+
+ private:
+ UStringSourceProvider(const UString& source, const UString& url)
+ : SourceProvider(url)
+ , m_source(source)
+ {
+ }
+
+ UString m_source;
+ };
+
+} // namespace KJS
+
+#endif // SourceProvider_h
#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
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;
class JSGlobalObject;
class JSObject;
class JSValue;
+ class SourceCode;
class UString;
class List;
* @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
* @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.
* @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 *);
* @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
* @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);
/**
* @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:
UString s = x->toString(exec);
- int sourceId;
int errLine;
UString errMsg;
- RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg);
- Debugger* dbg = exec->dynamicGlobalObject()->debugger();
- if (dbg) {
- bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg);
- if (!cont)
- return jsUndefined();
- }
+ SourceCode source = makeSource(s);
+ RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(source, &errLine, &errMsg);
+
+ // debugger code removed
// No program node means a syntax occurred
if (!evalNode)
- return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
+ return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL);
bool switchGlobal = thisObj && thisObj != exec->dynamicGlobalObject() && thisObj->isGlobalObject();
}
// parse the source code
- int sourceId;
int errLine;
UString errMsg;
- RefPtr<FunctionBodyNode> functionBody = parser().parse<FunctionBodyNode>(sourceURL, lineNumber, body.data(), body.size(), &sourceId, &errLine, &errMsg);
-
- // notify debugger that source has been parsed
- Debugger* dbg = exec->dynamicGlobalObject()->debugger();
- if (dbg) {
- // send empty sourceURL to indicate constructed code
- bool cont = dbg->sourceParsed(exec, sourceId, UString(), body, lineNumber, errLine, errMsg);
- if (!cont) {
- dbg->imp()->abort();
- return new JSObject();
- }
- }
+ SourceCode source = makeSource(body, sourceURL, lineNumber);
+ RefPtr<FunctionBodyNode> functionBody = parser().parse<FunctionBodyNode>(source, &errLine, &errMsg);
+
+ // debugger code removed
// No program node == syntax error - throw a syntax error
if (!functionBody)
// We can't return a Completion(Throw) here, so just set the exception
// and return it
- return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL);
+ return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
ScopeChain scopeChain;
scopeChain.push(exec->lexicalGlobalObject());
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*);
%token RSHIFTEQUAL URSHIFTEQUAL /* >>= and >>>= */
%token ANDEQUAL MODEQUAL /* &= and %= */
%token XOREQUAL OREQUAL /* ^= and |= */
+%token <intValue> OPENBRACE /* { (with char offset) */
+%token <intValue> CLOSEBRACE /* { (with char offset) */
/* terminal types */
%token <doubleValue> NUMBER
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:
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:
;
Block:
- '{' '}' { $$ = createNodeInfo<StatementNode*>(new BlockNode(0), 0, 0);
+ OPENBRACE CLOSEBRACE { $$ = createNodeInfo<StatementNode*>(new BlockNode(0), 0, 0);
DBG($$.m_node, @1, @2); }
- | '{' SourceElements '}' { $$ = createNodeInfo<StatementNode*>(new BlockNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations);
+ | OPENBRACE SourceElements CLOSEBRACE { $$ = createNodeInfo<StatementNode*>(new BlockNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations);
DBG($$.m_node, @1, @3); }
;
;
CaseBlock:
- '{' CaseClausesOpt '}' { $$ = createNodeInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations); }
- | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}'
+ OPENBRACE CaseClausesOpt CLOSEBRACE { $$ = createNodeInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations); }
+ | OPENBRACE CaseClausesOpt DefaultClause CaseClausesOpt CLOSEBRACE
{ $$ = createNodeInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, $3.m_node, $4.m_node.head),
mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $3.m_varDeclarations), $4.m_varDeclarations),
mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $3.m_funcDeclarations), $4.m_funcDeclarations)); }
;
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:
;
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:
FunctionDeclaration { $$ = createNodeInfo<StatementNode*>($1, 0, new ParserRefCountedData<DeclarationStacks::FunctionStack>); $$.m_funcDeclarations->data.append($1); }
| Statement { $$ = $1; }
;
-
+
+// Start NoNodes
+
+Literal_NoNode:
+ NULLTOKEN
+ | TRUETOKEN
+ | FALSETOKEN
+ | NUMBER { }
+ | STRING { }
+ | '/' /* regexp */ { Lexer& l = lexer(); if (!l.scanRegExp()) YYABORT; }
+ | DIVEQUAL /* regexp with /= */ { Lexer& l = lexer(); if (!l.scanRegExp()) YYABORT; }
+;
+
+Property_NoNode:
+ IDENT ':' AssignmentExpr_NoNode { }
+ | STRING ':' AssignmentExpr_NoNode { }
+ | NUMBER ':' AssignmentExpr_NoNode { }
+ | IDENT IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; }
+ | IDENT IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; }
+;
+
+PropertyList_NoNode:
+ Property_NoNode
+ | PropertyList_NoNode ',' Property_NoNode
+;
+
+PrimaryExpr_NoNode:
+ PrimaryExprNoBrace_NoNode
+ | OPENBRACE CLOSEBRACE { }
+ | OPENBRACE PropertyList_NoNode CLOSEBRACE { }
+ /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
+ | OPENBRACE PropertyList_NoNode ',' CLOSEBRACE { }
+;
+
+PrimaryExprNoBrace_NoNode:
+ THISTOKEN
+ | Literal_NoNode
+ | ArrayLiteral_NoNode
+ | IDENT { }
+ | '(' Expr_NoNode ')'
+;
+
+ArrayLiteral_NoNode:
+ '[' ElisionOpt_NoNode ']'
+ | '[' ElementList_NoNode ']'
+ | '[' ElementList_NoNode ',' ElisionOpt_NoNode ']'
+;
+
+ElementList_NoNode:
+ ElisionOpt_NoNode AssignmentExpr_NoNode
+ | ElementList_NoNode ',' ElisionOpt_NoNode AssignmentExpr_NoNode
+;
+
+ElisionOpt_NoNode:
+ /* nothing */
+ | Elision_NoNode
+;
+
+Elision_NoNode:
+ ','
+ | Elision_NoNode ','
+;
+
+MemberExpr_NoNode:
+ PrimaryExpr_NoNode
+ | FunctionExpr_NoNode
+ | MemberExpr_NoNode '[' Expr_NoNode ']'
+ | MemberExpr_NoNode '.' IDENT
+ | NEW MemberExpr_NoNode Arguments_NoNode
+;
+
+MemberExprNoBF_NoNode:
+ PrimaryExprNoBrace_NoNode
+ | MemberExprNoBF_NoNode '[' Expr_NoNode ']'
+ | MemberExprNoBF_NoNode '.' IDENT
+ | NEW MemberExpr_NoNode Arguments_NoNode
+;
+
+NewExpr_NoNode:
+ MemberExpr_NoNode
+ | NEW NewExpr_NoNode
+;
+
+NewExprNoBF_NoNode:
+ MemberExprNoBF_NoNode
+ | NEW NewExpr_NoNode
+;
+
+CallExpr_NoNode:
+ MemberExpr_NoNode Arguments_NoNode
+ | CallExpr_NoNode Arguments_NoNode
+ | CallExpr_NoNode '[' Expr_NoNode ']'
+ | CallExpr_NoNode '.' IDENT
+;
+
+CallExprNoBF_NoNode:
+ MemberExprNoBF_NoNode Arguments_NoNode
+ | CallExprNoBF_NoNode Arguments_NoNode
+ | CallExprNoBF_NoNode '[' Expr_NoNode ']'
+ | CallExprNoBF_NoNode '.' IDENT
+;
+
+Arguments_NoNode:
+ '(' ')'
+ | '(' ArgumentList_NoNode ')'
+;
+
+ArgumentList_NoNode:
+ AssignmentExpr_NoNode
+ | ArgumentList_NoNode ',' AssignmentExpr_NoNode
+;
+
+LeftHandSideExpr_NoNode:
+ NewExpr_NoNode
+ | CallExpr_NoNode
+;
+
+LeftHandSideExprNoBF_NoNode:
+ NewExprNoBF_NoNode
+ | CallExprNoBF_NoNode
+;
+
+PostfixExpr_NoNode:
+ LeftHandSideExpr_NoNode
+ | LeftHandSideExpr_NoNode PLUSPLUS
+ | LeftHandSideExpr_NoNode MINUSMINUS
+;
+
+PostfixExprNoBF_NoNode:
+ LeftHandSideExprNoBF_NoNode
+ | LeftHandSideExprNoBF_NoNode PLUSPLUS
+ | LeftHandSideExprNoBF_NoNode MINUSMINUS
+;
+
+UnaryExprCommon_NoNode:
+ DELETETOKEN UnaryExpr_NoNode
+ | VOIDTOKEN UnaryExpr_NoNode
+ | TYPEOF UnaryExpr_NoNode
+ | PLUSPLUS UnaryExpr_NoNode
+ | AUTOPLUSPLUS UnaryExpr_NoNode
+ | MINUSMINUS UnaryExpr_NoNode
+ | AUTOMINUSMINUS UnaryExpr_NoNode
+ | '+' UnaryExpr_NoNode
+ | '-' UnaryExpr_NoNode
+ | '~' UnaryExpr_NoNode
+ | '!' UnaryExpr_NoNode
+
+UnaryExpr_NoNode:
+ PostfixExpr_NoNode
+ | UnaryExprCommon_NoNode
+;
+
+UnaryExprNoBF_NoNode:
+ PostfixExprNoBF_NoNode
+ | UnaryExprCommon_NoNode
+;
+
+MultiplicativeExpr_NoNode:
+ UnaryExpr_NoNode
+ | MultiplicativeExpr_NoNode '*' UnaryExpr_NoNode
+ | MultiplicativeExpr_NoNode '/' UnaryExpr_NoNode
+ | MultiplicativeExpr_NoNode '%' UnaryExpr_NoNode
+;
+
+MultiplicativeExprNoBF_NoNode:
+ UnaryExprNoBF_NoNode
+ | MultiplicativeExprNoBF_NoNode '*' UnaryExpr_NoNode
+ | MultiplicativeExprNoBF_NoNode '/' UnaryExpr_NoNode
+ | MultiplicativeExprNoBF_NoNode '%' UnaryExpr_NoNode
+;
+
+AdditiveExpr_NoNode:
+ MultiplicativeExpr_NoNode
+ | AdditiveExpr_NoNode '+' MultiplicativeExpr_NoNode
+ | AdditiveExpr_NoNode '-' MultiplicativeExpr_NoNode
+;
+
+AdditiveExprNoBF_NoNode:
+ MultiplicativeExprNoBF_NoNode
+ | AdditiveExprNoBF_NoNode '+' MultiplicativeExpr_NoNode
+ | AdditiveExprNoBF_NoNode '-' MultiplicativeExpr_NoNode
+;
+
+ShiftExpr_NoNode:
+ AdditiveExpr_NoNode
+ | ShiftExpr_NoNode LSHIFT AdditiveExpr_NoNode
+ | ShiftExpr_NoNode RSHIFT AdditiveExpr_NoNode
+ | ShiftExpr_NoNode URSHIFT AdditiveExpr_NoNode
+;
+
+ShiftExprNoBF_NoNode:
+ AdditiveExprNoBF_NoNode
+ | ShiftExprNoBF_NoNode LSHIFT AdditiveExpr_NoNode
+ | ShiftExprNoBF_NoNode RSHIFT AdditiveExpr_NoNode
+ | ShiftExprNoBF_NoNode URSHIFT AdditiveExpr_NoNode
+;
+
+RelationalExpr_NoNode:
+ ShiftExpr_NoNode
+ | RelationalExpr_NoNode '<' ShiftExpr_NoNode
+ | RelationalExpr_NoNode '>' ShiftExpr_NoNode
+ | RelationalExpr_NoNode LE ShiftExpr_NoNode
+ | RelationalExpr_NoNode GE ShiftExpr_NoNode
+ | RelationalExpr_NoNode INSTANCEOF ShiftExpr_NoNode
+ | RelationalExpr_NoNode INTOKEN ShiftExpr_NoNode
+;
+
+RelationalExprNoIn_NoNode:
+ ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode '<' ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode '>' ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode LE ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode GE ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode INSTANCEOF ShiftExpr_NoNode
+;
+
+RelationalExprNoBF_NoNode:
+ ShiftExprNoBF_NoNode
+ | RelationalExprNoBF_NoNode '<' ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode '>' ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode LE ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode GE ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode INSTANCEOF ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode INTOKEN ShiftExpr_NoNode
+;
+
+EqualityExpr_NoNode:
+ RelationalExpr_NoNode
+ | EqualityExpr_NoNode EQEQ RelationalExpr_NoNode
+ | EqualityExpr_NoNode NE RelationalExpr_NoNode
+ | EqualityExpr_NoNode STREQ RelationalExpr_NoNode
+ | EqualityExpr_NoNode STRNEQ RelationalExpr_NoNode
+;
+
+EqualityExprNoIn_NoNode:
+ RelationalExprNoIn_NoNode
+ | EqualityExprNoIn_NoNode EQEQ RelationalExprNoIn_NoNode
+ | EqualityExprNoIn_NoNode NE RelationalExprNoIn_NoNode
+ | EqualityExprNoIn_NoNode STREQ RelationalExprNoIn_NoNode
+ | EqualityExprNoIn_NoNode STRNEQ RelationalExprNoIn_NoNode
+;
+
+EqualityExprNoBF_NoNode:
+ RelationalExprNoBF_NoNode
+ | EqualityExprNoBF_NoNode EQEQ RelationalExpr_NoNode
+ | EqualityExprNoBF_NoNode NE RelationalExpr_NoNode
+ | EqualityExprNoBF_NoNode STREQ RelationalExpr_NoNode
+ | EqualityExprNoBF_NoNode STRNEQ RelationalExpr_NoNode
+;
+
+BitwiseANDExpr_NoNode:
+ EqualityExpr_NoNode
+ | BitwiseANDExpr_NoNode '&' EqualityExpr_NoNode
+;
+
+BitwiseANDExprNoIn_NoNode:
+ EqualityExprNoIn_NoNode
+ | BitwiseANDExprNoIn_NoNode '&' EqualityExprNoIn_NoNode
+;
+
+BitwiseANDExprNoBF_NoNode:
+ EqualityExprNoBF_NoNode
+ | BitwiseANDExprNoBF_NoNode '&' EqualityExpr_NoNode
+;
+
+BitwiseXORExpr_NoNode:
+ BitwiseANDExpr_NoNode
+ | BitwiseXORExpr_NoNode '^' BitwiseANDExpr_NoNode
+;
+
+BitwiseXORExprNoIn_NoNode:
+ BitwiseANDExprNoIn_NoNode
+ | BitwiseXORExprNoIn_NoNode '^' BitwiseANDExprNoIn_NoNode
+;
+
+BitwiseXORExprNoBF_NoNode:
+ BitwiseANDExprNoBF_NoNode
+ | BitwiseXORExprNoBF_NoNode '^' BitwiseANDExpr_NoNode
+;
+
+BitwiseORExpr_NoNode:
+ BitwiseXORExpr_NoNode
+ | BitwiseORExpr_NoNode '|' BitwiseXORExpr_NoNode
+;
+
+BitwiseORExprNoIn_NoNode:
+ BitwiseXORExprNoIn_NoNode
+ | BitwiseORExprNoIn_NoNode '|' BitwiseXORExprNoIn_NoNode
+;
+
+BitwiseORExprNoBF_NoNode:
+ BitwiseXORExprNoBF_NoNode
+ | BitwiseORExprNoBF_NoNode '|' BitwiseXORExpr_NoNode
+;
+
+LogicalANDExpr_NoNode:
+ BitwiseORExpr_NoNode
+ | LogicalANDExpr_NoNode AND BitwiseORExpr_NoNode
+;
+
+LogicalANDExprNoIn_NoNode:
+ BitwiseORExprNoIn_NoNode
+ | LogicalANDExprNoIn_NoNode AND BitwiseORExprNoIn_NoNode
+;
+
+LogicalANDExprNoBF_NoNode:
+ BitwiseORExprNoBF_NoNode
+ | LogicalANDExprNoBF_NoNode AND BitwiseORExpr_NoNode
+;
+
+LogicalORExpr_NoNode:
+ LogicalANDExpr_NoNode
+ | LogicalORExpr_NoNode OR LogicalANDExpr_NoNode
+;
+
+LogicalORExprNoIn_NoNode:
+ LogicalANDExprNoIn_NoNode
+ | LogicalORExprNoIn_NoNode OR LogicalANDExprNoIn_NoNode
+;
+
+LogicalORExprNoBF_NoNode:
+ LogicalANDExprNoBF_NoNode
+ | LogicalORExprNoBF_NoNode OR LogicalANDExpr_NoNode
+;
+
+ConditionalExpr_NoNode:
+ LogicalORExpr_NoNode
+ | LogicalORExpr_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode
+;
+
+ConditionalExprNoIn_NoNode:
+ LogicalORExprNoIn_NoNode
+ | LogicalORExprNoIn_NoNode '?' AssignmentExprNoIn_NoNode ':' AssignmentExprNoIn_NoNode
+;
+
+ConditionalExprNoBF_NoNode:
+ LogicalORExprNoBF_NoNode
+ | LogicalORExprNoBF_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode
+;
+
+AssignmentExpr_NoNode:
+ ConditionalExpr_NoNode
+ | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode
+;
+
+AssignmentExprNoIn_NoNode:
+ ConditionalExprNoIn_NoNode
+ | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExprNoIn_NoNode
+;
+
+AssignmentExprNoBF_NoNode:
+ ConditionalExprNoBF_NoNode
+ | LeftHandSideExprNoBF_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode
+;
+
+AssignmentOperator_NoNode:
+ '='
+ | PLUSEQUAL
+ | MINUSEQUAL
+ | MULTEQUAL
+ | DIVEQUAL
+ | LSHIFTEQUAL
+ | RSHIFTEQUAL
+ | URSHIFTEQUAL
+ | ANDEQUAL
+ | XOREQUAL
+ | OREQUAL
+ | MODEQUAL
+;
+
+Expr_NoNode:
+ AssignmentExpr_NoNode
+ | Expr_NoNode ',' AssignmentExpr_NoNode
+;
+
+ExprNoIn_NoNode:
+ AssignmentExprNoIn_NoNode
+ | ExprNoIn_NoNode ',' AssignmentExprNoIn_NoNode
+;
+
+ExprNoBF_NoNode:
+ AssignmentExprNoBF_NoNode
+ | ExprNoBF_NoNode ',' AssignmentExpr_NoNode
+;
+
+Statement_NoNode:
+ Block_NoNode
+ | VariableStatement_NoNode
+ | ConstStatement_NoNode
+ | EmptyStatement_NoNode
+ | ExprStatement_NoNode
+ | IfStatement_NoNode
+ | IterationStatement_NoNode
+ | ContinueStatement_NoNode
+ | BreakStatement_NoNode
+ | ReturnStatement_NoNode
+ | WithStatement_NoNode
+ | SwitchStatement_NoNode
+ | LabelledStatement_NoNode
+ | ThrowStatement_NoNode
+ | TryStatement_NoNode
+ | DebuggerStatement_NoNode
+;
+
+Block_NoNode:
+ OPENBRACE CLOSEBRACE { }
+ | OPENBRACE SourceElements_NoNode CLOSEBRACE { }
+;
+
+VariableStatement_NoNode:
+ VAR VariableDeclarationList_NoNode ';'
+ | VAR VariableDeclarationList_NoNode error { AUTO_SEMICOLON; }
+;
+
+VariableDeclarationList_NoNode:
+ IDENT { }
+ | IDENT Initializer_NoNode { }
+ | VariableDeclarationList_NoNode ',' IDENT
+ | VariableDeclarationList_NoNode ',' IDENT Initializer_NoNode
+;
+
+VariableDeclarationListNoIn_NoNode:
+ IDENT { }
+ | IDENT InitializerNoIn_NoNode { }
+ | VariableDeclarationListNoIn_NoNode ',' IDENT
+ | VariableDeclarationListNoIn_NoNode ',' IDENT InitializerNoIn_NoNode
+;
+
+ConstStatement_NoNode:
+ CONSTTOKEN ConstDeclarationList_NoNode ';'
+ | CONSTTOKEN ConstDeclarationList_NoNode error { AUTO_SEMICOLON; }
+;
+
+ConstDeclarationList_NoNode:
+ ConstDeclaration_NoNode
+ | ConstDeclarationList_NoNode ',' ConstDeclaration_NoNode
+;
+
+ConstDeclaration_NoNode:
+ IDENT { }
+ | IDENT Initializer_NoNode { }
+;
+
+Initializer_NoNode:
+ '=' AssignmentExpr_NoNode
+;
+
+InitializerNoIn_NoNode:
+ '=' AssignmentExprNoIn_NoNode
+;
+
+EmptyStatement_NoNode:
+ ';'
+;
+
+ExprStatement_NoNode:
+ ExprNoBF_NoNode ';'
+ | ExprNoBF_NoNode error { AUTO_SEMICOLON; }
+;
+
+IfStatement_NoNode:
+ IF '(' Expr_NoNode ')' Statement_NoNode %prec IF_WITHOUT_ELSE
+ | IF '(' Expr_NoNode ')' Statement_NoNode ELSE Statement_NoNode
+;
+
+IterationStatement_NoNode:
+ DO Statement_NoNode WHILE '(' Expr_NoNode ')' ';'
+ | DO Statement_NoNode WHILE '(' Expr_NoNode ')' error // Always performs automatic semicolon insertion
+ | WHILE '(' Expr_NoNode ')' Statement_NoNode
+ | FOR '(' ExprNoInOpt_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode
+ | FOR '(' VAR VariableDeclarationListNoIn_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode
+ | FOR '(' LeftHandSideExpr_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode
+ | FOR '(' VAR IDENT INTOKEN Expr_NoNode ')' Statement_NoNode
+ | FOR '(' VAR IDENT InitializerNoIn_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode
+;
+
+ExprOpt_NoNode:
+ /* nothing */
+ | Expr_NoNode
+;
+
+ExprNoInOpt_NoNode:
+ /* nothing */
+ | ExprNoIn_NoNode
+;
+
+ContinueStatement_NoNode:
+ CONTINUE ';'
+ | CONTINUE error { AUTO_SEMICOLON; }
+ | CONTINUE IDENT ';'
+ | CONTINUE IDENT error { AUTO_SEMICOLON; }
+;
+
+BreakStatement_NoNode:
+ BREAK ';'
+ | BREAK error { AUTO_SEMICOLON; }
+ | BREAK IDENT ';'
+ | BREAK IDENT error { AUTO_SEMICOLON; }
+;
+
+ReturnStatement_NoNode:
+ RETURN ';'
+ | RETURN error { AUTO_SEMICOLON; }
+ | RETURN Expr_NoNode ';'
+ | RETURN Expr_NoNode error { AUTO_SEMICOLON; }
+;
+
+WithStatement_NoNode:
+ WITH '(' Expr_NoNode ')' Statement_NoNode
+;
+
+SwitchStatement_NoNode:
+ SWITCH '(' Expr_NoNode ')' CaseBlock_NoNode
+;
+
+CaseBlock_NoNode:
+ OPENBRACE CaseClausesOpt_NoNode CLOSEBRACE { }
+ | OPENBRACE CaseClausesOpt_NoNode DefaultClause_NoNode CaseClausesOpt_NoNode CLOSEBRACE { }
+;
+
+CaseClausesOpt_NoNode:
+ /* nothing */
+ | CaseClauses_NoNode
+;
+
+CaseClauses_NoNode:
+ CaseClause_NoNode
+ | CaseClauses_NoNode CaseClause_NoNode
+;
+
+CaseClause_NoNode:
+ CASE Expr_NoNode ':'
+ | CASE Expr_NoNode ':' SourceElements_NoNode
+;
+
+DefaultClause_NoNode:
+ DEFAULT ':'
+ | DEFAULT ':' SourceElements_NoNode
+;
+
+LabelledStatement_NoNode:
+ IDENT ':' Statement_NoNode { }
+;
+
+ThrowStatement_NoNode:
+ THROW Expr_NoNode ';'
+ | THROW Expr_NoNode error { AUTO_SEMICOLON; }
+;
+
+TryStatement_NoNode:
+ TRY Block_NoNode FINALLY Block_NoNode
+ | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode
+ | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode FINALLY Block_NoNode
+;
+
+DebuggerStatement_NoNode:
+ DEBUGGER ';'
+ | DEBUGGER error { AUTO_SEMICOLON; }
+;
+
+FunctionDeclaration_NoNode:
+ FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+ | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+;
+
+FunctionExpr_NoNode:
+ FUNCTION '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+ | FUNCTION '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+ | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+ | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+;
+
+FormalParameterList_NoNode:
+ IDENT { }
+ | FormalParameterList_NoNode ',' IDENT
+;
+
+FunctionBody_NoNode:
+ /* not in spec */
+ | SourceElements_NoNode
+;
+
+SourceElements_NoNode:
+ SourceElement_NoNode
+ | SourceElements_NoNode SourceElement_NoNode
+;
+
+SourceElement_NoNode:
+ FunctionDeclaration_NoNode
+ | Statement_NoNode
+;
+
+// End NoNodes
+
%%
static AddNode* makeAddNode(ExpressionNode* left, ExpressionNode* right)
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")
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)
/* 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)
namespace KJS {
-Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code)
-{
- return checkSyntax(exec, sourceURL, startingLineNumber, code.data(), code.size());
-}
-
-Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength)
+Completion Interpreter::checkSyntax(ExecState* exec, const SourceCode& source)
{
JSLock lock;
int errLine;
UString errMsg;
- RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
+ RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(source, &errLine, &errMsg);
if (!progNode)
- return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, 0, sourceURL));
+ return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
return Completion(Normal);
}
-Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
-{
- return evaluate(exec, sourceURL, startingLineNumber, code.data(), code.size(), thisV);
-}
-
-Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
+Completion Interpreter::evaluate(ExecState* exec, const SourceCode& source, JSValue* thisV)
{
JSLock lock;
return Completion(Throw, Error::create(exec, GeneralError, "Recursion too deep"));
// parse the source code
- int sourceId;
int errLine;
UString errMsg;
- RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg);
+ RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(source, &errLine, &errMsg);
- // notify debugger that source has been parsed
- if (globalObject->debugger()) {
- bool cont = globalObject->debugger()->sourceParsed(exec, sourceId, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
- if (!cont)
- return Completion(Break);
- }
+ // removed debugger support
// no program node means a syntax error occurred
if (!progNode)
- return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL));
+ return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
exec->clearException();
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)
#ifndef KJS_Interpreter_h
#define KJS_Interpreter_h
+#include <wtf/PassRefPtr.h>
+
namespace KJS {
class Completion;
class ExecState;
class JSValue;
+ class SourceCode;
class UString;
struct UChar;
* @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.
* 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);
, 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);
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;
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);
}
stackToken = 0;
}
+ int startOffset = m_currentOffset;
while (!done) {
if (skipLF && current != '\n') // found \r but not \n afterwards
skipLF = false;
}
switch (state) {
case Start:
+ startOffset = m_currentOffset;
if (isWhiteSpace()) {
// do nothing
} else if (current == '/' && next1 == '/') {
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 {
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);
case '%':
case '(':
case ')':
- case '{':
- case '}':
case '[':
case ']':
case ';':
shift(1);
return static_cast<int>(c1);
+ case '{':
+ charPos = pos - 4;
+ shift(1);
+ return OPENBRACE;
+ case '}':
+ charPos = pos - 4;
+ shift(1);
+ return CLOSEBRACE;
default:
return -1;
}
#ifndef Lexer_h
#define Lexer_h
+#include "SourceCode.h"
#include "ustring.h"
#include <wtf/Vector.h>
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; }
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();
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);
KJS::Identifier* makeIdentifier(const Vector<UChar>& buffer);
UString* makeUString(const Vector<UChar>& buffer);
+ const SourceCode* m_source;
const UChar* code;
unsigned int length;
int yycolumn;
// current and following unicode characters (int to allow for -1 for end-of-file marker)
int current, next1, next2, next3;
+ int m_currentOffset;
+ int m_nextOffset1;
+ int m_nextOffset2;
+ int m_nextOffset3;
+
Vector<UString*> m_strings;
Vector<KJS::Identifier*> m_identifiers;
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;
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)
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)
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)
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)
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)
}
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();
}
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);
}
// ------------------------------ BlockNode ------------------------------------
+BlockNode::BlockNode()
+{
+}
+
BlockNode::BlockNode(SourceElements* children)
{
if (children)
// ------------------------------ 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)
// ------------------------------ 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)
JSValue* FunctionBodyNode::execute(ExecState* exec)
{
+ if (m_children.isEmpty())
+ parser().reparse(this);
processDeclarations(exec);
return ScopeNode::execute(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();
}
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();
}
#include "internal.h"
#include "regexp.h"
+#include "SourceCode.h"
#include "SymbolTable.h"
#include <wtf/ListRefPtr.h>
#include <wtf/MathExtras.h>
{
}
- 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; }
virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
+ virtual bool isFuncExprNode() const KJS_FAST_CALL { return false; }
JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
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;
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; }
};
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; }
};
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; }
};
{
}
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
};
class NumberNode : public ExpressionNode {
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; }
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:
}
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:
}
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 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; }
}
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
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:
}
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;
}
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;
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; }
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; }
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; }
}
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;
}
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); }
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:
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:
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:
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:
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:
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();
};
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();
};
}
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 {
}
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 {
}
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 {
}
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 {
}
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:
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:
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:
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:
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:
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:
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; }
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:
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; }
};
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; }
};
}
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 {
}
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 {
}
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 {
}
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 {
}
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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*);
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
}
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:
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:
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
void evaluateSingle(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<ConstDeclNode> m_next;
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;
}
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; }
};
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
+ virtual bool isExprStatement() const KJS_FAST_CALL { return true; }
+
+ ExpressionNode* expr() const { return m_expr.get(); }
private:
RefPtr<ExpressionNode> m_expr;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
protected:
RefPtr<ExpressionNode> m_condition;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<StatementNode> m_elseBlock;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<StatementNode> m_statement;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr1;
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;
}
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;
}
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;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> m_value;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
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;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<StatementNode> m_tryBlock;
Identifier ident() KJS_FAST_CALL { return m_ident; }
ParameterNode *nextParam() KJS_FAST_CALL { return m_next.get(); }
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
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;
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;
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; }
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;
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;
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;
}
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;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); }
ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); }
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
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:
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL;
virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
- virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+ virtual void streamTo(SourceStream&) KJS_FAST_CALL;
virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
private:
SourceStream& operator<<(UnindentType);
SourceStream& operator<<(DotExprType);
SourceStream& operator<<(Precedence);
- SourceStream& operator<<(const Node*);
+ SourceStream& operator<<(Node*);
template <typename T> SourceStream& operator<<(const RefPtr<T>& n) { return *this << n.get(); }
private:
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;
}
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 << ' '
// --------
-UString Node::toString() const
+UString Node::toString()
{
SourceStream stream;
streamTo(stream);
// --------
-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++)
}
}
-void ArrayNode::streamTo(SourceStream& s) const
+void ArrayNode::streamTo(SourceStream& s)
{
s << '[' << m_element;
for (int i = 0; i < m_elision; i++)
s << ']';
}
-void ObjectLiteralNode::streamTo(SourceStream& s) const
+void ObjectLiteralNode::streamTo(SourceStream& s)
{
if (m_list)
s << "{ " << m_list << " }";
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: {
}
}
-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)
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;
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)
}
}
-void ConstStatementNode::streamTo(SourceStream& s) const
+void ConstStatementNode::streamTo(SourceStream& s)
{
s << Endl << "const " << m_next << ';';
}
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;
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 " : "")
<< ')' << Indent << m_statement << Unindent;
}
-void ForInNode::streamTo(SourceStream& s) const
+void ForInNode::streamTo(SourceStream& s)
{
s << Endl << "for (";
if (m_identIsVarDecl) {
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())
s << ';';
}
-void BreakNode::streamTo(SourceStream& s) const
+void BreakNode::streamTo(SourceStream& s)
{
s << Endl << "break";
if (!m_ident.isNull())
s << ';';
}
-void ReturnNode::streamTo(SourceStream& s) const
+void ReturnNode::streamTo(SourceStream& s)
{
s << Endl << "return";
if (m_value)
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)
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();
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)
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;
}
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) {
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));
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;
}
* @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);
/**
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);
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "Parser.h"
+#include "SourceCode.h"
#include "collector.h"
#include "interpreter.h"
#include "nodes.h"
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());
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();
}
{
int errLine = 0;
UString errMsg;
- UString scriptUString(script.data());
- RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(fileName, 0, scriptUString.data(), scriptUString.size(), 0, &errLine, &errMsg);
+
+ RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(makeSource(script.data(), fileName), &errLine, &errMsg);
if (!programNode) {
fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
return false;
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;
}
}
PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar *d, int l)
{
- ASSERT(JSLock::lockCount() > 0);
-
int sizeInBytes = l * sizeof(UChar);
UChar *copyD = static_cast<UChar *>(fastMalloc(sizeInBytes));
memcpy(copyD, d, sizeInBytes);
PassRefPtr<UString::Rep> UString::Rep::create(UChar *d, int l)
{
- ASSERT(JSLock::lockCount() > 0);
-
Rep* r = new Rep;
r->offset = 0;
r->len = l;
PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length)
{
- ASSERT(JSLock::lockCount() > 0);
ASSERT(base);
int baseOffset = base->offset;
void UString::Rep::destroy()
{
- ASSERT(JSLock::lockCount() > 0);
-
if (isIdentifier)
Identifier::remove(this);
if (baseString != this) {
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;
// 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;
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();
}
if (new_end > new_start) {
// Note -- ignoring most return codes, because if this fails it
// doesn't matter...
- while (madvise(reinterpret_cast<char*>(new_start), new_end - new_start,
- MADV_DONTNEED) == -1 &&
+ // The msync call with MS_KILLPAGES on Leopard is equivalent to an
+ // madvise call with MADV_FREE on SnowLeopard
+ while (msync(reinterpret_cast<char*>(new_start), new_end - new_start,
+ MS_KILLPAGES) == -1 &&
errno == EAGAIN) {
// NOP
}
-// -*- mode: c++; c-basic-offset: 4 -*-
/*
* Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
*
#include <utility>
namespace WTF {
-
+
using std::min;
using std::max;
+ // WTF_ALIGN_OF / WTF_ALIGNED
+#if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(WINSCW)
+#define WTF_ALIGN_OF(type) __alignof__(type)
+#define WTF_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((__aligned__(n)))
+#elif COMPILER(MSVC)
+#define WTF_ALIGN_OF(type) __alignof(type)
+#define WTF_ALIGNED(variable_type, variable, n) __declspec(align(n)) variable_type variable
+#else
+#error WTF_ALIGN macros need alignment control.
+#endif
+
+#if COMPILER(GCC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
+ typedef char __attribute__((__may_alias__)) AlignedBufferChar;
+#else
+ typedef char AlignedBufferChar;
+#endif
+
+ template <size_t size, size_t alignment> struct AlignedBuffer;
+ template <size_t size> struct AlignedBuffer<size, 1> { AlignedBufferChar buffer[size]; };
+ template <size_t size> struct AlignedBuffer<size, 2> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2); };
+ template <size_t size> struct AlignedBuffer<size, 4> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4); };
+ template <size_t size> struct AlignedBuffer<size, 8> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8); };
+ template <size_t size> struct AlignedBuffer<size, 16> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); };
+ template <size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); };
+ template <size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); };
+
template <bool needsDestruction, typename T>
class VectorDestructor;
-
+
template<typename T>
struct VectorDestructor<false, T>
{
static void destruct(T*, T*) {}
};
-
+
template<typename T>
struct VectorDestructor<true, T>
{
cur->~T();
}
};
-
+
template <bool needsInitialization, bool canInitializeWithMemset, typename T>
class VectorInitializer;
-
+
template<bool ignore, typename T>
struct VectorInitializer<false, ignore, T>
{
static void initialize(T*, T*) {}
};
-
+
template<typename T>
struct VectorInitializer<true, false, T>
{
new (cur) T;
}
};
-
+
template<typename T>
struct VectorInitializer<true, true, T>
{
memset(begin, 0, reinterpret_cast<char*>(end) - reinterpret_cast<char*>(begin));
}
};
-
+
template <bool canMoveWithMemcpy, typename T>
class VectorMover;
-
+
template<typename T>
struct VectorMover<false, T>
{
}
}
};
-
+
template<typename T>
struct VectorMover<true, T>
{
memmove(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src));
}
};
-
+
template <bool canCopyWithMemcpy, typename T>
class VectorCopier;
-
+
template<typename T>
struct VectorCopier<false, T>
{
}
}
};
-
+
template<typename T>
struct VectorCopier<true, T>
{
memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src));
}
};
-
+
template <bool canFillWithMemset, typename T>
class VectorFiller;
-
+
template<typename T>
struct VectorFiller<false, T>
{
}
}
};
-
+
template<typename T>
struct VectorFiller<true, T>
{
return true;
}
};
-
+
template<typename T>
struct VectorComparer<true, T>
{
{
VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, end);
}
-
+
static void initialize(T* begin, T* end)
{
VectorInitializer<VectorTraits<T>::needsInitialization, VectorTraits<T>::canInitializeWithMemset, T>::initialize(begin, end);
}
-
+
static void move(const T* src, const T* srcEnd, T* dst)
{
VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::move(src, srcEnd, dst);
}
-
+
static void moveOverlapping(const T* src, const T* srcEnd, T* dst)
{
VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::moveOverlapping(src, srcEnd, dst);
}
-
+
static void uninitializedCopy(const T* src, const T* srcEnd, T* dst)
{
VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(src, srcEnd, dst);
}
-
+
static void uninitializedFill(T* dst, T* dstEnd, const T& val)
{
VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFill(dst, dstEnd, val);
return VectorComparer<VectorTraits<T>::canCompareWithMemcmp, T>::compare(a, b, size);
}
};
-
+
template<typename T>
class VectorBufferBase : Noncopyable {
public:
void allocateBuffer(size_t newCapacity)
{
- ASSERT(newCapacity >= m_capacity);
m_capacity = newCapacity;
if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
CRASH();
m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T)));
}
-
+
void deallocateBuffer(T* bufferToDeallocate)
{
+ if (m_buffer == bufferToDeallocate) {
+ m_buffer = 0;
+ m_capacity = 0;
+ }
fastFree(bufferToDeallocate);
}
-
+
T* buffer() { return m_buffer; }
const T* buffer() const { return m_buffer; }
+ T** bufferSlot() { return &m_buffer; }
size_t capacity() const { return m_capacity; }
-
+
T* releaseBuffer()
{
T* buffer = m_buffer;
m_capacity = 0;
return buffer;
}
-
+
protected:
VectorBufferBase()
- : m_buffer(0)
- , m_capacity(0)
+ : m_buffer(0)
+ , m_capacity(0)
{
}
-
+
VectorBufferBase(T* buffer, size_t capacity)
- : m_buffer(buffer)
- , m_capacity(capacity)
+ : m_buffer(buffer)
+ , m_capacity(capacity)
{
}
-
+
~VectorBufferBase()
{
// FIXME: It would be nice to find a way to ASSERT that m_buffer hasn't leaked here.
}
-
+
T* m_buffer;
size_t m_capacity;
};
-
+
template<typename T, size_t inlineCapacity>
class VectorBuffer;
-
+
template<typename T>
class VectorBuffer<T, 0> : private VectorBufferBase<T> {
private:
VectorBuffer()
{
}
-
+
VectorBuffer(size_t capacity)
{
allocateBuffer(capacity);
}
-
+
~VectorBuffer()
{
deallocateBuffer(buffer());
std::swap(m_buffer, other.m_buffer);
std::swap(m_capacity, other.m_capacity);
}
-
+
+ void restoreInlineBufferIfNeeded() { }
+
using Base::allocateBuffer;
using Base::deallocateBuffer;
-
+
using Base::buffer;
+ using Base::bufferSlot;
using Base::capacity;
-
+
using Base::releaseBuffer;
private:
using Base::m_buffer;
using Base::m_capacity;
};
-
+
template<typename T, size_t inlineCapacity>
class VectorBuffer : private VectorBufferBase<T> {
private:
typedef VectorBufferBase<T> Base;
public:
VectorBuffer()
- : Base(inlineBuffer(), inlineCapacity)
+ : Base(inlineBuffer(), inlineCapacity)
{
}
-
+
VectorBuffer(size_t capacity)
- : Base(inlineBuffer(), inlineCapacity)
+ : Base(inlineBuffer(), inlineCapacity)
{
- if (capacity > inlineCapacity)
- allocateBuffer(capacity);
+ allocateBuffer(capacity);
}
-
+
~VectorBuffer()
{
deallocateBuffer(buffer());
}
-
- using Base::allocateBuffer;
-
+
+ void allocateBuffer(size_t newCapacity)
+ {
+ if (newCapacity > inlineCapacity)
+ Base::allocateBuffer(newCapacity);
+ }
+
void deallocateBuffer(T* bufferToDeallocate)
{
if (bufferToDeallocate == inlineBuffer())
return;
Base::deallocateBuffer(bufferToDeallocate);
}
-
+
+ void restoreInlineBufferIfNeeded()
+ {
+ if (m_buffer)
+ return;
+ m_buffer = inlineBuffer();
+ m_capacity = inlineCapacity;
+ }
+
using Base::buffer;
+ using Base::bufferSlot;
using Base::capacity;
-
+
T* releaseBuffer()
{
if (buffer() == inlineBuffer())
return 0;
return Base::releaseBuffer();
}
-
+
private:
using Base::m_buffer;
using Base::m_capacity;
-
+
static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T);
-#if PLATFORM(ARM)
- T *inlineBuffer() { return reinterpret_cast<T*>((void*)((&m_inlineBuffer))); }
-
- __attribute__ ((aligned (4))) char m_inlineBuffer[m_inlineBufferSize];
-#else
- T* inlineBuffer() { return reinterpret_cast<T*>(&m_inlineBuffer); }
-
- // FIXME: Nothing guarantees this buffer is appropriately aligned to hold objects of type T.
- char m_inlineBuffer[m_inlineBufferSize];
-#endif
+ T* inlineBuffer() { return reinterpret_cast<T*>(m_inlineBuffer.buffer); }
+
+ AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer;
};
-
+
template<typename T, size_t inlineCapacity = 0>
class Vector {
- private:
- typedef VectorBuffer<T, inlineCapacity> Buffer;
- typedef VectorTypeOperations<T> TypeOperations;
-
- public:
- typedef T ValueType;
-
- typedef T* iterator;
- typedef const T* const_iterator;
-
- Vector()
- : m_size(0)
- {
- }
-
- explicit Vector(size_t size)
- : m_size(size)
- , m_buffer(size)
- {
- TypeOperations::initialize(begin(), end());
- }
-
- ~Vector()
- {
- clear();
- }
-
- Vector(const Vector&);
- template<size_t otherCapacity>
- Vector(const Vector<T, otherCapacity>&);
-
- Vector& operator=(const Vector&);
- template<size_t otherCapacity>
- Vector& operator=(const Vector<T, otherCapacity>&);
-
- size_t size() const { return m_size; }
- size_t capacity() const { return m_buffer.capacity(); }
- bool isEmpty() const { return !size(); }
-
- T& at(size_t i)
- {
- ASSERT(i < size());
- return m_buffer.buffer()[i];
- }
- const T& at(size_t i) const
- {
- ASSERT(i < size());
- return m_buffer.buffer()[i];
- }
-
- T& operator[](size_t i) { return at(i); }
- const T& operator[](size_t i) const { return at(i); }
-
- T* data() { return m_buffer.buffer(); }
- const T* data() const { return m_buffer.buffer(); }
-
- iterator begin() { return data(); }
- iterator end() { return begin() + m_size; }
- const_iterator begin() const { return data(); }
- const_iterator end() const { return begin() + m_size; }
-
- T& first() { return at(0); }
- const T& first() const { return at(0); }
- T& last() { return at(size() - 1); }
- const T& last() const { return at(size() - 1); }
-
- void shrink(size_t size);
- void grow(size_t size);
- void resize(size_t size);
- void reserveCapacity(size_t newCapacity);
-
- void clear() { if (m_size) shrink(0); }
-
- template<typename U> void append(const U*, size_t);
- template<typename U> void append(const U&);
- template<typename U> void uncheckedAppend(const U& val);
- template<typename U, size_t c> void append(const Vector<U, c>&);
-
- template<typename U> void insert(size_t position, const U*, size_t);
- template<typename U> void insert(size_t position, const U&);
- template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&);
-
- template<typename U> void prepend(const U*, size_t);
- template<typename U> void prepend(const U&);
- template<typename U, size_t c> void prepend(const Vector<U, c>&);
-
- void remove(size_t position);
-
- void removeLast()
- {
- ASSERT(!isEmpty());
- shrink(size() - 1);
- }
-
- Vector(size_t size, const T& val)
- : m_size(size)
- , m_buffer(size)
- {
- TypeOperations::uninitializedFill(begin(), end(), val);
- }
-
- void fill(const T&, size_t);
- void fill(const T& val) { fill(val, size()); }
-
- template<typename Iterator> void appendRange(Iterator start, Iterator end);
-
- T* releaseBuffer();
-
- void swap(Vector<T, inlineCapacity>& other)
- {
- std::swap(m_size, other.m_size);
- m_buffer.swap(other.m_buffer);
- }
-
- private:
- void expandCapacity(size_t newMinCapacity);
- const T* expandCapacity(size_t newMinCapacity, const T*);
- template<typename U> U* expandCapacity(size_t newMinCapacity, U*);
-
- size_t m_size;
- Buffer m_buffer;
- };
-
- template<typename T, size_t inlineCapacity>
- Vector<T, inlineCapacity>::Vector(const Vector& other)
- : m_size(other.size())
- , m_buffer(other.capacity())
+private:
+ typedef VectorBuffer<T, inlineCapacity> Buffer;
+ typedef VectorTypeOperations<T> TypeOperations;
+
+public:
+ typedef T ValueType;
+
+ typedef T* iterator;
+ typedef const T* const_iterator;
+
+ Vector()
+ : m_size(0)
{
- TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
}
-
- template<typename T, size_t inlineCapacity>
- template<size_t otherCapacity>
- Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other)
- : m_size(other.size())
- , m_buffer(other.capacity())
+
+ explicit Vector(size_t size)
+ : m_size(size)
+ , m_buffer(size)
{
- TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
+ if (begin())
+ TypeOperations::initialize(begin(), end());
}
-
- template<typename T, size_t inlineCapacity>
- Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other)
+
+ ~Vector()
{
- if (&other == this)
- return *this;
-
- if (size() > other.size())
- shrink(other.size());
- else if (other.size() > capacity()) {
- clear();
- reserveCapacity(other.size());
- }
-
- std::copy(other.begin(), other.begin() + size(), begin());
- TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
- m_size = other.size();
-
- return *this;
+ if (m_size) shrink(0);
}
-
- template<typename T, size_t inlineCapacity>
+
+ Vector(const Vector&);
template<size_t otherCapacity>
- Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other)
- {
- if (&other == this)
- return *this;
-
- if (size() > other.size())
- shrink(other.size());
- else if (other.size() > capacity()) {
- clear();
- reserveCapacity(other.size());
- }
-
- std::copy(other.begin(), other.begin() + size(), begin());
- TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
- m_size = other.size();
-
- return *this;
+ Vector(const Vector<T, otherCapacity>&);
+
+ Vector& operator=(const Vector&);
+ template<size_t otherCapacity>
+ Vector& operator=(const Vector<T, otherCapacity>&);
+
+ size_t size() const { return m_size; }
+ size_t capacity() const { return m_buffer.capacity(); }
+ bool isEmpty() const { return !size(); }
+
+ T& at(size_t i)
+ {
+ ASSERT(i < size());
+ return m_buffer.buffer()[i];
}
-
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize)
+ const T& at(size_t i) const
{
- if (size() > newSize)
- shrink(newSize);
- else if (newSize > capacity()) {
- clear();
- reserveCapacity(newSize);
- }
-
- std::fill(begin(), end(), val);
- TypeOperations::uninitializedFill(end(), begin() + newSize, val);
- m_size = newSize;
+ ASSERT(i < size());
+ return m_buffer.buffer()[i];
}
-
- template<typename T, size_t inlineCapacity>
- template<typename Iterator>
- void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end)
+
+ T& operator[](size_t i) { return at(i); }
+ const T& operator[](size_t i) const { return at(i); }
+
+ T* data() { return m_buffer.buffer(); }
+ const T* data() const { return m_buffer.buffer(); }
+ T** dataSlot() { return m_buffer.bufferSlot(); }
+
+ iterator begin() { return data(); }
+ iterator end() { return begin() + m_size; }
+ const_iterator begin() const { return data(); }
+ const_iterator end() const { return begin() + m_size; }
+
+ T& first() { return at(0); }
+ const T& first() const { return at(0); }
+ T& last() { return at(size() - 1); }
+ const T& last() const { return at(size() - 1); }
+
+ template<typename U> size_t find(const U&) const;
+
+ void shrink(size_t size);
+ void grow(size_t size);
+ void resize(size_t size);
+ void reserveCapacity(size_t newCapacity);
+ void shrinkCapacity(size_t newCapacity);
+ void shrinkToFit() { shrinkCapacity(size()); }
+
+ void clear() { shrinkCapacity(0); }
+
+ template<typename U> void append(const U*, size_t);
+ template<typename U> void append(const U&);
+ template<typename U> void uncheckedAppend(const U& val);
+ template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&);
+
+ template<typename U> void insert(size_t position, const U*, size_t);
+ template<typename U> void insert(size_t position, const U&);
+ template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&);
+
+ template<typename U> void prepend(const U*, size_t);
+ template<typename U> void prepend(const U&);
+ template<typename U, size_t c> void prepend(const Vector<U, c>&);
+
+ void remove(size_t position);
+ void remove(size_t position, size_t length);
+
+ void removeLast()
{
- for (Iterator it = start; it != end; ++it)
- append(*it);
+ ASSERT(!isEmpty());
+ shrink(size() - 1);
}
-
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
+
+ Vector(size_t size, const T& val)
+ : m_size(size)
+ , m_buffer(size)
{
- reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
+ if (begin())
+ TypeOperations::uninitializedFill(begin(), end(), val);
}
- template<typename T, size_t inlineCapacity>
- const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr)
+ void fill(const T&, size_t);
+ void fill(const T& val) { fill(val, size()); }
+
+ template<typename Iterator> void appendRange(Iterator start, Iterator end);
+
+ T* releaseBuffer();
+
+ void swap(Vector<T, inlineCapacity>& other)
{
- if (ptr < begin() || ptr >= end()) {
- expandCapacity(newMinCapacity);
- return ptr;
- }
- size_t index = ptr - begin();
- expandCapacity(newMinCapacity);
- return begin() + index;
+ std::swap(m_size, other.m_size);
+ m_buffer.swap(other.m_buffer);
}
+
+private:
+ void expandCapacity(size_t newMinCapacity);
+ const T* expandCapacity(size_t newMinCapacity, const T*);
+ template<typename U> U* expandCapacity(size_t newMinCapacity, U*);
+
+ size_t m_size;
+ Buffer m_buffer;
+};
+
+template<typename T, size_t inlineCapacity>
+Vector<T, inlineCapacity>::Vector(const Vector& other)
+: m_size(other.size())
+, m_buffer(other.capacity())
+{
+ if (begin())
+ TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
+}
+
+template<typename T, size_t inlineCapacity>
+template<size_t otherCapacity>
+Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other)
+: m_size(other.size())
+, m_buffer(other.capacity())
+{
+ if (begin())
+ TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
+}
- template<typename T, size_t inlineCapacity> template<typename U>
- inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
- {
+template<typename T, size_t inlineCapacity>
+Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other)
+{
+ if (&other == this)
+ return *this;
+
+ if (size() > other.size())
+ shrink(other.size());
+ else if (other.size() > capacity()) {
+ clear();
+ reserveCapacity(other.size());
+ if (!begin())
+ return *this;
+ }
+
+ std::copy(other.begin(), other.begin() + size(), begin());
+ TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
+ m_size = other.size();
+
+ return *this;
+}
+
+template<typename T, size_t inlineCapacity>
+template<size_t otherCapacity>
+Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other)
+{
+ if (&other == this)
+ return *this;
+
+ if (size() > other.size())
+ shrink(other.size());
+ else if (other.size() > capacity()) {
+ clear();
+ reserveCapacity(other.size());
+ if (!begin())
+ return *this;
+ }
+
+ std::copy(other.begin(), other.begin() + size(), begin());
+ TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
+ m_size = other.size();
+
+ return *this;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize)
+{
+ if (size() > newSize)
+ shrink(newSize);
+ else if (newSize > capacity()) {
+ clear();
+ reserveCapacity(newSize);
+ if (!begin())
+ return;
+ }
+
+ std::fill(begin(), end(), val);
+ TypeOperations::uninitializedFill(end(), begin() + newSize, val);
+ m_size = newSize;
+}
+
+template<typename T, size_t inlineCapacity>
+template<typename Iterator>
+void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end)
+{
+ for (Iterator it = start; it != end; ++it)
+ append(*it);
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
+{
+ reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
+}
+
+template<typename T, size_t inlineCapacity>
+const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr)
+{
+ if (ptr < begin() || ptr >= end()) {
expandCapacity(newMinCapacity);
return ptr;
}
-
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::resize(size_t size)
- {
- if (size <= m_size)
- TypeOperations::destruct(begin() + size, end());
- else {
- if (size > capacity())
- expandCapacity(size);
- TypeOperations::initialize(end(), begin() + size);
- }
-
- m_size = size;
- }
-
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::shrink(size_t size)
- {
- ASSERT(size <= m_size);
+ size_t index = ptr - begin();
+ expandCapacity(newMinCapacity);
+ return begin() + index;
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
+{
+ expandCapacity(newMinCapacity);
+ return ptr;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::resize(size_t size)
+{
+ if (size <= m_size)
TypeOperations::destruct(begin() + size, end());
- m_size = size;
- }
-
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::grow(size_t size)
- {
- ASSERT(size >= m_size);
+ else {
if (size > capacity())
expandCapacity(size);
- TypeOperations::initialize(end(), begin() + size);
- m_size = size;
+ if (begin())
+ TypeOperations::initialize(end(), begin() + size);
}
-
- template<typename T, size_t inlineCapacity>
- void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity)
- {
- if (newCapacity <= capacity())
- return;
- T* oldBuffer = begin();
+
+ m_size = size;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::shrink(size_t size)
+{
+ ASSERT(size <= m_size);
+ TypeOperations::destruct(begin() + size, end());
+ m_size = size;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::grow(size_t size)
+{
+ ASSERT(size >= m_size);
+ if (size > capacity())
+ expandCapacity(size);
+ if (begin())
+ TypeOperations::initialize(end(), begin() + size);
+ m_size = size;
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity)
+{
+ if (newCapacity <= capacity())
+ return;
+ T* oldBuffer = begin();
+ T* oldEnd = end();
+ m_buffer.allocateBuffer(newCapacity);
+ if (begin())
+ TypeOperations::move(oldBuffer, oldEnd, begin());
+ m_buffer.deallocateBuffer(oldBuffer);
+}
+
+template<typename T, size_t inlineCapacity>
+void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity)
+{
+ if (newCapacity >= capacity())
+ return;
+
+ if (newCapacity < size())
+ shrink(newCapacity);
+
+ T* oldBuffer = begin();
+ if (newCapacity > 0) {
T* oldEnd = end();
m_buffer.allocateBuffer(newCapacity);
- TypeOperations::move(oldBuffer, oldEnd, begin());
- m_buffer.deallocateBuffer(oldBuffer);
+ if (begin() != oldBuffer)
+ TypeOperations::move(oldBuffer, oldEnd, begin());
}
-
- // Templatizing these is better than just letting the conversion happen implicitly,
- // because for instance it allows a PassRefPtr to be appended to a RefPtr vector
- // without refcount thrash.
-
- template<typename T, size_t inlineCapacity> template<typename U>
- void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize)
- {
- size_t newSize = m_size + dataSize;
- if (newSize > capacity())
- data = expandCapacity(newSize, data);
- T* dest = end();
- for (size_t i = 0; i < dataSize; ++i)
- new (&dest[i]) T(data[i]);
- m_size = newSize;
+
+ m_buffer.deallocateBuffer(oldBuffer);
+ m_buffer.restoreInlineBufferIfNeeded();
+}
+
+// Templatizing these is better than just letting the conversion happen implicitly,
+// because for instance it allows a PassRefPtr to be appended to a RefPtr vector
+// without refcount thrash.
+
+template<typename T, size_t inlineCapacity> template<typename U>
+void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize)
+{
+ size_t newSize = m_size + dataSize;
+ if (newSize > capacity()) {
+ data = expandCapacity(newSize, data);
+ if (!begin())
+ return;
}
-
- template<typename T, size_t inlineCapacity> template<typename U>
- inline void Vector<T, inlineCapacity>::append(const U& val)
- {
- const U* ptr = &val;
- if (size() == capacity())
- ptr = expandCapacity(size() + 1, ptr);
-
+ T* dest = end();
+ for (size_t i = 0; i < dataSize; ++i)
+ new (&dest[i]) T(data[i]);
+ m_size = newSize;
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline void Vector<T, inlineCapacity>::append(const U& val)
+{
+ const U* ptr = &val;
+ if (size() == capacity()) {
+ ptr = expandCapacity(size() + 1, ptr);
+ if (!begin())
+ return;
+ }
+
#if COMPILER(MSVC7)
- // FIXME: MSVC7 generates compilation errors when trying to assign
- // a pointer to a Vector of its base class (i.e. can't downcast). So far
- // I've been unable to determine any logical reason for this, so I can
- // only assume it is a bug with the compiler. Casting is a bad solution,
- // however, because it subverts implicit conversions, so a better
- // one is needed.
- new (end()) T(static_cast<T>(*ptr));
+ // FIXME: MSVC7 generates compilation errors when trying to assign
+ // a pointer to a Vector of its base class (i.e. can't downcast). So far
+ // I've been unable to determine any logical reason for this, so I can
+ // only assume it is a bug with the compiler. Casting is a bad solution,
+ // however, because it subverts implicit conversions, so a better
+ // one is needed.
+ new (end()) T(static_cast<T>(*ptr));
#else
- new (end()) T(*ptr);
+ new (end()) T(*ptr);
#endif
- ++m_size;
- }
-
- // This version of append saves a branch in the case where you know that the
- // vector's capacity is large enough for the append to succeed.
-
- template<typename T, size_t inlineCapacity> template<typename U>
- inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val)
- {
- ASSERT(size() < capacity());
- const U* ptr = &val;
- new (end()) T(*ptr);
- ++m_size;
- }
-
- template<typename T, size_t inlineCapacity> template<typename U, size_t c>
- inline void Vector<T, inlineCapacity>::append(const Vector<U, c>& val)
- {
- append(val.begin(), val.size());
- }
-
- template<typename T, size_t inlineCapacity> template<typename U>
- void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize)
- {
- ASSERT(position <= size());
- size_t newSize = m_size + dataSize;
- if (newSize > capacity())
- data = expandCapacity(newSize, data);
- T* spot = begin() + position;
- TypeOperations::moveOverlapping(spot, end(), spot + dataSize);
- for (size_t i = 0; i < dataSize; ++i)
- new (&spot[i]) T(data[i]);
- m_size = newSize;
- }
-
- template<typename T, size_t inlineCapacity> template<typename U>
- inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val)
- {
- ASSERT(position <= size());
- const U* data = &val;
- if (size() == capacity())
- data = expandCapacity(size() + 1, data);
- T* spot = begin() + position;
- TypeOperations::moveOverlapping(spot, end(), spot + 1);
- new (spot) T(*data);
- ++m_size;
- }
-
- template<typename T, size_t inlineCapacity> template<typename U, size_t c>
- inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val)
- {
- insert(position, val.begin(), val.size());
- }
-
- template<typename T, size_t inlineCapacity> template<typename U>
- void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize)
- {
- insert(0, data, dataSize);
+ ++m_size;
+}
+
+// This version of append saves a branch in the case where you know that the
+// vector's capacity is large enough for the append to succeed.
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val)
+{
+ ASSERT(size() < capacity());
+ const U* ptr = &val;
+ new (end()) T(*ptr);
+ ++m_size;
+}
+
+// This method should not be called append, a better name would be appendElements.
+// It could also be eliminated entirely, and call sites could just use
+// appendRange(val.begin(), val.end()).
+template<typename T, size_t inlineCapacity> template<size_t otherCapacity>
+inline void Vector<T, inlineCapacity>::append(const Vector<T, otherCapacity>& val)
+{
+ append(val.begin(), val.size());
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize)
+{
+ ASSERT(position <= size());
+ size_t newSize = m_size + dataSize;
+ if (newSize > capacity()) {
+ data = expandCapacity(newSize, data);
+ if (!begin())
+ return;
}
-
- template<typename T, size_t inlineCapacity> template<typename U>
- inline void Vector<T, inlineCapacity>::prepend(const U& val)
- {
- insert(0, val);
+ T* spot = begin() + position;
+ TypeOperations::moveOverlapping(spot, end(), spot + dataSize);
+ for (size_t i = 0; i < dataSize; ++i)
+ new (&spot[i]) T(data[i]);
+ m_size = newSize;
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val)
+{
+ ASSERT(position <= size());
+ const U* data = &val;
+ if (size() == capacity()) {
+ data = expandCapacity(size() + 1, data);
+ if (!begin())
+ return;
}
-
- template<typename T, size_t inlineCapacity> template<typename U, size_t c>
- inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val)
- {
- insert(0, val.begin(), val.size());
+ T* spot = begin() + position;
+ TypeOperations::moveOverlapping(spot, end(), spot + 1);
+ new (spot) T(*data);
+ ++m_size;
+}
+
+template<typename T, size_t inlineCapacity> template<typename U, size_t c>
+inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val)
+{
+ insert(position, val.begin(), val.size());
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize)
+{
+ insert(0, data, dataSize);
+}
+
+template<typename T, size_t inlineCapacity> template<typename U>
+inline void Vector<T, inlineCapacity>::prepend(const U& val)
+{
+ insert(0, val);
+}
+
+template<typename T, size_t inlineCapacity> template<typename U, size_t c>
+inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val)
+{
+ insert(0, val.begin(), val.size());
+}
+
+template<typename T, size_t inlineCapacity>
+inline void Vector<T, inlineCapacity>::remove(size_t position)
+{
+ ASSERT(position < size());
+ T* spot = begin() + position;
+ spot->~T();
+ TypeOperations::moveOverlapping(spot + 1, end(), spot);
+ --m_size;
+}
+
+template<typename T, size_t inlineCapacity>
+inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length)
+{
+ ASSERT(position < size());
+ ASSERT(position + length < size());
+ T* beginSpot = begin() + position;
+ T* endSpot = beginSpot + length;
+ TypeOperations::destruct(beginSpot, endSpot);
+ TypeOperations::moveOverlapping(endSpot, end(), beginSpot);
+ m_size -= length;
+}
+
+template<typename T, size_t inlineCapacity>
+inline T* Vector<T, inlineCapacity>::releaseBuffer()
+{
+ T* buffer = m_buffer.releaseBuffer();
+ if (inlineCapacity && !buffer && m_size) {
+ // If the vector had some data, but no buffer to release,
+ // that means it was using the inline buffer. In that case,
+ // we create a brand new buffer so the caller always gets one.
+ size_t bytes = m_size * sizeof(T);
+ buffer = static_cast<T*>(fastMalloc(bytes));
+ memcpy(buffer, data(), bytes);
}
+ m_size = 0;
+ return buffer;
+}
+
+template<typename T, size_t inlineCapacity>
+void deleteAllValues(const Vector<T, inlineCapacity>& collection)
+{
+ typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
+ iterator end = collection.end();
+ for (iterator it = collection.begin(); it != end; ++it)
+ delete *it;
+}
+
+template<typename T, size_t inlineCapacity>
+inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b)
+{
+ a.swap(b);
+}
+
+template<typename T, size_t inlineCapacity>
+bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
+{
+ if (a.size() != b.size())
+ return false;
- template<typename T, size_t inlineCapacity>
- inline void Vector<T, inlineCapacity>::remove(size_t position)
- {
- ASSERT(position < size());
- T* spot = begin() + position;
- spot->~T();
- TypeOperations::moveOverlapping(spot + 1, end(), spot);
- --m_size;
- }
-
- template<typename T, size_t inlineCapacity>
- inline T* Vector<T, inlineCapacity>::releaseBuffer()
- {
- T* buffer = m_buffer.releaseBuffer();
- if (inlineCapacity && !buffer && m_size) {
- // If the vector had some data, but no buffer to release,
- // that means it was using the inline buffer. In that case,
- // we create a brand new buffer so the caller always gets one.
- size_t bytes = m_size * sizeof(T);
- buffer = static_cast<T*>(fastMalloc(bytes));
- memcpy(buffer, data(), bytes);
- }
- ASSERT(buffer);
- m_size = 0;
- return buffer;
- }
-
- template<typename T, size_t inlineCapacity>
- void deleteAllValues(const Vector<T, inlineCapacity>& collection)
- {
- typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
- iterator end = collection.end();
- for (iterator it = collection.begin(); it != end; ++it)
- delete *it;
- }
-
- template<typename T, size_t inlineCapacity>
- inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b)
- {
- a.swap(b);
- }
-
- template<typename T, size_t inlineCapacity>
- bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
- {
- if (a.size() != b.size())
- return false;
-
- return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size());
- }
-
- template<typename T, size_t inlineCapacity>
- inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
- {
- return !(a == b);
- }
+ return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size());
+}
+
+template<typename T, size_t inlineCapacity>
+inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
+{
+ return !(a == b);
+}
} // namespace WTF