• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 *  Copyright (C) 2007 Maks Orlovich
7 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8 *
9 *  This library is free software; you can redistribute it and/or
10 *  modify it under the terms of the GNU Library General Public
11 *  License as published by the Free Software Foundation; either
12 *  version 2 of the License, or (at your option) any later version.
13 *
14 *  This library is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 *  Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Library General Public License
20 *  along with this library; see the file COPYING.LIB.  If not, write to
21 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25 
26 #include "config.h"
27 #include "Nodes.h"
28 
29 #include "BytecodeGenerator.h"
30 #include "CallFrame.h"
31 #include "JSGlobalObject.h"
32 #include "JSStaticScopeObject.h"
33 #include "LabelScope.h"
34 #include "Parser.h"
35 #include "PropertyNameArray.h"
36 #include "RegExpObject.h"
37 #include "SamplingTool.h"
38 #include "Debugger.h"
39 #include "Lexer.h"
40 #include "Operations.h"
41 #include <math.h>
42 #include <wtf/Assertions.h>
43 #include <wtf/HashCountedSet.h>
44 #include <wtf/HashSet.h>
45 #include <wtf/MathExtras.h>
46 #include <wtf/RefCountedLeakCounter.h>
47 #include <wtf/Threading.h>
48 
49 using namespace WTF;
50 
51 namespace JSC {
52 
53 static void substitute(UString& string, const UString& substring) JSC_FAST_CALL;
54 
55 // ------------------------------ NodeReleaser --------------------------------
56 
57 class NodeReleaser : Noncopyable {
58 public:
59     // Call this function inside the destructor of a class derived from Node.
60     // This will traverse the tree below this node, destroying all of those nodes,
61     // but without relying on recursion.
62     static void releaseAllNodes(ParserRefCounted* root);
63 
64     // Call this on each node in a the releaseNodes virtual function.
65     // It gives the node to the NodeReleaser, which will then release the
66     // node later at the end of the releaseAllNodes process.
release(RefPtr<T> & node)67     template <typename T> void release(RefPtr<T>& node) { if (node) adopt(node.release()); }
release(RefPtr<FunctionBodyNode> & node)68     void release(RefPtr<FunctionBodyNode>& node) { if (node) adoptFunctionBodyNode(node); }
69 
70 private:
NodeReleaser()71     NodeReleaser() { }
~NodeReleaser()72     ~NodeReleaser() { }
73 
74     void adopt(PassRefPtr<ParserRefCounted>);
75     void adoptFunctionBodyNode(RefPtr<FunctionBodyNode>&);
76 
77     typedef Vector<RefPtr<ParserRefCounted> > NodeReleaseVector;
78     OwnPtr<NodeReleaseVector> m_vector;
79 };
80 
releaseAllNodes(ParserRefCounted * root)81 void NodeReleaser::releaseAllNodes(ParserRefCounted* root)
82 {
83     ASSERT(root);
84     NodeReleaser releaser;
85     root->releaseNodes(releaser);
86     if (!releaser.m_vector)
87         return;
88     // Note: The call to release.m_vector->size() is intentionally inside
89     // the loop, since calls to releaseNodes are expected to increase the size.
90     for (size_t i = 0; i < releaser.m_vector->size(); ++i) {
91         ParserRefCounted* node = (*releaser.m_vector)[i].get();
92         if (node->hasOneRef())
93             node->releaseNodes(releaser);
94     }
95 }
96 
adopt(PassRefPtr<ParserRefCounted> node)97 void NodeReleaser::adopt(PassRefPtr<ParserRefCounted> node)
98 {
99     ASSERT(node);
100     if (!node->hasOneRef())
101         return;
102     if (!m_vector)
103         m_vector.set(new NodeReleaseVector);
104     m_vector->append(node);
105 }
106 
adoptFunctionBodyNode(RefPtr<FunctionBodyNode> & functionBodyNode)107 void NodeReleaser::adoptFunctionBodyNode(RefPtr<FunctionBodyNode>& functionBodyNode)
108 {
109     // This sidesteps a problem where if you assign a PassRefPtr<FunctionBodyNode>
110     // to a PassRefPtr<Node> we leave the two reference counts (FunctionBodyNode
111     // and ParserRefCounted) unbalanced. It would be nice to fix this problem in
112     // a cleaner way -- perhaps we could remove the FunctionBodyNode reference
113     // count at some point.
114     RefPtr<Node> node = functionBodyNode;
115     functionBodyNode = 0;
116     adopt(node.release());
117 }
118 
119 // ------------------------------ ParserRefCounted -----------------------------------------
120 
121 #ifndef NDEBUG
122 static RefCountedLeakCounter parserRefCountedCounter("JSC::Node");
123 #endif
124 
ParserRefCounted(JSGlobalData * globalData)125 ParserRefCounted::ParserRefCounted(JSGlobalData* globalData)
126     : m_globalData(globalData)
127 {
128 #ifndef NDEBUG
129     parserRefCountedCounter.increment();
130 #endif
131     if (!m_globalData->newParserObjects)
132         m_globalData->newParserObjects = new HashSet<ParserRefCounted*>;
133     m_globalData->newParserObjects->add(this);
134     ASSERT(m_globalData->newParserObjects->contains(this));
135 }
136 
~ParserRefCounted()137 ParserRefCounted::~ParserRefCounted()
138 {
139 #ifndef NDEBUG
140     parserRefCountedCounter.decrement();
141 #endif
142 }
143 
releaseNodes(NodeReleaser &)144 void ParserRefCounted::releaseNodes(NodeReleaser&)
145 {
146 }
147 
ref()148 void ParserRefCounted::ref()
149 {
150     // bumping from 0 to 1 is just removing from the new nodes set
151     if (m_globalData->newParserObjects) {
152         HashSet<ParserRefCounted*>::iterator it = m_globalData->newParserObjects->find(this);
153         if (it != m_globalData->newParserObjects->end()) {
154             m_globalData->newParserObjects->remove(it);
155             ASSERT(!m_globalData->parserObjectExtraRefCounts || !m_globalData->parserObjectExtraRefCounts->contains(this));
156             return;
157         }
158     }
159 
160     ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
161 
162     if (!m_globalData->parserObjectExtraRefCounts)
163         m_globalData->parserObjectExtraRefCounts = new HashCountedSet<ParserRefCounted*>;
164     m_globalData->parserObjectExtraRefCounts->add(this);
165 }
166 
deref()167 void ParserRefCounted::deref()
168 {
169     ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
170 
171     if (!m_globalData->parserObjectExtraRefCounts) {
172         delete this;
173         return;
174     }
175 
176     HashCountedSet<ParserRefCounted*>::iterator it = m_globalData->parserObjectExtraRefCounts->find(this);
177     if (it == m_globalData->parserObjectExtraRefCounts->end())
178         delete this;
179     else
180         m_globalData->parserObjectExtraRefCounts->remove(it);
181 }
182 
hasOneRef()183 bool ParserRefCounted::hasOneRef()
184 {
185     if (m_globalData->newParserObjects && m_globalData->newParserObjects->contains(this)) {
186         ASSERT(!m_globalData->parserObjectExtraRefCounts || !m_globalData->parserObjectExtraRefCounts->contains(this));
187         return false;
188     }
189 
190     ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
191 
192     if (!m_globalData->parserObjectExtraRefCounts)
193         return true;
194 
195     return !m_globalData->parserObjectExtraRefCounts->contains(this);
196 }
197 
deleteNewObjects(JSGlobalData * globalData)198 void ParserRefCounted::deleteNewObjects(JSGlobalData* globalData)
199 {
200     if (!globalData->newParserObjects)
201         return;
202 
203 #ifndef NDEBUG
204     HashSet<ParserRefCounted*>::iterator end = globalData->newParserObjects->end();
205     for (HashSet<ParserRefCounted*>::iterator it = globalData->newParserObjects->begin(); it != end; ++it)
206         ASSERT(!globalData->parserObjectExtraRefCounts || !globalData->parserObjectExtraRefCounts->contains(*it));
207 #endif
208     deleteAllValues(*globalData->newParserObjects);
209     delete globalData->newParserObjects;
210     globalData->newParserObjects = 0;
211 }
212 
213 // ------------------------------ Node --------------------------------
214 
Node(JSGlobalData * globalData)215 Node::Node(JSGlobalData* globalData)
216     : ParserRefCounted(globalData)
217 {
218     m_line = globalData->lexer->lineNo();
219 }
220 
221 // ------------------------------ ThrowableExpressionData --------------------------------
222 
substitute(UString & string,const UString & substring)223 static void substitute(UString& string, const UString& substring)
224 {
225     int position = string.find("%s");
226     ASSERT(position != -1);
227     UString newString = string.substr(0, position);
228     newString.append(substring);
229     newString.append(string.substr(position + 2));
230     string = newString;
231 }
232 
emitThrowError(BytecodeGenerator & generator,ErrorType e,const char * msg)233 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg)
234 {
235     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
236     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), msg));
237     generator.emitThrow(exception);
238     return exception;
239 }
240 
emitThrowError(BytecodeGenerator & generator,ErrorType e,const char * msg,const Identifier & label)241 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
242 {
243     UString message = msg;
244     substitute(message, label.ustring());
245     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
246     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), message));
247     generator.emitThrow(exception);
248     return exception;
249 }
250 
251 // ------------------------------ StatementNode --------------------------------
252 
StatementNode(JSGlobalData * globalData)253 StatementNode::StatementNode(JSGlobalData* globalData)
254     : Node(globalData)
255     , m_lastLine(-1)
256 {
257 }
258 
setLoc(int firstLine,int lastLine)259 void StatementNode::setLoc(int firstLine, int lastLine)
260 {
261     m_line = firstLine;
262     m_lastLine = lastLine;
263 }
264 
265 // ------------------------------ SourceElements --------------------------------
266 
append(PassRefPtr<StatementNode> statement)267 void SourceElements::append(PassRefPtr<StatementNode> statement)
268 {
269     if (statement->isEmptyStatement())
270         return;
271 
272     m_statements.append(statement);
273 }
274 
275 // ------------------------------ NullNode -------------------------------------
276 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)277 RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
278 {
279     if (dst == generator.ignoredResult())
280         return 0;
281     return generator.emitLoad(dst, jsNull());
282 }
283 
284 // ------------------------------ BooleanNode ----------------------------------
285 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)286 RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
287 {
288     if (dst == generator.ignoredResult())
289         return 0;
290     return generator.emitLoad(dst, m_value);
291 }
292 
293 // ------------------------------ NumberNode -----------------------------------
294 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)295 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
296 {
297     if (dst == generator.ignoredResult())
298         return 0;
299     return generator.emitLoad(dst, m_double);
300 }
301 
302 // ------------------------------ StringNode -----------------------------------
303 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)304 RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
305 {
306     if (dst == generator.ignoredResult())
307         return 0;
308     return generator.emitLoad(dst, m_value);
309 }
310 
311 // ------------------------------ RegExpNode -----------------------------------
312 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)313 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
314 {
315     RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags);
316     if (!regExp->isValid())
317         return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str());
318     if (dst == generator.ignoredResult())
319         return 0;
320     return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
321 }
322 
323 // ------------------------------ ThisNode -------------------------------------
324 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)325 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
326 {
327     if (dst == generator.ignoredResult())
328         return 0;
329     return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
330 }
331 
332 // ------------------------------ ResolveNode ----------------------------------
333 
isPure(BytecodeGenerator & generator) const334 bool ResolveNode::isPure(BytecodeGenerator& generator) const
335 {
336     return generator.isLocal(m_ident);
337 }
338 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)339 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
340 {
341     if (RegisterID* local = generator.registerFor(m_ident)) {
342         if (dst == generator.ignoredResult())
343             return 0;
344         return generator.moveToDestinationIfNeeded(dst, local);
345     }
346 
347     generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0);
348     return generator.emitResolve(generator.finalDestination(dst), m_ident);
349 }
350 
351 // ------------------------------ ElementNode ------------------------------------
352 
~ElementNode()353 ElementNode::~ElementNode()
354 {
355     NodeReleaser::releaseAllNodes(this);
356 }
357 
releaseNodes(NodeReleaser & releaser)358 void ElementNode::releaseNodes(NodeReleaser& releaser)
359 {
360     releaser.release(m_next);
361     releaser.release(m_node);
362 }
363 
364 // ------------------------------ ArrayNode ------------------------------------
365 
~ArrayNode()366 ArrayNode::~ArrayNode()
367 {
368     NodeReleaser::releaseAllNodes(this);
369 }
370 
releaseNodes(NodeReleaser & releaser)371 void ArrayNode::releaseNodes(NodeReleaser& releaser)
372 {
373     releaser.release(m_element);
374 }
375 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)376 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
377 {
378     // FIXME: Should we put all of this code into emitNewArray?
379 
380     unsigned length = 0;
381     ElementNode* firstPutElement;
382     for (firstPutElement = m_element.get(); firstPutElement; firstPutElement = firstPutElement->next()) {
383         if (firstPutElement->elision())
384             break;
385         ++length;
386     }
387 
388     if (!firstPutElement && !m_elision)
389         return generator.emitNewArray(generator.finalDestination(dst), m_element.get());
390 
391     RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element.get());
392 
393     for (ElementNode* n = firstPutElement; n; n = n->next()) {
394         RegisterID* value = generator.emitNode(n->value());
395         length += n->elision();
396         generator.emitPutByIndex(array.get(), length++, value);
397     }
398 
399     if (m_elision) {
400         RegisterID* value = generator.emitLoad(0, jsNumber(generator.globalData(), m_elision + length));
401         generator.emitPutById(array.get(), generator.propertyNames().length, value);
402     }
403 
404     return generator.moveToDestinationIfNeeded(dst, array.get());
405 }
406 
407 // ------------------------------ PropertyNode ----------------------------
408 
~PropertyNode()409 PropertyNode::~PropertyNode()
410 {
411     NodeReleaser::releaseAllNodes(this);
412 }
413 
releaseNodes(NodeReleaser & releaser)414 void PropertyNode::releaseNodes(NodeReleaser& releaser)
415 {
416     releaser.release(m_assign);
417 }
418 
419 // ------------------------------ ObjectLiteralNode ----------------------------
420 
~ObjectLiteralNode()421 ObjectLiteralNode::~ObjectLiteralNode()
422 {
423     NodeReleaser::releaseAllNodes(this);
424 }
425 
releaseNodes(NodeReleaser & releaser)426 void ObjectLiteralNode::releaseNodes(NodeReleaser& releaser)
427 {
428     releaser.release(m_list);
429 }
430 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)431 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
432 {
433      if (!m_list) {
434          if (dst == generator.ignoredResult())
435              return 0;
436          return generator.emitNewObject(generator.finalDestination(dst));
437      }
438      return generator.emitNode(dst, m_list.get());
439 }
440 
441 // ------------------------------ PropertyListNode -----------------------------
442 
~PropertyListNode()443 PropertyListNode::~PropertyListNode()
444 {
445     NodeReleaser::releaseAllNodes(this);
446 }
447 
releaseNodes(NodeReleaser & releaser)448 void PropertyListNode::releaseNodes(NodeReleaser& releaser)
449 {
450     releaser.release(m_node);
451     releaser.release(m_next);
452 }
453 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)454 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
455 {
456     RefPtr<RegisterID> newObj = generator.tempDestination(dst);
457 
458     generator.emitNewObject(newObj.get());
459 
460     for (PropertyListNode* p = this; p; p = p->m_next.get()) {
461         RegisterID* value = generator.emitNode(p->m_node->m_assign.get());
462 
463         switch (p->m_node->m_type) {
464             case PropertyNode::Constant: {
465                 generator.emitPutById(newObj.get(), p->m_node->name(), value);
466                 break;
467             }
468             case PropertyNode::Getter: {
469                 generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
470                 break;
471             }
472             case PropertyNode::Setter: {
473                 generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
474                 break;
475             }
476             default:
477                 ASSERT_NOT_REACHED();
478         }
479     }
480 
481     return generator.moveToDestinationIfNeeded(dst, newObj.get());
482 }
483 
484 // ------------------------------ BracketAccessorNode --------------------------------
485 
~BracketAccessorNode()486 BracketAccessorNode::~BracketAccessorNode()
487 {
488     NodeReleaser::releaseAllNodes(this);
489 }
490 
releaseNodes(NodeReleaser & releaser)491 void BracketAccessorNode::releaseNodes(NodeReleaser& releaser)
492 {
493     releaser.release(m_base);
494     releaser.release(m_subscript);
495 }
496 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)497 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
498 {
499     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript->isPure(generator));
500     RegisterID* property = generator.emitNode(m_subscript.get());
501     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
502     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
503 }
504 
505 // ------------------------------ DotAccessorNode --------------------------------
506 
~DotAccessorNode()507 DotAccessorNode::~DotAccessorNode()
508 {
509     NodeReleaser::releaseAllNodes(this);
510 }
511 
releaseNodes(NodeReleaser & releaser)512 void DotAccessorNode::releaseNodes(NodeReleaser& releaser)
513 {
514     releaser.release(m_base);
515 }
516 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)517 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
518 {
519     RegisterID* base = generator.emitNode(m_base.get());
520     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
521     return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
522 }
523 
524 // ------------------------------ ArgumentListNode -----------------------------
525 
~ArgumentListNode()526 ArgumentListNode::~ArgumentListNode()
527 {
528     NodeReleaser::releaseAllNodes(this);
529 }
530 
releaseNodes(NodeReleaser & releaser)531 void ArgumentListNode::releaseNodes(NodeReleaser& releaser)
532 {
533     releaser.release(m_next);
534     releaser.release(m_expr);
535 }
536 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)537 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
538 {
539     ASSERT(m_expr);
540     return generator.emitNode(dst, m_expr.get());
541 }
542 
543 // ------------------------------ ArgumentsNode -----------------------------
544 
~ArgumentsNode()545 ArgumentsNode::~ArgumentsNode()
546 {
547     NodeReleaser::releaseAllNodes(this);
548 }
549 
releaseNodes(NodeReleaser & releaser)550 void ArgumentsNode::releaseNodes(NodeReleaser& releaser)
551 {
552     releaser.release(m_listNode);
553 }
554 
555 // ------------------------------ NewExprNode ----------------------------------
556 
~NewExprNode()557 NewExprNode::~NewExprNode()
558 {
559     NodeReleaser::releaseAllNodes(this);
560 }
561 
releaseNodes(NodeReleaser & releaser)562 void NewExprNode::releaseNodes(NodeReleaser& releaser)
563 {
564     releaser.release(m_expr);
565     releaser.release(m_args);
566 }
567 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)568 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
569 {
570     RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
571     return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args.get(), divot(), startOffset(), endOffset());
572 }
573 
574 // ------------------------------ EvalFunctionCallNode ----------------------------------
575 
~EvalFunctionCallNode()576 EvalFunctionCallNode::~EvalFunctionCallNode()
577 {
578     NodeReleaser::releaseAllNodes(this);
579 }
580 
releaseNodes(NodeReleaser & releaser)581 void EvalFunctionCallNode::releaseNodes(NodeReleaser& releaser)
582 {
583     releaser.release(m_args);
584 }
585 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)586 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
587 {
588     RefPtr<RegisterID> func = generator.tempDestination(dst);
589     RefPtr<RegisterID> thisRegister = generator.newTemporary();
590     generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
591     generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
592     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
593 }
594 
595 // ------------------------------ FunctionCallValueNode ----------------------------------
596 
~FunctionCallValueNode()597 FunctionCallValueNode::~FunctionCallValueNode()
598 {
599     NodeReleaser::releaseAllNodes(this);
600 }
601 
releaseNodes(NodeReleaser & releaser)602 void FunctionCallValueNode::releaseNodes(NodeReleaser& releaser)
603 {
604     releaser.release(m_expr);
605     releaser.release(m_args);
606 }
607 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)608 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
609 {
610     RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
611     RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
612     return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
613 }
614 
615 // ------------------------------ FunctionCallResolveNode ----------------------------------
616 
~FunctionCallResolveNode()617 FunctionCallResolveNode::~FunctionCallResolveNode()
618 {
619     NodeReleaser::releaseAllNodes(this);
620 }
621 
releaseNodes(NodeReleaser & releaser)622 void FunctionCallResolveNode::releaseNodes(NodeReleaser& releaser)
623 {
624     releaser.release(m_args);
625 }
626 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)627 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
628 {
629     if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
630         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
631         return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
632     }
633 
634     int index = 0;
635     size_t depth = 0;
636     JSObject* globalObject = 0;
637     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
638         RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
639         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
640         return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
641     }
642 
643     RefPtr<RegisterID> func = generator.tempDestination(dst);
644     RefPtr<RegisterID> thisRegister = generator.newTemporary();
645     int identifierStart = divot() - startOffset();
646     generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
647     generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
648     return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
649 }
650 
651 // ------------------------------ FunctionCallBracketNode ----------------------------------
652 
~FunctionCallBracketNode()653 FunctionCallBracketNode::~FunctionCallBracketNode()
654 {
655     NodeReleaser::releaseAllNodes(this);
656 }
657 
releaseNodes(NodeReleaser & releaser)658 void FunctionCallBracketNode::releaseNodes(NodeReleaser& releaser)
659 {
660     releaser.release(m_base);
661     releaser.release(m_subscript);
662     releaser.release(m_args);
663 }
664 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)665 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
666 {
667     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
668     RegisterID* property = generator.emitNode(m_subscript.get());
669     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
670     RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
671     RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
672     return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
673 }
674 
675 // ------------------------------ FunctionCallDotNode ----------------------------------
676 
~FunctionCallDotNode()677 FunctionCallDotNode::~FunctionCallDotNode()
678 {
679     NodeReleaser::releaseAllNodes(this);
680 }
681 
releaseNodes(NodeReleaser & releaser)682 void FunctionCallDotNode::releaseNodes(NodeReleaser& releaser)
683 {
684     releaser.release(m_base);
685     releaser.release(m_args);
686 }
687 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)688 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
689 {
690     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
691     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
692     RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
693     RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
694     return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
695 }
696 
697 // ------------------------------ PostfixResolveNode ----------------------------------
698 
emitPreIncOrDec(BytecodeGenerator & generator,RegisterID * srcDst,Operator oper)699 static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
700 {
701     return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
702 }
703 
emitPostIncOrDec(BytecodeGenerator & generator,RegisterID * dst,RegisterID * srcDst,Operator oper)704 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
705 {
706     return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
707 }
708 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)709 RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
710 {
711     if (RegisterID* local = generator.registerFor(m_ident)) {
712         if (generator.isLocalConstant(m_ident)) {
713             if (dst == generator.ignoredResult())
714                 return 0;
715             return generator.emitToJSNumber(generator.finalDestination(dst), local);
716         }
717 
718         if (dst == generator.ignoredResult())
719             return emitPreIncOrDec(generator, local, m_operator);
720         return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
721     }
722 
723     int index = 0;
724     size_t depth = 0;
725     JSObject* globalObject = 0;
726     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
727         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
728         RegisterID* oldValue;
729         if (dst == generator.ignoredResult()) {
730             oldValue = 0;
731             emitPreIncOrDec(generator, value.get(), m_operator);
732         } else {
733             oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
734         }
735         generator.emitPutScopedVar(depth, index, value.get(), globalObject);
736         return oldValue;
737     }
738 
739     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
740     RefPtr<RegisterID> value = generator.newTemporary();
741     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
742     RegisterID* oldValue;
743     if (dst == generator.ignoredResult()) {
744         oldValue = 0;
745         emitPreIncOrDec(generator, value.get(), m_operator);
746     } else {
747         oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
748     }
749     generator.emitPutById(base.get(), m_ident, value.get());
750     return oldValue;
751 }
752 
753 // ------------------------------ PostfixBracketNode ----------------------------------
754 
~PostfixBracketNode()755 PostfixBracketNode::~PostfixBracketNode()
756 {
757     NodeReleaser::releaseAllNodes(this);
758 }
759 
releaseNodes(NodeReleaser & releaser)760 void PostfixBracketNode::releaseNodes(NodeReleaser& releaser)
761 {
762     releaser.release(m_base);
763     releaser.release(m_subscript);
764 }
765 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)766 RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
767 {
768     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
769     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
770 
771     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
772     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
773     RegisterID* oldValue;
774     if (dst == generator.ignoredResult()) {
775         oldValue = 0;
776         if (m_operator == OpPlusPlus)
777             generator.emitPreInc(value.get());
778         else
779             generator.emitPreDec(value.get());
780     } else {
781         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
782     }
783     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
784     generator.emitPutByVal(base.get(), property.get(), value.get());
785     return oldValue;
786 }
787 
788 // ------------------------------ PostfixDotNode ----------------------------------
789 
~PostfixDotNode()790 PostfixDotNode::~PostfixDotNode()
791 {
792     NodeReleaser::releaseAllNodes(this);
793 }
794 
releaseNodes(NodeReleaser & releaser)795 void PostfixDotNode::releaseNodes(NodeReleaser& releaser)
796 {
797     releaser.release(m_base);
798 }
799 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)800 RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
801 {
802     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
803 
804     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
805     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
806     RegisterID* oldValue;
807     if (dst == generator.ignoredResult()) {
808         oldValue = 0;
809         if (m_operator == OpPlusPlus)
810             generator.emitPreInc(value.get());
811         else
812             generator.emitPreDec(value.get());
813     } else {
814         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
815     }
816     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
817     generator.emitPutById(base.get(), m_ident, value.get());
818     return oldValue;
819 }
820 
821 // ------------------------------ PostfixErrorNode -----------------------------------
822 
~PostfixErrorNode()823 PostfixErrorNode::~PostfixErrorNode()
824 {
825     NodeReleaser::releaseAllNodes(this);
826 }
827 
releaseNodes(NodeReleaser & releaser)828 void PostfixErrorNode::releaseNodes(NodeReleaser& releaser)
829 {
830     releaser.release(m_expr);
831 }
832 
emitBytecode(BytecodeGenerator & generator,RegisterID *)833 RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
834 {
835     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
836 }
837 
838 // ------------------------------ DeleteResolveNode -----------------------------------
839 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)840 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
841 {
842     if (generator.registerFor(m_ident))
843         return generator.emitUnexpectedLoad(generator.finalDestination(dst), false);
844 
845     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
846     RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
847     return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
848 }
849 
850 // ------------------------------ DeleteBracketNode -----------------------------------
851 
~DeleteBracketNode()852 DeleteBracketNode::~DeleteBracketNode()
853 {
854     NodeReleaser::releaseAllNodes(this);
855 }
856 
releaseNodes(NodeReleaser & releaser)857 void DeleteBracketNode::releaseNodes(NodeReleaser& releaser)
858 {
859     releaser.release(m_base);
860     releaser.release(m_subscript);
861 }
862 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)863 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
864 {
865     RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
866     RegisterID* r1 = generator.emitNode(m_subscript.get());
867 
868     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
869     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
870 }
871 
872 // ------------------------------ DeleteDotNode -----------------------------------
873 
~DeleteDotNode()874 DeleteDotNode::~DeleteDotNode()
875 {
876     NodeReleaser::releaseAllNodes(this);
877 }
878 
releaseNodes(NodeReleaser & releaser)879 void DeleteDotNode::releaseNodes(NodeReleaser& releaser)
880 {
881     releaser.release(m_base);
882 }
883 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)884 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
885 {
886     RegisterID* r0 = generator.emitNode(m_base.get());
887 
888     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
889     return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
890 }
891 
892 // ------------------------------ DeleteValueNode -----------------------------------
893 
~DeleteValueNode()894 DeleteValueNode::~DeleteValueNode()
895 {
896     NodeReleaser::releaseAllNodes(this);
897 }
898 
releaseNodes(NodeReleaser & releaser)899 void DeleteValueNode::releaseNodes(NodeReleaser& releaser)
900 {
901     releaser.release(m_expr);
902 }
903 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)904 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
905 {
906     generator.emitNode(generator.ignoredResult(), m_expr.get());
907 
908     // delete on a non-location expression ignores the value and returns true
909     return generator.emitUnexpectedLoad(generator.finalDestination(dst), true);
910 }
911 
912 // ------------------------------ VoidNode -------------------------------------
913 
~VoidNode()914 VoidNode::~VoidNode()
915 {
916     NodeReleaser::releaseAllNodes(this);
917 }
918 
releaseNodes(NodeReleaser & releaser)919 void VoidNode::releaseNodes(NodeReleaser& releaser)
920 {
921     releaser.release(m_expr);
922 }
923 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)924 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
925 {
926     if (dst == generator.ignoredResult()) {
927         generator.emitNode(generator.ignoredResult(), m_expr.get());
928         return 0;
929     }
930     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
931     return generator.emitLoad(dst, jsUndefined());
932 }
933 
934 // ------------------------------ TypeOfValueNode -----------------------------------
935 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)936 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
937 {
938     if (RegisterID* local = generator.registerFor(m_ident)) {
939         if (dst == generator.ignoredResult())
940             return 0;
941         return generator.emitTypeOf(generator.finalDestination(dst), local);
942     }
943 
944     RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
945     generator.emitGetById(scratch.get(), scratch.get(), m_ident);
946     if (dst == generator.ignoredResult())
947         return 0;
948     return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
949 }
950 
951 // ------------------------------ TypeOfValueNode -----------------------------------
952 
~TypeOfValueNode()953 TypeOfValueNode::~TypeOfValueNode()
954 {
955     NodeReleaser::releaseAllNodes(this);
956 }
957 
releaseNodes(NodeReleaser & releaser)958 void TypeOfValueNode::releaseNodes(NodeReleaser& releaser)
959 {
960     releaser.release(m_expr);
961 }
962 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)963 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
964 {
965     if (dst == generator.ignoredResult()) {
966         generator.emitNode(generator.ignoredResult(), m_expr.get());
967         return 0;
968     }
969     RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
970     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
971 }
972 
973 // ------------------------------ PrefixResolveNode ----------------------------------
974 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)975 RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
976 {
977     if (RegisterID* local = generator.registerFor(m_ident)) {
978         if (generator.isLocalConstant(m_ident)) {
979             if (dst == generator.ignoredResult())
980                 return 0;
981             RefPtr<RegisterID> r0 = generator.emitUnexpectedLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
982             return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
983         }
984 
985         emitPreIncOrDec(generator, local, m_operator);
986         return generator.moveToDestinationIfNeeded(dst, local);
987     }
988 
989     int index = 0;
990     size_t depth = 0;
991     JSObject* globalObject = 0;
992     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
993         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
994         emitPreIncOrDec(generator, propDst.get(), m_operator);
995         generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
996         return generator.moveToDestinationIfNeeded(dst, propDst.get());
997     }
998 
999     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1000     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1001     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
1002     emitPreIncOrDec(generator, propDst.get(), m_operator);
1003     generator.emitPutById(base.get(), m_ident, propDst.get());
1004     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1005 }
1006 
1007 // ------------------------------ PrefixBracketNode ----------------------------------
1008 
~PrefixBracketNode()1009 PrefixBracketNode::~PrefixBracketNode()
1010 {
1011     NodeReleaser::releaseAllNodes(this);
1012 }
1013 
releaseNodes(NodeReleaser & releaser)1014 void PrefixBracketNode::releaseNodes(NodeReleaser& releaser)
1015 {
1016     releaser.release(m_base);
1017     releaser.release(m_subscript);
1018 }
1019 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1020 RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1021 {
1022     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1023     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
1024     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1025 
1026     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
1027     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1028     if (m_operator == OpPlusPlus)
1029         generator.emitPreInc(value);
1030     else
1031         generator.emitPreDec(value);
1032     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1033     generator.emitPutByVal(base.get(), property.get(), value);
1034     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1035 }
1036 
1037 // ------------------------------ PrefixDotNode ----------------------------------
1038 
~PrefixDotNode()1039 PrefixDotNode::~PrefixDotNode()
1040 {
1041     NodeReleaser::releaseAllNodes(this);
1042 }
1043 
releaseNodes(NodeReleaser & releaser)1044 void PrefixDotNode::releaseNodes(NodeReleaser& releaser)
1045 {
1046     releaser.release(m_base);
1047 }
1048 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1049 RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1050 {
1051     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1052     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1053 
1054     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
1055     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
1056     if (m_operator == OpPlusPlus)
1057         generator.emitPreInc(value);
1058     else
1059         generator.emitPreDec(value);
1060     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1061     generator.emitPutById(base.get(), m_ident, value);
1062     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1063 }
1064 
1065 // ------------------------------ PrefixErrorNode -----------------------------------
1066 
~PrefixErrorNode()1067 PrefixErrorNode::~PrefixErrorNode()
1068 {
1069     NodeReleaser::releaseAllNodes(this);
1070 }
1071 
releaseNodes(NodeReleaser & releaser)1072 void PrefixErrorNode::releaseNodes(NodeReleaser& releaser)
1073 {
1074     releaser.release(m_expr);
1075 }
1076 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1077 RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1078 {
1079     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
1080 }
1081 
1082 // ------------------------------ Unary Operation Nodes -----------------------------------
1083 
~UnaryOpNode()1084 UnaryOpNode::~UnaryOpNode()
1085 {
1086     NodeReleaser::releaseAllNodes(this);
1087 }
1088 
releaseNodes(NodeReleaser & releaser)1089 void UnaryOpNode::releaseNodes(NodeReleaser& releaser)
1090 {
1091     releaser.release(m_expr);
1092 }
1093 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1094 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1095 {
1096     RegisterID* src = generator.emitNode(m_expr.get());
1097     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
1098 }
1099 
1100 // ------------------------------ Binary Operation Nodes -----------------------------------
1101 
~BinaryOpNode()1102 BinaryOpNode::~BinaryOpNode()
1103 {
1104     NodeReleaser::releaseAllNodes(this);
1105 }
1106 
releaseNodes(NodeReleaser & releaser)1107 void BinaryOpNode::releaseNodes(NodeReleaser& releaser)
1108 {
1109     releaser.release(m_expr1);
1110     releaser.release(m_expr2);
1111 }
1112 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1113 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1114 {
1115     OpcodeID opcodeID = this->opcodeID();
1116     if (opcodeID == op_neq) {
1117         if (m_expr1->isNull() || m_expr2->isNull()) {
1118             RefPtr<RegisterID> src = generator.tempDestination(dst);
1119             generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
1120             return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
1121         }
1122     }
1123 
1124     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1125     RegisterID* src2 = generator.emitNode(m_expr2.get());
1126     return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1127 }
1128 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1129 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1130 {
1131     if (m_expr1->isNull() || m_expr2->isNull()) {
1132         RefPtr<RegisterID> src = generator.tempDestination(dst);
1133         generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
1134         return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
1135     }
1136 
1137     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1138     RegisterID* src2 = generator.emitNode(m_expr2.get());
1139     return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
1140 }
1141 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1142 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1143 {
1144     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1145     RegisterID* src2 = generator.emitNode(m_expr2.get());
1146     return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
1147 }
1148 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1149 RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1150 {
1151     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1152     RegisterID* src2 = generator.emitNode(m_expr2.get());
1153     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
1154 }
1155 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1156 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1157 {
1158     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1159     RegisterID* src2 = generator.emitNode(m_expr2.get());
1160     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1161     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1162 }
1163 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1164 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1165 {
1166     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1167     RefPtr<RegisterID> src2 = generator.emitNode(m_expr2.get());
1168 
1169     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1170     generator.emitGetByIdExceptionInfo(op_instanceof);
1171     RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
1172 
1173     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1174     return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
1175 }
1176 
1177 // ------------------------------ LogicalOpNode ----------------------------
1178 
~LogicalOpNode()1179 LogicalOpNode::~LogicalOpNode()
1180 {
1181     NodeReleaser::releaseAllNodes(this);
1182 }
1183 
releaseNodes(NodeReleaser & releaser)1184 void LogicalOpNode::releaseNodes(NodeReleaser& releaser)
1185 {
1186     releaser.release(m_expr1);
1187     releaser.release(m_expr2);
1188 }
1189 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1190 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1191 {
1192     RefPtr<RegisterID> temp = generator.tempDestination(dst);
1193     RefPtr<Label> target = generator.newLabel();
1194 
1195     generator.emitNode(temp.get(), m_expr1.get());
1196     if (m_operator == OpLogicalAnd)
1197         generator.emitJumpIfFalse(temp.get(), target.get());
1198     else
1199         generator.emitJumpIfTrue(temp.get(), target.get());
1200     generator.emitNode(temp.get(), m_expr2.get());
1201     generator.emitLabel(target.get());
1202 
1203     return generator.moveToDestinationIfNeeded(dst, temp.get());
1204 }
1205 
1206 // ------------------------------ ConditionalNode ------------------------------
1207 
~ConditionalNode()1208 ConditionalNode::~ConditionalNode()
1209 {
1210     NodeReleaser::releaseAllNodes(this);
1211 }
1212 
releaseNodes(NodeReleaser & releaser)1213 void ConditionalNode::releaseNodes(NodeReleaser& releaser)
1214 {
1215     releaser.release(m_logical);
1216     releaser.release(m_expr1);
1217     releaser.release(m_expr2);
1218 }
1219 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1220 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1221 {
1222     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1223     RefPtr<Label> beforeElse = generator.newLabel();
1224     RefPtr<Label> afterElse = generator.newLabel();
1225 
1226     RegisterID* cond = generator.emitNode(m_logical.get());
1227     generator.emitJumpIfFalse(cond, beforeElse.get());
1228 
1229     generator.emitNode(newDst.get(), m_expr1.get());
1230     generator.emitJump(afterElse.get());
1231 
1232     generator.emitLabel(beforeElse.get());
1233     generator.emitNode(newDst.get(), m_expr2.get());
1234 
1235     generator.emitLabel(afterElse.get());
1236 
1237     return newDst.get();
1238 }
1239 
1240 // ------------------------------ ReadModifyResolveNode -----------------------------------
1241 
~ReadModifyResolveNode()1242 ReadModifyResolveNode::~ReadModifyResolveNode()
1243 {
1244     NodeReleaser::releaseAllNodes(this);
1245 }
1246 
releaseNodes(NodeReleaser & releaser)1247 void ReadModifyResolveNode::releaseNodes(NodeReleaser& releaser)
1248 {
1249     releaser.release(m_right);
1250 }
1251 
1252 // FIXME: should this be moved to be a method on BytecodeGenerator?
emitReadModifyAssignment(BytecodeGenerator & generator,RegisterID * dst,RegisterID * src1,RegisterID * src2,Operator oper,OperandTypes types)1253 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper, OperandTypes types)
1254 {
1255     OpcodeID opcodeID;
1256     switch (oper) {
1257         case OpMultEq:
1258             opcodeID = op_mul;
1259             break;
1260         case OpDivEq:
1261             opcodeID = op_div;
1262             break;
1263         case OpPlusEq:
1264             opcodeID = op_add;
1265             break;
1266         case OpMinusEq:
1267             opcodeID = op_sub;
1268             break;
1269         case OpLShift:
1270             opcodeID = op_lshift;
1271             break;
1272         case OpRShift:
1273             opcodeID = op_rshift;
1274             break;
1275         case OpURShift:
1276             opcodeID = op_urshift;
1277             break;
1278         case OpAndEq:
1279             opcodeID = op_bitand;
1280             break;
1281         case OpXOrEq:
1282             opcodeID = op_bitxor;
1283             break;
1284         case OpOrEq:
1285             opcodeID = op_bitor;
1286             break;
1287         case OpModEq:
1288             opcodeID = op_mod;
1289             break;
1290         default:
1291             ASSERT_NOT_REACHED();
1292             return dst;
1293     }
1294 
1295     return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1296 }
1297 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1298 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1299 {
1300     if (RegisterID* local = generator.registerFor(m_ident)) {
1301         if (generator.isLocalConstant(m_ident)) {
1302             RegisterID* src2 = generator.emitNode(m_right.get());
1303             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1304         }
1305 
1306         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1307             RefPtr<RegisterID> result = generator.newTemporary();
1308             generator.emitMove(result.get(), local);
1309             RegisterID* src2 = generator.emitNode(m_right.get());
1310             emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1311             generator.emitMove(local, result.get());
1312             return generator.moveToDestinationIfNeeded(dst, result.get());
1313         }
1314 
1315         RegisterID* src2 = generator.emitNode(m_right.get());
1316         RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1317         return generator.moveToDestinationIfNeeded(dst, result);
1318     }
1319 
1320     int index = 0;
1321     size_t depth = 0;
1322     JSObject* globalObject = 0;
1323     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1324         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
1325         RegisterID* src2 = generator.emitNode(m_right.get());
1326         RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1327         generator.emitPutScopedVar(depth, index, result, globalObject);
1328         return result;
1329     }
1330 
1331     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
1332     generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
1333     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
1334     RegisterID* src2 = generator.emitNode(m_right.get());
1335     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1336     RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1337     return generator.emitPutById(base.get(), m_ident, result);
1338 }
1339 
1340 // ------------------------------ AssignResolveNode -----------------------------------
1341 
~AssignResolveNode()1342 AssignResolveNode::~AssignResolveNode()
1343 {
1344     NodeReleaser::releaseAllNodes(this);
1345 }
1346 
releaseNodes(NodeReleaser & releaser)1347 void AssignResolveNode::releaseNodes(NodeReleaser& releaser)
1348 {
1349     releaser.release(m_right);
1350 }
1351 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1352 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1353 {
1354     if (RegisterID* local = generator.registerFor(m_ident)) {
1355         if (generator.isLocalConstant(m_ident))
1356             return generator.emitNode(dst, m_right.get());
1357 
1358         RegisterID* result = generator.emitNode(local, m_right.get());
1359         return generator.moveToDestinationIfNeeded(dst, result);
1360     }
1361 
1362     int index = 0;
1363     size_t depth = 0;
1364     JSObject* globalObject = 0;
1365     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1366         if (dst == generator.ignoredResult())
1367             dst = 0;
1368         RegisterID* value = generator.emitNode(dst, m_right.get());
1369         generator.emitPutScopedVar(depth, index, value, globalObject);
1370         return value;
1371     }
1372 
1373     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1374     if (dst == generator.ignoredResult())
1375         dst = 0;
1376     RegisterID* value = generator.emitNode(dst, m_right.get());
1377     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1378     return generator.emitPutById(base.get(), m_ident, value);
1379 }
1380 
1381 // ------------------------------ AssignDotNode -----------------------------------
1382 
~AssignDotNode()1383 AssignDotNode::~AssignDotNode()
1384 {
1385     NodeReleaser::releaseAllNodes(this);
1386 }
1387 
releaseNodes(NodeReleaser & releaser)1388 void AssignDotNode::releaseNodes(NodeReleaser& releaser)
1389 {
1390     releaser.release(m_base);
1391     releaser.release(m_right);
1392 }
1393 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1394 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1395 {
1396     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1397     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1398     RegisterID* result = generator.emitNode(value.get(), m_right.get());
1399     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1400     generator.emitPutById(base.get(), m_ident, result);
1401     return generator.moveToDestinationIfNeeded(dst, result);
1402 }
1403 
1404 // ------------------------------ ReadModifyDotNode -----------------------------------
1405 
~ReadModifyDotNode()1406 ReadModifyDotNode::~ReadModifyDotNode()
1407 {
1408     NodeReleaser::releaseAllNodes(this);
1409 }
1410 
releaseNodes(NodeReleaser & releaser)1411 void ReadModifyDotNode::releaseNodes(NodeReleaser& releaser)
1412 {
1413     releaser.release(m_base);
1414     releaser.release(m_right);
1415 }
1416 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1417 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1418 {
1419     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1420 
1421     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1422     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1423     RegisterID* change = generator.emitNode(m_right.get());
1424     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1425 
1426     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1427     return generator.emitPutById(base.get(), m_ident, updatedValue);
1428 }
1429 
1430 // ------------------------------ AssignErrorNode -----------------------------------
1431 
~AssignErrorNode()1432 AssignErrorNode::~AssignErrorNode()
1433 {
1434     NodeReleaser::releaseAllNodes(this);
1435 }
1436 
releaseNodes(NodeReleaser & releaser)1437 void AssignErrorNode::releaseNodes(NodeReleaser& releaser)
1438 {
1439     releaser.release(m_left);
1440     releaser.release(m_right);
1441 }
1442 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1443 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1444 {
1445     return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
1446 }
1447 
1448 // ------------------------------ AssignBracketNode -----------------------------------
1449 
~AssignBracketNode()1450 AssignBracketNode::~AssignBracketNode()
1451 {
1452     NodeReleaser::releaseAllNodes(this);
1453 }
1454 
releaseNodes(NodeReleaser & releaser)1455 void AssignBracketNode::releaseNodes(NodeReleaser& releaser)
1456 {
1457     releaser.release(m_base);
1458     releaser.release(m_subscript);
1459     releaser.release(m_right);
1460 }
1461 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1462 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1463 {
1464     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1465     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1466     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1467     RegisterID* result = generator.emitNode(value.get(), m_right.get());
1468 
1469     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1470     generator.emitPutByVal(base.get(), property.get(), result);
1471     return generator.moveToDestinationIfNeeded(dst, result);
1472 }
1473 
1474 // ------------------------------ ReadModifyBracketNode -----------------------------------
1475 
~ReadModifyBracketNode()1476 ReadModifyBracketNode::~ReadModifyBracketNode()
1477 {
1478     NodeReleaser::releaseAllNodes(this);
1479 }
1480 
releaseNodes(NodeReleaser & releaser)1481 void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser)
1482 {
1483     releaser.release(m_base);
1484     releaser.release(m_subscript);
1485     releaser.release(m_right);
1486 }
1487 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1488 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1489 {
1490     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1491     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1492 
1493     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1494     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1495     RegisterID* change = generator.emitNode(m_right.get());
1496     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1497 
1498     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1499     generator.emitPutByVal(base.get(), property.get(), updatedValue);
1500 
1501     return updatedValue;
1502 }
1503 
1504 // ------------------------------ CommaNode ------------------------------------
1505 
~CommaNode()1506 CommaNode::~CommaNode()
1507 {
1508     NodeReleaser::releaseAllNodes(this);
1509 }
1510 
releaseNodes(NodeReleaser & releaser)1511 void CommaNode::releaseNodes(NodeReleaser& releaser)
1512 {
1513     releaser.release(m_expr1);
1514     releaser.release(m_expr2);
1515 }
1516 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1517 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1518 {
1519     generator.emitNode(generator.ignoredResult(), m_expr1.get());
1520     return generator.emitNode(dst, m_expr2.get());
1521 }
1522 
1523 // ------------------------------ ConstDeclNode ------------------------------------
1524 
~ConstDeclNode()1525 ConstDeclNode::~ConstDeclNode()
1526 {
1527     NodeReleaser::releaseAllNodes(this);
1528 }
1529 
releaseNodes(NodeReleaser & releaser)1530 void ConstDeclNode::releaseNodes(NodeReleaser& releaser)
1531 {
1532     releaser.release(m_next);
1533     releaser.release(m_init);
1534 }
1535 
ConstDeclNode(JSGlobalData * globalData,const Identifier & ident,ExpressionNode * init)1536 ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
1537     : ExpressionNode(globalData)
1538     , m_ident(ident)
1539     , m_init(init)
1540 {
1541 }
1542 
emitCodeSingle(BytecodeGenerator & generator)1543 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1544 {
1545     if (RegisterID* local = generator.constRegisterFor(m_ident)) {
1546         if (!m_init)
1547             return local;
1548 
1549         return generator.emitNode(local, m_init.get());
1550     }
1551 
1552     // FIXME: While this code should only be hit in eval code, it will potentially
1553     // assign to the wrong base if m_ident exists in an intervening dynamic scope.
1554     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1555     RegisterID* value = m_init ? generator.emitNode(m_init.get()) : generator.emitLoad(0, jsUndefined());
1556     return generator.emitPutById(base.get(), m_ident, value);
1557 }
1558 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1559 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1560 {
1561     RegisterID* result = 0;
1562     for (ConstDeclNode* n = this; n; n = n->m_next.get())
1563         result = n->emitCodeSingle(generator);
1564 
1565     return result;
1566 }
1567 
1568 // ------------------------------ ConstStatementNode -----------------------------
1569 
~ConstStatementNode()1570 ConstStatementNode::~ConstStatementNode()
1571 {
1572     NodeReleaser::releaseAllNodes(this);
1573 }
1574 
releaseNodes(NodeReleaser & releaser)1575 void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
1576 {
1577     releaser.release(m_next);
1578 }
1579 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1580 RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1581 {
1582     return generator.emitNode(m_next.get());
1583 }
1584 
1585 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1586 
statementListEmitCode(const StatementVector & statements,BytecodeGenerator & generator,RegisterID * dst)1587 static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
1588 {
1589     StatementVector::const_iterator end = statements.end();
1590     for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
1591         StatementNode* n = it->get();
1592         if (!n->isLoop())
1593             generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
1594         generator.emitNode(dst, n);
1595     }
1596     return 0;
1597 }
1598 
1599 // ------------------------------ BlockNode ------------------------------------
1600 
~BlockNode()1601 BlockNode::~BlockNode()
1602 {
1603     NodeReleaser::releaseAllNodes(this);
1604 }
1605 
releaseNodes(NodeReleaser & releaser)1606 void BlockNode::releaseNodes(NodeReleaser& releaser)
1607 {
1608     size_t size = m_children.size();
1609     for (size_t i = 0; i < size; ++i)
1610         releaser.release(m_children[i]);
1611 }
1612 
BlockNode(JSGlobalData * globalData,SourceElements * children)1613 BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
1614     : StatementNode(globalData)
1615 {
1616     if (children)
1617         children->releaseContentsIntoVector(m_children);
1618 }
1619 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1620 RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1621 {
1622     return statementListEmitCode(m_children, generator, dst);
1623 }
1624 
1625 // ------------------------------ EmptyStatementNode ---------------------------
1626 
emitBytecode(BytecodeGenerator &,RegisterID * dst)1627 RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
1628 {
1629     return dst;
1630 }
1631 
1632 // ------------------------------ DebuggerStatementNode ---------------------------
1633 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1634 RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1635 {
1636     generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1637     return dst;
1638 }
1639 
1640 // ------------------------------ ExprStatementNode ----------------------------
1641 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1642 RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1643 {
1644     ASSERT(m_expr);
1645     return generator.emitNode(dst, m_expr.get());
1646 }
1647 
1648 // ------------------------------ VarStatementNode ----------------------------
1649 
~VarStatementNode()1650 VarStatementNode::~VarStatementNode()
1651 {
1652     NodeReleaser::releaseAllNodes(this);
1653 }
1654 
releaseNodes(NodeReleaser & releaser)1655 void VarStatementNode::releaseNodes(NodeReleaser& releaser)
1656 {
1657     releaser.release(m_expr);
1658 }
1659 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1660 RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1661 {
1662     ASSERT(m_expr);
1663     return generator.emitNode(m_expr.get());
1664 }
1665 
1666 // ------------------------------ IfNode ---------------------------------------
1667 
~IfNode()1668 IfNode::~IfNode()
1669 {
1670     NodeReleaser::releaseAllNodes(this);
1671 }
1672 
releaseNodes(NodeReleaser & releaser)1673 void IfNode::releaseNodes(NodeReleaser& releaser)
1674 {
1675     releaser.release(m_condition);
1676     releaser.release(m_ifBlock);
1677 }
1678 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1679 RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1680 {
1681     RefPtr<Label> afterThen = generator.newLabel();
1682 
1683     RegisterID* cond = generator.emitNode(m_condition.get());
1684     generator.emitJumpIfFalse(cond, afterThen.get());
1685 
1686     if (!m_ifBlock->isBlock())
1687         generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1688 
1689     generator.emitNode(dst, m_ifBlock.get());
1690     generator.emitLabel(afterThen.get());
1691 
1692     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1693     return 0;
1694 }
1695 
1696 // ------------------------------ IfElseNode ---------------------------------------
1697 
~IfElseNode()1698 IfElseNode::~IfElseNode()
1699 {
1700     NodeReleaser::releaseAllNodes(this);
1701 }
1702 
releaseNodes(NodeReleaser & releaser)1703 void IfElseNode::releaseNodes(NodeReleaser& releaser)
1704 {
1705     releaser.release(m_elseBlock);
1706     IfNode::releaseNodes(releaser);
1707 }
1708 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1709 RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1710 {
1711     RefPtr<Label> beforeElse = generator.newLabel();
1712     RefPtr<Label> afterElse = generator.newLabel();
1713 
1714     RegisterID* cond = generator.emitNode(m_condition.get());
1715     generator.emitJumpIfFalse(cond, beforeElse.get());
1716 
1717     if (!m_ifBlock->isBlock())
1718         generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1719 
1720     generator.emitNode(dst, m_ifBlock.get());
1721     generator.emitJump(afterElse.get());
1722 
1723     generator.emitLabel(beforeElse.get());
1724 
1725     if (!m_elseBlock->isBlock())
1726         generator.emitDebugHook(WillExecuteStatement, m_elseBlock->firstLine(), m_elseBlock->lastLine());
1727 
1728     generator.emitNode(dst, m_elseBlock.get());
1729 
1730     generator.emitLabel(afterElse.get());
1731 
1732     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1733     return 0;
1734 }
1735 
1736 // ------------------------------ DoWhileNode ----------------------------------
1737 
~DoWhileNode()1738 DoWhileNode::~DoWhileNode()
1739 {
1740     NodeReleaser::releaseAllNodes(this);
1741 }
1742 
releaseNodes(NodeReleaser & releaser)1743 void DoWhileNode::releaseNodes(NodeReleaser& releaser)
1744 {
1745     releaser.release(m_statement);
1746     releaser.release(m_expr);
1747 }
1748 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1749 RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1750 {
1751     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1752 
1753     RefPtr<Label> topOfLoop = generator.newLabel();
1754     generator.emitLabel(topOfLoop.get());
1755 
1756     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1757 
1758     if (!m_statement->isBlock())
1759         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1760 
1761     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1762 
1763     generator.emitLabel(scope->continueTarget());
1764     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1765     RegisterID* cond = generator.emitNode(m_expr.get());
1766     generator.emitJumpIfTrue(cond, topOfLoop.get());
1767 
1768     generator.emitLabel(scope->breakTarget());
1769     return result.get();
1770 }
1771 
1772 // ------------------------------ WhileNode ------------------------------------
1773 
~WhileNode()1774 WhileNode::~WhileNode()
1775 {
1776     NodeReleaser::releaseAllNodes(this);
1777 }
1778 
releaseNodes(NodeReleaser & releaser)1779 void WhileNode::releaseNodes(NodeReleaser& releaser)
1780 {
1781     releaser.release(m_expr);
1782     releaser.release(m_statement);
1783 }
1784 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1785 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1786 {
1787     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1788 
1789     generator.emitJump(scope->continueTarget());
1790 
1791     RefPtr<Label> topOfLoop = generator.newLabel();
1792     generator.emitLabel(topOfLoop.get());
1793 
1794     if (!m_statement->isBlock())
1795         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1796 
1797     generator.emitNode(dst, m_statement.get());
1798 
1799     generator.emitLabel(scope->continueTarget());
1800     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1801     RegisterID* cond = generator.emitNode(m_expr.get());
1802     generator.emitJumpIfTrue(cond, topOfLoop.get());
1803 
1804     generator.emitLabel(scope->breakTarget());
1805 
1806     // FIXME: This should return the last statement executed so that it can be returned as a Completion
1807     return 0;
1808 }
1809 
1810 // ------------------------------ ForNode --------------------------------------
1811 
~ForNode()1812 ForNode::~ForNode()
1813 {
1814     NodeReleaser::releaseAllNodes(this);
1815 }
1816 
releaseNodes(NodeReleaser & releaser)1817 void ForNode::releaseNodes(NodeReleaser& releaser)
1818 {
1819     releaser.release(m_expr1);
1820     releaser.release(m_expr2);
1821     releaser.release(m_expr3);
1822     releaser.release(m_statement);
1823 }
1824 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1825 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1826 {
1827     if (dst == generator.ignoredResult())
1828         dst = 0;
1829 
1830     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1831 
1832     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1833 
1834     if (m_expr1)
1835         generator.emitNode(generator.ignoredResult(), m_expr1.get());
1836 
1837     RefPtr<Label> condition = generator.newLabel();
1838     generator.emitJump(condition.get());
1839 
1840     RefPtr<Label> topOfLoop = generator.newLabel();
1841     generator.emitLabel(topOfLoop.get());
1842 
1843     if (!m_statement->isBlock())
1844         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1845     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1846 
1847     generator.emitLabel(scope->continueTarget());
1848     if (m_expr3)
1849         generator.emitNode(generator.ignoredResult(), m_expr3.get());
1850 
1851     generator.emitLabel(condition.get());
1852     if (m_expr2) {
1853         RegisterID* cond = generator.emitNode(m_expr2.get());
1854         generator.emitJumpIfTrue(cond, topOfLoop.get());
1855     } else
1856         generator.emitJump(topOfLoop.get());
1857 
1858     generator.emitLabel(scope->breakTarget());
1859     return result.get();
1860 }
1861 
1862 // ------------------------------ ForInNode ------------------------------------
1863 
~ForInNode()1864 ForInNode::~ForInNode()
1865 {
1866     NodeReleaser::releaseAllNodes(this);
1867 }
1868 
releaseNodes(NodeReleaser & releaser)1869 void ForInNode::releaseNodes(NodeReleaser& releaser)
1870 {
1871     releaser.release(m_init);
1872     releaser.release(m_lexpr);
1873     releaser.release(m_expr);
1874     releaser.release(m_statement);
1875 }
1876 
ForInNode(JSGlobalData * globalData,ExpressionNode * l,ExpressionNode * expr,StatementNode * statement)1877 ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
1878     : StatementNode(globalData)
1879     , m_init(0L)
1880     , m_lexpr(l)
1881     , m_expr(expr)
1882     , m_statement(statement)
1883     , m_identIsVarDecl(false)
1884 {
1885 }
1886 
ForInNode(JSGlobalData * globalData,const Identifier & ident,ExpressionNode * in,ExpressionNode * expr,StatementNode * statement,int divot,int startOffset,int endOffset)1887 ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
1888     : StatementNode(globalData)
1889     , m_ident(ident)
1890     , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset))
1891     , m_expr(expr)
1892     , m_statement(statement)
1893     , m_identIsVarDecl(true)
1894 {
1895     if (in) {
1896         AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true);
1897         node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
1898         m_init = node;
1899     }
1900     // for( var foo = bar in baz )
1901 }
1902 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1903 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1904 {
1905     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1906 
1907     if (!m_lexpr->isLocation())
1908         return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
1909 
1910     RefPtr<Label> continueTarget = generator.newLabel();
1911 
1912     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1913 
1914     if (m_init)
1915         generator.emitNode(generator.ignoredResult(), m_init.get());
1916     RegisterID* forInBase = generator.emitNode(m_expr.get());
1917     RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
1918     generator.emitJump(scope->continueTarget());
1919 
1920     RefPtr<Label> loopStart = generator.newLabel();
1921     generator.emitLabel(loopStart.get());
1922 
1923     RegisterID* propertyName;
1924     if (m_lexpr->isResolveNode()) {
1925         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
1926         propertyName = generator.registerFor(ident);
1927         if (!propertyName) {
1928             propertyName = generator.newTemporary();
1929             RefPtr<RegisterID> protect = propertyName;
1930             RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1931 
1932             generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1933             generator.emitPutById(base, ident, propertyName);
1934         }
1935     } else if (m_lexpr->isDotAccessorNode()) {
1936         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
1937         const Identifier& ident = assignNode->identifier();
1938         propertyName = generator.newTemporary();
1939         RefPtr<RegisterID> protect = propertyName;
1940         RegisterID* base = generator.emitNode(assignNode->base());
1941 
1942         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1943         generator.emitPutById(base, ident, propertyName);
1944     } else {
1945         ASSERT(m_lexpr->isBracketAccessorNode());
1946         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
1947         propertyName = generator.newTemporary();
1948         RefPtr<RegisterID> protect = propertyName;
1949         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1950         RegisterID* subscript = generator.emitNode(assignNode->subscript());
1951 
1952         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1953         generator.emitPutByVal(base.get(), subscript, propertyName);
1954     }
1955 
1956     if (!m_statement->isBlock())
1957         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1958     generator.emitNode(dst, m_statement.get());
1959 
1960     generator.emitLabel(scope->continueTarget());
1961     generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
1962     generator.emitLabel(scope->breakTarget());
1963     return dst;
1964 }
1965 
1966 // ------------------------------ ContinueNode ---------------------------------
1967 
1968 // ECMA 12.7
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1969 RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1970 {
1971     LabelScope* scope = generator.continueTarget(m_ident);
1972 
1973     if (!scope)
1974         return m_ident.isEmpty()
1975             ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
1976             : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1977 
1978     generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1979     return dst;
1980 }
1981 
1982 // ------------------------------ BreakNode ------------------------------------
1983 
1984 // ECMA 12.8
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1985 RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1986 {
1987     LabelScope* scope = generator.breakTarget(m_ident);
1988 
1989     if (!scope)
1990         return m_ident.isEmpty()
1991             ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
1992             : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1993 
1994     generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1995     return dst;
1996 }
1997 
1998 // ------------------------------ ReturnNode -----------------------------------
1999 
~ReturnNode()2000 ReturnNode::~ReturnNode()
2001 {
2002     NodeReleaser::releaseAllNodes(this);
2003 }
2004 
releaseNodes(NodeReleaser & releaser)2005 void ReturnNode::releaseNodes(NodeReleaser& releaser)
2006 {
2007     releaser.release(m_value);
2008 }
2009 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2010 RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2011 {
2012     if (generator.codeType() != FunctionCode)
2013         return emitThrowError(generator, SyntaxError, "Invalid return statement.");
2014 
2015     if (dst == generator.ignoredResult())
2016         dst = 0;
2017     RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
2018     if (generator.scopeDepth()) {
2019         RefPtr<Label> l0 = generator.newLabel();
2020         generator.emitJumpScopes(l0.get(), 0);
2021         generator.emitLabel(l0.get());
2022     }
2023     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2024     return generator.emitReturn(r0);
2025 }
2026 
2027 // ------------------------------ WithNode -------------------------------------
2028 
~WithNode()2029 WithNode::~WithNode()
2030 {
2031     NodeReleaser::releaseAllNodes(this);
2032 }
2033 
releaseNodes(NodeReleaser & releaser)2034 void WithNode::releaseNodes(NodeReleaser& releaser)
2035 {
2036     releaser.release(m_expr);
2037     releaser.release(m_statement);
2038 }
2039 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2040 RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2041 {
2042     RefPtr<RegisterID> scope = generator.newTemporary();
2043     generator.emitNode(scope.get(), m_expr.get()); // scope must be protected until popped
2044     generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
2045     generator.emitPushScope(scope.get());
2046     RegisterID* result = generator.emitNode(dst, m_statement.get());
2047     generator.emitPopScope();
2048     return result;
2049 }
2050 
2051 // ------------------------------ CaseClauseNode --------------------------------
2052 
~CaseClauseNode()2053 CaseClauseNode::~CaseClauseNode()
2054 {
2055     NodeReleaser::releaseAllNodes(this);
2056 }
2057 
releaseNodes(NodeReleaser & releaser)2058 void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
2059 {
2060     releaser.release(m_expr);
2061 }
2062 
2063 // ------------------------------ ClauseListNode --------------------------------
2064 
~ClauseListNode()2065 ClauseListNode::~ClauseListNode()
2066 {
2067     NodeReleaser::releaseAllNodes(this);
2068 }
2069 
releaseNodes(NodeReleaser & releaser)2070 void ClauseListNode::releaseNodes(NodeReleaser& releaser)
2071 {
2072     releaser.release(m_clause);
2073     releaser.release(m_next);
2074 }
2075 
2076 // ------------------------------ CaseBlockNode --------------------------------
2077 
~CaseBlockNode()2078 CaseBlockNode::~CaseBlockNode()
2079 {
2080     NodeReleaser::releaseAllNodes(this);
2081 }
2082 
releaseNodes(NodeReleaser & releaser)2083 void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
2084 {
2085     releaser.release(m_list1);
2086     releaser.release(m_defaultClause);
2087     releaser.release(m_list2);
2088 }
2089 
2090 enum SwitchKind {
2091     SwitchUnset = 0,
2092     SwitchNumber = 1,
2093     SwitchString = 2,
2094     SwitchNeither = 3
2095 };
2096 
processClauseList(ClauseListNode * list,Vector<ExpressionNode *,8> & literalVector,SwitchKind & typeForTable,bool & singleCharacterSwitch,int32_t & min_num,int32_t & max_num)2097 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2098 {
2099     for (; list; list = list->getNext()) {
2100         ExpressionNode* clauseExpression = list->getClause()->expr();
2101         literalVector.append(clauseExpression);
2102         if (clauseExpression->isNumber()) {
2103             double value = static_cast<NumberNode*>(clauseExpression)->value();
2104             JSValuePtr jsValue = JSValuePtr::makeInt32Fast(static_cast<int32_t>(value));
2105             if ((typeForTable & ~SwitchNumber) || !jsValue || (jsValue.getInt32Fast() != value)) {
2106                 typeForTable = SwitchNeither;
2107                 break;
2108             }
2109             int32_t intVal = static_cast<int32_t>(value);
2110             ASSERT(intVal == value);
2111             if (intVal < min_num)
2112                 min_num = intVal;
2113             if (intVal > max_num)
2114                 max_num = intVal;
2115             typeForTable = SwitchNumber;
2116             continue;
2117         }
2118         if (clauseExpression->isString()) {
2119             if (typeForTable & ~SwitchString) {
2120                 typeForTable = SwitchNeither;
2121                 break;
2122             }
2123             const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
2124             if (singleCharacterSwitch &= value.size() == 1) {
2125                 int32_t intVal = value.rep()->data()[0];
2126                 if (intVal < min_num)
2127                     min_num = intVal;
2128                 if (intVal > max_num)
2129                     max_num = intVal;
2130             }
2131             typeForTable = SwitchString;
2132             continue;
2133         }
2134         typeForTable = SwitchNeither;
2135         break;
2136     }
2137 }
2138 
tryOptimizedSwitch(Vector<ExpressionNode *,8> & literalVector,int32_t & min_num,int32_t & max_num)2139 SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2140 {
2141     SwitchKind typeForTable = SwitchUnset;
2142     bool singleCharacterSwitch = true;
2143 
2144     processClauseList(m_list1.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2145     processClauseList(m_list2.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2146 
2147     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2148         return SwitchInfo::SwitchNone;
2149 
2150     if (typeForTable == SwitchNumber) {
2151         int32_t range = max_num - min_num;
2152         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2153             return SwitchInfo::SwitchImmediate;
2154         return SwitchInfo::SwitchNone;
2155     }
2156 
2157     ASSERT(typeForTable == SwitchString);
2158 
2159     if (singleCharacterSwitch) {
2160         int32_t range = max_num - min_num;
2161         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2162             return SwitchInfo::SwitchCharacter;
2163     }
2164 
2165     return SwitchInfo::SwitchString;
2166 }
2167 
emitBytecodeForBlock(BytecodeGenerator & generator,RegisterID * switchExpression,RegisterID * dst)2168 RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2169 {
2170     RefPtr<Label> defaultLabel;
2171     Vector<RefPtr<Label>, 8> labelVector;
2172     Vector<ExpressionNode*, 8> literalVector;
2173     int32_t min_num = std::numeric_limits<int32_t>::max();
2174     int32_t max_num = std::numeric_limits<int32_t>::min();
2175     SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
2176 
2177     if (switchType != SwitchInfo::SwitchNone) {
2178         // Prepare the various labels
2179         for (uint32_t i = 0; i < literalVector.size(); i++)
2180             labelVector.append(generator.newLabel());
2181         defaultLabel = generator.newLabel();
2182         generator.beginSwitch(switchExpression, switchType);
2183     } else {
2184         // Setup jumps
2185         for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2186             RefPtr<RegisterID> clauseVal = generator.newTemporary();
2187             generator.emitNode(clauseVal.get(), list->getClause()->expr());
2188             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2189             labelVector.append(generator.newLabel());
2190             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2191         }
2192 
2193         for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2194             RefPtr<RegisterID> clauseVal = generator.newTemporary();
2195             generator.emitNode(clauseVal.get(), list->getClause()->expr());
2196             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2197             labelVector.append(generator.newLabel());
2198             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2199         }
2200         defaultLabel = generator.newLabel();
2201         generator.emitJump(defaultLabel.get());
2202     }
2203 
2204     RegisterID* result = 0;
2205 
2206     size_t i = 0;
2207     for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2208         generator.emitLabel(labelVector[i++].get());
2209         result = statementListEmitCode(list->getClause()->children(), generator, dst);
2210     }
2211 
2212     if (m_defaultClause) {
2213         generator.emitLabel(defaultLabel.get());
2214         result = statementListEmitCode(m_defaultClause->children(), generator, dst);
2215     }
2216 
2217     for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2218         generator.emitLabel(labelVector[i++].get());
2219         result = statementListEmitCode(list->getClause()->children(), generator, dst);
2220     }
2221     if (!m_defaultClause)
2222         generator.emitLabel(defaultLabel.get());
2223 
2224     ASSERT(i == labelVector.size());
2225     if (switchType != SwitchInfo::SwitchNone) {
2226         ASSERT(labelVector.size() == literalVector.size());
2227         generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2228     }
2229     return result;
2230 }
2231 
2232 // ------------------------------ SwitchNode -----------------------------------
2233 
~SwitchNode()2234 SwitchNode::~SwitchNode()
2235 {
2236     NodeReleaser::releaseAllNodes(this);
2237 }
2238 
releaseNodes(NodeReleaser & releaser)2239 void SwitchNode::releaseNodes(NodeReleaser& releaser)
2240 {
2241     releaser.release(m_expr);
2242     releaser.release(m_block);
2243 }
2244 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2245 RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2246 {
2247     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
2248 
2249     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2250     RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2251 
2252     generator.emitLabel(scope->breakTarget());
2253     return r1;
2254 }
2255 
2256 // ------------------------------ LabelNode ------------------------------------
2257 
~LabelNode()2258 LabelNode::~LabelNode()
2259 {
2260     NodeReleaser::releaseAllNodes(this);
2261 }
2262 
releaseNodes(NodeReleaser & releaser)2263 void LabelNode::releaseNodes(NodeReleaser& releaser)
2264 {
2265     releaser.release(m_statement);
2266 }
2267 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2268 RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2269 {
2270     if (generator.breakTarget(m_name))
2271         return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
2272 
2273     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2274     RegisterID* r0 = generator.emitNode(dst, m_statement.get());
2275 
2276     generator.emitLabel(scope->breakTarget());
2277     return r0;
2278 }
2279 
2280 // ------------------------------ ThrowNode ------------------------------------
2281 
~ThrowNode()2282 ThrowNode::~ThrowNode()
2283 {
2284     NodeReleaser::releaseAllNodes(this);
2285 }
2286 
releaseNodes(NodeReleaser & releaser)2287 void ThrowNode::releaseNodes(NodeReleaser& releaser)
2288 {
2289     releaser.release(m_expr);
2290 }
2291 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2292 RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2293 {
2294     if (dst == generator.ignoredResult())
2295         dst = 0;
2296     RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
2297     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
2298     generator.emitThrow(expr.get());
2299     return dst;
2300 }
2301 
2302 // ------------------------------ TryNode --------------------------------------
2303 
~TryNode()2304 TryNode::~TryNode()
2305 {
2306     NodeReleaser::releaseAllNodes(this);
2307 }
2308 
releaseNodes(NodeReleaser & releaser)2309 void TryNode::releaseNodes(NodeReleaser& releaser)
2310 {
2311     releaser.release(m_tryBlock);
2312     releaser.release(m_catchBlock);
2313     releaser.release(m_finallyBlock);
2314 }
2315 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2316 RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2317 {
2318     RefPtr<Label> tryStartLabel = generator.newLabel();
2319     RefPtr<Label> tryEndLabel = generator.newLabel();
2320     RefPtr<Label> finallyStart;
2321     RefPtr<RegisterID> finallyReturnAddr;
2322     if (m_finallyBlock) {
2323         finallyStart = generator.newLabel();
2324         finallyReturnAddr = generator.newTemporary();
2325         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
2326     }
2327     generator.emitLabel(tryStartLabel.get());
2328     generator.emitNode(dst, m_tryBlock.get());
2329     generator.emitLabel(tryEndLabel.get());
2330 
2331     if (m_catchBlock) {
2332         RefPtr<Label> handlerEndLabel = generator.newLabel();
2333         generator.emitJump(handlerEndLabel.get());
2334         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
2335         if (m_catchHasEval) {
2336             RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
2337             generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
2338             generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
2339             generator.emitPushScope(exceptionRegister.get());
2340         } else
2341             generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
2342         generator.emitNode(dst, m_catchBlock.get());
2343         generator.emitPopScope();
2344         generator.emitLabel(handlerEndLabel.get());
2345     }
2346 
2347     if (m_finallyBlock) {
2348         generator.popFinallyContext();
2349         // there may be important registers live at the time we jump
2350         // to a finally block (such as for a return or throw) so we
2351         // ref the highest register ever used as a conservative
2352         // approach to not clobbering anything important
2353         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
2354         RefPtr<Label> finallyEndLabel = generator.newLabel();
2355         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2356         // Use a label to record the subtle fact that sret will return to the
2357         // next instruction. sret is the only way to jump without an explicit label.
2358         generator.emitLabel(generator.newLabel().get());
2359         generator.emitJump(finallyEndLabel.get());
2360 
2361         // Finally block for exception path
2362         RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
2363         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2364         // Use a label to record the subtle fact that sret will return to the
2365         // next instruction. sret is the only way to jump without an explicit label.
2366         generator.emitLabel(generator.newLabel().get());
2367         generator.emitThrow(tempExceptionRegister.get());
2368 
2369         // emit the finally block itself
2370         generator.emitLabel(finallyStart.get());
2371         generator.emitNode(dst, m_finallyBlock.get());
2372         generator.emitSubroutineReturn(finallyReturnAddr.get());
2373 
2374         generator.emitLabel(finallyEndLabel.get());
2375     }
2376 
2377     return dst;
2378 }
2379 
2380 // ------------------------------ ParameterNode -----------------------------
2381 
~ParameterNode()2382 ParameterNode::~ParameterNode()
2383 {
2384     NodeReleaser::releaseAllNodes(this);
2385 }
2386 
releaseNodes(NodeReleaser & releaser)2387 void ParameterNode::releaseNodes(NodeReleaser& releaser)
2388 {
2389     releaser.release(m_next);
2390 }
2391 
2392 // -----------------------------ScopeNodeData ---------------------------
2393 
ScopeNodeData(SourceElements * children,VarStack * varStack,FunctionStack * funcStack,int numConstants)2394 ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
2395     : m_numConstants(numConstants)
2396 {
2397     if (varStack)
2398         m_varStack = *varStack;
2399     if (funcStack)
2400         m_functionStack = *funcStack;
2401     if (children)
2402         children->releaseContentsIntoVector(m_children);
2403 }
2404 
mark()2405 void ScopeNodeData::mark()
2406 {
2407     FunctionStack::iterator end = m_functionStack.end();
2408     for (FunctionStack::iterator ptr = m_functionStack.begin(); ptr != end; ++ptr) {
2409         FunctionBodyNode* body = (*ptr)->body();
2410         if (!body->isGenerated())
2411             continue;
2412         body->generatedBytecode().mark();
2413     }
2414 }
2415 
2416 // ------------------------------ ScopeNode -----------------------------
2417 
ScopeNode(JSGlobalData * globalData)2418 ScopeNode::ScopeNode(JSGlobalData* globalData)
2419     : StatementNode(globalData)
2420     , m_features(NoFeatures)
2421 {
2422 #if ENABLE(OPCODE_SAMPLING)
2423     globalData->interpreter->sampler()->notifyOfScope(this);
2424 #endif
2425 }
2426 
ScopeNode(JSGlobalData * globalData,const SourceCode & source,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,CodeFeatures features,int numConstants)2427 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
2428     : StatementNode(globalData)
2429     , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
2430     , m_features(features)
2431     , m_source(source)
2432 {
2433 #if ENABLE(OPCODE_SAMPLING)
2434     globalData->interpreter->sampler()->notifyOfScope(this);
2435 #endif
2436 }
2437 
~ScopeNode()2438 ScopeNode::~ScopeNode()
2439 {
2440     NodeReleaser::releaseAllNodes(this);
2441 }
2442 
releaseNodes(NodeReleaser & releaser)2443 void ScopeNode::releaseNodes(NodeReleaser& releaser)
2444 {
2445     if (!m_data)
2446         return;
2447     size_t size = m_data->m_children.size();
2448     for (size_t i = 0; i < size; ++i)
2449         releaser.release(m_data->m_children[i]);
2450 }
2451 
2452 // ------------------------------ ProgramNode -----------------------------
2453 
ProgramNode(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,const SourceCode & source,CodeFeatures features,int numConstants)2454 ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2455     : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2456 {
2457 }
2458 
create(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,const SourceCode & source,CodeFeatures features,int numConstants)2459 ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2460 {
2461     return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
2462 }
2463 
emitBytecode(BytecodeGenerator & generator,RegisterID *)2464 RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2465 {
2466     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2467 
2468     RefPtr<RegisterID> dstRegister = generator.newTemporary();
2469     generator.emitLoad(dstRegister.get(), jsUndefined());
2470     statementListEmitCode(children(), generator, dstRegister.get());
2471 
2472     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2473     generator.emitEnd(dstRegister.get());
2474     return 0;
2475 }
2476 
generateBytecode(ScopeChainNode * scopeChainNode)2477 void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
2478 {
2479     ScopeChain scopeChain(scopeChainNode);
2480     JSGlobalObject* globalObject = scopeChain.globalObject();
2481 
2482     m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
2483 
2484     BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
2485     generator.generate();
2486 
2487     destroyData();
2488 }
2489 
2490 // ------------------------------ EvalNode -----------------------------
2491 
EvalNode(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,const SourceCode & source,CodeFeatures features,int numConstants)2492 EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2493     : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2494 {
2495 }
2496 
create(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,const SourceCode & source,CodeFeatures features,int numConstants)2497 EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2498 {
2499     return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
2500 }
2501 
emitBytecode(BytecodeGenerator & generator,RegisterID *)2502 RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2503 {
2504     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2505 
2506     RefPtr<RegisterID> dstRegister = generator.newTemporary();
2507     generator.emitLoad(dstRegister.get(), jsUndefined());
2508     statementListEmitCode(children(), generator, dstRegister.get());
2509 
2510     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2511     generator.emitEnd(dstRegister.get());
2512     return 0;
2513 }
2514 
generateBytecode(ScopeChainNode * scopeChainNode)2515 void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
2516 {
2517     ScopeChain scopeChain(scopeChainNode);
2518     JSGlobalObject* globalObject = scopeChain.globalObject();
2519 
2520     m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
2521 
2522     BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2523     generator.generate();
2524 
2525     // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
2526     // so the entire ScopeNodeData cannot be destoyed.
2527     children().clear();
2528 }
2529 
bytecodeForExceptionInfoReparse(ScopeChainNode * scopeChainNode,CodeBlock * codeBlockBeingRegeneratedFrom)2530 EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
2531 {
2532     ASSERT(!m_code);
2533 
2534     ScopeChain scopeChain(scopeChainNode);
2535     JSGlobalObject* globalObject = scopeChain.globalObject();
2536 
2537     m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
2538 
2539     BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2540     generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
2541     generator.generate();
2542 
2543     return *m_code;
2544 }
2545 
mark()2546 void EvalNode::mark()
2547 {
2548     // We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that
2549     data()->mark();
2550 }
2551 
2552 // ------------------------------ FunctionBodyNode -----------------------------
2553 
FunctionBodyNode(JSGlobalData * globalData)2554 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
2555     : ScopeNode(globalData)
2556     , m_parameters(0)
2557     , m_parameterCount(0)
2558     , m_refCount(0)
2559 {
2560 }
2561 
FunctionBodyNode(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,const SourceCode & sourceCode,CodeFeatures features,int numConstants)2562 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2563     : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
2564     , m_parameters(0)
2565     , m_parameterCount(0)
2566     , m_refCount(0)
2567 {
2568 }
2569 
~FunctionBodyNode()2570 FunctionBodyNode::~FunctionBodyNode()
2571 {
2572     ASSERT(!m_refCount);
2573     for (size_t i = 0; i < m_parameterCount; ++i)
2574         m_parameters[i].~Identifier();
2575     fastFree(m_parameters);
2576 }
2577 
finishParsing(const SourceCode & source,ParameterNode * firstParameter)2578 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
2579 {
2580     Vector<Identifier> parameters;
2581     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
2582         parameters.append(parameter->ident());
2583     size_t count = parameters.size();
2584 
2585     setSource(source);
2586     finishParsing(parameters.releaseBuffer(), count);
2587 }
2588 
finishParsing(Identifier * parameters,size_t parameterCount)2589 void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
2590 {
2591     ASSERT(!source().isNull());
2592     m_parameters = parameters;
2593     m_parameterCount = parameterCount;
2594 }
2595 
mark()2596 void FunctionBodyNode::mark()
2597 {
2598     if (m_code)
2599         m_code->mark();
2600 }
2601 
create(JSGlobalData * globalData)2602 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
2603 {
2604     return new FunctionBodyNode(globalData);
2605 }
2606 
create(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,const SourceCode & sourceCode,CodeFeatures features,int numConstants)2607 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2608 {
2609     return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
2610 }
2611 
generateBytecode(ScopeChainNode * scopeChainNode)2612 void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
2613 {
2614     // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
2615     // calling Parser::parse<FunctionBodyNode>().
2616     if (!data())
2617         scopeChainNode->globalData->parser->reparseInPlace(scopeChainNode->globalData, this);
2618     ASSERT(data());
2619 
2620     ScopeChain scopeChain(scopeChainNode);
2621     JSGlobalObject* globalObject = scopeChain.globalObject();
2622 
2623     m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2624 
2625     BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2626     generator.generate();
2627 
2628     destroyData();
2629 }
2630 
bytecodeForExceptionInfoReparse(ScopeChainNode * scopeChainNode,CodeBlock * codeBlockBeingRegeneratedFrom)2631 CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
2632 {
2633     ASSERT(!m_code);
2634 
2635     ScopeChain scopeChain(scopeChainNode);
2636     JSGlobalObject* globalObject = scopeChain.globalObject();
2637 
2638     m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2639 
2640     BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2641     generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
2642     generator.generate();
2643 
2644     return *m_code;
2645 }
2646 
emitBytecode(BytecodeGenerator & generator,RegisterID *)2647 RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2648 {
2649     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
2650     statementListEmitCode(children(), generator, generator.ignoredResult());
2651     if (children().size() && children().last()->isBlock()) {
2652         BlockNode* blockNode = static_cast<BlockNode*>(children().last().get());
2653         if (blockNode->children().size() && blockNode->children().last()->isReturnNode())
2654             return 0;
2655     }
2656 
2657     RegisterID* r0 = generator.emitLoad(0, jsUndefined());
2658     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2659     generator.emitReturn(r0);
2660     return 0;
2661 }
2662 
paramString() const2663 UString FunctionBodyNode::paramString() const
2664 {
2665     UString s("");
2666     for (size_t pos = 0; pos < m_parameterCount; ++pos) {
2667         if (!s.isEmpty())
2668             s += ", ";
2669         s += parameters()[pos].ustring();
2670     }
2671 
2672     return s;
2673 }
2674 
copyParameters()2675 Identifier* FunctionBodyNode::copyParameters()
2676 {
2677     Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
2678     VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
2679     return parameters;
2680 }
2681 
2682 // ------------------------------ FuncDeclNode ---------------------------------
2683 
~FuncDeclNode()2684 FuncDeclNode::~FuncDeclNode()
2685 {
2686     NodeReleaser::releaseAllNodes(this);
2687 }
2688 
releaseNodes(NodeReleaser & releaser)2689 void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
2690 {
2691     releaser.release(m_parameter);
2692     releaser.release(m_body);
2693 }
2694 
makeFunction(ExecState * exec,ScopeChainNode * scopeChain)2695 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2696 {
2697     return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2698 }
2699 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2700 RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2701 {
2702     if (dst == generator.ignoredResult())
2703         dst = 0;
2704     return dst;
2705 }
2706 
2707 // ------------------------------ FuncExprNode ---------------------------------
2708 
~FuncExprNode()2709 FuncExprNode::~FuncExprNode()
2710 {
2711     NodeReleaser::releaseAllNodes(this);
2712 }
2713 
releaseNodes(NodeReleaser & releaser)2714 void FuncExprNode::releaseNodes(NodeReleaser& releaser)
2715 {
2716     releaser.release(m_parameter);
2717     releaser.release(m_body);
2718 }
2719 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2720 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2721 {
2722     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2723 }
2724 
makeFunction(ExecState * exec,ScopeChainNode * scopeChain)2725 JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2726 {
2727     JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2728 
2729     /*
2730         The Identifier in a FunctionExpression can be referenced from inside
2731         the FunctionExpression's FunctionBody to allow the function to call
2732         itself recursively. However, unlike in a FunctionDeclaration, the
2733         Identifier in a FunctionExpression cannot be referenced from and
2734         does not affect the scope enclosing the FunctionExpression.
2735      */
2736 
2737     if (!m_ident.isNull()) {
2738         JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete);
2739         func->scope().push(functionScopeObject);
2740     }
2741 
2742     return func;
2743 }
2744 
2745 #ifdef ANDROID_INSTRUMENT
2746 static size_t nodesSize = 0;
2747 
operator new(size_t s)2748 void* Node::operator new(size_t s) throw()
2749 {
2750     nodesSize += s;
2751     return ::operator new(s);
2752 }
2753 
operator delete(void * ptr,size_t s)2754 void Node::operator delete(void* ptr, size_t s)
2755 {
2756     nodesSize -= s;
2757     ::operator delete(ptr);
2758 }
2759 
reportJavaScriptNodesSize()2760 size_t Node::reportJavaScriptNodesSize()
2761 {
2762     return nodesSize;
2763 }
2764 #endif
2765 
2766 } // namespace JSC
2767