Changeset 13304 in webkit


Ignore:
Timestamp:
Mar 15, 2006, 2:21:48 AM (19 years ago)
Author:
mjs
Message:

Reviewed by Anders.


The memory usage of Node was reduced by 2 machine words per node:

  • sourceURL was removed and only kept on FunctionBodyNode. The source URL can only be distinct per function or top-level program node, and you always have one.


  • refcount was removed and kept in a separate hashtable when greater than 1. newNodes set represents floating nodes with refcount of 0. This helps because almost all nodes have a refcount of 1 for almost all of their lifetime.


  • bindings/runtime_method.cpp: (RuntimeMethod::RuntimeMethod): Pass null body, added FIXME.
  • kjs/Parser.cpp: (KJS::clearNewNodes): New nodes are tracked in nodes.cpp now, but still clear them at the appropriate time.
  • kjs/context.h: (KJS::ContextImp::currentBody): added; used to retrieve source URL and sid for current code. (KJS::ContextImp::pushIteration): moved here from LabelStack (KJS::ContextImp::popIteration): ditto (KJS::ContextImp::inIteration): ditto (KJS::ContextImp::pushSwitch): ditto (KJS::ContextImp::popSwitch): ditto (KJS::ContextImp::inSwitch): ditto
  • kjs/function.cpp: (KJS::FunctionImp::FunctionImp): Add FunctionBodyNode* parameter. (KJS::FunctionImp::callAsFunction): Pass body to ContextImp. (KJS::FunctionImp::argumentsGetter): _context renamed to m_context. (KJS::DeclaredFunctionImp::DeclaredFunctionImp): Pass body to superclass constructor. (KJS::GlobalFuncImp::callAsFunction): Pass progNode as body for ContextImp in eval.
  • kjs/function.h: Move body field from DeclaredFunctionImp to FunctionImp.
  • kjs/grammar.y: Change DBG; statements no longer have a sourceid.
  • kjs/internal.cpp: (KJS::ContextImp::ContextImp): Initialize new m_currentBody, m_iterationDepth and m_switchDepth data members. New FunctionBodyNode* parameter - the function body provides source URL and SourceId. (KJS::InterpreterImp::mark): Use exception() function, not _exception directly. (KJS::InterpreterImp::evaluate): Pass progNode to ContextImp constructor to use as the body.
  • kjs/internal.h: (KJS::LabelStack::LabelStack): Remove iteration depth and switch depth; statement label stacks don't need these and it bloats their size. Put them in the ContextImp instead.
  • kjs/interpreter.cpp: (KJS::ExecState::lexicalInterpreter): Renamed _context to m_context.
  • kjs/interpreter.h: (KJS::ExecState::dynamicInterpreter): Renamed _context to m_context. (KJS::ExecState::context): ditto (KJS::ExecState::setException): Renamed _exception to m_exception (KJS::ExecState::clearException): ditto (KJS::ExecState::exception): ditto (KJS::ExecState::hadException): ditto (KJS::ExecState::ExecState): ditto both above renames
  • kjs/nodes.cpp: (Node::Node): Removed initialization of line, source URL and refcount. Add to local newNodes set instead of involving parser. (Node::ref): Instead of managing refcount directly, story refcount over 1 in a HashCountedSet, and keep a separate HashSet of "floating" nodes with refcount 0. (Node::deref): ditto (Node::refcount): ditto (Node::clearNewNodes): Destroy anything left in the new nodes set. (currentSourceId): Inline helper to get sourceId from function body via context. (currentSourceURL): ditto for sourceURL. (Node::createErrorCompletion): use new helper (Node::throwError): ditto (Node::setExceptionDetailsIfNeeded): ditto (StatementNode::StatementNode): remove initialization of l0 and sid, rename l1 to m_lastLine. (StatementNode::setLoc): Set own m_lastLine and Node's m_line. (StatementNode::hitStatement): Get sid, first line, last line in the proper new ways. (StatListNode::StatListNode): updated for setLoc changes (BlockNode::BlockNode): ditto (DoWhileNode::execute): excpect iteraton counts on ContextImp, not LabelStack (WhileNode::execute): ditto (ForNode::execute): ditto (ForInNode::execute): ditto (ContinueNode::execute): excpect inIteration on ContextImp, not LabelStack (BreakNode::execute): excpect inIteration and inSwitch on ContextImp, not LabelStack (SwitchNode::execute): expect switch counts on ContextImp, not LabelStack (FunctionBodyNode::FunctionBodyNode): update for new setLoc (FunctionBodyNode::processFuncDecl): reindent (SourceElementsNode::SourceElementsNode): update for new setLoc
  • kjs/nodes.h: (KJS::Node::lineNo): Renamed _line to m_line (KJS::StatementNode::firstLine): Use lineNo() (KJS::StatementNode::lastLine): Renamed l1 to m_lastLine (KJS::FunctionBodyNode::sourceId): added (KJS::FunctionBodyNode::sourceURL): added
  • kjs/testkjs.cpp:
Location:
trunk/JavaScriptCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r13294 r13304  
     12006-03-13  Maciej Stachowiak  <[email protected]>
     2
     3        Reviewed by Anders.
     4       
     5        - KJS::Node and KJS::StatementNode are bigger than they need to be
     6        http://bugzilla.opendarwin.org/show_bug.cgi?id=7775
     7
     8        The memory usage of Node was reduced by 2 machine words per node:
     9
     10        - sourceURL was removed and only kept on FunctionBodyNode. The
     11        source URL can only be distinct per function or top-level program node,
     12        and you always have one.
     13       
     14        - refcount was removed and kept in a separate hashtable when
     15        greater than 1. newNodes set represents floating nodes with
     16        refcount of 0. This helps because almost all nodes have a refcount of 1
     17        for almost all of their lifetime.
     18       
     19        * bindings/runtime_method.cpp:
     20        (RuntimeMethod::RuntimeMethod): Pass null body, added FIXME.
     21        * kjs/Parser.cpp:
     22        (KJS::clearNewNodes): New nodes are tracked in nodes.cpp now, but still clear
     23        them at the appropriate time.
     24        * kjs/context.h:
     25        (KJS::ContextImp::currentBody): added; used to retrieve source URL and sid
     26        for current code.
     27        (KJS::ContextImp::pushIteration): moved here from LabelStack
     28        (KJS::ContextImp::popIteration): ditto
     29        (KJS::ContextImp::inIteration): ditto
     30        (KJS::ContextImp::pushSwitch): ditto
     31        (KJS::ContextImp::popSwitch): ditto
     32        (KJS::ContextImp::inSwitch): ditto
     33        * kjs/function.cpp:
     34        (KJS::FunctionImp::FunctionImp): Add FunctionBodyNode* parameter.
     35        (KJS::FunctionImp::callAsFunction): Pass body to ContextImp.
     36        (KJS::FunctionImp::argumentsGetter): _context renamed to m_context.
     37        (KJS::DeclaredFunctionImp::DeclaredFunctionImp): Pass body to superclass
     38        constructor.
     39        (KJS::GlobalFuncImp::callAsFunction): Pass progNode as body for ContextImp in
     40        eval.
     41        * kjs/function.h: Move body field from DeclaredFunctionImp to
     42        FunctionImp.
     43        * kjs/grammar.y: Change DBG; statements no longer have a sourceid.
     44        * kjs/internal.cpp:
     45        (KJS::ContextImp::ContextImp): Initialize new m_currentBody, m_iterationDepth
     46        and m_switchDepth data members. New FunctionBodyNode* parameter - the
     47        function body provides source URL and SourceId.
     48        (KJS::InterpreterImp::mark): Use exception() function, not _exception directly.
     49        (KJS::InterpreterImp::evaluate): Pass progNode to ContextImp constructor
     50        to use as the body.
     51        * kjs/internal.h:
     52        (KJS::LabelStack::LabelStack): Remove iteration depth and switch depth;
     53        statement label stacks don't need these and it bloats their size. Put them
     54        in the ContextImp instead.
     55        * kjs/interpreter.cpp:
     56        (KJS::ExecState::lexicalInterpreter): Renamed _context to m_context.
     57        * kjs/interpreter.h:
     58        (KJS::ExecState::dynamicInterpreter): Renamed _context to m_context.
     59        (KJS::ExecState::context): ditto
     60        (KJS::ExecState::setException): Renamed _exception to m_exception
     61        (KJS::ExecState::clearException): ditto
     62        (KJS::ExecState::exception): ditto
     63        (KJS::ExecState::hadException): ditto
     64        (KJS::ExecState::ExecState): ditto both above renames
     65        * kjs/nodes.cpp:
     66        (Node::Node): Removed initialization of line, source URL and refcount. Add to
     67        local newNodes set instead of involving parser.
     68        (Node::ref): Instead of managing refcount directly, story refcount over 1 in a
     69        HashCountedSet, and keep a separate HashSet of "floating" nodes with refcount
     70        0.
     71        (Node::deref): ditto
     72        (Node::refcount): ditto
     73        (Node::clearNewNodes): Destroy anything left in the new nodes set.
     74        (currentSourceId): Inline helper to get sourceId from function body via context.
     75        (currentSourceURL): ditto for sourceURL.
     76        (Node::createErrorCompletion): use new helper
     77        (Node::throwError): ditto
     78        (Node::setExceptionDetailsIfNeeded): ditto
     79        (StatementNode::StatementNode): remove initialization of l0 and sid, rename
     80        l1 to m_lastLine.
     81        (StatementNode::setLoc): Set own m_lastLine and Node's m_line.
     82        (StatementNode::hitStatement): Get sid, first line, last line in the proper new ways.
     83        (StatListNode::StatListNode): updated for setLoc changes
     84        (BlockNode::BlockNode): ditto
     85        (DoWhileNode::execute): excpect iteraton counts on ContextImp, not LabelStack
     86        (WhileNode::execute): ditto
     87        (ForNode::execute): ditto
     88        (ForInNode::execute): ditto
     89        (ContinueNode::execute): excpect inIteration on ContextImp, not LabelStack
     90        (BreakNode::execute): excpect inIteration and inSwitch on ContextImp, not LabelStack
     91        (SwitchNode::execute): expect switch counts on ContextImp, not LabelStack
     92        (FunctionBodyNode::FunctionBodyNode): update for new setLoc
     93        (FunctionBodyNode::processFuncDecl): reindent
     94        (SourceElementsNode::SourceElementsNode): update for new setLoc
     95        * kjs/nodes.h:
     96        (KJS::Node::lineNo): Renamed _line to m_line
     97        (KJS::StatementNode::firstLine): Use lineNo()
     98        (KJS::StatementNode::lastLine): Renamed l1 to m_lastLine
     99        (KJS::FunctionBodyNode::sourceId): added
     100        (KJS::FunctionBodyNode::sourceURL): added
     101        * kjs/testkjs.cpp:
     102
    11032006-03-14  Geoffrey Garen  <[email protected]>
    2104
  • trunk/JavaScriptCore/bindings/runtime_method.cpp

    r13015 r13304  
    3333using namespace KJS;
    3434
    35 RuntimeMethod::RuntimeMethod(ExecState *exec, const Identifier &ident, Bindings::MethodList &m) : FunctionImp (exec, ident)
     35// FIXME: this should probably use InternalFunctionImp, not FunctionImp
     36RuntimeMethod::RuntimeMethod(ExecState *exec, const Identifier &ident, Bindings::MethodList &m)
     37    : FunctionImp (exec, ident, 0)
    3638{
    3739    _methodList = m;
  • trunk/JavaScriptCore/kjs/Parser.cpp

    r13153 r13304  
    3838
    3939static RefPtr<ProgramNode>* progNode;
    40 static Vector<RefPtr<Node> >* newNodes;
    4140static HashSet<Node*>* nodeCycles;
    42 
    43 void Parser::saveNewNode(Node *node)
    44 {
    45     if (!newNodes)
    46         newNodes = new Vector<RefPtr<Node> >;
    47     newNodes->append(node);
    48 }
    4941
    5042void Parser::noteNodeCycle(Node *node)
     
    6961        nodeCycles = 0;
    7062    }
    71 
    72     delete newNodes;
    73     newNodes = 0;
     63    Node::clearNewNodes();
    7464}
    7565
  • trunk/JavaScriptCore/kjs/context.h

    r12317 r13304  
    3636  class ContextImp {
    3737  public:
    38     ContextImp(JSObject *glob, InterpreterImp *, JSObject *thisV, CodeType type = GlobalCode,
    39                ContextImp *callingContext = 0, FunctionImp *functiion = 0, const List *args = 0);
     38    ContextImp(JSObject* global, InterpreterImp*, JSObject* thisV, FunctionBodyNode* currentBody,
     39               CodeType type = GlobalCode, ContextImp* callingContext = 0, FunctionImp* function = 0, const List* args = 0);
    4040    ~ContextImp();
     41
     42    FunctionBodyNode* currentBody() { return m_currentBody; }
    4143
    4244    const ScopeChain &scopeChain() const { return scope; }
     
    5355    void popScope() { scope.pop(); }
    5456    LabelStack *seenLabels() { return &ls; }
     57
     58
     59    void pushIteration() { m_iterationDepth++; }
     60    void popIteration() { m_iterationDepth--; }
     61    bool inIteration() const { return (m_iterationDepth > 0); }
    5562   
     63    void pushSwitch() { m_switchDepth++; }
     64    void popSwitch() { m_switchDepth--; }
     65    bool inSwitch() const { return (m_switchDepth > 0); }
     66       
    5667    void mark();
    5768
     
    5970    InterpreterImp *_interpreter;
    6071    ContextImp *_callingContext;
     72    FunctionBodyNode* m_currentBody;
     73
    6174    FunctionImp *_function;
    6275    const List *_arguments;
     
    7184
    7285    LabelStack ls;
     86    int m_iterationDepth;
     87    int m_switchDepth;
    7388    CodeType m_codeType;
    7489  };
  • trunk/JavaScriptCore/kjs/function.cpp

    r13015 r13304  
    5656  };
    5757
    58 FunctionImp::FunctionImp(ExecState *exec, const Identifier &n)
     58FunctionImp::FunctionImp(ExecState *exec, const Identifier &n, FunctionBodyNode* b)
    5959  : InternalFunctionImp(static_cast<FunctionPrototype*>
    6060                        (exec->lexicalInterpreter()->builtinFunctionPrototype()), n)
     61  , body(b)
    6162{
    6263}
     
    6667}
    6768
    68 JSValue *FunctionImp::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
     69JSValue *FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    6970{
    7071  JSObject *globalObj = exec->dynamicInterpreter()->globalObject();
    7172
    7273  // enter a new execution context
    73   ContextImp ctx(globalObj, exec->dynamicInterpreter()->imp(), thisObj, codeType(),
    74                  exec->context().imp(), this, &args);
     74  ContextImp ctx(globalObj, exec->dynamicInterpreter()->imp(), thisObj, body.get(),
     75                 codeType(), exec->context().imp(), this, &args);
    7576  ExecState newExec(exec->dynamicInterpreter(), &ctx);
    7677  newExec.setException(exec->exception()); // could be null
     
    203204{
    204205  FunctionImp *thisObj = static_cast<FunctionImp *>(slot.slotBase());
    205   ContextImp *context = exec->_context;
     206  ContextImp *context = exec->m_context;
    206207  while (context) {
    207208    if (context->function() == thisObj) {
     
    295296DeclaredFunctionImp::DeclaredFunctionImp(ExecState *exec, const Identifier &n,
    296297                                         FunctionBodyNode *b, const ScopeChain &sc)
    297   : FunctionImp(exec,n), body(b)
     298  : FunctionImp(exec, n, b)
    298299{
    299300  setScope(sc);
     
    804805                       exec->dynamicInterpreter()->imp(),
    805806                       thisVal,
     807                       progNode.get(),
    806808                       EvalCode,
    807809                       exec->context().imp());
  • trunk/JavaScriptCore/kjs/function.h

    r13153 r13304  
    4040    friend class ActivationImp;
    4141  public:
    42     FunctionImp(ExecState *exec, const Identifier &n = Identifier::null());
     42    FunctionImp(ExecState* exec, const Identifier& n, FunctionBodyNode* b);
    4343    virtual ~FunctionImp();
    4444
     
    5959    virtual const ClassInfo *classInfo() const { return &info; }
    6060    static const ClassInfo info;
     61
     62    RefPtr<FunctionBodyNode> body;
     63
    6164  protected:
    6265    OwnPtr<Parameter> param;
     
    8083    virtual Completion execute(ExecState *exec);
    8184    CodeType codeType() const { return FunctionCode; }
    82     RefPtr<FunctionBodyNode> body;
    8385
    8486    virtual const ClassInfo *classInfo() const { return &info; }
    8587    static const ClassInfo info;
     88
    8689  private:
    8790    virtual void processVarDecls(ExecState *exec);
  • trunk/JavaScriptCore/kjs/grammar.y

    r13089 r13304  
    4949
    5050#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon()) YYABORT; } while (0)
    51 #define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line, Parser::sid)
     51#define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line)
    5252
    5353using namespace KJS;
  • trunk/JavaScriptCore/kjs/internal.cpp

    r13153 r13304  
    189189
    190190// ECMA 10.2
    191 ContextImp::ContextImp(JSObject *glob, InterpreterImp *interpreter, JSObject *thisV, CodeType type,
    192                        ContextImp *callingCon, FunctionImp *func, const List *args)
    193     : _interpreter(interpreter), _function(func), _arguments(args)
     191ContextImp::ContextImp(JSObject *glob, InterpreterImp *interpreter, JSObject *thisV, FunctionBodyNode* currentBody,
     192                       
     193                       CodeType type, ContextImp *callingCon, FunctionImp *func, const List *args)
     194    : _interpreter(interpreter)
     195    , m_currentBody(currentBody)
     196    , _function(func)
     197    , _arguments(args)
     198    , m_iterationDepth(0)
     199    , m_switchDepth(0)
    194200{
    195201  m_codeType = type;
     
    443449  if (global)
    444450      global->mark();
    445   if (globExec._exception)
    446       globExec._exception->mark();
     451  if (globExec.exception())
     452      globExec.exception()->mark();
    447453}
    448454
     
    498504  else {
    499505    // execute the code
    500     ContextImp ctx(globalObj, this, thisObj);
     506    ContextImp ctx(globalObj, this, thisObj, progNode.get());
    501507    ExecState newExec(m_interpreter, &ctx);
    502508    progNode->processVarDecls(&newExec);
  • trunk/JavaScriptCore/kjs/internal.h

    r13153 r13304  
    9494  class LabelStack : Noncopyable {
    9595  public:
    96     LabelStack(): tos(0), iterationDepth(0), switchDepth(0) {}
     96    LabelStack()
     97      : tos(0)
     98    {
     99    }
    97100    ~LabelStack();
    98101
     
    111114    void pop();
    112115   
    113     void pushIteration() { iterationDepth++; }
    114     void popIteration() { iterationDepth--; }
    115     bool inIteration() const { return (iterationDepth > 0); }
    116    
    117     void pushSwitch() { switchDepth++; }
    118     void popSwitch() { switchDepth--; }
    119     bool inSwitch() const { return (switchDepth > 0); }
    120    
    121116  private:
    122117    struct StackElem {
     
    126121
    127122    StackElem *tos;
    128     int iterationDepth;
    129     int switchDepth;
    130123  };
    131124
  • trunk/JavaScriptCore/kjs/interpreter.cpp

    r13089 r13304  
    362362Interpreter *ExecState::lexicalInterpreter() const
    363363{
    364   if (!_context) {
     364  if (!m_context) {
    365365    return dynamicInterpreter();
    366366  }
    367367
    368   InterpreterImp *result = InterpreterImp::interpreterWithGlobalObject(_context->scopeChain().bottom());
     368  InterpreterImp *result = InterpreterImp::interpreterWithGlobalObject(m_context->scopeChain().bottom());
    369369
    370370  if (!result) {
  • trunk/JavaScriptCore/kjs/interpreter.h

    r13089 r13304  
    445445     * @return The interpreter executing the script
    446446     */
    447     Interpreter *dynamicInterpreter() const { return _interpreter; }
     447    Interpreter *dynamicInterpreter() const { return m_interpreter; }
    448448
    449449    // for compatibility
     
    463463     * @return The current execution state context
    464464     */
    465     Context context() const { return _context; }
    466 
    467     void setException(JSValue* e) { _exception = e; }
    468     void clearException() { _exception = 0; }
    469     JSValue* exception() const { return _exception; }
    470     bool hadException() const { return _exception; }
     465    Context context() const { return m_context; }
     466
     467    void setException(JSValue* e) { m_exception = e; }
     468    void clearException() { m_exception = 0; }
     469    JSValue* exception() const { return m_exception; }
     470    bool hadException() const { return m_exception; }
    471471
    472472  private:
    473473    ExecState(Interpreter* interp, ContextImp* con)
    474         : _interpreter(interp), _context(con), _exception(0) { }
    475     Interpreter* _interpreter;
    476     ContextImp* _context;
    477     JSValue* _exception;
     474        : m_interpreter(interp)
     475        , m_context(con)
     476        , m_exception(0)
     477    {
     478    }
     479    Interpreter* m_interpreter;
     480    ContextImp* m_context;
     481    JSValue* m_exception;
    478482  };
    479483
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r13138 r13304  
    4545#include "ustring.h"
    4646#include "reference_list.h"
     47#include <kxmlcore/HashSet.h>
     48#include <kxmlcore/HashCountedSet.h>
    4749
    4850using namespace KJS;
     
    9698#endif NDEBUG
    9799
     100static HashSet<Node*>* newNodes;
     101static HashCountedSet<Node*>* nodeExtraRefCounts;
    98102
    99103Node::Node()
     
    102106    ++NodeCounter::count;
    103107#endif
    104   line = Lexer::curr()->lineNo();
    105   sourceURL = Lexer::curr()->sourceURL();
    106   m_refcount = 0;
    107   Parser::saveNewNode(this);
     108  m_line = Lexer::curr()->lineNo();
     109  if (!newNodes)
     110      newNodes = new HashSet<Node*>;
     111  newNodes->add(this);
    108112}
    109113
     
    115119}
    116120
     121void Node::ref()
     122{
     123    // bumping from 0 to 1 is just removing from the new nodes set
     124    if (newNodes) {
     125        HashSet<Node*>::iterator it = newNodes->find(this);
     126        if (it != newNodes->end()) {
     127            newNodes->remove(it);
     128            return;
     129        }
     130    }   
     131   
     132    if (!nodeExtraRefCounts)
     133        nodeExtraRefCounts = new HashCountedSet<Node*>;
     134    nodeExtraRefCounts->add(this);
     135}
     136
     137void Node::deref()
     138{
     139    HashCountedSet<Node*>::iterator it = nodeExtraRefCounts->find(this);
     140    if (it == nodeExtraRefCounts->end())
     141        delete this;
     142    else
     143        nodeExtraRefCounts->remove(it);
     144}
     145
     146unsigned int Node::refcount()
     147{
     148    if (newNodes && newNodes->contains(this))
     149        return 0;
     150
     151    if (!nodeExtraRefCounts)
     152        return 1;
     153
     154    return 1 + nodeExtraRefCounts->count(this);
     155}
     156
     157void Node::clearNewNodes()
     158{
     159    if (newNodes) {
     160        deleteAllValues(*newNodes);
     161        delete newNodes;
     162        newNodes = 0;
     163    }
     164}
     165
    117166static void substitute(UString &string, const UString &substring)
    118167{
     
    122171}
    123172
    124 Completion Node::createErrorCompletion(ExecState *exec, ErrorType e, const char *msg)
    125 {
    126     return Completion(Throw, Error::create(exec, e, msg, lineNo(), sourceId(), &sourceURL));
     173static inline int currentSourceId(ExecState* exec)
     174{
     175    return exec->context().imp()->currentBody()->sourceId();
     176}
     177
     178static inline const UString& currentSourceURL(ExecState* exec)
     179{
     180    return exec->context().imp()->currentBody()->sourceURL();
     181}
     182
     183Completion Node::createErrorCompletion(ExecState* exec, ErrorType e, const char *msg)
     184{
     185    return Completion(Throw, Error::create(exec, e, msg, lineNo(), currentSourceId(exec), &currentSourceURL(exec)));
    127186}
    128187
     
    131190    UString message = msg;
    132191    substitute(message, ident.ustring());
    133     return Completion(Throw, Error::create(exec, e, message, lineNo(), sourceId(), &sourceURL));
    134 }
    135 
    136 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg)
    137 {
    138     return KJS::throwError(exec, e, msg, lineNo(), sourceId(), &sourceURL);
     192    return Completion(Throw, Error::create(exec, e, message, lineNo(), currentSourceId(exec), &currentSourceURL(exec)));
     193}
     194
     195JSValue *Node::throwError(ExecState* exec, ErrorType e, const char *msg)
     196{
     197    return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), &currentSourceURL(exec));
    139198}
    140199
     
    144203    substitute(message, v->toString(exec));
    145204    substitute(message, expr->toString());
    146     return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);
     205    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), &currentSourceURL(exec));
    147206}
    148207
     
    152211    UString message = msg;
    153212    substitute(message, label.ustring());
    154     return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);
     213    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), &currentSourceURL(exec));
    155214}
    156215
     
    161220    substitute(message, e1->toString());
    162221    substitute(message, e2->toString());
    163     return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);
     222    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), &currentSourceURL(exec));
    164223}
    165224
     
    170229    substitute(message, expr->toString());
    171230    substitute(message, label.ustring());
    172     return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);
     231    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), &currentSourceURL(exec));
    173232}
    174233
     
    178237    substitute(message, v->toString(exec));
    179238    substitute(message, label.ustring());
    180     return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);
     239    return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), &currentSourceURL(exec));
    181240}
    182241
     
    192251        JSObject *exception = static_cast<JSObject *>(exceptionValue);
    193252        if (!exception->hasProperty(exec, "line") && !exception->hasProperty(exec, "sourceURL")) {
    194             exception->put(exec, "line", jsNumber(line));
    195             exception->put(exec, "sourceURL", jsString(sourceURL));
     253            exception->put(exec, "line", jsNumber(m_line));
     254            exception->put(exec, "sourceURL", jsString(currentSourceURL(exec)));
    196255        }
    197256    }
     
    205264// ------------------------------ StatementNode --------------------------------
    206265
    207 StatementNode::StatementNode() : l0(-1), l1(-1), sid(-1)
    208 {
    209 }
    210 
    211 void StatementNode::setLoc(int line0, int line1, int sourceId)
    212 {
    213     l0 = line0;
    214     l1 = line1;
    215     sid = sourceId;
     266StatementNode::StatementNode()
     267    : m_lastLine(-1)
     268{
     269    m_line = -1;
     270}
     271
     272void StatementNode::setLoc(int firstLine, int lastLine)
     273{
     274    m_line = firstLine;
     275    m_lastLine = lastLine;
    216276}
    217277
    218278// return true if the debugger wants us to stop at this point
    219 bool StatementNode::hitStatement(ExecState *exec)
     279bool StatementNode::hitStatement(ExecState* exec)
    220280{
    221281  Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
    222282  if (dbg)
    223     return dbg->atStatement(exec,sid,l0,l1);
     283    return dbg->atStatement(exec, currentSourceId(exec), firstLine(), lastLine());
    224284  else
    225285    return true; // continue
     
    14431503{
    14441504    Parser::noteNodeCycle(this);
    1445     setLoc(s->firstLine(), s->lastLine(), s->sourceId());
     1505    setLoc(s->firstLine(), s->lastLine());
    14461506}
    14471507 
     
    14501510{
    14511511  l->next = this;
    1452   setLoc(l->firstLine(), s->lastLine(), l->sourceId());
     1512  setLoc(l->firstLine(), s->lastLine());
    14531513}
    14541514
     
    16011661    Parser::removeNodeCycle(source.get());
    16021662    s->next = 0;
    1603     setLoc(s->firstLine(), s->lastLine(), s->sourceId());
     1663    setLoc(s->firstLine(), s->lastLine());
    16041664  } else {
    16051665    source = 0;
     
    16901750    KJS_CHECKEXCEPTION
    16911751
    1692     exec->context().imp()->seenLabels()->pushIteration();
     1752    exec->context().imp()->pushIteration();
    16931753    c = statement->execute(exec);
    1694     exec->context().imp()->seenLabels()->popIteration();
     1754    exec->context().imp()->popIteration();
    16951755    if (!((c.complType() == Continue) && ls.contains(c.target()))) {
    16961756      if ((c.complType() == Break) && ls.contains(c.target()))
     
    17341794      return Completion(Normal, value);
    17351795
    1736     exec->context().imp()->seenLabels()->pushIteration();
     1796    exec->context().imp()->pushIteration();
    17371797    c = statement->execute(exec);
    1738     exec->context().imp()->seenLabels()->popIteration();
     1798    exec->context().imp()->popIteration();
    17391799    if (c.isValueCompletion())
    17401800      value = c.value();
     
    17771837    KJS_CHECKEXCEPTION
    17781838
    1779     exec->context().imp()->seenLabels()->pushIteration();
     1839    exec->context().imp()->pushIteration();
    17801840    Completion c = statement->execute(exec);
    1781     exec->context().imp()->seenLabels()->popIteration();
     1841    exec->context().imp()->popIteration();
    17821842    if (c.isValueCompletion())
    17831843      cval = c.value();
     
    19051965    KJS_CHECKEXCEPTION
    19061966
    1907     exec->context().imp()->seenLabels()->pushIteration();
     1967    exec->context().imp()->pushIteration();
    19081968    c = statement->execute(exec);
    1909     exec->context().imp()->seenLabels()->popIteration();
     1969    exec->context().imp()->popIteration();
    19101970    if (c.isValueCompletion())
    19111971      retval = c.value();
     
    19422002  KJS_BREAKPOINT;
    19432003
    1944   if (ident.isEmpty() && !exec->context().imp()->seenLabels()->inIteration())
     2004  if (ident.isEmpty() && !exec->context().imp()->inIteration())
    19452005    return createErrorCompletion(exec, SyntaxError, "Invalid continue statement.");
    19462006  else if (!ident.isEmpty() && !exec->context().imp()->seenLabels()->contains(ident))
     
    19572017  KJS_BREAKPOINT;
    19582018
    1959   if (ident.isEmpty() && !exec->context().imp()->seenLabels()->inIteration() &&
    1960       !exec->context().imp()->seenLabels()->inSwitch())
     2019  if (ident.isEmpty() && !exec->context().imp()->inIteration() &&
     2020      !exec->context().imp()->inSwitch())
    19612021    return createErrorCompletion(exec, SyntaxError, "Invalid break statement.");
    19622022  else if (!ident.isEmpty() && !exec->context().imp()->seenLabels()->contains(ident))
     
    21722232  KJS_CHECKEXCEPTION
    21732233
    2174   exec->context().imp()->seenLabels()->pushSwitch();
     2234  exec->context().imp()->pushSwitch();
    21752235  Completion res = block->evalBlock(exec,v);
    2176   exec->context().imp()->seenLabels()->popSwitch();
     2236  exec->context().imp()->popSwitch();
    21772237
    21782238  if ((res.complType() == Break) && ls.contains(res.target()))
     
    22702330
    22712331FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
    2272   : BlockNode(s)
    2273 {
    2274   setLoc(-1, -1, -1);
     2332    : BlockNode(s)
     2333    , m_sourceURL(Lexer::curr()->sourceURL())
     2334    , m_sourceId(Parser::sid)
     2335{
     2336
     2337  setLoc(-1, -1);
    22752338}
    22762339
    22772340void FunctionBodyNode::processFuncDecl(ExecState *exec)
    22782341{
    2279   if (source)
    2280     source->processFuncDecl(exec);
     2342    if (source)
     2343        source->processFuncDecl(exec);
    22812344}
    22822345
     
    23632426{
    23642427    Parser::noteNodeCycle(this);
    2365     setLoc(s1->firstLine(), s1->lastLine(), s1->sourceId());
     2428    setLoc(s1->firstLine(), s1->lastLine());
    23662429}
    23672430
     
    23702433{
    23712434  s1->next = this;
    2372   setLoc(s1->firstLine(), s2->lastLine(), s1->sourceId());
     2435  setLoc(s1->firstLine(), s2->lastLine());
    23732436}
    23742437
  • trunk/JavaScriptCore/kjs/nodes.h

    r13153 r13304  
    8181    virtual void streamTo(SourceStream &s) const = 0;
    8282    virtual void processVarDecls(ExecState *) {}
    83     int lineNo() const { return line; }
    84 
    85     // reference counting mechanism
    86     void ref() { ++m_refcount; }
    87     void deref() { --m_refcount; if (!m_refcount) delete this; }
    88     unsigned int refcount() { return m_refcount; }
     83    int lineNo() const { return m_line; }
     84
     85    void ref();
     86    void deref();
     87    unsigned int refcount();
     88    static void clearNewNodes();
    8989
    9090    virtual Node *nodeInsideAllParens();
     
    113113    void setExceptionDetailsIfNeeded(ExecState *);
    114114
    115     int line;
    116     UString sourceURL;
    117     unsigned int m_refcount;
    118     virtual int sourceId() const { return -1; }
    119 
     115    int m_line;
    120116  private:
    121117    // disallow assignment
     
    127123  public:
    128124    StatementNode();
    129     void setLoc(int line0, int line1, int sourceId);
    130     int firstLine() const { return l0; }
    131     int lastLine() const { return l1; }
    132     int sourceId() const { return sid; }
     125    void setLoc(int line0, int line1);
     126    int firstLine() const { return lineNo(); }
     127    int lastLine() const { return m_lastLine; }
    133128    bool hitStatement(ExecState *exec);
    134129    virtual Completion execute(ExecState *exec) = 0;
     
    139134  private:
    140135    JSValue *evaluate(ExecState */*exec*/) { return jsUndefined(); }
    141     int l0, l1;
    142     int sid;
     136    int m_lastLine;
    143137  };
    144138
     
    10541048  class FunctionBodyNode : public BlockNode {
    10551049  public:
    1056     FunctionBodyNode(SourceElementsNode *s);
    1057     void processFuncDecl(ExecState *exec);
     1050    FunctionBodyNode(SourceElementsNode *);
     1051    virtual void processFuncDecl(ExecState *exec);
     1052    int sourceId() { return m_sourceId; }
     1053    const UString& sourceURL() { return m_sourceURL; }
     1054  private:
     1055    UString m_sourceURL;
     1056    int m_sourceId;
    10581057  };
    10591058
Note: See TracChangeset for help on using the changeset viewer.