⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nodes.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/**  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)*  Copyright (C) 2001 Peter Kelly (pmk@post.com)*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.*  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)*  Copyright (C) 2007 Maks Orlovich*  Copyright (C) 2007 Eric Seidel <eric@webkit.org>**  This library is free software; you can redistribute it and/or*  modify it under the terms of the GNU Library General Public*  License as published by the Free Software Foundation; either*  version 2 of the License, or (at your option) any later version.**  This library is distributed in the hope that it will be useful,*  but WITHOUT ANY WARRANTY; without even the implied warranty of*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU*  Library General Public License for more details.**  You should have received a copy of the GNU Library General Public License*  along with this library; see the file COPYING.LIB.  If not, write to*  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,*  Boston, MA 02110-1301, USA.**/#include "config.h"#include "Nodes.h"#include "BytecodeGenerator.h"#include "CallFrame.h"#include "JSGlobalObject.h"#include "JSStaticScopeObject.h"#include "LabelScope.h"#include "Parser.h"#include "PropertyNameArray.h"#include "RegExpObject.h"#include "SamplingTool.h"#include "Debugger.h"#include "Lexer.h"#include "Operations.h"#include <math.h>#include <wtf/Assertions.h>#include <wtf/HashCountedSet.h>#include <wtf/HashSet.h>#include <wtf/MathExtras.h>#include <wtf/RefCountedLeakCounter.h>#include <wtf/Threading.h>using namespace WTF;namespace JSC {static void substitute(UString& string, const UString& substring) JSC_FAST_CALL;// ------------------------------ NodeReleaser --------------------------------class NodeReleaser : Noncopyable {public:    // Call this function inside the destructor of a class derived from Node.    // This will traverse the tree below this node, destroying all of those nodes,    // but without relying on recursion.    static void releaseAllNodes(ParserRefCounted* root);    // Call this on each node in a the releaseNodes virtual function.    // It gives the node to the NodeReleaser, which will then release the    // node later at the end of the releaseAllNodes process.    template <typename T> void release(RefPtr<T>& node) { if (node) adopt(node.release()); }    void release(RefPtr<FunctionBodyNode>& node) { if (node) adoptFunctionBodyNode(node); }private:    NodeReleaser() { }    ~NodeReleaser() { }    void adopt(PassRefPtr<ParserRefCounted>);    void adoptFunctionBodyNode(RefPtr<FunctionBodyNode>&);    typedef Vector<RefPtr<ParserRefCounted> > NodeReleaseVector;    OwnPtr<NodeReleaseVector> m_vector;};void NodeReleaser::releaseAllNodes(ParserRefCounted* root){    ASSERT(root);    NodeReleaser releaser;    root->releaseNodes(releaser);    if (!releaser.m_vector)        return;    // Note: The call to release.m_vector->size() is intentionally inside    // the loop, since calls to releaseNodes are expected to increase the size.    for (size_t i = 0; i < releaser.m_vector->size(); ++i) {        ParserRefCounted* node = (*releaser.m_vector)[i].get();        if (node->hasOneRef())            node->releaseNodes(releaser);    }}void NodeReleaser::adopt(PassRefPtr<ParserRefCounted> node){    ASSERT(node);    if (!node->hasOneRef())        return;    if (!m_vector)        m_vector.set(new NodeReleaseVector);    m_vector->append(node);}void NodeReleaser::adoptFunctionBodyNode(RefPtr<FunctionBodyNode>& functionBodyNode){    // This sidesteps a problem where if you assign a PassRefPtr<FunctionBodyNode>    // to a PassRefPtr<Node> we leave the two reference counts (FunctionBodyNode    // and ParserRefCounted) unbalanced. It would be nice to fix this problem in    // a cleaner way -- perhaps we could remove the FunctionBodyNode reference    // count at some point.    RefPtr<Node> node = functionBodyNode;    functionBodyNode = 0;    adopt(node.release());}// ------------------------------ ParserRefCounted -----------------------------------------#ifndef NDEBUGstatic RefCountedLeakCounter parserRefCountedCounter("JSC::Node");#endifParserRefCounted::ParserRefCounted(JSGlobalData* globalData)    : m_globalData(globalData){#ifndef NDEBUG    parserRefCountedCounter.increment();#endif    if (!m_globalData->newParserObjects)        m_globalData->newParserObjects = new HashSet<ParserRefCounted*>;    m_globalData->newParserObjects->add(this);    ASSERT(m_globalData->newParserObjects->contains(this));}ParserRefCounted::~ParserRefCounted(){#ifndef NDEBUG    parserRefCountedCounter.decrement();#endif}void ParserRefCounted::releaseNodes(NodeReleaser&){}void ParserRefCounted::ref(){    // bumping from 0 to 1 is just removing from the new nodes set    if (m_globalData->newParserObjects) {        HashSet<ParserRefCounted*>::iterator it = m_globalData->newParserObjects->find(this);        if (it != m_globalData->newParserObjects->end()) {            m_globalData->newParserObjects->remove(it);            ASSERT(!m_globalData->parserObjectExtraRefCounts || !m_globalData->parserObjectExtraRefCounts->contains(this));            return;        }    }    ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));    if (!m_globalData->parserObjectExtraRefCounts)        m_globalData->parserObjectExtraRefCounts = new HashCountedSet<ParserRefCounted*>;    m_globalData->parserObjectExtraRefCounts->add(this);}void ParserRefCounted::deref(){    ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));    if (!m_globalData->parserObjectExtraRefCounts) {        delete this;        return;    }    HashCountedSet<ParserRefCounted*>::iterator it = m_globalData->parserObjectExtraRefCounts->find(this);    if (it == m_globalData->parserObjectExtraRefCounts->end())        delete this;    else        m_globalData->parserObjectExtraRefCounts->remove(it);}bool ParserRefCounted::hasOneRef(){    if (m_globalData->newParserObjects && m_globalData->newParserObjects->contains(this)) {        ASSERT(!m_globalData->parserObjectExtraRefCounts || !m_globalData->parserObjectExtraRefCounts->contains(this));        return false;    }    ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));    if (!m_globalData->parserObjectExtraRefCounts)        return true;    return !m_globalData->parserObjectExtraRefCounts->contains(this);}void ParserRefCounted::deleteNewObjects(JSGlobalData* globalData){    if (!globalData->newParserObjects)        return;#ifndef NDEBUG    HashSet<ParserRefCounted*>::iterator end = globalData->newParserObjects->end();    for (HashSet<ParserRefCounted*>::iterator it = globalData->newParserObjects->begin(); it != end; ++it)        ASSERT(!globalData->parserObjectExtraRefCounts || !globalData->parserObjectExtraRefCounts->contains(*it));#endif    deleteAllValues(*globalData->newParserObjects);    delete globalData->newParserObjects;    globalData->newParserObjects = 0;}// ------------------------------ Node --------------------------------Node::Node(JSGlobalData* globalData)    : ParserRefCounted(globalData){    m_line = globalData->lexer->lineNo();}// ------------------------------ ThrowableExpressionData --------------------------------static void substitute(UString& string, const UString& substring){    int position = string.find("%s");    ASSERT(position != -1);    UString newString = string.substr(0, position);    newString.append(substring);    newString.append(string.substr(position + 2));    string = newString;}RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg){    generator.emitExpressionInfo(divot(), startOffset(), endOffset());    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), msg));    generator.emitThrow(exception);    return exception;}RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label){    UString message = msg;    substitute(message, label.ustring());    generator.emitExpressionInfo(divot(), startOffset(), endOffset());    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), message));    generator.emitThrow(exception);    return exception;}    // ------------------------------ StatementNode --------------------------------StatementNode::StatementNode(JSGlobalData* globalData)    : Node(globalData)    , m_lastLine(-1){}void StatementNode::setLoc(int firstLine, int lastLine){    m_line = firstLine;    m_lastLine = lastLine;}// ------------------------------ SourceElements --------------------------------void SourceElements::append(PassRefPtr<StatementNode> statement){    if (statement->isEmptyStatement())        return;    m_statements.append(statement);}// ------------------------------ NullNode -------------------------------------RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){    if (dst == generator.ignoredResult())        return 0;    return generator.emitLoad(dst, jsNull());}// ------------------------------ BooleanNode ----------------------------------RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){    if (dst == generator.ignoredResult())        return 0;    return generator.emitLoad(dst, m_value);}// ------------------------------ NumberNode -----------------------------------RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){    if (dst == generator.ignoredResult())        return 0;    return generator.emitLoad(dst, m_double);}// ------------------------------ StringNode -----------------------------------RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){    if (dst == generator.ignoredResult())        return 0;    return generator.emitLoad(dst, m_value);}// ------------------------------ RegExpNode -----------------------------------RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){    RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags);    if (!regExp->isValid())        return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str());    if (dst == generator.ignoredResult())        return 0;    return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());}// ------------------------------ ThisNode -------------------------------------RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){    if (dst == generator.ignoredResult())        return 0;    return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());}// ------------------------------ ResolveNode ----------------------------------bool ResolveNode::isPure(BytecodeGenerator& generator) const{    return generator.isLocal(m_ident);}RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){    if (RegisterID* local = generator.registerFor(m_ident)) {        if (dst == generator.ignoredResult())            return 0;        return generator.moveToDestinationIfNeeded(dst, local);    }        generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0);    return generator.emitResolve(generator.finalDestination(dst), m_ident);}// ------------------------------ ElementNode ------------------------------------ElementNode::~ElementNode(){    NodeReleaser::releaseAllNodes(this);}void ElementNode::releaseNodes(NodeReleaser& releaser){    releaser.release(m_next);    releaser.release(m_node);}// ------------------------------ ArrayNode ------------------------------------ArrayNode::~ArrayNode(){    NodeReleaser::releaseAllNodes(this);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -