Ignore:
Timestamp:
Aug 26, 2005, 4:42:16 PM (20 years ago)
Author:
mjs
Message:

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):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/internal.cpp

    r10207 r10352  
    5353
    5454extern int kjsyyparse();
     55
     56using namespace kxmlcore;
    5557
    5658namespace KJS {
     
    346348// ------------------------------ Parser ---------------------------------------
    347349
    348 ProgramNode *Parser::progNode = 0;
     350static SharedPtr<ProgramNode> *progNode;
    349351int Parser::sid = 0;
    350352
    351 ProgramNode *Parser::parse(const UString &sourceURL, int startingLineNumber,
    352                            const UChar *code, unsigned int length, int *sourceId,
    353                            int *errLine, UString *errMsg)
     353SharedPtr<ProgramNode> Parser::parse(const UString &sourceURL, int startingLineNumber,
     354                                     const UChar *code, unsigned int length, int *sourceId,
     355                                     int *errLine, UString *errMsg)
    354356{
    355357  if (errLine)
     
    357359  if (errMsg)
    358360    *errMsg = 0;
    359  
     361  if (!progNode)
     362    progNode = new SharedPtr<ProgramNode>;
     363
    360364  Lexer::curr()->setCode(sourceURL, startingLineNumber, code, length);
    361   progNode = 0;
     365  *progNode = 0;
    362366  sid++;
    363367  if (sourceId)
     
    369373  bool lexError = Lexer::curr()->sawError();
    370374  Lexer::curr()->doneParsing();
    371   ProgramNode *prog = progNode;
    372   progNode = 0;
     375  SharedPtr<ProgramNode> prog = *progNode;
     376  *progNode = 0;
    373377
    374378  if (parseError || lexError) {
     
    378382    if (errMsg)
    379383      *errMsg = "Parse error";
    380     if (prog) {
    381       // must ref and deref to clean up properly
    382       prog->ref();
    383       prog->deref();
    384       delete prog;
    385     }
    386     return 0;
     384    return SharedPtr<ProgramNode>();
    387385  }
    388386
    389387  return prog;
    390388}
     389
     390void Parser::accept(ProgramNode *prog)
     391{
     392  *progNode = prog;
     393}
     394
    391395
    392396// ------------------------------ InterpreterImp -------------------------------
     
    612616{
    613617  // Parser::parse() returns 0 in a syntax error occurs, so we just check for that
    614   ProgramNode *progNode = Parser::parse(UString(), 0, code.data(),code.size(),0,0,0);
    615   bool ok = (progNode != 0);
    616   if (progNode) {
    617     // must ref and deref to clean up properly
    618     progNode->ref();
    619     progNode->deref();
    620     delete progNode;
    621   }
    622   return ok;
     618  SharedPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(),code.size(),0,0,0);
     619  return progNode;
    623620}
    624621
     
    643640  int errLine;
    644641  UString errMsg;
    645   ProgramNode *progNode = Parser::parse(sourceURL, startingLineNumber, code.data(),code.size(),&sid,&errLine,&errMsg);
     642  SharedPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code.data(),code.size(),&sid,&errLine,&errMsg);
    646643
    647644  // notify debugger that source has been parsed
     
    671668
    672669  recursion++;
    673   progNode->ref();
    674670
    675671  ObjectImp *globalObj = globalObject();
     
    699695  }
    700696
    701   if (progNode->deref())
    702     delete progNode;
    703697  recursion--;
    704698
Note: See TracChangeset for help on using the changeset viewer.