Changeset 13304 in webkit
- Timestamp:
- Mar 15, 2006, 2:21:48 AM (19 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r13294 r13304 1 2006-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 1 103 2006-03-14 Geoffrey Garen <[email protected]> 2 104 -
trunk/JavaScriptCore/bindings/runtime_method.cpp
r13015 r13304 33 33 using namespace KJS; 34 34 35 RuntimeMethod::RuntimeMethod(ExecState *exec, const Identifier &ident, Bindings::MethodList &m) : FunctionImp (exec, ident) 35 // FIXME: this should probably use InternalFunctionImp, not FunctionImp 36 RuntimeMethod::RuntimeMethod(ExecState *exec, const Identifier &ident, Bindings::MethodList &m) 37 : FunctionImp (exec, ident, 0) 36 38 { 37 39 _methodList = m; -
trunk/JavaScriptCore/kjs/Parser.cpp
r13153 r13304 38 38 39 39 static RefPtr<ProgramNode>* progNode; 40 static Vector<RefPtr<Node> >* newNodes;41 40 static 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 }49 41 50 42 void Parser::noteNodeCycle(Node *node) … … 69 61 nodeCycles = 0; 70 62 } 71 72 delete newNodes; 73 newNodes = 0; 63 Node::clearNewNodes(); 74 64 } 75 65 -
trunk/JavaScriptCore/kjs/context.h
r12317 r13304 36 36 class ContextImp { 37 37 public: 38 ContextImp(JSObject *glob, InterpreterImp *, JSObject *thisV, CodeType type = GlobalCode,39 Co ntextImp *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); 40 40 ~ContextImp(); 41 42 FunctionBodyNode* currentBody() { return m_currentBody; } 41 43 42 44 const ScopeChain &scopeChain() const { return scope; } … … 53 55 void popScope() { scope.pop(); } 54 56 LabelStack *seenLabels() { return &ls; } 57 58 59 void pushIteration() { m_iterationDepth++; } 60 void popIteration() { m_iterationDepth--; } 61 bool inIteration() const { return (m_iterationDepth > 0); } 55 62 63 void pushSwitch() { m_switchDepth++; } 64 void popSwitch() { m_switchDepth--; } 65 bool inSwitch() const { return (m_switchDepth > 0); } 66 56 67 void mark(); 57 68 … … 59 70 InterpreterImp *_interpreter; 60 71 ContextImp *_callingContext; 72 FunctionBodyNode* m_currentBody; 73 61 74 FunctionImp *_function; 62 75 const List *_arguments; … … 71 84 72 85 LabelStack ls; 86 int m_iterationDepth; 87 int m_switchDepth; 73 88 CodeType m_codeType; 74 89 }; -
trunk/JavaScriptCore/kjs/function.cpp
r13015 r13304 56 56 }; 57 57 58 FunctionImp::FunctionImp(ExecState *exec, const Identifier &n )58 FunctionImp::FunctionImp(ExecState *exec, const Identifier &n, FunctionBodyNode* b) 59 59 : InternalFunctionImp(static_cast<FunctionPrototype*> 60 60 (exec->lexicalInterpreter()->builtinFunctionPrototype()), n) 61 , body(b) 61 62 { 62 63 } … … 66 67 } 67 68 68 JSValue *FunctionImp::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)69 JSValue *FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) 69 70 { 70 71 JSObject *globalObj = exec->dynamicInterpreter()->globalObject(); 71 72 72 73 // 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); 75 76 ExecState newExec(exec->dynamicInterpreter(), &ctx); 76 77 newExec.setException(exec->exception()); // could be null … … 203 204 { 204 205 FunctionImp *thisObj = static_cast<FunctionImp *>(slot.slotBase()); 205 ContextImp *context = exec-> _context;206 ContextImp *context = exec->m_context; 206 207 while (context) { 207 208 if (context->function() == thisObj) { … … 295 296 DeclaredFunctionImp::DeclaredFunctionImp(ExecState *exec, const Identifier &n, 296 297 FunctionBodyNode *b, const ScopeChain &sc) 297 : FunctionImp(exec, n), body(b)298 : FunctionImp(exec, n, b) 298 299 { 299 300 setScope(sc); … … 804 805 exec->dynamicInterpreter()->imp(), 805 806 thisVal, 807 progNode.get(), 806 808 EvalCode, 807 809 exec->context().imp()); -
trunk/JavaScriptCore/kjs/function.h
r13153 r13304 40 40 friend class ActivationImp; 41 41 public: 42 FunctionImp(ExecState *exec, const Identifier &n = Identifier::null());42 FunctionImp(ExecState* exec, const Identifier& n, FunctionBodyNode* b); 43 43 virtual ~FunctionImp(); 44 44 … … 59 59 virtual const ClassInfo *classInfo() const { return &info; } 60 60 static const ClassInfo info; 61 62 RefPtr<FunctionBodyNode> body; 63 61 64 protected: 62 65 OwnPtr<Parameter> param; … … 80 83 virtual Completion execute(ExecState *exec); 81 84 CodeType codeType() const { return FunctionCode; } 82 RefPtr<FunctionBodyNode> body;83 85 84 86 virtual const ClassInfo *classInfo() const { return &info; } 85 87 static const ClassInfo info; 88 86 89 private: 87 90 virtual void processVarDecls(ExecState *exec); -
trunk/JavaScriptCore/kjs/grammar.y
r13089 r13304 49 49 50 50 #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) 52 52 53 53 using namespace KJS; -
trunk/JavaScriptCore/kjs/internal.cpp
r13153 r13304 189 189 190 190 // 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) 191 ContextImp::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) 194 200 { 195 201 m_codeType = type; … … 443 449 if (global) 444 450 global->mark(); 445 if (globExec. _exception)446 globExec. _exception->mark();451 if (globExec.exception()) 452 globExec.exception()->mark(); 447 453 } 448 454 … … 498 504 else { 499 505 // execute the code 500 ContextImp ctx(globalObj, this, thisObj );506 ContextImp ctx(globalObj, this, thisObj, progNode.get()); 501 507 ExecState newExec(m_interpreter, &ctx); 502 508 progNode->processVarDecls(&newExec); -
trunk/JavaScriptCore/kjs/internal.h
r13153 r13304 94 94 class LabelStack : Noncopyable { 95 95 public: 96 LabelStack(): tos(0), iterationDepth(0), switchDepth(0) {} 96 LabelStack() 97 : tos(0) 98 { 99 } 97 100 ~LabelStack(); 98 101 … … 111 114 void pop(); 112 115 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 121 116 private: 122 117 struct StackElem { … … 126 121 127 122 StackElem *tos; 128 int iterationDepth;129 int switchDepth;130 123 }; 131 124 -
trunk/JavaScriptCore/kjs/interpreter.cpp
r13089 r13304 362 362 Interpreter *ExecState::lexicalInterpreter() const 363 363 { 364 if (! _context) {364 if (!m_context) { 365 365 return dynamicInterpreter(); 366 366 } 367 367 368 InterpreterImp *result = InterpreterImp::interpreterWithGlobalObject( _context->scopeChain().bottom());368 InterpreterImp *result = InterpreterImp::interpreterWithGlobalObject(m_context->scopeChain().bottom()); 369 369 370 370 if (!result) { -
trunk/JavaScriptCore/kjs/interpreter.h
r13089 r13304 445 445 * @return The interpreter executing the script 446 446 */ 447 Interpreter *dynamicInterpreter() const { return _interpreter; }447 Interpreter *dynamicInterpreter() const { return m_interpreter; } 448 448 449 449 // for compatibility … … 463 463 * @return The current execution state context 464 464 */ 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; } 471 471 472 472 private: 473 473 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; 478 482 }; 479 483 -
trunk/JavaScriptCore/kjs/nodes.cpp
r13138 r13304 45 45 #include "ustring.h" 46 46 #include "reference_list.h" 47 #include <kxmlcore/HashSet.h> 48 #include <kxmlcore/HashCountedSet.h> 47 49 48 50 using namespace KJS; … … 96 98 #endif NDEBUG 97 99 100 static HashSet<Node*>* newNodes; 101 static HashCountedSet<Node*>* nodeExtraRefCounts; 98 102 99 103 Node::Node() … … 102 106 ++NodeCounter::count; 103 107 #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); 108 112 } 109 113 … … 115 119 } 116 120 121 void 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 137 void 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 146 unsigned 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 157 void Node::clearNewNodes() 158 { 159 if (newNodes) { 160 deleteAllValues(*newNodes); 161 delete newNodes; 162 newNodes = 0; 163 } 164 } 165 117 166 static void substitute(UString &string, const UString &substring) 118 167 { … … 122 171 } 123 172 124 Completion Node::createErrorCompletion(ExecState *exec, ErrorType e, const char *msg) 125 { 126 return Completion(Throw, Error::create(exec, e, msg, lineNo(), sourceId(), &sourceURL)); 173 static inline int currentSourceId(ExecState* exec) 174 { 175 return exec->context().imp()->currentBody()->sourceId(); 176 } 177 178 static inline const UString& currentSourceURL(ExecState* exec) 179 { 180 return exec->context().imp()->currentBody()->sourceURL(); 181 } 182 183 Completion Node::createErrorCompletion(ExecState* exec, ErrorType e, const char *msg) 184 { 185 return Completion(Throw, Error::create(exec, e, msg, lineNo(), currentSourceId(exec), ¤tSourceURL(exec))); 127 186 } 128 187 … … 131 190 UString message = msg; 132 191 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), ¤tSourceURL(exec))); 193 } 194 195 JSValue *Node::throwError(ExecState* exec, ErrorType e, const char *msg) 196 { 197 return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), ¤tSourceURL(exec)); 139 198 } 140 199 … … 144 203 substitute(message, v->toString(exec)); 145 204 substitute(message, expr->toString()); 146 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);205 return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), ¤tSourceURL(exec)); 147 206 } 148 207 … … 152 211 UString message = msg; 153 212 substitute(message, label.ustring()); 154 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);213 return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), ¤tSourceURL(exec)); 155 214 } 156 215 … … 161 220 substitute(message, e1->toString()); 162 221 substitute(message, e2->toString()); 163 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);222 return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), ¤tSourceURL(exec)); 164 223 } 165 224 … … 170 229 substitute(message, expr->toString()); 171 230 substitute(message, label.ustring()); 172 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);231 return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), ¤tSourceURL(exec)); 173 232 } 174 233 … … 178 237 substitute(message, v->toString(exec)); 179 238 substitute(message, label.ustring()); 180 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL);239 return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), ¤tSourceURL(exec)); 181 240 } 182 241 … … 192 251 JSObject *exception = static_cast<JSObject *>(exceptionValue); 193 252 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))); 196 255 } 197 256 } … … 205 264 // ------------------------------ StatementNode -------------------------------- 206 265 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; 266 StatementNode::StatementNode() 267 : m_lastLine(-1) 268 { 269 m_line = -1; 270 } 271 272 void StatementNode::setLoc(int firstLine, int lastLine) 273 { 274 m_line = firstLine; 275 m_lastLine = lastLine; 216 276 } 217 277 218 278 // return true if the debugger wants us to stop at this point 219 bool StatementNode::hitStatement(ExecState *exec)279 bool StatementNode::hitStatement(ExecState* exec) 220 280 { 221 281 Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger(); 222 282 if (dbg) 223 return dbg->atStatement(exec, sid,l0,l1);283 return dbg->atStatement(exec, currentSourceId(exec), firstLine(), lastLine()); 224 284 else 225 285 return true; // continue … … 1443 1503 { 1444 1504 Parser::noteNodeCycle(this); 1445 setLoc(s->firstLine(), s->lastLine() , s->sourceId());1505 setLoc(s->firstLine(), s->lastLine()); 1446 1506 } 1447 1507 … … 1450 1510 { 1451 1511 l->next = this; 1452 setLoc(l->firstLine(), s->lastLine() , l->sourceId());1512 setLoc(l->firstLine(), s->lastLine()); 1453 1513 } 1454 1514 … … 1601 1661 Parser::removeNodeCycle(source.get()); 1602 1662 s->next = 0; 1603 setLoc(s->firstLine(), s->lastLine() , s->sourceId());1663 setLoc(s->firstLine(), s->lastLine()); 1604 1664 } else { 1605 1665 source = 0; … … 1690 1750 KJS_CHECKEXCEPTION 1691 1751 1692 exec->context().imp()-> seenLabels()->pushIteration();1752 exec->context().imp()->pushIteration(); 1693 1753 c = statement->execute(exec); 1694 exec->context().imp()-> seenLabels()->popIteration();1754 exec->context().imp()->popIteration(); 1695 1755 if (!((c.complType() == Continue) && ls.contains(c.target()))) { 1696 1756 if ((c.complType() == Break) && ls.contains(c.target())) … … 1734 1794 return Completion(Normal, value); 1735 1795 1736 exec->context().imp()-> seenLabels()->pushIteration();1796 exec->context().imp()->pushIteration(); 1737 1797 c = statement->execute(exec); 1738 exec->context().imp()-> seenLabels()->popIteration();1798 exec->context().imp()->popIteration(); 1739 1799 if (c.isValueCompletion()) 1740 1800 value = c.value(); … … 1777 1837 KJS_CHECKEXCEPTION 1778 1838 1779 exec->context().imp()-> seenLabels()->pushIteration();1839 exec->context().imp()->pushIteration(); 1780 1840 Completion c = statement->execute(exec); 1781 exec->context().imp()-> seenLabels()->popIteration();1841 exec->context().imp()->popIteration(); 1782 1842 if (c.isValueCompletion()) 1783 1843 cval = c.value(); … … 1905 1965 KJS_CHECKEXCEPTION 1906 1966 1907 exec->context().imp()-> seenLabels()->pushIteration();1967 exec->context().imp()->pushIteration(); 1908 1968 c = statement->execute(exec); 1909 exec->context().imp()-> seenLabels()->popIteration();1969 exec->context().imp()->popIteration(); 1910 1970 if (c.isValueCompletion()) 1911 1971 retval = c.value(); … … 1942 2002 KJS_BREAKPOINT; 1943 2003 1944 if (ident.isEmpty() && !exec->context().imp()-> seenLabels()->inIteration())2004 if (ident.isEmpty() && !exec->context().imp()->inIteration()) 1945 2005 return createErrorCompletion(exec, SyntaxError, "Invalid continue statement."); 1946 2006 else if (!ident.isEmpty() && !exec->context().imp()->seenLabels()->contains(ident)) … … 1957 2017 KJS_BREAKPOINT; 1958 2018 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()) 1961 2021 return createErrorCompletion(exec, SyntaxError, "Invalid break statement."); 1962 2022 else if (!ident.isEmpty() && !exec->context().imp()->seenLabels()->contains(ident)) … … 2172 2232 KJS_CHECKEXCEPTION 2173 2233 2174 exec->context().imp()-> seenLabels()->pushSwitch();2234 exec->context().imp()->pushSwitch(); 2175 2235 Completion res = block->evalBlock(exec,v); 2176 exec->context().imp()-> seenLabels()->popSwitch();2236 exec->context().imp()->popSwitch(); 2177 2237 2178 2238 if ((res.complType() == Break) && ls.contains(res.target())) … … 2270 2330 2271 2331 FunctionBodyNode::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); 2275 2338 } 2276 2339 2277 2340 void FunctionBodyNode::processFuncDecl(ExecState *exec) 2278 2341 { 2279 if (source)2280 source->processFuncDecl(exec);2342 if (source) 2343 source->processFuncDecl(exec); 2281 2344 } 2282 2345 … … 2363 2426 { 2364 2427 Parser::noteNodeCycle(this); 2365 setLoc(s1->firstLine(), s1->lastLine() , s1->sourceId());2428 setLoc(s1->firstLine(), s1->lastLine()); 2366 2429 } 2367 2430 … … 2370 2433 { 2371 2434 s1->next = this; 2372 setLoc(s1->firstLine(), s2->lastLine() , s1->sourceId());2435 setLoc(s1->firstLine(), s2->lastLine()); 2373 2436 } 2374 2437 -
trunk/JavaScriptCore/kjs/nodes.h
r13153 r13304 81 81 virtual void streamTo(SourceStream &s) const = 0; 82 82 virtual void processVarDecls(ExecState *) {} 83 int lineNo() const { return line; }84 85 // reference counting mechanism86 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(); 89 89 90 90 virtual Node *nodeInsideAllParens(); … … 113 113 void setExceptionDetailsIfNeeded(ExecState *); 114 114 115 int line; 116 UString sourceURL; 117 unsigned int m_refcount; 118 virtual int sourceId() const { return -1; } 119 115 int m_line; 120 116 private: 121 117 // disallow assignment … … 127 123 public: 128 124 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; } 133 128 bool hitStatement(ExecState *exec); 134 129 virtual Completion execute(ExecState *exec) = 0; … … 139 134 private: 140 135 JSValue *evaluate(ExecState */*exec*/) { return jsUndefined(); } 141 int l0, l1; 142 int sid; 136 int m_lastLine; 143 137 }; 144 138 … … 1054 1048 class FunctionBodyNode : public BlockNode { 1055 1049 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; 1058 1057 }; 1059 1058
Note:
See TracChangeset
for help on using the changeset viewer.