[webkit-changes] cvs commit: JavaScriptCore/kjs shared_ptr.h function.cpp function.h function_object.cpp grammar.y internal.cpp internal.h nodes.cpp nodes.h nodes2string.cpp

Maciej mjs at opensource.apple.com
Fri Aug 26 16:42:19 PDT 2005


mjs         05/08/26 16:42:18

  Modified:    .        ChangeLog
               JavaScriptCore.xcodeproj project.pbxproj
               kjs      function.cpp function.h function_object.cpp
                        grammar.y internal.cpp internal.h nodes.cpp nodes.h
                        nodes2string.cpp
  Added:       kjs      shared_ptr.h
  Log:
          Reviewed by John.
  
  	- fixed <rdar://problem/4232452> many many leaks in kjsyyparse on some well-formed JavaScript (can repro on sony.com, webkit tests)
  
  	Fixed by changing the refcounting scheme for nodes. Instead of each node implementing a custom ref and
  	deref for all its children (and being responsible for deleting them), nodes use a smart pointer to
  	hold their children, and smart pointers are used outside the node tree as well. This change mostly
  	removes code.
  
  	* JavaScriptCore.xcodeproj/project.pbxproj:
          * kjs/function.cpp:
          (KJS::DeclaredFunctionImp::DeclaredFunctionImp):
          (KJS::GlobalFuncImp::callAsFunction):
          * kjs/function.h:
          * kjs/function_object.cpp:
          (FunctionObjectImp::construct):
          * kjs/grammar.y:
          * kjs/internal.cpp:
          (KJS::Parser::parse):
          (KJS::Parser::accept):
          (KJS::InterpreterImp::checkSyntax):
          (KJS::InterpreterImp::evaluate):
          * kjs/internal.h:
          * kjs/nodes.cpp:
          (Node::Node):
          (Node::~Node):
          (ElementNode::evaluate):
          (PropertyValueNode::evaluate):
          (ArgumentListNode::evaluateList):
          (NewExprNode::evaluate):
          (FunctionCallValueNode::evaluate):
          (FunctionCallBracketNode::evaluate):
          (FunctionCallDotNode::evaluate):
          (RelationalNode::evaluate):
          (StatListNode::execute):
          (StatListNode::processVarDecls):
          (VarDeclListNode::evaluate):
          (VarDeclListNode::processVarDecls):
          (ForInNode::ForInNode):
          (ClauseListNode::processVarDecls):
          (CaseBlockNode::evalBlock):
          (FuncDeclNode::processFuncDecl):
          (FuncExprNode::evaluate):
          (SourceElementsNode::execute):
          (SourceElementsNode::processFuncDecl):
          (SourceElementsNode::processVarDecls):
          * kjs/nodes.h:
          (KJS::Node::ref):
          (KJS::Node::deref):
          (KJS::NumberNode::NumberNode):
          (KJS::GroupNode::GroupNode):
          (KJS::ElementNode::ElementNode):
          (KJS::ArrayNode::ArrayNode):
          (KJS::PropertyValueNode::PropertyValueNode):
          (KJS::ObjectLiteralNode::ObjectLiteralNode):
          (KJS::BracketAccessorNode::BracketAccessorNode):
          (KJS::DotAccessorNode::DotAccessorNode):
          (KJS::ArgumentListNode::ArgumentListNode):
          (KJS::ArgumentsNode::ArgumentsNode):
          (KJS::NewExprNode::NewExprNode):
          (KJS::FunctionCallValueNode::FunctionCallValueNode):
          (KJS::FunctionCallResolveNode::FunctionCallResolveNode):
          (KJS::FunctionCallBracketNode::FunctionCallBracketNode):
          (KJS::FunctionCallDotNode::FunctionCallDotNode):
          (KJS::PostfixNode::PostfixNode):
          (KJS::DeleteNode::DeleteNode):
          (KJS::VoidNode::VoidNode):
          (KJS::TypeOfNode::TypeOfNode):
          (KJS::PrefixNode::PrefixNode):
          (KJS::UnaryPlusNode::UnaryPlusNode):
          (KJS::NegateNode::NegateNode):
          (KJS::BitwiseNotNode::BitwiseNotNode):
          (KJS::LogicalNotNode::LogicalNotNode):
          (KJS::MultNode::MultNode):
          (KJS::AddNode::AddNode):
          (KJS::ShiftNode::ShiftNode):
          (KJS::RelationalNode::RelationalNode):
          (KJS::EqualNode::EqualNode):
          (KJS::BitOperNode::BitOperNode):
          (KJS::BinaryLogicalNode::BinaryLogicalNode):
          (KJS::ConditionalNode::ConditionalNode):
          (KJS::AssignResolveNode::AssignResolveNode):
          (KJS::AssignBracketNode::AssignBracketNode):
          (KJS::AssignDotNode::AssignDotNode):
          (KJS::CommaNode::CommaNode):
          (KJS::AssignExprNode::AssignExprNode):
          (KJS::VarDeclListNode::VarDeclListNode):
          (KJS::VarStatementNode::VarStatementNode):
          (KJS::ExprStatementNode::ExprStatementNode):
          (KJS::IfNode::IfNode):
          (KJS::DoWhileNode::DoWhileNode):
          (KJS::WhileNode::WhileNode):
          (KJS::ForNode::ForNode):
          (KJS::ReturnNode::ReturnNode):
          (KJS::WithNode::WithNode):
          (KJS::CaseClauseNode::CaseClauseNode):
          (KJS::ClauseListNode::ClauseListNode):
          (KJS::ClauseListNode::clause):
          (KJS::ClauseListNode::next):
          (KJS::SwitchNode::SwitchNode):
          (KJS::LabelNode::LabelNode):
          (KJS::ThrowNode::ThrowNode):
          (KJS::CatchNode::CatchNode):
          (KJS::FinallyNode::FinallyNode):
          (KJS::TryNode::TryNode):
          (KJS::ParameterNode::ParameterNode):
          (KJS::ParameterNode::nextParam):
          (KJS::FuncDeclNode::FuncDeclNode):
          (KJS::FuncExprNode::FuncExprNode):
          * kjs/nodes2string.cpp:
          (KJS::SourceStream::operator<<):
          (ElementNode::streamTo):
          (PropertyValueNode::streamTo):
          (ArgumentListNode::streamTo):
          (StatListNode::streamTo):
          (VarDeclListNode::streamTo):
          (CaseBlockNode::streamTo):
          (ParameterNode::streamTo):
          (SourceElementsNode::streamTo):
          * kjs/shared_ptr.h: Added.
          (kxmlcore::SharedPtr::SharedPtr):
          (kxmlcore::SharedPtr::~SharedPtr):
          (kxmlcore::SharedPtr::isNull):
          (kxmlcore::SharedPtr::notNull):
          (kxmlcore::SharedPtr::reset):
          (kxmlcore::SharedPtr::get):
          (kxmlcore::SharedPtr::operator*):
          (kxmlcore::SharedPtr::operator->):
          (kxmlcore::SharedPtr::operator!):
          (kxmlcore::SharedPtr::operator bool):
          (kxmlcore::SharedPtr::operator==):
          (kxmlcore::::operator):
          (kxmlcore::operator!=):
          (kxmlcore::static_pointer_cast):
          (kxmlcore::const_pointer_cast):
  
  Revision  Changes    Path
  1.808     +138 -0    JavaScriptCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/ChangeLog,v
  retrieving revision 1.807
  retrieving revision 1.808
  diff -u -r1.807 -r1.808
  --- ChangeLog	26 Aug 2005 17:58:26 -0000	1.807
  +++ ChangeLog	26 Aug 2005 23:42:16 -0000	1.808
  @@ -1,3 +1,141 @@
  +2005-08-26  Maciej Stachowiak  <mjs at apple.com>
  +
  +        Reviewed by John.
  +
  +	- fixed <rdar://problem/4232452> many many leaks in kjsyyparse on some well-formed JavaScript (can repro on sony.com, webkit tests)
  +        
  +	Fixed by changing the refcounting scheme for nodes. Instead of each node implementing a custom ref and
  +	deref for all its children (and being responsible for deleting them), nodes use a smart pointer to
  +	hold their children, and smart pointers are used outside the node tree as well. This change mostly
  +	removes code.
  +	
  +	* JavaScriptCore.xcodeproj/project.pbxproj:
  +        * kjs/function.cpp:
  +        (KJS::DeclaredFunctionImp::DeclaredFunctionImp):
  +        (KJS::GlobalFuncImp::callAsFunction):
  +        * kjs/function.h:
  +        * kjs/function_object.cpp:
  +        (FunctionObjectImp::construct):
  +        * kjs/grammar.y:
  +        * kjs/internal.cpp:
  +        (KJS::Parser::parse):
  +        (KJS::Parser::accept):
  +        (KJS::InterpreterImp::checkSyntax):
  +        (KJS::InterpreterImp::evaluate):
  +        * kjs/internal.h:
  +        * kjs/nodes.cpp:
  +        (Node::Node):
  +        (Node::~Node):
  +        (ElementNode::evaluate):
  +        (PropertyValueNode::evaluate):
  +        (ArgumentListNode::evaluateList):
  +        (NewExprNode::evaluate):
  +        (FunctionCallValueNode::evaluate):
  +        (FunctionCallBracketNode::evaluate):
  +        (FunctionCallDotNode::evaluate):
  +        (RelationalNode::evaluate):
  +        (StatListNode::execute):
  +        (StatListNode::processVarDecls):
  +        (VarDeclListNode::evaluate):
  +        (VarDeclListNode::processVarDecls):
  +        (ForInNode::ForInNode):
  +        (ClauseListNode::processVarDecls):
  +        (CaseBlockNode::evalBlock):
  +        (FuncDeclNode::processFuncDecl):
  +        (FuncExprNode::evaluate):
  +        (SourceElementsNode::execute):
  +        (SourceElementsNode::processFuncDecl):
  +        (SourceElementsNode::processVarDecls):
  +        * kjs/nodes.h:
  +        (KJS::Node::ref):
  +        (KJS::Node::deref):
  +        (KJS::NumberNode::NumberNode):
  +        (KJS::GroupNode::GroupNode):
  +        (KJS::ElementNode::ElementNode):
  +        (KJS::ArrayNode::ArrayNode):
  +        (KJS::PropertyValueNode::PropertyValueNode):
  +        (KJS::ObjectLiteralNode::ObjectLiteralNode):
  +        (KJS::BracketAccessorNode::BracketAccessorNode):
  +        (KJS::DotAccessorNode::DotAccessorNode):
  +        (KJS::ArgumentListNode::ArgumentListNode):
  +        (KJS::ArgumentsNode::ArgumentsNode):
  +        (KJS::NewExprNode::NewExprNode):
  +        (KJS::FunctionCallValueNode::FunctionCallValueNode):
  +        (KJS::FunctionCallResolveNode::FunctionCallResolveNode):
  +        (KJS::FunctionCallBracketNode::FunctionCallBracketNode):
  +        (KJS::FunctionCallDotNode::FunctionCallDotNode):
  +        (KJS::PostfixNode::PostfixNode):
  +        (KJS::DeleteNode::DeleteNode):
  +        (KJS::VoidNode::VoidNode):
  +        (KJS::TypeOfNode::TypeOfNode):
  +        (KJS::PrefixNode::PrefixNode):
  +        (KJS::UnaryPlusNode::UnaryPlusNode):
  +        (KJS::NegateNode::NegateNode):
  +        (KJS::BitwiseNotNode::BitwiseNotNode):
  +        (KJS::LogicalNotNode::LogicalNotNode):
  +        (KJS::MultNode::MultNode):
  +        (KJS::AddNode::AddNode):
  +        (KJS::ShiftNode::ShiftNode):
  +        (KJS::RelationalNode::RelationalNode):
  +        (KJS::EqualNode::EqualNode):
  +        (KJS::BitOperNode::BitOperNode):
  +        (KJS::BinaryLogicalNode::BinaryLogicalNode):
  +        (KJS::ConditionalNode::ConditionalNode):
  +        (KJS::AssignResolveNode::AssignResolveNode):
  +        (KJS::AssignBracketNode::AssignBracketNode):
  +        (KJS::AssignDotNode::AssignDotNode):
  +        (KJS::CommaNode::CommaNode):
  +        (KJS::AssignExprNode::AssignExprNode):
  +        (KJS::VarDeclListNode::VarDeclListNode):
  +        (KJS::VarStatementNode::VarStatementNode):
  +        (KJS::ExprStatementNode::ExprStatementNode):
  +        (KJS::IfNode::IfNode):
  +        (KJS::DoWhileNode::DoWhileNode):
  +        (KJS::WhileNode::WhileNode):
  +        (KJS::ForNode::ForNode):
  +        (KJS::ReturnNode::ReturnNode):
  +        (KJS::WithNode::WithNode):
  +        (KJS::CaseClauseNode::CaseClauseNode):
  +        (KJS::ClauseListNode::ClauseListNode):
  +        (KJS::ClauseListNode::clause):
  +        (KJS::ClauseListNode::next):
  +        (KJS::SwitchNode::SwitchNode):
  +        (KJS::LabelNode::LabelNode):
  +        (KJS::ThrowNode::ThrowNode):
  +        (KJS::CatchNode::CatchNode):
  +        (KJS::FinallyNode::FinallyNode):
  +        (KJS::TryNode::TryNode):
  +        (KJS::ParameterNode::ParameterNode):
  +        (KJS::ParameterNode::nextParam):
  +        (KJS::FuncDeclNode::FuncDeclNode):
  +        (KJS::FuncExprNode::FuncExprNode):
  +        * kjs/nodes2string.cpp:
  +        (KJS::SourceStream::operator<<):
  +        (ElementNode::streamTo):
  +        (PropertyValueNode::streamTo):
  +        (ArgumentListNode::streamTo):
  +        (StatListNode::streamTo):
  +        (VarDeclListNode::streamTo):
  +        (CaseBlockNode::streamTo):
  +        (ParameterNode::streamTo):
  +        (SourceElementsNode::streamTo):
  +        * kjs/shared_ptr.h: Added.
  +        (kxmlcore::SharedPtr::SharedPtr):
  +        (kxmlcore::SharedPtr::~SharedPtr):
  +        (kxmlcore::SharedPtr::isNull):
  +        (kxmlcore::SharedPtr::notNull):
  +        (kxmlcore::SharedPtr::reset):
  +        (kxmlcore::SharedPtr::get):
  +        (kxmlcore::SharedPtr::operator*):
  +        (kxmlcore::SharedPtr::operator->):
  +        (kxmlcore::SharedPtr::operator!):
  +        (kxmlcore::SharedPtr::operator bool):
  +        (kxmlcore::SharedPtr::operator==):
  +        (kxmlcore::::operator):
  +        (kxmlcore::operator!=):
  +        (kxmlcore::static_pointer_cast):
  +        (kxmlcore::const_pointer_cast):
  +
   2005-08-26  Geoff Garen  <ggaren at apple.com>
   
           Reviewed by John.
  
  
  
  1.9       +6 -0      JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
  
  Index: project.pbxproj
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- project.pbxproj	19 Aug 2005 01:39:37 -0000	1.8
  +++ project.pbxproj	26 Aug 2005 23:42:16 -0000	1.9
  @@ -31,6 +31,8 @@
   		65621E6E089E859700760F35 /* property_slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* property_slot.h */; settings = {ATTRIBUTES = (Private, ); }; };
   		65621E6F089E85D300760F35 /* property_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* property_slot.cpp */; };
   		65621E70089E85D300760F35 /* property_slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* property_slot.h */; settings = {ATTRIBUTES = (Private, ); }; };
  +		65EF2DF508BECC80000894BB /* shared_ptr.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EF2DF408BECC80000894BB /* shared_ptr.h */; settings = {ATTRIBUTES = (Private, ); }; };
  +		65EF2DF808BECC8A000894BB /* shared_ptr.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EF2DF408BECC80000894BB /* shared_ptr.h */; settings = {ATTRIBUTES = (Private, ); }; };
   		932F5B400822A1C700736975 /* array_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A84E0255597D01FF60F7 /* array_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
   		932F5B420822A1C700736975 /* collector.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8530255597D01FF60F7 /* collector.h */; settings = {ATTRIBUTES = (Private, ); }; };
   		932F5B430822A1C700736975 /* date_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8560255597D01FF60F7 /* date_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
  @@ -472,6 +474,7 @@
   		65AB004806261CBA0076DE63 /* interpreter_map.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = interpreter_map.cpp; sourceTree = "<group>"; };
   		65AB004906261CBA0076DE63 /* interpreter_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = interpreter_map.h; sourceTree = "<group>"; };
   		65C02FBB0637462A003E7EE6 /* protect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = protect.h; sourceTree = "<group>"; };
  +		65EF2DF408BECC80000894BB /* shared_ptr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = shared_ptr.h; sourceTree = "<group>"; };
   		700DA117065984CE00747C0B /* WebScriptObjectPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = WebScriptObjectPrivate.h; path = bindings/objc/WebScriptObjectPrivate.h; sourceTree = "<group>"; };
   		704FD35305697E6D003DBED9 /* bool_object.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = bool_object.h; sourceTree = "<group>"; };
   		704FD44505698F17003DBED9 /* runtime.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = runtime.cpp; path = bindings/runtime.cpp; sourceTree = "<group>"; };
  @@ -645,6 +648,7 @@
   			isa = PBXGroup;
   			children = (
   				65305EAE08A58DDE00F31E73 /* protected_object.h */,
  +				65EF2DF408BECC80000894BB /* shared_ptr.h */,
   				65621E6B089E859700760F35 /* property_slot.cpp */,
   				65621E6C089E859700760F35 /* property_slot.h */,
   				938772E5038BFE19008635CE /* array_instance.h */,
  @@ -919,6 +923,7 @@
   				932FC11D0824A6A3005B3C75 /* create_hash_table in Headers */,
   				65621E6E089E859700760F35 /* property_slot.h in Headers */,
   				93E26CCF08B2921900F85226 /* softlinking.h in Headers */,
  +				65EF2DF508BECC80000894BB /* shared_ptr.h in Headers */,
   			);
   			runOnlyForDeploymentPostprocessing = 0;
   		};
  @@ -1001,6 +1006,7 @@
   				65621E70089E85D300760F35 /* property_slot.h in Headers */,
   				A85D823F087B2822006A9172 /* create_hash_table in Headers */,
   				93E26CD008B2921900F85226 /* softlinking.h in Headers */,
  +				65EF2DF808BECC8A000894BB /* shared_ptr.h in Headers */,
   			);
   			runOnlyForDeploymentPostprocessing = 0;
   		};
  
  
  
  1.54      +7 -15     JavaScriptCore/kjs/function.cpp
  
  Index: function.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/function.cpp,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -r1.53 -r1.54
  --- function.cpp	16 Aug 2005 00:47:25 -0000	1.53
  +++ function.cpp	26 Aug 2005 23:42:17 -0000	1.54
  @@ -31,6 +31,7 @@
   #include "operations.h"
   #include "debugger.h"
   #include "context.h"
  +#include "shared_ptr.h"
   
   #include <stdio.h>
   #include <errno.h>
  @@ -42,6 +43,8 @@
   #include <unicode/uchar.h>
   #endif
   
  +using namespace kxmlcore;
  +
   namespace KJS {
   
   // ----------------------------- FunctionImp ----------------------------------
  @@ -303,16 +306,9 @@
   					 FunctionBodyNode *b, const ScopeChain &sc)
     : FunctionImp(exec,n), body(b)
   {
  -  body->ref();
     setScope(sc);
   }
   
  -DeclaredFunctionImp::~DeclaredFunctionImp()
  -{
  -  if ( body->deref() )
  -    delete body;
  -}
  -
   bool DeclaredFunctionImp::implementsConstruct() const
   {
     return true;
  @@ -793,7 +789,7 @@
           int sid;
           int errLine;
           UString errMsg;
  -        ProgramNode *progNode = Parser::parse(UString(), 0, s.data(),s.size(),&sid,&errLine,&errMsg);
  +        SharedPtr<ProgramNode> progNode(Parser::parse(UString(), 0, s.data(),s.size(),&sid,&errLine,&errMsg));
   
           Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
           if (dbg) {
  @@ -803,11 +799,10 @@
           }
   
           // no program node means a syntax occurred
  -        if (!progNode)
  +        if (!progNode) {
             return throwError(exec, SyntaxError, errMsg, errLine, sid, NULL);
  -        
  -        progNode->ref();
  -        
  +        }
  +
           // enter a new execution context
           ObjectImp *thisVal = static_cast<ObjectImp *>(exec->context().thisValue());
           ContextImp ctx(exec->dynamicInterpreter()->globalObject(),
  @@ -832,9 +827,6 @@
             exec->setException(c.value());
           else if (c.isValueCompletion())
               res = c.value();
  -
  -        if ( progNode->deref() )
  -          delete progNode;
         }
         break;
       }
  
  
  
  1.32      +1 -2      JavaScriptCore/kjs/function.h
  
  Index: function.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/function.h,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- function.h	12 Aug 2005 07:36:00 -0000	1.31
  +++ function.h	26 Aug 2005 23:42:17 -0000	1.32
  @@ -76,14 +76,13 @@
     public:
       DeclaredFunctionImp(ExecState *exec, const Identifier &n,
   			FunctionBodyNode *b, const ScopeChain &sc);
  -    ~DeclaredFunctionImp();
   
       bool implementsConstruct() const;
       ObjectImp *construct(ExecState *exec, const List &args);
   
       virtual Completion execute(ExecState *exec);
       CodeType codeType() const { return FunctionCode; }
  -    FunctionBodyNode *body;
  +    kxmlcore::SharedPtr<FunctionBodyNode> body;
   
       virtual const ClassInfo *classInfo() const { return &info; }
       static const ClassInfo info;
  
  
  
  1.30      +3 -2      JavaScriptCore/kjs/function_object.cpp
  
  Index: function_object.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/function_object.cpp,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- function_object.cpp	16 Aug 2005 00:47:25 -0000	1.29
  +++ function_object.cpp	26 Aug 2005 23:42:17 -0000	1.30
  @@ -34,6 +34,7 @@
   #include <string.h>
   
   using namespace KJS;
  +using namespace kxmlcore;
   
   // ------------------------------ FunctionPrototypeImp -------------------------
   
  @@ -197,7 +198,7 @@
     int sid;
     int errLine;
     UString errMsg;
  -  ProgramNode *progNode = Parser::parse(sourceURL, lineNumber, body.data(),body.size(),&sid,&errLine,&errMsg);
  +  SharedPtr<ProgramNode> progNode = Parser::parse(sourceURL, lineNumber, body.data(),body.size(),&sid,&errLine,&errMsg);
   
     // notify debugger that source has been parsed
     Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
  @@ -218,7 +219,7 @@
   
     ScopeChain scopeChain;
     scopeChain.push(exec->dynamicInterpreter()->globalObject());
  -  FunctionBodyNode *bodyNode = progNode;
  +  FunctionBodyNode *bodyNode = progNode.get();
   
     FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), bodyNode,
   					      scopeChain);
  
  
  
  1.26      +2 -2      JavaScriptCore/kjs/grammar.y
  
  Index: grammar.y
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/grammar.y,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- grammar.y	12 Aug 2005 07:36:00 -0000	1.25
  +++ grammar.y	26 Aug 2005 23:42:17 -0000	1.26
  @@ -692,9 +692,9 @@
   
   Program:
       /* nothing, empty script */      { $$ = new ProgramNode(0);
  -                                     Parser::progNode = $$; }
  +                                     Parser::accept($$); }
       | SourceElements                 { $$ = new ProgramNode($1);
  -                                     Parser::progNode = $$; }
  +                                     Parser::accept($$); }
   ;
   
   SourceElements:
  
  
  
  1.65      +22 -28    JavaScriptCore/kjs/internal.cpp
  
  Index: internal.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/internal.cpp,v
  retrieving revision 1.64
  retrieving revision 1.65
  diff -u -r1.64 -r1.65
  --- internal.cpp	16 Aug 2005 00:47:25 -0000	1.64
  +++ internal.cpp	26 Aug 2005 23:42:17 -0000	1.65
  @@ -53,6 +53,8 @@
   
   extern int kjsyyparse();
   
  +using namespace kxmlcore;
  +
   namespace KJS {
   
   #if !APPLE_CHANGES
  @@ -345,20 +347,22 @@
   
   // ------------------------------ Parser ---------------------------------------
   
  -ProgramNode *Parser::progNode = 0;
  +static SharedPtr<ProgramNode> *progNode;
   int Parser::sid = 0;
   
  -ProgramNode *Parser::parse(const UString &sourceURL, int startingLineNumber,
  -                           const UChar *code, unsigned int length, int *sourceId,
  -			   int *errLine, UString *errMsg)
  +SharedPtr<ProgramNode> Parser::parse(const UString &sourceURL, int startingLineNumber,
  +                                     const UChar *code, unsigned int length, int *sourceId,
  +                                     int *errLine, UString *errMsg)
   {
     if (errLine)
       *errLine = -1;
     if (errMsg)
       *errMsg = 0;
  -  
  +  if (!progNode)
  +    progNode = new SharedPtr<ProgramNode>;
  +
     Lexer::curr()->setCode(sourceURL, startingLineNumber, code, length);
  -  progNode = 0;
  +  *progNode = 0;
     sid++;
     if (sourceId)
       *sourceId = sid;
  @@ -368,8 +372,8 @@
     int parseError = kjsyyparse();
     bool lexError = Lexer::curr()->sawError();
     Lexer::curr()->doneParsing();
  -  ProgramNode *prog = progNode;
  -  progNode = 0;
  +  SharedPtr<ProgramNode> prog = *progNode;
  +  *progNode = 0;
   
     if (parseError || lexError) {
       int eline = Lexer::curr()->lineNo();
  @@ -377,18 +381,18 @@
         *errLine = eline;
       if (errMsg)
         *errMsg = "Parse error";
  -    if (prog) {
  -      // must ref and deref to clean up properly
  -      prog->ref();
  -      prog->deref();
  -      delete prog;
  -    }
  -    return 0;
  +    return SharedPtr<ProgramNode>();
     }
   
     return prog;
   }
   
  +void Parser::accept(ProgramNode *prog)
  +{
  +  *progNode = prog;
  +}
  +
  +
   // ------------------------------ InterpreterImp -------------------------------
   
   InterpreterImp* InterpreterImp::s_hook = 0L;
  @@ -611,15 +615,8 @@
   bool InterpreterImp::checkSyntax(const UString &code)
   {
     // Parser::parse() returns 0 in a syntax error occurs, so we just check for that
  -  ProgramNode *progNode = Parser::parse(UString(), 0, code.data(),code.size(),0,0,0);
  -  bool ok = (progNode != 0);
  -  if (progNode) {
  -    // must ref and deref to clean up properly
  -    progNode->ref();
  -    progNode->deref();
  -    delete progNode;
  -  }
  -  return ok;
  +  SharedPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(),code.size(),0,0,0);
  +  return progNode;
   }
   
   Completion InterpreterImp::evaluate(const UString &code, ValueImp *thisV, const UString &sourceURL, int startingLineNumber)
  @@ -642,7 +639,7 @@
     int sid;
     int errLine;
     UString errMsg;
  -  ProgramNode *progNode = Parser::parse(sourceURL, startingLineNumber, code.data(),code.size(),&sid,&errLine,&errMsg);
  +  SharedPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code.data(),code.size(),&sid,&errLine,&errMsg);
   
     // notify debugger that source has been parsed
     if (dbg) {
  @@ -670,7 +667,6 @@
     globExec.clearException();
   
     recursion++;
  -  progNode->ref();
   
     ObjectImp *globalObj = globalObject();
     ObjectImp *thisObj = globalObject();
  @@ -698,8 +694,6 @@
       res = progNode->execute(&newExec);
     }
   
  -  if (progNode->deref())
  -    delete progNode;
     recursion--;
   
   #if APPLE_CHANGES
  
  
  
  1.35      +5 -4      JavaScriptCore/kjs/internal.h
  
  Index: internal.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/internal.h,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- internal.h	14 Aug 2005 16:41:47 -0000	1.34
  +++ internal.h	26 Aug 2005 23:42:17 -0000	1.35
  @@ -32,6 +32,7 @@
   #include "types.h"
   #include "interpreter.h"
   #include "scope_chain.h"
  +#include "shared_ptr.h"
   
   #define I18N_NOOP(s) s
   
  @@ -194,11 +195,11 @@
      */
     class Parser {
     public:
  -    static ProgramNode *parse(const UString &sourceURL, int startingLineNumber,
  -                              const UChar *code, unsigned int length, int *sourceId = 0,
  -			      int *errLine = 0, UString *errMsg = 0);
  +    static kxmlcore::SharedPtr<ProgramNode> parse(const UString &sourceURL, int startingLineNumber,
  +                                                  const UChar *code, unsigned int length, int *sourceId = 0,
  +                                                  int *errLine = 0, UString *errMsg = 0);
  +    static void accept(ProgramNode *prog);
   
  -    static ProgramNode *progNode;
       static int sid;
     };
   
  
  
  
  1.77      +30 -1130  JavaScriptCore/kjs/nodes.cpp
  
  Index: nodes.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/nodes.cpp,v
  retrieving revision 1.76
  retrieving revision 1.77
  diff -u -r1.76 -r1.77
  --- nodes.cpp	19 Aug 2005 16:01:55 -0000	1.76
  +++ nodes.cpp	26 Aug 2005 23:42:17 -0000	1.77
  @@ -98,19 +98,11 @@
   {
     line = Lexer::curr()->lineNo();
     sourceURL = Lexer::curr()->sourceURL();
  -  refcount = 0;
  -#ifdef KJS_DEBUG_MEM
  -  if (!s_nodes)
  -    s_nodes = new std::list<Node *>;
  -  s_nodes->push_back(this);
  -#endif
  +  m_refcount = 0;
   }
   
   Node::~Node()
   {
  -#ifdef KJS_DEBUG_MEM
  -  s_nodes->remove( this );
  -#endif
   }
   
   Reference Node::evaluateReference(ExecState *exec)
  @@ -336,20 +328,6 @@
   
   // ------------------------------ GroupNode ------------------------------------
   
  -void GroupNode::ref()
  -{
  -  Node::ref();
  -  if ( group )
  -    group->ref();
  -}
  -
  -bool GroupNode::deref()
  -{
  -  if ( group && group->deref() )
  -    delete group;
  -  return Node::deref();
  -}
  -
   // ECMA 11.1.6
   ValueImp *GroupNode::evaluate(ExecState *exec)
   {
  @@ -363,34 +341,12 @@
   
   // ------------------------------ ElementNode ----------------------------------
   
  -void ElementNode::ref()
  -{
  -  for (ElementNode *n = this; n; n = n->list) {
  -    n->Node::ref();
  -    if (n->node)
  -      n->node->ref();
  -  }
  -}
  -
  -bool ElementNode::deref()
  -{
  -  ElementNode *next;
  -  for (ElementNode *n = this; n; n = next) {
  -    next = n->list;
  -    if (n->node && n->node->deref())
  -      delete n->node;
  -    if (n != this && n->Node::deref())
  -      delete n;
  -  }
  -  return Node::deref();
  -}
  -
   // ECMA 11.1.4
   ValueImp *ElementNode::evaluate(ExecState *exec)
   {
     ObjectImp *array = exec->lexicalInterpreter()->builtinArray()->construct(exec, List::empty());
     int length = 0;
  -  for (ElementNode *n = this; n; n = n->list) {
  +  for (ElementNode *n = this; n; n = n->list.get()) {
       ValueImp *val = n->node->evaluate(exec);
       KJS_CHECKEXCEPTIONVALUE
       length += n->elision;
  @@ -401,20 +357,6 @@
   
   // ------------------------------ ArrayNode ------------------------------------
   
  -void ArrayNode::ref()
  -{
  -  Node::ref();
  -  if ( element )
  -    element->ref();
  -}
  -
  -bool ArrayNode::deref()
  -{
  -  if ( element && element->deref() )
  -    delete element;
  -  return Node::deref();
  -}
  -
   // ECMA 11.1.4
   ValueImp *ArrayNode::evaluate(ExecState *exec)
   {
  @@ -439,20 +381,6 @@
   
   // ------------------------------ ObjectLiteralNode ----------------------------
   
  -void ObjectLiteralNode::ref()
  -{
  -  Node::ref();
  -  if ( list )
  -    list->ref();
  -}
  -
  -bool ObjectLiteralNode::deref()
  -{
  -  if ( list && list->deref() )
  -    delete list;
  -  return Node::deref();
  -}
  -
   // ECMA 11.1.5
   ValueImp *ObjectLiteralNode::evaluate(ExecState *exec)
   {
  @@ -464,38 +392,12 @@
   
   // ------------------------------ PropertyValueNode ----------------------------
   
  -void PropertyValueNode::ref()
  -{
  -  for (PropertyValueNode *n = this; n; n = n->list) {
  -    n->Node::ref();
  -    if (n->name)
  -      n->name->ref();
  -    if (n->assign)
  -      n->assign->ref();
  -  }
  -}
  -
  -bool PropertyValueNode::deref()
  -{
  -  PropertyValueNode *next;
  -  for (PropertyValueNode *n = this; n; n = next) {
  -    next = n->list;
  -    if ( n->name && n->name->deref() )
  -      delete n->name;
  -    if ( n->assign && n->assign->deref() )
  -      delete n->assign;
  -    if (n != this && n->Node::deref() )
  -      delete n;
  -  }
  -  return Node::deref();
  -}
  -
   // ECMA 11.1.5
   ValueImp *PropertyValueNode::evaluate(ExecState *exec)
   {
     ObjectImp *obj = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
     
  -  for (PropertyValueNode *p = this; p; p = p->list) {
  +  for (PropertyValueNode *p = this; p; p = p->list.get()) {
       ValueImp *n = p->name->evaluate(exec);
       KJS_CHECKEXCEPTIONVALUE
       ValueImp *v = p->assign->evaluate(exec);
  @@ -525,24 +427,6 @@
   
   // ------------------------------ BracketAccessorNode --------------------------------
   
  -void BracketAccessorNode::ref()
  -{
  -  Node::ref();
  -  if ( expr1 )
  -    expr1->ref();
  -  if ( expr2 )
  -    expr2->ref();
  -}
  -
  -bool BracketAccessorNode::deref()
  -{
  -  if ( expr1 && expr1->deref() )
  -    delete expr1;
  -  if ( expr2 && expr2->deref() )
  -    delete expr2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.2.1a
   ValueImp *BracketAccessorNode::evaluate(ExecState *exec)
   {
  @@ -572,20 +456,6 @@
   
   // ------------------------------ DotAccessorNode --------------------------------
   
  -void DotAccessorNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool DotAccessorNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.2.1b
   ValueImp *DotAccessorNode::evaluate(ExecState *exec)
   {
  @@ -605,28 +475,6 @@
   
   // ------------------------------ ArgumentListNode -----------------------------
   
  -void ArgumentListNode::ref()
  -{
  -  for (ArgumentListNode *n = this; n; n = n->list) {
  -    n->Node::ref();
  -    if (n->expr)
  -      n->expr->ref();
  -  }
  -}
  -
  -bool ArgumentListNode::deref()
  -{
  -  ArgumentListNode *next;
  -  for (ArgumentListNode *n = this; n; n = next) {
  -    next = n->list;
  -    if (n->expr && n->expr->deref())
  -      delete n->expr;
  -    if (n != this && n->Node::deref())
  -      delete n;
  -  }
  -  return Node::deref();
  -}
  -
   ValueImp *ArgumentListNode::evaluate(ExecState */*exec*/)
   {
     assert(0);
  @@ -638,7 +486,7 @@
   {
     List l;
   
  -  for (ArgumentListNode *n = this; n; n = n->list) {
  +  for (ArgumentListNode *n = this; n; n = n->list.get()) {
       ValueImp *v = n->expr->evaluate(exec);
       KJS_CHECKEXCEPTIONLIST
       l.append(v);
  @@ -649,20 +497,6 @@
   
   // ------------------------------ ArgumentsNode --------------------------------
   
  -void ArgumentsNode::ref()
  -{
  -  Node::ref();
  -  if ( list )
  -    list->ref();
  -}
  -
  -bool ArgumentsNode::deref()
  -{
  -  if ( list && list->deref() )
  -    delete list;
  -  return Node::deref();
  -}
  -
   ValueImp *ArgumentsNode::evaluate(ExecState */*exec*/)
   {
     assert(0);
  @@ -682,24 +516,6 @@
   
   // ECMA 11.2.2
   
  -void NewExprNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -  if ( args )
  -    args->ref();
  -}
  -
  -bool NewExprNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  if ( args && args->deref() )
  -    delete args;
  -  return Node::deref();
  -}
  -
   ValueImp *NewExprNode::evaluate(ExecState *exec)
   {
     ValueImp *v = expr->evaluate(exec);
  @@ -712,35 +528,17 @@
     }
   
     if (!v->isObject()) {
  -    return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr);
  +    return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr.get());
     }
   
     ObjectImp *constr = static_cast<ObjectImp*>(v);
     if (!constr->implementsConstruct()) {
  -    return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr);
  +    return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr.get());
     }
   
     return constr->construct(exec, argList);
   }
   
  -void FunctionCallValueNode::ref()
  -{
  -  Node::ref();
  -  if (expr)
  -    expr->ref();
  -  if (args)
  -    args->ref();
  -}
  -
  -bool FunctionCallValueNode::deref()
  -{
  -  if (expr && expr->deref())
  -    delete expr;
  -  if (args && args->deref())
  -    delete args;
  -  return Node::deref();
  -}
  -
   // ECMA 11.2.3
   ValueImp *FunctionCallValueNode::evaluate(ExecState *exec)
   {
  @@ -748,13 +546,13 @@
     KJS_CHECKEXCEPTIONVALUE
   
     if (!v->isObject()) {
  -    return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, expr);
  +    return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, expr.get());
     }
     
     ObjectImp *func = static_cast<ObjectImp*>(v);
   
     if (!func->implementsCall()) {
  -    return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr);
  +    return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr.get());
     }
   
     List argList = args->evaluateList(exec);
  @@ -765,21 +563,6 @@
     return func->call(exec, thisObj, argList);
   }
   
  -
  -void FunctionCallResolveNode::ref()
  -{
  -  Node::ref();
  -  if (args)
  -    args->ref();
  -}
  -
  -bool FunctionCallResolveNode::deref()
  -{
  -  if (args && args->deref())
  -    delete args;
  -  return Node::deref();
  -}
  -
   // ECMA 11.2.3
   ValueImp *FunctionCallResolveNode::evaluate(ExecState *exec)
   {
  @@ -829,28 +612,6 @@
     return undefinedVariableError(exec, ident);
   }
   
  -void FunctionCallBracketNode::ref()
  -{
  -  Node::ref();
  -  if (base)
  -    base->ref();
  -  if (subscript)
  -    base->ref();
  -  if (args)
  -    args->ref();
  -}
  -
  -bool FunctionCallBracketNode::deref()
  -{
  -  if (base && base->deref())
  -    delete base;
  -  if (subscript && subscript->deref())
  -    delete subscript;
  -  if (args && args->deref())
  -    delete args;
  -  return Node::deref();
  -}
  -
   // ECMA 11.2.3
   ValueImp *FunctionCallBracketNode::evaluate(ExecState *exec)
   {
  @@ -880,13 +641,13 @@
     KJS_CHECKEXCEPTIONVALUE
     
     if (!funcVal->isObject()) {
  -    return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, base, subscript);
  +    return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, base.get(), subscript.get());
     }
     
     ObjectImp *func = static_cast<ObjectImp*>(funcVal);
   
     if (!func->implementsCall()) {
  -    return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, base, subscript);
  +    return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, base.get(), subscript.get());
     }
   
     List argList = args->evaluateList(exec);
  @@ -900,25 +661,6 @@
     return func->call(exec, thisObj, argList);
   }
   
  -
  -void FunctionCallDotNode::ref()
  -{
  -  Node::ref();
  -  if (base)
  -    base->ref();
  -  if (args)
  -    args->ref();
  -}
  -
  -bool FunctionCallDotNode::deref()
  -{
  -  if (base && base->deref())
  -    delete base;
  -  if (args && args->deref())
  -    delete args;
  -  return Node::deref();
  -}
  -
   static const char *dotExprNotAnObjectString()
   {
     return "Value %s (result of expression %s.%s) is not object.";
  @@ -940,12 +682,12 @@
     KJS_CHECKEXCEPTIONVALUE
   
     if (!funcVal->isObject())
  -    return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, base, ident);
  +    return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, base.get(), ident);
     
     ObjectImp *func = static_cast<ObjectImp*>(funcVal);
   
     if (!func->implementsCall())
  -    return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, base, ident);
  +    return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, base.get(), ident);
   
     List argList = args->evaluateList(exec);
     KJS_CHECKEXCEPTIONVALUE
  @@ -960,20 +702,6 @@
   
   // ------------------------------ PostfixNode ----------------------------------
   
  -void PostfixNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool PostfixNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.3
   ValueImp *PostfixNode::evaluate(ExecState *exec)
   {
  @@ -992,20 +720,6 @@
   
   // ------------------------------ DeleteNode -----------------------------------
   
  -void DeleteNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool DeleteNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.4.1
   ValueImp *DeleteNode::evaluate(ExecState *exec)
   {
  @@ -1016,20 +730,6 @@
   
   // ------------------------------ VoidNode -------------------------------------
   
  -void VoidNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool VoidNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.4.2
   ValueImp *VoidNode::evaluate(ExecState *exec)
   {
  @@ -1041,20 +741,6 @@
   
   // ------------------------------ TypeOfNode -----------------------------------
   
  -void TypeOfNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool TypeOfNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.4.3
   ValueImp *TypeOfNode::evaluate(ExecState *exec)
   {
  @@ -1095,20 +781,6 @@
   
   // ------------------------------ PrefixNode -----------------------------------
   
  -void PrefixNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool PrefixNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.4.4 and 11.4.5
   ValueImp *PrefixNode::evaluate(ExecState *exec)
   {
  @@ -1129,20 +801,6 @@
   
   // ------------------------------ UnaryPlusNode --------------------------------
   
  -void UnaryPlusNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool UnaryPlusNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.4.6
   ValueImp *UnaryPlusNode::evaluate(ExecState *exec)
   {
  @@ -1154,20 +812,6 @@
   
   // ------------------------------ NegateNode -----------------------------------
   
  -void NegateNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool NegateNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.4.7
   ValueImp *NegateNode::evaluate(ExecState *exec)
   {
  @@ -1181,20 +825,6 @@
   
   // ------------------------------ BitwiseNotNode -------------------------------
   
  -void BitwiseNotNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool BitwiseNotNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.4.8
   ValueImp *BitwiseNotNode::evaluate(ExecState *exec)
   {
  @@ -1205,20 +835,6 @@
   
   // ------------------------------ LogicalNotNode -------------------------------
   
  -void LogicalNotNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool LogicalNotNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 11.4.9
   ValueImp *LogicalNotNode::evaluate(ExecState *exec)
   {
  @@ -1229,24 +845,6 @@
   
   // ------------------------------ MultNode -------------------------------------
   
  -void MultNode::ref()
  -{
  -  Node::ref();
  -  if ( term1 )
  -    term1->ref();
  -  if ( term2 )
  -    term2->ref();
  -}
  -
  -bool MultNode::deref()
  -{
  -  if ( term1 && term1->deref() )
  -    delete term1;
  -  if ( term2 && term2->deref() )
  -    delete term2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.5
   ValueImp *MultNode::evaluate(ExecState *exec)
   {
  @@ -1261,24 +859,6 @@
   
   // ------------------------------ AddNode --------------------------------------
   
  -void AddNode::ref()
  -{
  -  Node::ref();
  -  if ( term1 )
  -    term1->ref();
  -  if ( term2 )
  -    term2->ref();
  -}
  -
  -bool AddNode::deref()
  -{
  -  if ( term1 && term1->deref() )
  -    delete term1;
  -  if ( term2 && term2->deref() )
  -    delete term2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.6
   ValueImp *AddNode::evaluate(ExecState *exec)
   {
  @@ -1293,24 +873,6 @@
   
   // ------------------------------ ShiftNode ------------------------------------
   
  -void ShiftNode::ref()
  -{
  -  Node::ref();
  -  if ( term1 )
  -    term1->ref();
  -  if ( term2 )
  -    term2->ref();
  -}
  -
  -bool ShiftNode::deref()
  -{
  -  if ( term1 && term1->deref() )
  -    delete term1;
  -  if ( term2 && term2->deref() )
  -    delete term2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.7
   ValueImp *ShiftNode::evaluate(ExecState *exec)
   {
  @@ -1336,24 +898,6 @@
   
   // ------------------------------ RelationalNode -------------------------------
   
  -void RelationalNode::ref()
  -{
  -  Node::ref();
  -  if ( expr1 )
  -    expr1->ref();
  -  if ( expr2 )
  -    expr2->ref();
  -}
  -
  -bool RelationalNode::deref()
  -{
  -  if ( expr1 && expr1->deref() )
  -    delete expr1;
  -  if ( expr2 && expr2->deref() )
  -    delete expr2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.8
   ValueImp *RelationalNode::evaluate(ExecState *exec)
   {
  @@ -1379,13 +923,13 @@
         // Is all of this OK for host objects?
         if (!v2->isObject())
             return throwError(exec,  TypeError,
  -                             "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2);
  +                             "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2.get());
         ObjectImp *o2(static_cast<ObjectImp*>(v2));
         b = o2->hasProperty(exec, Identifier(v1->toString(exec)));
     } else {
       if (!v2->isObject())
           return throwError(exec,  TypeError,
  -                           "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2);
  +                           "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2.get());
   
       ObjectImp *o2(static_cast<ObjectImp*>(v2));
       if (!o2->implementsHasInstance()) {
  @@ -1405,24 +949,6 @@
   
   // ------------------------------ EqualNode ------------------------------------
   
  -void EqualNode::ref()
  -{
  -  Node::ref();
  -  if ( expr1 )
  -    expr1->ref();
  -  if ( expr2 )
  -    expr2->ref();
  -}
  -
  -bool EqualNode::deref()
  -{
  -  if ( expr1 && expr1->deref() )
  -    delete expr1;
  -  if ( expr2 && expr2->deref() )
  -    delete expr2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.9
   ValueImp *EqualNode::evaluate(ExecState *exec)
   {
  @@ -1446,24 +972,6 @@
   
   // ------------------------------ BitOperNode ----------------------------------
   
  -void BitOperNode::ref()
  -{
  -  Node::ref();
  -  if ( expr1 )
  -    expr1->ref();
  -  if ( expr2 )
  -    expr2->ref();
  -}
  -
  -bool BitOperNode::deref()
  -{
  -  if ( expr1 && expr1->deref() )
  -    delete expr1;
  -  if ( expr2 && expr2->deref() )
  -    delete expr2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.10
   ValueImp *BitOperNode::evaluate(ExecState *exec)
   {
  @@ -1486,24 +994,6 @@
   
   // ------------------------------ BinaryLogicalNode ----------------------------
   
  -void BinaryLogicalNode::ref()
  -{
  -  Node::ref();
  -  if ( expr1 )
  -    expr1->ref();
  -  if ( expr2 )
  -    expr2->ref();
  -}
  -
  -bool BinaryLogicalNode::deref()
  -{
  -  if ( expr1 && expr1->deref() )
  -    delete expr1;
  -  if ( expr2 && expr2->deref() )
  -    delete expr2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.11
   ValueImp *BinaryLogicalNode::evaluate(ExecState *exec)
   {
  @@ -1521,28 +1011,6 @@
   
   // ------------------------------ ConditionalNode ------------------------------
   
  -void ConditionalNode::ref()
  -{
  -  Node::ref();
  -  if ( expr1 )
  -    expr1->ref();
  -  if ( expr2 )
  -    expr2->ref();
  -  if ( logical )
  -    logical->ref();
  -}
  -
  -bool ConditionalNode::deref()
  -{
  -  if ( expr1 && expr1->deref() )
  -    delete expr1;
  -  if ( expr2 && expr2->deref() )
  -    delete expr2;
  -  if ( logical && logical->deref() )
  -    delete logical;
  -  return Node::deref();
  -}
  -
   // ECMA 11.12
   ValueImp *ConditionalNode::evaluate(ExecState *exec)
   {
  @@ -1631,21 +1099,6 @@
   
   // ------------------------------ AssignResolveNode -----------------------------------
   
  -void AssignResolveNode::ref()
  -{
  -  Node::ref();
  -  if (m_right)
  -    m_right->ref();
  -}
  -
  -bool AssignResolveNode::deref()
  -{
  -  if (m_right && m_right->deref())
  -    delete m_right;
  -
  -  return Node::deref();
  -}
  -
   ValueImp *AssignResolveNode::evaluate(ExecState *exec)
   {
     const ScopeChain& chain = exec->context().imp()->scopeChain();
  @@ -1688,24 +1141,6 @@
   
   // ------------------------------ AssignDotNode -----------------------------------
   
  -void AssignDotNode::ref()
  -{
  -  Node::ref();
  -  if (m_base)
  -    m_base->ref();
  -  if (m_right)
  -    m_right->ref();
  -}
  -
  -bool AssignDotNode::deref()
  -{
  -  if (m_base && m_base->deref())
  -    delete m_base;
  -  if (m_right && m_right->deref())
  -    delete m_right;
  -  return Node::deref();
  -}
  -
   ValueImp *AssignDotNode::evaluate(ExecState *exec)
   {
     ValueImp *baseValue = m_base->evaluate(exec);
  @@ -1732,29 +1167,6 @@
   
   // ------------------------------ AssignBracketNode -----------------------------------
   
  -void AssignBracketNode::ref()
  -{
  -  Node::ref();
  -  if (m_base)
  -    m_base->ref();
  -  if (m_subscript)
  -    m_subscript->ref();
  -  if (m_right)
  -    m_right->ref();
  -}
  -
  -bool AssignBracketNode::deref()
  -{
  -  if (m_base && m_base->deref())
  -    delete m_base;
  -  if (m_subscript && m_subscript->deref())
  -    delete m_subscript;
  -  if (m_right && m_right->deref())
  -    delete m_right;
  -
  -  return Node::deref();
  -}
  -
   ValueImp *AssignBracketNode::evaluate(ExecState *exec)
   {
     ValueImp *baseValue = m_base->evaluate(exec);
  @@ -1804,24 +1216,6 @@
   
   // ------------------------------ CommaNode ------------------------------------
   
  -void CommaNode::ref()
  -{
  -  Node::ref();
  -  if ( expr1 )
  -    expr1->ref();
  -  if ( expr2 )
  -    expr2->ref();
  -}
  -
  -bool CommaNode::deref()
  -{
  -  if ( expr1 && expr1->deref() )
  -    delete expr1;
  -  if ( expr2 && expr2->deref() )
  -    delete expr2;
  -  return Node::deref();
  -}
  -
   // ECMA 11.14
   ValueImp *CommaNode::evaluate(ExecState *exec)
   {
  @@ -1848,28 +1242,6 @@
     setLoc(l->firstLine(), s->lastLine(), l->sourceId());
   }
   
  -void StatListNode::ref()
  -{
  -  for (StatListNode *n = this; n; n = n->list) {
  -    n->Node::ref();
  -    if (n->statement)
  -      n->statement->ref();
  -  }
  -}
  -
  -bool StatListNode::deref()
  -{
  -  StatListNode *next;
  -  for (StatListNode *n = this; n; n = next) {
  -    next = n->list;
  -    if (n->statement && n->statement->deref())
  -      delete n->statement;
  -    if (n != this && n->Node::deref())
  -      delete n;
  -  }
  -  return Node::deref();
  -}
  -
   // ECMA 12.1
   Completion StatListNode::execute(ExecState *exec)
   {
  @@ -1886,7 +1258,7 @@
     
     ValueImp *v = c.value();
     
  -  for (StatListNode *n = list; n; n = n->list) {
  +  for (StatListNode *n = list.get(); n; n = n->list.get()) {
       Completion c2 = n->statement->execute(exec);
       KJS_ABORTPOINT
       if (c2.complType() != Normal)
  @@ -1908,26 +1280,12 @@
   
   void StatListNode::processVarDecls(ExecState *exec)
   {
  -  for (StatListNode *n = this; n; n = n->list)
  +  for (StatListNode *n = this; n; n = n->list.get())
       n->statement->processVarDecls(exec);
   }
   
   // ------------------------------ AssignExprNode -------------------------------
   
  -void AssignExprNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool AssignExprNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 12.2
   ValueImp *AssignExprNode::evaluate(ExecState *exec)
   {
  @@ -1942,20 +1300,6 @@
   {
   }
   
  -void VarDeclNode::ref()
  -{
  -  Node::ref();
  -  if ( init )
  -    init->ref();
  -}
  -
  -bool VarDeclNode::deref()
  -{
  -  if ( init && init->deref() )
  -    delete init;
  -  return Node::deref();
  -}
  -
   // ECMA 12.2
   ValueImp *VarDeclNode::evaluate(ExecState *exec)
   {
  @@ -2006,33 +1350,10 @@
   
   // ------------------------------ VarDeclListNode ------------------------------
   
  -void VarDeclListNode::ref()
  -{
  -  for (VarDeclListNode *n = this; n; n = n->list) {
  -    n->Node::ref();
  -    if (n->var)
  -      n->var->ref();
  -  }
  -}
  -
  -bool VarDeclListNode::deref()
  -{
  -  VarDeclListNode *next;
  -  for (VarDeclListNode *n = this; n; n = next) {
  -    next = n->list;
  -    if (n->var && n->var->deref())
  -      delete n->var;
  -    if (n != this && n->Node::deref())
  -      delete n;
  -  }
  -  return Node::deref();
  -}
  -
  -
   // ECMA 12.2
   ValueImp *VarDeclListNode::evaluate(ExecState *exec)
   {
  -  for (VarDeclListNode *n = this; n; n = n->list) {
  +  for (VarDeclListNode *n = this; n; n = n->list.get()) {
       n->var->evaluate(exec);
       KJS_CHECKEXCEPTIONVALUE
     }
  @@ -2041,26 +1362,12 @@
   
   void VarDeclListNode::processVarDecls(ExecState *exec)
   {
  -  for (VarDeclListNode *n = this; n; n = n->list)
  +  for (VarDeclListNode *n = this; n; n = n->list.get())
       n->var->processVarDecls(exec);
   }
   
   // ------------------------------ VarStatementNode -----------------------------
   
  -void VarStatementNode::ref()
  -{
  -  Node::ref();
  -  if ( list )
  -    list->ref();
  -}
  -
  -bool VarStatementNode::deref()
  -{
  -  if ( list && list->deref() )
  -    delete list;
  -  return Node::deref();
  -}
  -
   // ECMA 12.2
   Completion VarStatementNode::execute(ExecState *exec)
   {
  @@ -2090,20 +1397,6 @@
     }
   }
   
  -void BlockNode::ref()
  -{
  -  Node::ref();
  -  if ( source )
  -    source->ref();
  -}
  -
  -bool BlockNode::deref()
  -{
  -  if ( source && source->deref() )
  -    delete source;
  -  return Node::deref();
  -}
  -
   // ECMA 12.1
   Completion BlockNode::execute(ExecState *exec)
   {
  @@ -2131,20 +1424,6 @@
   
   // ------------------------------ ExprStatementNode ----------------------------
   
  -void ExprStatementNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool ExprStatementNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 12.4
   Completion ExprStatementNode::execute(ExecState *exec)
   {
  @@ -2158,28 +1437,6 @@
   
   // ------------------------------ IfNode ---------------------------------------
   
  -void IfNode::ref()
  -{
  -  Node::ref();
  -  if ( statement1 )
  -    statement1->ref();
  -  if ( statement2 )
  -    statement2->ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool IfNode::deref()
  -{
  -  if ( statement1 && statement1->deref() )
  -    delete statement1;
  -  if ( statement2 && statement2->deref() )
  -    delete statement2;
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 12.5
   Completion IfNode::execute(ExecState *exec)
   {
  @@ -2211,24 +1468,6 @@
   
   // ------------------------------ DoWhileNode ----------------------------------
   
  -void DoWhileNode::ref()
  -{
  -  Node::ref();
  -  if ( statement )
  -    statement->ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool DoWhileNode::deref()
  -{
  -  if ( statement && statement->deref() )
  -    delete statement;
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 12.6.1
   Completion DoWhileNode::execute(ExecState *exec)
   {
  @@ -2264,24 +1503,6 @@
   
   // ------------------------------ WhileNode ------------------------------------
   
  -void WhileNode::ref()
  -{
  -  Node::ref();
  -  if ( statement )
  -    statement->ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool WhileNode::deref()
  -{
  -  if ( statement && statement->deref() )
  -    delete statement;
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 12.6.2
   Completion WhileNode::execute(ExecState *exec)
   {
  @@ -2327,32 +1548,6 @@
   
   // ------------------------------ ForNode --------------------------------------
   
  -void ForNode::ref()
  -{
  -  Node::ref();
  -  if ( statement )
  -    statement->ref();
  -  if ( expr1 )
  -    expr1->ref();
  -  if ( expr2 )
  -    expr2->ref();
  -  if ( expr3 )
  -    expr3->ref();
  -}
  -
  -bool ForNode::deref()
  -{
  -  if ( statement && statement->deref() )
  -    delete statement;
  -  if ( expr1 && expr1->deref() )
  -    delete expr1;
  -  if ( expr2 && expr2->deref() )
  -    delete expr2;
  -  if ( expr3 && expr3->deref() )
  -    delete expr3;
  -  return Node::deref();
  -}
  -
   // ECMA 12.6.3
   Completion ForNode::execute(ExecState *exec)
   {
  @@ -2411,40 +1606,10 @@
     : ident(i), init(in), expr(e), statement(s)
   {
     // for( var foo = bar in baz )
  -  varDecl = new VarDeclNode(ident, init, VarDeclNode::Variable);
  +  varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
     lexpr = new ResolveNode(ident);
   }
   
  -void ForInNode::ref()
  -{
  -  Node::ref();
  -  if ( statement )
  -    statement->ref();
  -  if ( expr )
  -    expr->ref();
  -  if ( lexpr )
  -    lexpr->ref();
  -  if ( init )
  -    init->ref();
  -  if ( varDecl )
  -    varDecl->ref();
  -}
  -
  -bool ForInNode::deref()
  -{
  -  if ( statement && statement->deref() )
  -    delete statement;
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  if ( lexpr && lexpr->deref() )
  -    delete lexpr;
  -  if ( init && init->deref() )
  -    delete init;
  -  if ( varDecl && varDecl->deref() )
  -    delete varDecl;
  -  return Node::deref();
  -}
  -
   // ECMA 12.6.4
   Completion ForInNode::execute(ExecState *exec)
   {
  @@ -2551,20 +1716,6 @@
   
   // ------------------------------ ReturnNode -----------------------------------
   
  -void ReturnNode::ref()
  -{
  -  Node::ref();
  -  if ( value )
  -    value->ref();
  -}
  -
  -bool ReturnNode::deref()
  -{
  -  if ( value && value->deref() )
  -    delete value;
  -  return Node::deref();
  -}
  -
   // ECMA 12.9
   Completion ReturnNode::execute(ExecState *exec)
   {
  @@ -2586,24 +1737,6 @@
   
   // ------------------------------ WithNode -------------------------------------
   
  -void WithNode::ref()
  -{
  -  Node::ref();
  -  if ( statement )
  -    statement->ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool WithNode::deref()
  -{
  -  if ( statement && statement->deref() )
  -    delete statement;
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 12.10
   Completion WithNode::execute(ExecState *exec)
   {
  @@ -2627,24 +1760,6 @@
   
   // ------------------------------ CaseClauseNode -------------------------------
   
  -void CaseClauseNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -  if ( list )
  -    list->ref();
  -}
  -
  -bool CaseClauseNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  if ( list && list->deref() )
  -    delete list;
  -  return Node::deref();
  -}
  -
   // ECMA 12.11
   ValueImp *CaseClauseNode::evaluate(ExecState *exec)
   {
  @@ -2671,28 +1786,6 @@
   
   // ------------------------------ ClauseListNode -------------------------------
   
  -void ClauseListNode::ref()
  -{
  -  for (ClauseListNode *n = this; n; n = n->nx) {
  -    n->Node::ref();
  -    if (n->cl)
  -      n->cl->ref();
  -  }
  -}
  -
  -bool ClauseListNode::deref()
  -{
  -  ClauseListNode *next;
  -  for (ClauseListNode *n = this; n; n = next) {
  -    next = n->nx;
  -    if (n->cl && n->cl->deref())
  -      delete n->cl;
  -    if (n != this && n->Node::deref())
  -      delete n;
  -  }
  -  return Node::deref();
  -}
  -
   ValueImp *ClauseListNode::evaluate(ExecState */*exec*/)
   {
     /* should never be called */
  @@ -2703,7 +1796,7 @@
   // ECMA 12.11
   void ClauseListNode::processVarDecls(ExecState *exec)
   {
  -  for (ClauseListNode *n = this; n; n = n->nx)
  +  for (ClauseListNode *n = this; n; n = n->nx.get())
       if (n->cl)
         n->cl->processVarDecls(exec);
   }
  @@ -2730,28 +1823,6 @@
     }
   }
    
  -void CaseBlockNode::ref()
  -{
  -  Node::ref();
  -  if ( def )
  -    def->ref();
  -  if ( list1 )
  -    list1->ref();
  -  if ( list2 )
  -    list2->ref();
  -}
  -
  -bool CaseBlockNode::deref()
  -{
  -  if ( def && def->deref() )
  -    delete def;
  -  if ( list1 && list1->deref() )
  -    delete list1;
  -  if ( list2 && list2->deref() )
  -    delete list2;
  -  return Node::deref();
  -}
  -
   ValueImp *CaseBlockNode::evaluate(ExecState */*exec*/)
   {
     /* should never be called */
  @@ -2764,7 +1835,8 @@
   {
     ValueImp *v;
     Completion res;
  -  ClauseListNode *a = list1, *b = list2;
  +  ClauseListNode *a = list1.get();
  +  ClauseListNode *b = list2.get();
     CaseClauseNode *clause;
   
       while (a) {
  @@ -2805,7 +1877,7 @@
       if (res.complType() != Normal)
         return res;
     }
  -  b = list2;
  +  b = list2.get();
    step18:
     while (b) {
       clause = b->clause();
  @@ -2833,24 +1905,6 @@
   
   // ------------------------------ SwitchNode -----------------------------------
   
  -void SwitchNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -  if ( block )
  -    block->ref();
  -}
  -
  -bool SwitchNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  if ( block && block->deref() )
  -    delete block;
  -  return Node::deref();
  -}
  -
   // ECMA 12.11
   Completion SwitchNode::execute(ExecState *exec)
   {
  @@ -2875,20 +1929,6 @@
   
   // ------------------------------ LabelNode ------------------------------------
   
  -void LabelNode::ref()
  -{
  -  Node::ref();
  -  if ( statement )
  -    statement->ref();
  -}
  -
  -bool LabelNode::deref()
  -{
  -  if ( statement && statement->deref() )
  -    delete statement;
  -  return Node::deref();
  -}
  -
   // ECMA 12.12
   Completion LabelNode::execute(ExecState *exec)
   {
  @@ -2913,20 +1953,6 @@
   
   // ------------------------------ ThrowNode ------------------------------------
   
  -void ThrowNode::ref()
  -{
  -  Node::ref();
  -  if ( expr )
  -    expr->ref();
  -}
  -
  -bool ThrowNode::deref()
  -{
  -  if ( expr && expr->deref() )
  -    delete expr;
  -  return Node::deref();
  -}
  -
   // ECMA 12.13
   Completion ThrowNode::execute(ExecState *exec)
   {
  @@ -2940,20 +1966,6 @@
   
   // ------------------------------ CatchNode ------------------------------------
   
  -void CatchNode::ref()
  -{
  -  Node::ref();
  -  if ( block )
  -    block->ref();
  -}
  -
  -bool CatchNode::deref()
  -{
  -  if ( block && block->deref() )
  -    delete block;
  -  return Node::deref();
  -}
  -
   Completion CatchNode::execute(ExecState */*exec*/)
   {
     // should never be reached. execute(exec, arg) is used instead
  @@ -2984,20 +1996,6 @@
   
   // ------------------------------ FinallyNode ----------------------------------
   
  -void FinallyNode::ref()
  -{
  -  Node::ref();
  -  if ( block )
  -    block->ref();
  -}
  -
  -bool FinallyNode::deref()
  -{
  -  if ( block && block->deref() )
  -    delete block;
  -  return Node::deref();
  -}
  -
   // ECMA 12.14
   Completion FinallyNode::execute(ExecState *exec)
   {
  @@ -3011,28 +2009,6 @@
   
   // ------------------------------ TryNode --------------------------------------
   
  -void TryNode::ref()
  -{
  -  Node::ref();
  -  if ( block )
  -    block->ref();
  -  if ( _final )
  -    _final->ref();
  -  if ( _catch )
  -    _catch->ref();
  -}
  -
  -bool TryNode::deref()
  -{
  -  if ( block && block->deref() )
  -    delete block;
  -  if ( _final && _final->deref() )
  -    delete _final;
  -  if ( _catch && _catch->deref() )
  -    delete _catch;
  -  return Node::deref();
  -}
  -
   // ECMA 12.14
   Completion TryNode::execute(ExecState *exec)
   {
  @@ -3078,23 +2054,6 @@
   
   // ------------------------------ ParameterNode --------------------------------
   
  -void ParameterNode::ref()
  -{
  -  for (ParameterNode *n = this; n; n = n->next)
  -    n->Node::ref();
  -}
  -
  -bool ParameterNode::deref()
  -{
  -  ParameterNode *next;
  -  for (ParameterNode *n = this; n; n = next) {
  -    next = n->next;
  -    if (n != this && n->Node::deref())
  -      delete n;
  -  }
  -  return Node::deref();
  -}
  -
   // ECMA 13
   ValueImp *ParameterNode::evaluate(ExecState */*exec*/)
   {
  @@ -3118,31 +2077,13 @@
   
   // ------------------------------ FuncDeclNode ---------------------------------
   
  -void FuncDeclNode::ref()
  -{
  -  Node::ref();
  -  if ( param )
  -    param->ref();
  -  if ( body )
  -    body->ref();
  -}
  -
  -bool FuncDeclNode::deref()
  -{
  -  if ( param && param->deref() )
  -    delete param;
  -  if ( body && body->deref() )
  -    delete body;
  -  return Node::deref();
  -}
  -
   // ECMA 13
   void FuncDeclNode::processFuncDecl(ExecState *exec)
   {
     ContextImp *context = exec->context().imp();
   
     // TODO: let this be an object with [[Class]] property "Function"
  -  FunctionImp *fimp = new DeclaredFunctionImp(exec, ident, body, context->scopeChain());
  +  FunctionImp *fimp = new DeclaredFunctionImp(exec, ident, body.get(), context->scopeChain());
     ObjectImp *func(fimp); // protect from GC
   
     ObjectImp *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
  @@ -3150,7 +2091,7 @@
     func->put(exec, prototypePropertyName, proto, Internal|DontDelete);
   
     int plen = 0;
  -  for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
  +  for(ParameterNode *p = param.get(); p != 0L; p = p->nextParam(), plen++)
       fimp->addParameter(p->ident());
   
     func->put(exec, lengthPropertyName, Number(plen), ReadOnly|DontDelete|DontEnum);
  @@ -3172,35 +2113,16 @@
   
   // ------------------------------ FuncExprNode ---------------------------------
   
  -void FuncExprNode::ref()
  -{
  -  Node::ref();
  -  if ( param )
  -    param->ref();
  -  if ( body )
  -    body->ref();
  -}
  -
  -bool FuncExprNode::deref()
  -{
  -  if ( param && param->deref() )
  -    delete param;
  -  if ( body && body->deref() )
  -    delete body;
  -  return Node::deref();
  -}
  -
  -
   // ECMA 13
   ValueImp *FuncExprNode::evaluate(ExecState *exec)
   {
  -  FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), body, exec->context().imp()->scopeChain());
  +  FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), body.get(), exec->context().imp()->scopeChain());
     ValueImp *ret(fimp);
     ValueImp *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
     fimp->put(exec, prototypePropertyName, proto, Internal|DontDelete);
   
     int plen = 0;
  -  for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
  +  for(ParameterNode *p = param.get(); p != 0L; p = p->nextParam(), plen++)
       fimp->addParameter(p->ident());
   
     return ret;
  @@ -3221,28 +2143,6 @@
     setLoc(s1->firstLine(), s2->lastLine(), s1->sourceId());
   }
   
  -void SourceElementsNode::ref()
  -{
  -  for (SourceElementsNode *n = this; n; n = n->elements) {
  -    n->Node::ref();
  -    if (n->element)
  -      n->element->ref();
  -  }
  -}
  -
  -bool SourceElementsNode::deref()
  -{
  -  SourceElementsNode *next;
  -  for (SourceElementsNode *n = this; n; n = next) {
  -    next = n->elements;
  -    if (n->element && n->element->deref())
  -      delete n->element;
  -    if (n != this && n->Node::deref())
  -      delete n;
  -  }
  -  return Node::deref();
  -}
  -
   // ECMA 14
   Completion SourceElementsNode::execute(ExecState *exec)
   {
  @@ -3253,7 +2153,7 @@
     if (c1.complType() != Normal)
       return c1;
     
  -  for (SourceElementsNode *n = elements; n; n = n->elements) {
  +  for (SourceElementsNode *n = elements.get(); n; n = n->elements.get()) {
       Completion c2 = n->element->execute(exec);
       if (c2.complType() != Normal)
         return c2;
  @@ -3269,13 +2169,13 @@
   // ECMA 14
   void SourceElementsNode::processFuncDecl(ExecState *exec)
   {
  -  for (SourceElementsNode *n = this; n; n = n->elements)
  +  for (SourceElementsNode *n = this; n; n = n->elements.get())
       n->element->processFuncDecl(exec);
   }
   
   void SourceElementsNode::processVarDecls(ExecState *exec)
   {
  -  for (SourceElementsNode *n = this; n; n = n->elements)
  +  for (SourceElementsNode *n = this; n; n = n->elements.get())
       n->element->processVarDecls(exec);
   }
   
  
  
  
  1.28      +118 -238  JavaScriptCore/kjs/nodes.h
  
  Index: nodes.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/nodes.h,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- nodes.h	12 Aug 2005 19:58:17 -0000	1.27
  +++ nodes.h	26 Aug 2005 23:42:17 -0000	1.28
  @@ -26,6 +26,7 @@
   #define _NODES_H_
   
   #include "fast_malloc.h"
  +#include "shared_ptr.h"
   
   #include "internal.h"
   //#include "debugger.h"
  @@ -91,17 +92,9 @@
   
     public:
       // reference counting mechanism
  -    virtual void ref() { refcount++; }
  -#ifdef KJS_DEBUG_MEM
  -    virtual bool deref() { assert( refcount > 0 ); return (!--refcount); }
  -#else
  -    virtual bool deref() { return (!--refcount); }
  -#endif
  -
  +    void ref() { ++m_refcount; }
  +    void deref() { --m_refcount; if (!m_refcount) delete this; }
   
  -#ifdef KJS_DEBUG_MEM
  -    static void finalCheck();
  -#endif
     protected:
       ValueImp *throwError(ExecState *exec, ErrorType e, const char *msg);
       ValueImp *throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Node *expr);
  @@ -113,13 +106,9 @@
       void setExceptionDetailsIfNeeded(ExecState *exec);
       int line;
       UString sourceURL;
  -    unsigned int refcount;
  +    unsigned int m_refcount;
       virtual int sourceId() const { return -1; }
     private:
  -#ifdef KJS_DEBUG_MEM
  -    // List of all nodes, for debugging purposes. Don't remove!
  -    static std::list<Node *> *s_nodes;
  -#endif
       // disallow assignment
       Node& operator=(const Node&);
       Node(const Node &other);
  @@ -164,7 +153,7 @@
   
     class NumberNode : public Node {
     public:
  -    NumberNode(double v) : value(v) { }
  +    NumberNode(double v) : value(v) {}
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  @@ -210,13 +199,11 @@
     class GroupNode : public Node {
     public:
       GroupNode(Node *g) : group(g) { }
  -    virtual void ref();
  -    virtual bool deref();
       virtual ValueImp *evaluate(ExecState *exec);
       virtual Reference evaluateReference(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *group;
  +    kxmlcore::SharedPtr<Node> group;
     };
   
     class ElementNode : public Node {
  @@ -225,15 +212,13 @@
       ElementNode(int e, Node *n) : list(this), elision(e), node(n) { }
       ElementNode(ElementNode *l, int e, Node *n)
         : list(l->list), elision(e), node(n) { l->list = this; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       friend class ArrayNode;
  -    ElementNode *list;
  +    kxmlcore::SharedPtr<ElementNode> list;
       int elision;
  -    Node *node;
  +    kxmlcore::SharedPtr<Node> node;
     };
   
     class ArrayNode : public Node {
  @@ -243,12 +228,10 @@
         : element(ele->list), elision(0), opt(false) { ele->list = 0; }
       ArrayNode(int eli, ElementNode *ele)
         : element(ele->list), elision(eli), opt(true) { ele->list = 0; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    ElementNode *element;
  +    kxmlcore::SharedPtr<ElementNode> element;
       int elision;
       bool opt;
     };
  @@ -260,27 +243,23 @@
         : name(n), assign(a), list(this) { }
       PropertyValueNode(PropertyNode *n, Node *a, PropertyValueNode *l)
         : name(n), assign(a), list(l->list) { l->list = this; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       friend class ObjectLiteralNode;
  -    PropertyNode *name;
  -    Node *assign;
  -    PropertyValueNode *list;
  +    kxmlcore::SharedPtr<PropertyNode> name;
  +    kxmlcore::SharedPtr<Node> assign;
  +    kxmlcore::SharedPtr<PropertyValueNode> list;
     };
   
     class ObjectLiteralNode : public Node {
     public:
       ObjectLiteralNode() : list(0) { }
       ObjectLiteralNode(PropertyValueNode *l) : list(l->list) { l->list = 0; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    PropertyValueNode *list;
  +    kxmlcore::SharedPtr<PropertyValueNode> list;
     };
   
     class PropertyNode : public Node {
  @@ -297,26 +276,22 @@
     class BracketAccessorNode : public Node {
     public:
       BracketAccessorNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual Reference evaluateReference(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr1;
  -    Node *expr2;
  +    kxmlcore::SharedPtr<Node> expr1;
  +    kxmlcore::SharedPtr<Node> expr2;
     };
   
     class DotAccessorNode : public Node {
     public:
       DotAccessorNode(Node *e, const Identifier &s) : expr(e), ident(s) { }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual Reference evaluateReference(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
       Identifier ident;
     };
   
  @@ -326,15 +301,13 @@
       ArgumentListNode(Node *e) : list(this), expr(e) { }
       ArgumentListNode(ArgumentListNode *l, Node *e)
         : list(l->list), expr(e) { l->list = this; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       List evaluateList(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       friend class ArgumentsNode;
  -    ArgumentListNode *list;
  -    Node *expr;
  +    kxmlcore::SharedPtr<ArgumentListNode> list;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class ArgumentsNode : public Node {
  @@ -342,63 +315,53 @@
       ArgumentsNode() : list(0) { }
       ArgumentsNode(ArgumentListNode *l)
         : list(l->list) { l->list = 0; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       List evaluateList(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    ArgumentListNode *list;
  +    kxmlcore::SharedPtr<ArgumentListNode> list;
     };
   
     class NewExprNode : public Node {
     public:
       NewExprNode(Node *e) : expr(e), args(0) {}
       NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  -    ArgumentsNode *args;
  +    kxmlcore::SharedPtr<Node> expr;
  +    kxmlcore::SharedPtr<ArgumentsNode> args;
     };
   
     class FunctionCallValueNode : public Node {
     public:
       FunctionCallValueNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  -    ArgumentsNode *args;
  +    kxmlcore::SharedPtr<Node> expr;
  +    kxmlcore::SharedPtr<ArgumentsNode> args;
     };
   
     class FunctionCallResolveNode : public Node {
     public:
       FunctionCallResolveNode(const Identifier& i, ArgumentsNode *a) : ident(i), args(a) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       Identifier ident;
  -    ArgumentsNode *args;
  +    kxmlcore::SharedPtr<ArgumentsNode> args;
     };
   
     class FunctionCallBracketNode : public Node {
     public:
       FunctionCallBracketNode(Node *b, Node *s, ArgumentsNode *a) : base(b), subscript(s), args(a) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     protected:
  -    Node *base;
  -    Node *subscript;
  -    ArgumentsNode *args;
  +    kxmlcore::SharedPtr<Node> base;
  +    kxmlcore::SharedPtr<Node> subscript;
  +    kxmlcore::SharedPtr<ArgumentsNode> args;
     };
   
     class FunctionCallParenBracketNode : public FunctionCallBracketNode {
  @@ -410,14 +373,12 @@
     class FunctionCallDotNode : public Node {
     public:
       FunctionCallDotNode(Node *b, const Identifier &i, ArgumentsNode *a) : base(b), ident(i), args(a) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     protected:
  -    Node *base;
  +    kxmlcore::SharedPtr<Node> base;
       Identifier ident;
  -    ArgumentsNode *args;
  +    kxmlcore::SharedPtr<ArgumentsNode> args;
     };
   
     class FunctionCallParenDotNode : public FunctionCallDotNode {
  @@ -429,125 +390,105 @@
     class PostfixNode : public Node {
     public:
       PostfixNode(Node *e, Operator o) : expr(e), oper(o) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
       Operator oper;
     };
   
     class DeleteNode : public Node {
     public:
       DeleteNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class VoidNode : public Node {
     public:
       VoidNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class TypeOfNode : public Node {
     public:
       TypeOfNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class PrefixNode : public Node {
     public:
       PrefixNode(Operator o, Node *e) : oper(o), expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       Operator oper;
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class UnaryPlusNode : public Node {
     public:
       UnaryPlusNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class NegateNode : public Node {
     public:
       NegateNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class BitwiseNotNode : public Node {
     public:
       BitwiseNotNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class LogicalNotNode : public Node {
     public:
       LogicalNotNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class MultNode : public Node {
     public:
       MultNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *term1, *term2;
  +    kxmlcore::SharedPtr<Node> term1;
  +    kxmlcore::SharedPtr<Node> term2;
       char oper;
     };
   
     class AddNode : public Node {
     public:
       AddNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *term1, *term2;
  +    kxmlcore::SharedPtr<Node> term1;
  +    kxmlcore::SharedPtr<Node> term2;
       char oper;
     };
   
  @@ -555,12 +496,11 @@
     public:
       ShiftNode(Node *t1, Operator o, Node *t2)
         : term1(t1), term2(t2), oper(o) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *term1, *term2;
  +    kxmlcore::SharedPtr<Node> term1;
  +    kxmlcore::SharedPtr<Node> term2;
       Operator oper;
     };
   
  @@ -568,12 +508,11 @@
     public:
       RelationalNode(Node *e1, Operator o, Node *e2) :
         expr1(e1), expr2(e2), oper(o) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr1, *expr2;
  +    kxmlcore::SharedPtr<Node> expr1;
  +    kxmlcore::SharedPtr<Node> expr2;
       Operator oper;
     };
   
  @@ -581,12 +520,11 @@
     public:
       EqualNode(Node *e1, Operator o, Node *e2)
         : expr1(e1), expr2(e2), oper(o) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr1, *expr2;
  +    kxmlcore::SharedPtr<Node> expr1;
  +    kxmlcore::SharedPtr<Node> expr2;
       Operator oper;
     };
   
  @@ -594,12 +532,11 @@
     public:
       BitOperNode(Node *e1, Operator o, Node *e2) :
         expr1(e1), expr2(e2), oper(o) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr1, *expr2;
  +    kxmlcore::SharedPtr<Node> expr1;
  +    kxmlcore::SharedPtr<Node> expr2;
       Operator oper;
     };
   
  @@ -610,12 +547,11 @@
     public:
       BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
         expr1(e1), expr2(e2), oper(o) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr1, *expr2;
  +    kxmlcore::SharedPtr<Node> expr1;
  +    kxmlcore::SharedPtr<Node> expr2;
       Operator oper;
     };
   
  @@ -626,67 +562,60 @@
     public:
       ConditionalNode(Node *l, Node *e1, Node *e2) :
         logical(l), expr1(e1), expr2(e2) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *logical, *expr1, *expr2;
  +    kxmlcore::SharedPtr<Node> logical;
  +    kxmlcore::SharedPtr<Node> expr1;
  +    kxmlcore::SharedPtr<Node> expr2;
     };
   
     class AssignResolveNode : public Node {
     public:
       AssignResolveNode(const Identifier &ident, Operator oper, Node *right) 
         : m_ident(ident), m_oper(oper), m_right(right) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     protected:
       Identifier m_ident;
       Operator m_oper;
  -    Node *m_right;
  +    kxmlcore::SharedPtr<Node> m_right;
     };
   
     class AssignBracketNode : public Node {
     public:
       AssignBracketNode(Node *base, Node *subscript, Operator oper, Node *right) 
         : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     protected:
  -    Node *m_base;
  -    Node *m_subscript;
  +    kxmlcore::SharedPtr<Node> m_base;
  +    kxmlcore::SharedPtr<Node> m_subscript;
       Operator m_oper;
  -    Node *m_right;
  +    kxmlcore::SharedPtr<Node> m_right;
     };
   
     class AssignDotNode : public Node {
     public:
       AssignDotNode(Node *base, const Identifier& ident, Operator oper, Node *right)
         : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     protected:
  -    Node *m_base;
  +    kxmlcore::SharedPtr<Node> m_base;
       Identifier m_ident;
       Operator m_oper;
  -    Node *m_right;
  +    kxmlcore::SharedPtr<Node> m_right;
     };
   
     class CommaNode : public Node {
     public:
       CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr1, *expr2;
  +    kxmlcore::SharedPtr<Node> expr1;
  +    kxmlcore::SharedPtr<Node> expr2;
     };
   
     class StatListNode : public StatementNode {
  @@ -694,41 +623,35 @@
       // list pointer is tail of a circular list, cracked in the CaseClauseNode ctor
       StatListNode(StatementNode *s);
       StatListNode(StatListNode *l, StatementNode *s);
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       friend class CaseClauseNode;
  -    StatementNode *statement;
  -    StatListNode *list;
  +    kxmlcore::SharedPtr<StatementNode> statement;
  +    kxmlcore::SharedPtr<StatListNode> list;
     };
   
     class AssignExprNode : public Node {
     public:
       AssignExprNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class VarDeclNode : public Node {
     public:
       enum Type { Variable, Constant };
       VarDeclNode(const Identifier &id, AssignExprNode *in, Type t);
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       Type varType;
       Identifier ident;
  -    AssignExprNode *init;
  +    kxmlcore::SharedPtr<AssignExprNode> init;
     };
   
     class VarDeclListNode : public Node {
  @@ -737,40 +660,34 @@
       VarDeclListNode(VarDeclNode *v) : list(this), var(v) {}
       VarDeclListNode(VarDeclListNode *l, VarDeclNode *v)
         : list(l->list), var(v) { l->list = this; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       friend class ForNode;
       friend class VarStatementNode;
  -    VarDeclListNode *list;
  -    VarDeclNode *var;
  +    kxmlcore::SharedPtr<VarDeclListNode> list;
  +    kxmlcore::SharedPtr<VarDeclNode> var;
     };
   
     class VarStatementNode : public StatementNode {
     public:
       VarStatementNode(VarDeclListNode *l) : list(l->list) { l->list = 0; }
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    VarDeclListNode *list;
  +    kxmlcore::SharedPtr<VarDeclListNode> list;
     };
   
     class BlockNode : public StatementNode {
     public:
       BlockNode(SourceElementsNode *s);
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     protected:
  -    SourceElementsNode *source;
  +    kxmlcore::SharedPtr<SourceElementsNode> source;
     };
   
     class EmptyStatementNode : public StatementNode {
  @@ -783,52 +700,45 @@
     class ExprStatementNode : public StatementNode {
     public:
       ExprStatementNode(Node *e) : expr(e) { }
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class IfNode : public StatementNode {
     public:
       IfNode(Node *e, StatementNode *s1, StatementNode *s2)
         : expr(e), statement1(s1), statement2(s2) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  -    StatementNode *statement1, *statement2;
  +    kxmlcore::SharedPtr<Node> expr;
  +    kxmlcore::SharedPtr<StatementNode> statement1;
  +    kxmlcore::SharedPtr<StatementNode> statement2;
     };
   
     class DoWhileNode : public StatementNode {
     public:
       DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    StatementNode *statement;
  -    Node *expr;
  +    kxmlcore::SharedPtr<StatementNode> statement;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class WhileNode : public StatementNode {
     public:
       WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  -    StatementNode *statement;
  +    kxmlcore::SharedPtr<Node> expr;
  +    kxmlcore::SharedPtr<StatementNode> statement;
     };
   
     class ForNode : public StatementNode {
  @@ -837,31 +747,30 @@
         expr1(e1), expr2(e2), expr3(e3), statement(s) {}
       ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) :
         expr1(e1->list), expr2(e2), expr3(e3), statement(s) { e1->list = 0; }
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr1, *expr2, *expr3;
  -    StatementNode *statement;
  +    kxmlcore::SharedPtr<Node> expr1;
  +    kxmlcore::SharedPtr<Node> expr2;
  +    kxmlcore::SharedPtr<Node> expr3;
  +    kxmlcore::SharedPtr<StatementNode> statement;
     };
   
     class ForInNode : public StatementNode {
     public:
       ForInNode(Node *l, Node *e, StatementNode *s);
       ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s);
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       Identifier ident;
  -    AssignExprNode *init;
  -    Node *lexpr, *expr;
  -    VarDeclNode *varDecl;
  -    StatementNode *statement;
  +    kxmlcore::SharedPtr<AssignExprNode> init;
  +    kxmlcore::SharedPtr<Node> lexpr;
  +    kxmlcore::SharedPtr<Node> expr;
  +    kxmlcore::SharedPtr<VarDeclNode> varDecl;
  +    kxmlcore::SharedPtr<StatementNode> statement;
     };
   
     class ContinueNode : public StatementNode {
  @@ -887,25 +796,21 @@
     class ReturnNode : public StatementNode {
     public:
       ReturnNode(Node *v) : value(v) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *value;
  +    kxmlcore::SharedPtr<Node> value;
     };
   
     class WithNode : public StatementNode {
     public:
       WithNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  -    StatementNode *statement;
  +    kxmlcore::SharedPtr<Node> expr;
  +    kxmlcore::SharedPtr<StatementNode> statement;
     };
   
     class CaseClauseNode : public Node {
  @@ -913,15 +818,13 @@
       CaseClauseNode(Node *e) : expr(e), list(0) { }
       CaseClauseNode(Node *e, StatListNode *l)
         : expr(e), list(l->list) { l->list = 0; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       Completion evalStatements(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  -    StatListNode *list;
  +    kxmlcore::SharedPtr<Node> expr;
  +    kxmlcore::SharedPtr<StatListNode> list;
     };
   
     class ClauseListNode : public Node {
  @@ -930,95 +833,81 @@
       ClauseListNode(CaseClauseNode *c) : cl(c), nx(this) { }
       ClauseListNode(ClauseListNode *n, CaseClauseNode *c)
         : cl(c), nx(n->nx) { n->nx = this; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
  -    CaseClauseNode *clause() const { return cl; }
  -    ClauseListNode *next() const { return nx; }
  +    CaseClauseNode *clause() const { return cl.get(); }
  +    ClauseListNode *next() const { return nx.get(); }
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       friend class CaseBlockNode;
  -    CaseClauseNode *cl;
  -    ClauseListNode *nx;
  +    kxmlcore::SharedPtr<CaseClauseNode> cl;
  +    kxmlcore::SharedPtr<ClauseListNode> nx;
     };
   
     class CaseBlockNode : public Node {
     public:
       CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2);
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       Completion evalBlock(ExecState *exec, ValueImp *input);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    ClauseListNode *list1;
  -    CaseClauseNode *def;
  -    ClauseListNode *list2;
  +    kxmlcore::SharedPtr<ClauseListNode> list1;
  +    kxmlcore::SharedPtr<CaseClauseNode> def;
  +    kxmlcore::SharedPtr<ClauseListNode> list2;
     };
   
     class SwitchNode : public StatementNode {
     public:
       SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  -    CaseBlockNode *block;
  +    kxmlcore::SharedPtr<Node> expr;
  +    kxmlcore::SharedPtr<CaseBlockNode> block;
     };
   
     class LabelNode : public StatementNode {
     public:
       LabelNode(const Identifier &l, StatementNode *s) : label(l), statement(s) { }
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       Identifier label;
  -    StatementNode *statement;
  +    kxmlcore::SharedPtr<StatementNode> statement;
     };
   
     class ThrowNode : public StatementNode {
     public:
       ThrowNode(Node *e) : expr(e) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    Node *expr;
  +    kxmlcore::SharedPtr<Node> expr;
     };
   
     class CatchNode : public StatementNode {
     public:
       CatchNode(const Identifier &i, StatementNode *b) : ident(i), block(b) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       Completion execute(ExecState *exec, ValueImp *arg);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       Identifier ident;
  -    StatementNode *block;
  +    kxmlcore::SharedPtr<StatementNode> block;
     };
   
     class FinallyNode : public StatementNode {
     public:
       FinallyNode(StatementNode *b) : block(b) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    StatementNode *block;
  +    kxmlcore::SharedPtr<StatementNode> block;
     };
   
     class TryNode : public StatementNode {
  @@ -1029,15 +918,13 @@
         : block(b), _catch(0), _final(f) {}
       TryNode(StatementNode *b, CatchNode *c, FinallyNode *f)
         : block(b), _catch(c), _final(f) {}
  -    virtual void ref();
  -    virtual bool deref();
       virtual Completion execute(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    StatementNode *block;
  -    CatchNode *_catch;
  -    FinallyNode *_final;
  +    kxmlcore::SharedPtr<StatementNode> block;
  +    kxmlcore::SharedPtr<CatchNode> _catch;
  +    kxmlcore::SharedPtr<FinallyNode> _final;
     };
   
     class ParameterNode : public Node {
  @@ -1046,17 +933,15 @@
       ParameterNode(const Identifier &i) : id(i), next(this) { }
       ParameterNode(ParameterNode *list, const Identifier &i)
         : id(i), next(list->next) { list->next = this; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       Identifier ident() { return id; }
  -    ParameterNode *nextParam() { return next; }
  +    ParameterNode *nextParam() { return next.get(); }
       virtual void streamTo(SourceStream &s) const;
     private:
       friend class FuncDeclNode;
       friend class FuncExprNode;
       Identifier id;
  -    ParameterNode *next;
  +    kxmlcore::SharedPtr<ParameterNode> next;
     };
   
     // inherited by ProgramNode
  @@ -1072,16 +957,14 @@
         : ident(i), param(0), body(b) { }
       FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
         : ident(i), param(p->next), body(b) { p->next = 0; }
  -    virtual void ref();
  -    virtual bool deref();
       Completion execute(ExecState */*exec*/)
         { /* empty */ return Completion(); }
       void processFuncDecl(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       Identifier ident;
  -    ParameterNode *param;
  -    FunctionBodyNode *body;
  +    kxmlcore::SharedPtr<ParameterNode> param;
  +    kxmlcore::SharedPtr<FunctionBodyNode> body;
     };
   
     class FuncExprNode : public Node {
  @@ -1089,13 +972,11 @@
       FuncExprNode(FunctionBodyNode *b) : param(0), body(b) { }
       FuncExprNode(ParameterNode *p, FunctionBodyNode *b)
         : param(p->next), body(b) { p->next = 0; }
  -    virtual void ref();
  -    virtual bool deref();
       ValueImp *evaluate(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
  -    ParameterNode *param;
  -    FunctionBodyNode *body;
  +    kxmlcore::SharedPtr<ParameterNode> param;
  +    kxmlcore::SharedPtr<FunctionBodyNode> body;
     };
   
     // A linked list of source element nodes
  @@ -1104,16 +985,15 @@
       // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
       SourceElementsNode(StatementNode *s1);
       SourceElementsNode(SourceElementsNode *s1, StatementNode *s2);
  -    virtual void ref();
  -    virtual bool deref();
  +
       Completion execute(ExecState *exec);
       void processFuncDecl(ExecState *exec);
       virtual void processVarDecls(ExecState *exec);
       virtual void streamTo(SourceStream &s) const;
     private:
       friend class BlockNode;
  -    StatementNode *element; // 'this' element
  -    SourceElementsNode *elements; // pointer to next
  +    kxmlcore::SharedPtr<StatementNode> element; // 'this' element
  +    kxmlcore::SharedPtr<SourceElementsNode> elements; // pointer to next
     };
   
     class ProgramNode : public FunctionBodyNode {
  
  
  
  1.15      +12 -9     JavaScriptCore/kjs/nodes2string.cpp
  
  Index: nodes2string.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/nodes2string.cpp,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- nodes2string.cpp	16 Aug 2005 22:01:31 -0000	1.14
  +++ nodes2string.cpp	26 Aug 2005 23:42:17 -0000	1.15
  @@ -23,6 +23,8 @@
   
   #include "nodes.h"
   
  +using namespace kxmlcore;
  +
   namespace KJS {
     /**
      * A simple text streaming class that helps with code indentation.
  @@ -40,6 +42,7 @@
       SourceStream& operator<<(char);
       SourceStream& operator<<(Format f);
       SourceStream& operator<<(const Node *);
  +    template <typename T> SourceStream& operator<<(SharedPtr<T> n) { return this->operator<<(n.get()); }
     private:
       UString str; /* TODO: buffer */
       UString ind;
  @@ -131,7 +134,7 @@
   
   void ElementNode::streamTo(SourceStream &s) const
   {
  -  for (const ElementNode *n = this; n; n = n->list) {
  +  for (const ElementNode *n = this; n; n = n->list.get()) {
       for (int i = 0; i < n->elision; i++)
         s << ",";
       s << n->node;
  @@ -156,7 +159,7 @@
   
   void PropertyValueNode::streamTo(SourceStream &s) const
   {
  -  for (const PropertyValueNode *n = this; n; n = n->list)
  +  for (const PropertyValueNode *n = this; n; n = n->list.get())
       s << n->name << ": " << n->assign;
   }
   
  @@ -181,7 +184,7 @@
   void ArgumentListNode::streamTo(SourceStream &s) const
   {
     s << expr;
  -  for (ArgumentListNode *n = list; n; n = n->list)
  +  for (ArgumentListNode *n = list.get(); n; n = n->list.get())
       s << ", " << n->expr;
   }
   
  @@ -442,7 +445,7 @@
   
   void StatListNode::streamTo(SourceStream &s) const
   {
  -  for (const StatListNode *n = this; n; n = n->list)
  +  for (const StatListNode *n = this; n; n = n->list.get())
       s << n->statement;
   }
   
  @@ -459,7 +462,7 @@
   void VarDeclListNode::streamTo(SourceStream &s) const
   {
     s << var;
  -  for (VarDeclListNode *n = list; n; n = n->list)
  +  for (VarDeclListNode *n = list.get(); n; n = n->list.get())
       s << ", " << n->var;
   }
   
  @@ -577,11 +580,11 @@
   
   void CaseBlockNode::streamTo(SourceStream &s) const
   {
  -  for (const ClauseListNode *n = list1; n; n = n->next())
  +  for (const ClauseListNode *n = list1.get(); n; n = n->next())
       s << n->clause();
     if (def)
       s << def;
  -  for (const ClauseListNode *n = list2; n; n = n->next())
  +  for (const ClauseListNode *n = list2.get(); n; n = n->next())
       s << n->clause();
   }
   
  @@ -623,7 +626,7 @@
   void ParameterNode::streamTo(SourceStream &s) const
   {
     s << id;
  -  for (ParameterNode *n = next; n; n = n->next)
  +  for (ParameterNode *n = next.get(); n; n = n->next.get())
       s << ", " << n->id;
   }
   
  @@ -643,7 +646,7 @@
   
   void SourceElementsNode::streamTo(SourceStream &s) const
   {
  -  for (const SourceElementsNode *n = this; n; n = n->elements)
  +  for (const SourceElementsNode *n = this; n; n = n->elements.get())
       s << n->element;
   }
   
  
  
  
  1.1                  JavaScriptCore/kjs/shared_ptr.h
  
  Index: shared_ptr.h
  ===================================================================
  // -*- c-basic-offset: 4 -*-
  /*
   *  This file is part of the KDE libraries
   *  Copyright (C) 2005 Apple Computer, Inc.
   *
   *  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 Steet, Fifth Floor,
   *  Boston, MA 02110-1301, USA.
   *
   */
  
  #ifndef KXMLCORE_SHARED_PTR_H
  #define KXMLCORE_SHARED_PTR_H
  
  namespace kxmlcore {
  
  template <class T> class SharedPtr
  {
  public:
      SharedPtr() : m_ptr(0) {}
      explicit SharedPtr(T *ptr) : m_ptr(ptr) { if (m_ptr) m_ptr->ref(); }
      SharedPtr(const SharedPtr &o) : m_ptr(o.m_ptr) { if (m_ptr) m_ptr->ref(); }
      ~SharedPtr() { if (m_ptr) m_ptr->deref(); }
  
      template <class U> explicit SharedPtr(SharedPtr<U> o)  : m_ptr(o.get()) { if (m_ptr) m_ptr->ref(); }
  	
      bool isNull() const { return m_ptr == 0; }
      bool notNull() const { return m_ptr != 0; }
  
      void reset() { if (m_ptr) m_ptr->deref(); m_ptr = 0; }
      void reset(T *o) { if (o) o->ref(); if (m_ptr) m_ptr->deref(); m_ptr = o; }
      
      T * get() const { return m_ptr; }
      T &operator*() const { return *m_ptr; }
      T *operator->() const { return m_ptr; }
  
      bool operator!() const { return m_ptr == 0; }
      operator bool() const { return m_ptr != 0; }
  
      inline friend bool operator==(const SharedPtr &a, const SharedPtr &b) { return a.m_ptr == b.m_ptr; }
      inline friend bool operator==(const SharedPtr &a, const T *b) { return a.m_ptr == b; }
      inline friend bool operator==(const T *a, const SharedPtr &b) { return a == b.m_ptr; }
  
      SharedPtr &operator=(const SharedPtr &);
      SharedPtr &operator=(T *);
  
  private:
      T* m_ptr;
  };
  
  template <class T> SharedPtr<T> &SharedPtr<T>::operator=(const SharedPtr<T> &o) 
  {
      if (o.m_ptr) 
          o.m_ptr->ref();
      if (m_ptr)
          m_ptr->deref();
      m_ptr = o.m_ptr;
      return *this;
  }
  
  template <class T> inline SharedPtr<T> &SharedPtr<T>::operator=(T *ptr) 
  {
      if (ptr) 
          ptr->ref();
      if (m_ptr)
          m_ptr->deref();
      m_ptr = ptr;
      return *this;
  }
  
  template <class T> inline bool operator!=(const SharedPtr<T> &a, const SharedPtr<T> &b) { return !(a==b); }
  template <class T> inline bool operator!=(const SharedPtr<T> &a, const T *b) { return !(a == b); }
  template <class T> inline bool operator!=(const T *a, const SharedPtr<T> &b) { return !(a == b); }
  
  template <class T, class U> inline SharedPtr<T> static_pointer_cast(const SharedPtr<U> &p) { return SharedPtr<T>(static_cast<T *>(p.get())); }
  template <class T, class U> inline SharedPtr<T> const_pointer_cast(const SharedPtr<U> &p) { return SharedPtr<T>(const_cast<T *>(p.get())); }
  
  }
  
  #endif // KXMLCORE_SHARED_PTR_H
  
  
  



More information about the webkit-changes mailing list