source: webkit/trunk/JavaScriptCore/parser/Nodes.cpp@ 41342

Last change on this file since 41342 was 41342, checked in by [email protected], 16 years ago

JavaScriptCore:

2009-03-01 Horia Olaru <[email protected]>

By looking in grammar.y there are only a few types of statement nodes
on which the debugger should stop.

Removed isBlock and isLoop virtual calls. No need to emit debug hooks in
the "statementListEmitCode" method as long as the necessary hooks can be
added in each "emitCode".

https://bugs.webkit.org/show_bug.cgi?id=21073

Reviewed by Kevin McCullough.

  • parser/Nodes.cpp: (JSC::ConstStatementNode::emitBytecode): (JSC::statementListEmitCode): (JSC::EmptyStatementNode::emitBytecode): (JSC::ExprStatementNode::emitBytecode): (JSC::VarStatementNode::emitBytecode): (JSC::IfNode::emitBytecode): (JSC::IfElseNode::emitBytecode): (JSC::DoWhileNode::emitBytecode): (JSC::WhileNode::emitBytecode): (JSC::ForNode::emitBytecode): (JSC::ForInNode::emitBytecode): (JSC::ContinueNode::emitBytecode): (JSC::BreakNode::emitBytecode): (JSC::ReturnNode::emitBytecode): (JSC::WithNode::emitBytecode): (JSC::SwitchNode::emitBytecode): (JSC::LabelNode::emitBytecode): (JSC::ThrowNode::emitBytecode): (JSC::TryNode::emitBytecode):
  • parser/Nodes.h:

WebCore:

2009-03-01 Horia Olaru <[email protected]>

Adding manual debugger test cases for bug.

https://bugs.webkit.org/show_bug.cgi?id=21073

Reviewed by Kevin McCullough.

  • manual-tests/inspector/debugger-step-on-do-while-statements.html: Added.
  • manual-tests/inspector/debugger-step-on-for-in-statements.html: Added.
  • manual-tests/inspector/debugger-step-on-for-statements.html: Added.
  • manual-tests/inspector/debugger-step-on-while-statements.html: Added.
  • manual-tests/inspector/resources/loop-statements.js: Added.
  • Property svn:eol-style set to native
File size: 95.6 KB
Line 
1/*
2* Copyright (C) 1999-2002 Harri Porten ([email protected])
3* Copyright (C) 2001 Peter Kelly ([email protected])
4* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5* Copyright (C) 2007 Cameron Zwarich ([email protected])
6* Copyright (C) 2007 Maks Orlovich
7* Copyright (C) 2007 Eric Seidel <[email protected]>
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
49using namespace WTF;
50
51namespace JSC {
52
53static void substitute(UString& string, const UString& substring) JSC_FAST_CALL;
54
55// ------------------------------ NodeReleaser --------------------------------
56
57class NodeReleaser : Noncopyable {
58public:
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.
67 template <typename T> void release(RefPtr<T>& node) { if (node) adopt(node.release()); }
68 void release(RefPtr<FunctionBodyNode>& node) { if (node) adoptFunctionBodyNode(node); }
69
70private:
71 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
81void 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
97void 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
107void 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
122static RefCountedLeakCounter parserRefCountedCounter("JSC::Node");
123#endif
124
125ParserRefCounted::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
137ParserRefCounted::~ParserRefCounted()
138{
139#ifndef NDEBUG
140 parserRefCountedCounter.decrement();
141#endif
142}
143
144void ParserRefCounted::releaseNodes(NodeReleaser&)
145{
146}
147
148void 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
167void 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
183bool 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
198void 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
215Node::Node(JSGlobalData* globalData)
216 : ParserRefCounted(globalData)
217{
218 m_line = globalData->lexer->lineNo();
219}
220
221// ------------------------------ ThrowableExpressionData --------------------------------
222
223static 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
233RegisterID* 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
241RegisterID* 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
253StatementNode::StatementNode(JSGlobalData* globalData)
254 : Node(globalData)
255 , m_lastLine(-1)
256{
257}
258
259void StatementNode::setLoc(int firstLine, int lastLine)
260{
261 m_line = firstLine;
262 m_lastLine = lastLine;
263}
264
265// ------------------------------ SourceElements --------------------------------
266
267void SourceElements::append(PassRefPtr<StatementNode> statement)
268{
269 if (statement->isEmptyStatement())
270 return;
271
272 m_statements.append(statement);
273}
274
275// ------------------------------ NullNode -------------------------------------
276
277RegisterID* 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
286RegisterID* 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
295RegisterID* 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
304RegisterID* 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
313RegisterID* 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
325RegisterID* 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
334bool ResolveNode::isPure(BytecodeGenerator& generator) const
335{
336 return generator.isLocal(m_ident);
337}
338
339RegisterID* 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
353ElementNode::~ElementNode()
354{
355 NodeReleaser::releaseAllNodes(this);
356}
357
358void ElementNode::releaseNodes(NodeReleaser& releaser)
359{
360 releaser.release(m_next);
361 releaser.release(m_node);
362}
363
364// ------------------------------ ArrayNode ------------------------------------
365
366ArrayNode::~ArrayNode()
367{
368 NodeReleaser::releaseAllNodes(this);
369}
370
371void ArrayNode::releaseNodes(NodeReleaser& releaser)
372{
373 releaser.release(m_element);
374}
375
376RegisterID* 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
409PropertyNode::~PropertyNode()
410{
411 NodeReleaser::releaseAllNodes(this);
412}
413
414void PropertyNode::releaseNodes(NodeReleaser& releaser)
415{
416 releaser.release(m_assign);
417}
418
419// ------------------------------ ObjectLiteralNode ----------------------------
420
421ObjectLiteralNode::~ObjectLiteralNode()
422{
423 NodeReleaser::releaseAllNodes(this);
424}
425
426void ObjectLiteralNode::releaseNodes(NodeReleaser& releaser)
427{
428 releaser.release(m_list);
429}
430
431RegisterID* 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
443PropertyListNode::~PropertyListNode()
444{
445 NodeReleaser::releaseAllNodes(this);
446}
447
448void PropertyListNode::releaseNodes(NodeReleaser& releaser)
449{
450 releaser.release(m_node);
451 releaser.release(m_next);
452}
453
454RegisterID* 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
486BracketAccessorNode::~BracketAccessorNode()
487{
488 NodeReleaser::releaseAllNodes(this);
489}
490
491void BracketAccessorNode::releaseNodes(NodeReleaser& releaser)
492{
493 releaser.release(m_base);
494 releaser.release(m_subscript);
495}
496
497RegisterID* 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
507DotAccessorNode::~DotAccessorNode()
508{
509 NodeReleaser::releaseAllNodes(this);
510}
511
512void DotAccessorNode::releaseNodes(NodeReleaser& releaser)
513{
514 releaser.release(m_base);
515}
516
517RegisterID* 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
526ArgumentListNode::~ArgumentListNode()
527{
528 NodeReleaser::releaseAllNodes(this);
529}
530
531void ArgumentListNode::releaseNodes(NodeReleaser& releaser)
532{
533 releaser.release(m_next);
534 releaser.release(m_expr);
535}
536
537RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
538{
539 ASSERT(m_expr);
540 return generator.emitNode(dst, m_expr.get());
541}
542
543// ------------------------------ ArgumentsNode -----------------------------
544
545ArgumentsNode::~ArgumentsNode()
546{
547 NodeReleaser::releaseAllNodes(this);
548}
549
550void ArgumentsNode::releaseNodes(NodeReleaser& releaser)
551{
552 releaser.release(m_listNode);
553}
554
555// ------------------------------ NewExprNode ----------------------------------
556
557NewExprNode::~NewExprNode()
558{
559 NodeReleaser::releaseAllNodes(this);
560}
561
562void NewExprNode::releaseNodes(NodeReleaser& releaser)
563{
564 releaser.release(m_expr);
565 releaser.release(m_args);
566}
567
568RegisterID* 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
576EvalFunctionCallNode::~EvalFunctionCallNode()
577{
578 NodeReleaser::releaseAllNodes(this);
579}
580
581void EvalFunctionCallNode::releaseNodes(NodeReleaser& releaser)
582{
583 releaser.release(m_args);
584}
585
586RegisterID* 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
597FunctionCallValueNode::~FunctionCallValueNode()
598{
599 NodeReleaser::releaseAllNodes(this);
600}
601
602void FunctionCallValueNode::releaseNodes(NodeReleaser& releaser)
603{
604 releaser.release(m_expr);
605 releaser.release(m_args);
606}
607
608RegisterID* 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
617FunctionCallResolveNode::~FunctionCallResolveNode()
618{
619 NodeReleaser::releaseAllNodes(this);
620}
621
622void FunctionCallResolveNode::releaseNodes(NodeReleaser& releaser)
623{
624 releaser.release(m_args);
625}
626
627RegisterID* 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.newTemporary();
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
653FunctionCallBracketNode::~FunctionCallBracketNode()
654{
655 NodeReleaser::releaseAllNodes(this);
656}
657
658void FunctionCallBracketNode::releaseNodes(NodeReleaser& releaser)
659{
660 releaser.release(m_base);
661 releaser.release(m_subscript);
662 releaser.release(m_args);
663}
664
665RegisterID* 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
677FunctionCallDotNode::~FunctionCallDotNode()
678{
679 NodeReleaser::releaseAllNodes(this);
680}
681
682void FunctionCallDotNode::releaseNodes(NodeReleaser& releaser)
683{
684 releaser.release(m_base);
685 releaser.release(m_args);
686}
687
688RegisterID* 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
699static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
700{
701 return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
702}
703
704static 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
709RegisterID* 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
755PostfixBracketNode::~PostfixBracketNode()
756{
757 NodeReleaser::releaseAllNodes(this);
758}
759
760void PostfixBracketNode::releaseNodes(NodeReleaser& releaser)
761{
762 releaser.release(m_base);
763 releaser.release(m_subscript);
764}
765
766RegisterID* 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
790PostfixDotNode::~PostfixDotNode()
791{
792 NodeReleaser::releaseAllNodes(this);
793}
794
795void PostfixDotNode::releaseNodes(NodeReleaser& releaser)
796{
797 releaser.release(m_base);
798}
799
800RegisterID* 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
823PostfixErrorNode::~PostfixErrorNode()
824{
825 NodeReleaser::releaseAllNodes(this);
826}
827
828void PostfixErrorNode::releaseNodes(NodeReleaser& releaser)
829{
830 releaser.release(m_expr);
831}
832
833RegisterID* 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
840RegisterID* 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
852DeleteBracketNode::~DeleteBracketNode()
853{
854 NodeReleaser::releaseAllNodes(this);
855}
856
857void DeleteBracketNode::releaseNodes(NodeReleaser& releaser)
858{
859 releaser.release(m_base);
860 releaser.release(m_subscript);
861}
862
863RegisterID* 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
874DeleteDotNode::~DeleteDotNode()
875{
876 NodeReleaser::releaseAllNodes(this);
877}
878
879void DeleteDotNode::releaseNodes(NodeReleaser& releaser)
880{
881 releaser.release(m_base);
882}
883
884RegisterID* 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
894DeleteValueNode::~DeleteValueNode()
895{
896 NodeReleaser::releaseAllNodes(this);
897}
898
899void DeleteValueNode::releaseNodes(NodeReleaser& releaser)
900{
901 releaser.release(m_expr);
902}
903
904RegisterID* 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
914VoidNode::~VoidNode()
915{
916 NodeReleaser::releaseAllNodes(this);
917}
918
919void VoidNode::releaseNodes(NodeReleaser& releaser)
920{
921 releaser.release(m_expr);
922}
923
924RegisterID* 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
936RegisterID* 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
953TypeOfValueNode::~TypeOfValueNode()
954{
955 NodeReleaser::releaseAllNodes(this);
956}
957
958void TypeOfValueNode::releaseNodes(NodeReleaser& releaser)
959{
960 releaser.release(m_expr);
961}
962
963RegisterID* 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
975RegisterID* 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
1009PrefixBracketNode::~PrefixBracketNode()
1010{
1011 NodeReleaser::releaseAllNodes(this);
1012}
1013
1014void PrefixBracketNode::releaseNodes(NodeReleaser& releaser)
1015{
1016 releaser.release(m_base);
1017 releaser.release(m_subscript);
1018}
1019
1020RegisterID* 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
1039PrefixDotNode::~PrefixDotNode()
1040{
1041 NodeReleaser::releaseAllNodes(this);
1042}
1043
1044void PrefixDotNode::releaseNodes(NodeReleaser& releaser)
1045{
1046 releaser.release(m_base);
1047}
1048
1049RegisterID* 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
1067PrefixErrorNode::~PrefixErrorNode()
1068{
1069 NodeReleaser::releaseAllNodes(this);
1070}
1071
1072void PrefixErrorNode::releaseNodes(NodeReleaser& releaser)
1073{
1074 releaser.release(m_expr);
1075}
1076
1077RegisterID* 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
1084UnaryOpNode::~UnaryOpNode()
1085{
1086 NodeReleaser::releaseAllNodes(this);
1087}
1088
1089void UnaryOpNode::releaseNodes(NodeReleaser& releaser)
1090{
1091 releaser.release(m_expr);
1092}
1093
1094RegisterID* 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
1102BinaryOpNode::~BinaryOpNode()
1103{
1104 NodeReleaser::releaseAllNodes(this);
1105}
1106
1107void BinaryOpNode::releaseNodes(NodeReleaser& releaser)
1108{
1109 releaser.release(m_expr1);
1110 releaser.release(m_expr2);
1111}
1112
1113RegisterID* 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
1129RegisterID* 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
1142RegisterID* 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
1149RegisterID* 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
1156RegisterID* 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
1164RegisterID* 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
1179LogicalOpNode::~LogicalOpNode()
1180{
1181 NodeReleaser::releaseAllNodes(this);
1182}
1183
1184void LogicalOpNode::releaseNodes(NodeReleaser& releaser)
1185{
1186 releaser.release(m_expr1);
1187 releaser.release(m_expr2);
1188}
1189
1190RegisterID* 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
1208ConditionalNode::~ConditionalNode()
1209{
1210 NodeReleaser::releaseAllNodes(this);
1211}
1212
1213void ConditionalNode::releaseNodes(NodeReleaser& releaser)
1214{
1215 releaser.release(m_logical);
1216 releaser.release(m_expr1);
1217 releaser.release(m_expr2);
1218}
1219
1220RegisterID* 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
1242ReadModifyResolveNode::~ReadModifyResolveNode()
1243{
1244 NodeReleaser::releaseAllNodes(this);
1245}
1246
1247void ReadModifyResolveNode::releaseNodes(NodeReleaser& releaser)
1248{
1249 releaser.release(m_right);
1250}
1251
1252// FIXME: should this be moved to be a method on BytecodeGenerator?
1253static 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
1298RegisterID* 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
1342AssignResolveNode::~AssignResolveNode()
1343{
1344 NodeReleaser::releaseAllNodes(this);
1345}
1346
1347void AssignResolveNode::releaseNodes(NodeReleaser& releaser)
1348{
1349 releaser.release(m_right);
1350}
1351
1352RegisterID* 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
1383AssignDotNode::~AssignDotNode()
1384{
1385 NodeReleaser::releaseAllNodes(this);
1386}
1387
1388void AssignDotNode::releaseNodes(NodeReleaser& releaser)
1389{
1390 releaser.release(m_base);
1391 releaser.release(m_right);
1392}
1393
1394RegisterID* 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
1406ReadModifyDotNode::~ReadModifyDotNode()
1407{
1408 NodeReleaser::releaseAllNodes(this);
1409}
1410
1411void ReadModifyDotNode::releaseNodes(NodeReleaser& releaser)
1412{
1413 releaser.release(m_base);
1414 releaser.release(m_right);
1415}
1416
1417RegisterID* 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
1432AssignErrorNode::~AssignErrorNode()
1433{
1434 NodeReleaser::releaseAllNodes(this);
1435}
1436
1437void AssignErrorNode::releaseNodes(NodeReleaser& releaser)
1438{
1439 releaser.release(m_left);
1440 releaser.release(m_right);
1441}
1442
1443RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1444{
1445 return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
1446}
1447
1448// ------------------------------ AssignBracketNode -----------------------------------
1449
1450AssignBracketNode::~AssignBracketNode()
1451{
1452 NodeReleaser::releaseAllNodes(this);
1453}
1454
1455void AssignBracketNode::releaseNodes(NodeReleaser& releaser)
1456{
1457 releaser.release(m_base);
1458 releaser.release(m_subscript);
1459 releaser.release(m_right);
1460}
1461
1462RegisterID* 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
1476ReadModifyBracketNode::~ReadModifyBracketNode()
1477{
1478 NodeReleaser::releaseAllNodes(this);
1479}
1480
1481void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser)
1482{
1483 releaser.release(m_base);
1484 releaser.release(m_subscript);
1485 releaser.release(m_right);
1486}
1487
1488RegisterID* 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
1506CommaNode::~CommaNode()
1507{
1508 NodeReleaser::releaseAllNodes(this);
1509}
1510
1511void CommaNode::releaseNodes(NodeReleaser& releaser)
1512{
1513 releaser.release(m_expr1);
1514 releaser.release(m_expr2);
1515}
1516
1517RegisterID* 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
1525ConstDeclNode::~ConstDeclNode()
1526{
1527 NodeReleaser::releaseAllNodes(this);
1528}
1529
1530void ConstDeclNode::releaseNodes(NodeReleaser& releaser)
1531{
1532 releaser.release(m_next);
1533 releaser.release(m_init);
1534}
1535
1536ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
1537 : ExpressionNode(globalData)
1538 , m_ident(ident)
1539 , m_init(init)
1540{
1541}
1542
1543RegisterID* 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
1559RegisterID* 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
1570ConstStatementNode::~ConstStatementNode()
1571{
1572 NodeReleaser::releaseAllNodes(this);
1573}
1574
1575void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
1576{
1577 releaser.release(m_next);
1578}
1579
1580RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1581{
1582 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1583 return generator.emitNode(m_next.get());
1584}
1585
1586// ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1587
1588static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
1589{
1590 StatementVector::const_iterator end = statements.end();
1591 for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
1592 StatementNode* n = it->get();
1593 generator.emitNode(dst, n);
1594 }
1595 return 0;
1596}
1597
1598// ------------------------------ BlockNode ------------------------------------
1599
1600BlockNode::~BlockNode()
1601{
1602 NodeReleaser::releaseAllNodes(this);
1603}
1604
1605void BlockNode::releaseNodes(NodeReleaser& releaser)
1606{
1607 size_t size = m_children.size();
1608 for (size_t i = 0; i < size; ++i)
1609 releaser.release(m_children[i]);
1610}
1611
1612BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
1613 : StatementNode(globalData)
1614{
1615 if (children)
1616 children->releaseContentsIntoVector(m_children);
1617}
1618
1619RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1620{
1621 return statementListEmitCode(m_children, generator, dst);
1622}
1623
1624// ------------------------------ EmptyStatementNode ---------------------------
1625
1626RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1627{
1628 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1629 return dst;
1630}
1631
1632// ------------------------------ DebuggerStatementNode ---------------------------
1633
1634RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1635{
1636 generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1637 return dst;
1638}
1639
1640// ------------------------------ ExprStatementNode ----------------------------
1641
1642RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1643{
1644 ASSERT(m_expr);
1645 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1646 return generator.emitNode(dst, m_expr.get());
1647}
1648
1649// ------------------------------ VarStatementNode ----------------------------
1650
1651VarStatementNode::~VarStatementNode()
1652{
1653 NodeReleaser::releaseAllNodes(this);
1654}
1655
1656void VarStatementNode::releaseNodes(NodeReleaser& releaser)
1657{
1658 releaser.release(m_expr);
1659}
1660
1661RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1662{
1663 ASSERT(m_expr);
1664 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1665 return generator.emitNode(m_expr.get());
1666}
1667
1668// ------------------------------ IfNode ---------------------------------------
1669
1670IfNode::~IfNode()
1671{
1672 NodeReleaser::releaseAllNodes(this);
1673}
1674
1675void IfNode::releaseNodes(NodeReleaser& releaser)
1676{
1677 releaser.release(m_condition);
1678 releaser.release(m_ifBlock);
1679}
1680
1681RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1682{
1683 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1684
1685 RefPtr<Label> afterThen = generator.newLabel();
1686
1687 RegisterID* cond = generator.emitNode(m_condition.get());
1688 generator.emitJumpIfFalse(cond, afterThen.get());
1689
1690 generator.emitNode(dst, m_ifBlock.get());
1691 generator.emitLabel(afterThen.get());
1692
1693 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1694 return 0;
1695}
1696
1697// ------------------------------ IfElseNode ---------------------------------------
1698
1699IfElseNode::~IfElseNode()
1700{
1701 NodeReleaser::releaseAllNodes(this);
1702}
1703
1704void IfElseNode::releaseNodes(NodeReleaser& releaser)
1705{
1706 releaser.release(m_elseBlock);
1707 IfNode::releaseNodes(releaser);
1708}
1709
1710RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1711{
1712 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1713
1714 RefPtr<Label> beforeElse = generator.newLabel();
1715 RefPtr<Label> afterElse = generator.newLabel();
1716
1717 RegisterID* cond = generator.emitNode(m_condition.get());
1718 generator.emitJumpIfFalse(cond, beforeElse.get());
1719
1720 generator.emitNode(dst, m_ifBlock.get());
1721 generator.emitJump(afterElse.get());
1722
1723 generator.emitLabel(beforeElse.get());
1724
1725 generator.emitNode(dst, m_elseBlock.get());
1726
1727 generator.emitLabel(afterElse.get());
1728
1729 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1730 return 0;
1731}
1732
1733// ------------------------------ DoWhileNode ----------------------------------
1734
1735DoWhileNode::~DoWhileNode()
1736{
1737 NodeReleaser::releaseAllNodes(this);
1738}
1739
1740void DoWhileNode::releaseNodes(NodeReleaser& releaser)
1741{
1742 releaser.release(m_statement);
1743 releaser.release(m_expr);
1744}
1745
1746RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1747{
1748 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1749
1750 RefPtr<Label> topOfLoop = generator.newLabel();
1751 generator.emitLabel(topOfLoop.get());
1752
1753 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1754
1755 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1756
1757 generator.emitLabel(scope->continueTarget());
1758 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1759 RegisterID* cond = generator.emitNode(m_expr.get());
1760 generator.emitJumpIfTrue(cond, topOfLoop.get());
1761
1762 generator.emitLabel(scope->breakTarget());
1763 return result.get();
1764}
1765
1766// ------------------------------ WhileNode ------------------------------------
1767
1768WhileNode::~WhileNode()
1769{
1770 NodeReleaser::releaseAllNodes(this);
1771}
1772
1773void WhileNode::releaseNodes(NodeReleaser& releaser)
1774{
1775 releaser.release(m_expr);
1776 releaser.release(m_statement);
1777}
1778
1779RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1780{
1781 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1782
1783 generator.emitJump(scope->continueTarget());
1784
1785 RefPtr<Label> topOfLoop = generator.newLabel();
1786 generator.emitLabel(topOfLoop.get());
1787
1788 generator.emitNode(dst, m_statement.get());
1789
1790 generator.emitLabel(scope->continueTarget());
1791 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1792 RegisterID* cond = generator.emitNode(m_expr.get());
1793 generator.emitJumpIfTrue(cond, topOfLoop.get());
1794
1795 generator.emitLabel(scope->breakTarget());
1796
1797 // FIXME: This should return the last statement executed so that it can be returned as a Completion
1798 return 0;
1799}
1800
1801// ------------------------------ ForNode --------------------------------------
1802
1803ForNode::~ForNode()
1804{
1805 NodeReleaser::releaseAllNodes(this);
1806}
1807
1808void ForNode::releaseNodes(NodeReleaser& releaser)
1809{
1810 releaser.release(m_expr1);
1811 releaser.release(m_expr2);
1812 releaser.release(m_expr3);
1813 releaser.release(m_statement);
1814}
1815
1816RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1817{
1818 if (dst == generator.ignoredResult())
1819 dst = 0;
1820
1821 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1822
1823 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1824
1825 if (m_expr1)
1826 generator.emitNode(generator.ignoredResult(), m_expr1.get());
1827
1828 RefPtr<Label> condition = generator.newLabel();
1829 generator.emitJump(condition.get());
1830
1831 RefPtr<Label> topOfLoop = generator.newLabel();
1832 generator.emitLabel(topOfLoop.get());
1833
1834 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1835
1836 generator.emitLabel(scope->continueTarget());
1837 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1838 if (m_expr3)
1839 generator.emitNode(generator.ignoredResult(), m_expr3.get());
1840
1841 generator.emitLabel(condition.get());
1842 if (m_expr2) {
1843 RegisterID* cond = generator.emitNode(m_expr2.get());
1844 generator.emitJumpIfTrue(cond, topOfLoop.get());
1845 } else
1846 generator.emitJump(topOfLoop.get());
1847
1848 generator.emitLabel(scope->breakTarget());
1849 return result.get();
1850}
1851
1852// ------------------------------ ForInNode ------------------------------------
1853
1854ForInNode::~ForInNode()
1855{
1856 NodeReleaser::releaseAllNodes(this);
1857}
1858
1859void ForInNode::releaseNodes(NodeReleaser& releaser)
1860{
1861 releaser.release(m_init);
1862 releaser.release(m_lexpr);
1863 releaser.release(m_expr);
1864 releaser.release(m_statement);
1865}
1866
1867ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
1868 : StatementNode(globalData)
1869 , m_init(0L)
1870 , m_lexpr(l)
1871 , m_expr(expr)
1872 , m_statement(statement)
1873 , m_identIsVarDecl(false)
1874{
1875}
1876
1877ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
1878 : StatementNode(globalData)
1879 , m_ident(ident)
1880 , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset))
1881 , m_expr(expr)
1882 , m_statement(statement)
1883 , m_identIsVarDecl(true)
1884{
1885 if (in) {
1886 AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true);
1887 node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
1888 m_init = node;
1889 }
1890 // for( var foo = bar in baz )
1891}
1892
1893RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1894{
1895 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1896
1897 if (!m_lexpr->isLocation())
1898 return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
1899
1900 RefPtr<Label> continueTarget = generator.newLabel();
1901
1902 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1903
1904 if (m_init)
1905 generator.emitNode(generator.ignoredResult(), m_init.get());
1906 RegisterID* forInBase = generator.emitNode(m_expr.get());
1907 RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
1908 generator.emitJump(scope->continueTarget());
1909
1910 RefPtr<Label> loopStart = generator.newLabel();
1911 generator.emitLabel(loopStart.get());
1912
1913 RegisterID* propertyName;
1914 if (m_lexpr->isResolveNode()) {
1915 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
1916 propertyName = generator.registerFor(ident);
1917 if (!propertyName) {
1918 propertyName = generator.newTemporary();
1919 RefPtr<RegisterID> protect = propertyName;
1920 RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1921
1922 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1923 generator.emitPutById(base, ident, propertyName);
1924 }
1925 } else if (m_lexpr->isDotAccessorNode()) {
1926 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
1927 const Identifier& ident = assignNode->identifier();
1928 propertyName = generator.newTemporary();
1929 RefPtr<RegisterID> protect = propertyName;
1930 RegisterID* base = generator.emitNode(assignNode->base());
1931
1932 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1933 generator.emitPutById(base, ident, propertyName);
1934 } else {
1935 ASSERT(m_lexpr->isBracketAccessorNode());
1936 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
1937 propertyName = generator.newTemporary();
1938 RefPtr<RegisterID> protect = propertyName;
1939 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1940 RegisterID* subscript = generator.emitNode(assignNode->subscript());
1941
1942 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1943 generator.emitPutByVal(base.get(), subscript, propertyName);
1944 }
1945
1946 generator.emitNode(dst, m_statement.get());
1947
1948 generator.emitLabel(scope->continueTarget());
1949 generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
1950 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1951 generator.emitLabel(scope->breakTarget());
1952 return dst;
1953}
1954
1955// ------------------------------ ContinueNode ---------------------------------
1956
1957// ECMA 12.7
1958RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1959{
1960 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1961
1962 LabelScope* scope = generator.continueTarget(m_ident);
1963
1964 if (!scope)
1965 return m_ident.isEmpty()
1966 ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
1967 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1968
1969 generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1970 return dst;
1971}
1972
1973// ------------------------------ BreakNode ------------------------------------
1974
1975// ECMA 12.8
1976RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1977{
1978 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1979
1980 LabelScope* scope = generator.breakTarget(m_ident);
1981
1982 if (!scope)
1983 return m_ident.isEmpty()
1984 ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
1985 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1986
1987 generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1988 return dst;
1989}
1990
1991// ------------------------------ ReturnNode -----------------------------------
1992
1993ReturnNode::~ReturnNode()
1994{
1995 NodeReleaser::releaseAllNodes(this);
1996}
1997
1998void ReturnNode::releaseNodes(NodeReleaser& releaser)
1999{
2000 releaser.release(m_value);
2001}
2002
2003RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2004{
2005 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
2006 if (generator.codeType() != FunctionCode)
2007 return emitThrowError(generator, SyntaxError, "Invalid return statement.");
2008
2009 if (dst == generator.ignoredResult())
2010 dst = 0;
2011 RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
2012 if (generator.scopeDepth()) {
2013 RefPtr<Label> l0 = generator.newLabel();
2014 generator.emitJumpScopes(l0.get(), 0);
2015 generator.emitLabel(l0.get());
2016 }
2017 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2018 return generator.emitReturn(r0);
2019}
2020
2021// ------------------------------ WithNode -------------------------------------
2022
2023WithNode::~WithNode()
2024{
2025 NodeReleaser::releaseAllNodes(this);
2026}
2027
2028void WithNode::releaseNodes(NodeReleaser& releaser)
2029{
2030 releaser.release(m_expr);
2031 releaser.release(m_statement);
2032}
2033
2034RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2035{
2036 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
2037
2038 RefPtr<RegisterID> scope = generator.newTemporary();
2039 generator.emitNode(scope.get(), m_expr.get()); // scope must be protected until popped
2040 generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
2041 generator.emitPushScope(scope.get());
2042 RegisterID* result = generator.emitNode(dst, m_statement.get());
2043 generator.emitPopScope();
2044 return result;
2045}
2046
2047// ------------------------------ CaseClauseNode --------------------------------
2048
2049CaseClauseNode::~CaseClauseNode()
2050{
2051 NodeReleaser::releaseAllNodes(this);
2052}
2053
2054void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
2055{
2056 releaser.release(m_expr);
2057}
2058
2059// ------------------------------ ClauseListNode --------------------------------
2060
2061ClauseListNode::~ClauseListNode()
2062{
2063 NodeReleaser::releaseAllNodes(this);
2064}
2065
2066void ClauseListNode::releaseNodes(NodeReleaser& releaser)
2067{
2068 releaser.release(m_clause);
2069 releaser.release(m_next);
2070}
2071
2072// ------------------------------ CaseBlockNode --------------------------------
2073
2074CaseBlockNode::~CaseBlockNode()
2075{
2076 NodeReleaser::releaseAllNodes(this);
2077}
2078
2079void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
2080{
2081 releaser.release(m_list1);
2082 releaser.release(m_defaultClause);
2083 releaser.release(m_list2);
2084}
2085
2086enum SwitchKind {
2087 SwitchUnset = 0,
2088 SwitchNumber = 1,
2089 SwitchString = 2,
2090 SwitchNeither = 3
2091};
2092
2093static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2094{
2095 for (; list; list = list->getNext()) {
2096 ExpressionNode* clauseExpression = list->getClause()->expr();
2097 literalVector.append(clauseExpression);
2098 if (clauseExpression->isNumber()) {
2099 double value = static_cast<NumberNode*>(clauseExpression)->value();
2100 JSValuePtr jsValue = JSValuePtr::makeInt32Fast(static_cast<int32_t>(value));
2101 if ((typeForTable & ~SwitchNumber) || !jsValue || (jsValue.getInt32Fast() != value)) {
2102 typeForTable = SwitchNeither;
2103 break;
2104 }
2105 int32_t intVal = static_cast<int32_t>(value);
2106 ASSERT(intVal == value);
2107 if (intVal < min_num)
2108 min_num = intVal;
2109 if (intVal > max_num)
2110 max_num = intVal;
2111 typeForTable = SwitchNumber;
2112 continue;
2113 }
2114 if (clauseExpression->isString()) {
2115 if (typeForTable & ~SwitchString) {
2116 typeForTable = SwitchNeither;
2117 break;
2118 }
2119 const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
2120 if (singleCharacterSwitch &= value.size() == 1) {
2121 int32_t intVal = value.rep()->data()[0];
2122 if (intVal < min_num)
2123 min_num = intVal;
2124 if (intVal > max_num)
2125 max_num = intVal;
2126 }
2127 typeForTable = SwitchString;
2128 continue;
2129 }
2130 typeForTable = SwitchNeither;
2131 break;
2132 }
2133}
2134
2135SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2136{
2137 SwitchKind typeForTable = SwitchUnset;
2138 bool singleCharacterSwitch = true;
2139
2140 processClauseList(m_list1.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2141 processClauseList(m_list2.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2142
2143 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2144 return SwitchInfo::SwitchNone;
2145
2146 if (typeForTable == SwitchNumber) {
2147 int32_t range = max_num - min_num;
2148 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2149 return SwitchInfo::SwitchImmediate;
2150 return SwitchInfo::SwitchNone;
2151 }
2152
2153 ASSERT(typeForTable == SwitchString);
2154
2155 if (singleCharacterSwitch) {
2156 int32_t range = max_num - min_num;
2157 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2158 return SwitchInfo::SwitchCharacter;
2159 }
2160
2161 return SwitchInfo::SwitchString;
2162}
2163
2164RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2165{
2166 RefPtr<Label> defaultLabel;
2167 Vector<RefPtr<Label>, 8> labelVector;
2168 Vector<ExpressionNode*, 8> literalVector;
2169 int32_t min_num = std::numeric_limits<int32_t>::max();
2170 int32_t max_num = std::numeric_limits<int32_t>::min();
2171 SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
2172
2173 if (switchType != SwitchInfo::SwitchNone) {
2174 // Prepare the various labels
2175 for (uint32_t i = 0; i < literalVector.size(); i++)
2176 labelVector.append(generator.newLabel());
2177 defaultLabel = generator.newLabel();
2178 generator.beginSwitch(switchExpression, switchType);
2179 } else {
2180 // Setup jumps
2181 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2182 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2183 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2184 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2185 labelVector.append(generator.newLabel());
2186 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2187 }
2188
2189 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2190 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2191 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2192 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2193 labelVector.append(generator.newLabel());
2194 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2195 }
2196 defaultLabel = generator.newLabel();
2197 generator.emitJump(defaultLabel.get());
2198 }
2199
2200 RegisterID* result = 0;
2201
2202 size_t i = 0;
2203 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2204 generator.emitLabel(labelVector[i++].get());
2205 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2206 }
2207
2208 if (m_defaultClause) {
2209 generator.emitLabel(defaultLabel.get());
2210 result = statementListEmitCode(m_defaultClause->children(), generator, dst);
2211 }
2212
2213 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2214 generator.emitLabel(labelVector[i++].get());
2215 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2216 }
2217 if (!m_defaultClause)
2218 generator.emitLabel(defaultLabel.get());
2219
2220 ASSERT(i == labelVector.size());
2221 if (switchType != SwitchInfo::SwitchNone) {
2222 ASSERT(labelVector.size() == literalVector.size());
2223 generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2224 }
2225 return result;
2226}
2227
2228// ------------------------------ SwitchNode -----------------------------------
2229
2230SwitchNode::~SwitchNode()
2231{
2232 NodeReleaser::releaseAllNodes(this);
2233}
2234
2235void SwitchNode::releaseNodes(NodeReleaser& releaser)
2236{
2237 releaser.release(m_expr);
2238 releaser.release(m_block);
2239}
2240
2241RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2242{
2243 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
2244
2245 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
2246
2247 RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2248 RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2249
2250 generator.emitLabel(scope->breakTarget());
2251 return r1;
2252}
2253
2254// ------------------------------ LabelNode ------------------------------------
2255
2256LabelNode::~LabelNode()
2257{
2258 NodeReleaser::releaseAllNodes(this);
2259}
2260
2261void LabelNode::releaseNodes(NodeReleaser& releaser)
2262{
2263 releaser.release(m_statement);
2264}
2265
2266RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2267{
2268 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
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
2282ThrowNode::~ThrowNode()
2283{
2284 NodeReleaser::releaseAllNodes(this);
2285}
2286
2287void ThrowNode::releaseNodes(NodeReleaser& releaser)
2288{
2289 releaser.release(m_expr);
2290}
2291
2292RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2293{
2294 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
2295
2296 if (dst == generator.ignoredResult())
2297 dst = 0;
2298 RefPtr<RegisterID> expr = generator.emitNode(m_expr.get());
2299 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
2300 generator.emitThrow(expr.get());
2301 return 0;
2302}
2303
2304// ------------------------------ TryNode --------------------------------------
2305
2306TryNode::~TryNode()
2307{
2308 NodeReleaser::releaseAllNodes(this);
2309}
2310
2311void TryNode::releaseNodes(NodeReleaser& releaser)
2312{
2313 releaser.release(m_tryBlock);
2314 releaser.release(m_catchBlock);
2315 releaser.release(m_finallyBlock);
2316}
2317
2318RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2319{
2320 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
2321
2322 RefPtr<Label> tryStartLabel = generator.newLabel();
2323 RefPtr<Label> tryEndLabel = generator.newLabel();
2324 RefPtr<Label> finallyStart;
2325 RefPtr<RegisterID> finallyReturnAddr;
2326 if (m_finallyBlock) {
2327 finallyStart = generator.newLabel();
2328 finallyReturnAddr = generator.newTemporary();
2329 generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
2330 }
2331 generator.emitLabel(tryStartLabel.get());
2332 generator.emitNode(dst, m_tryBlock.get());
2333 generator.emitLabel(tryEndLabel.get());
2334
2335 if (m_catchBlock) {
2336 RefPtr<Label> handlerEndLabel = generator.newLabel();
2337 generator.emitJump(handlerEndLabel.get());
2338 RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
2339 if (m_catchHasEval) {
2340 RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
2341 generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
2342 generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
2343 generator.emitPushScope(exceptionRegister.get());
2344 } else
2345 generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
2346 generator.emitNode(dst, m_catchBlock.get());
2347 generator.emitPopScope();
2348 generator.emitLabel(handlerEndLabel.get());
2349 }
2350
2351 if (m_finallyBlock) {
2352 generator.popFinallyContext();
2353 // there may be important registers live at the time we jump
2354 // to a finally block (such as for a return or throw) so we
2355 // ref the highest register ever used as a conservative
2356 // approach to not clobbering anything important
2357 RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
2358 RefPtr<Label> finallyEndLabel = generator.newLabel();
2359 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2360 // Use a label to record the subtle fact that sret will return to the
2361 // next instruction. sret is the only way to jump without an explicit label.
2362 generator.emitLabel(generator.newLabel().get());
2363 generator.emitJump(finallyEndLabel.get());
2364
2365 // Finally block for exception path
2366 RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
2367 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2368 // Use a label to record the subtle fact that sret will return to the
2369 // next instruction. sret is the only way to jump without an explicit label.
2370 generator.emitLabel(generator.newLabel().get());
2371 generator.emitThrow(tempExceptionRegister.get());
2372
2373 // emit the finally block itself
2374 generator.emitLabel(finallyStart.get());
2375 generator.emitNode(dst, m_finallyBlock.get());
2376 generator.emitSubroutineReturn(finallyReturnAddr.get());
2377
2378 generator.emitLabel(finallyEndLabel.get());
2379 }
2380
2381 return dst;
2382}
2383
2384// ------------------------------ ParameterNode -----------------------------
2385
2386ParameterNode::~ParameterNode()
2387{
2388 NodeReleaser::releaseAllNodes(this);
2389}
2390
2391void ParameterNode::releaseNodes(NodeReleaser& releaser)
2392{
2393 releaser.release(m_next);
2394}
2395
2396// -----------------------------ScopeNodeData ---------------------------
2397
2398ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
2399 : m_numConstants(numConstants)
2400{
2401 if (varStack)
2402 m_varStack = *varStack;
2403 if (funcStack)
2404 m_functionStack = *funcStack;
2405 if (children)
2406 children->releaseContentsIntoVector(m_children);
2407}
2408
2409void ScopeNodeData::mark()
2410{
2411 FunctionStack::iterator end = m_functionStack.end();
2412 for (FunctionStack::iterator ptr = m_functionStack.begin(); ptr != end; ++ptr) {
2413 FunctionBodyNode* body = (*ptr)->body();
2414 if (!body->isGenerated())
2415 continue;
2416 body->generatedBytecode().mark();
2417 }
2418}
2419
2420// ------------------------------ ScopeNode -----------------------------
2421
2422ScopeNode::ScopeNode(JSGlobalData* globalData)
2423 : StatementNode(globalData)
2424 , m_features(NoFeatures)
2425{
2426#if ENABLE(OPCODE_SAMPLING)
2427 globalData->interpreter->sampler()->notifyOfScope(this);
2428#endif
2429}
2430
2431ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
2432 : StatementNode(globalData)
2433 , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
2434 , m_features(features)
2435 , m_source(source)
2436{
2437#if ENABLE(OPCODE_SAMPLING)
2438 globalData->interpreter->sampler()->notifyOfScope(this);
2439#endif
2440}
2441
2442ScopeNode::~ScopeNode()
2443{
2444 NodeReleaser::releaseAllNodes(this);
2445}
2446
2447void ScopeNode::releaseNodes(NodeReleaser& releaser)
2448{
2449 if (!m_data)
2450 return;
2451 size_t size = m_data->m_children.size();
2452 for (size_t i = 0; i < size; ++i)
2453 releaser.release(m_data->m_children[i]);
2454}
2455
2456// ------------------------------ ProgramNode -----------------------------
2457
2458ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2459 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2460{
2461}
2462
2463ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2464{
2465 return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
2466}
2467
2468RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2469{
2470 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2471
2472 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2473 generator.emitLoad(dstRegister.get(), jsUndefined());
2474 statementListEmitCode(children(), generator, dstRegister.get());
2475
2476 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2477 generator.emitEnd(dstRegister.get());
2478 return 0;
2479}
2480
2481void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
2482{
2483 ScopeChain scopeChain(scopeChainNode);
2484 JSGlobalObject* globalObject = scopeChain.globalObject();
2485
2486 m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
2487
2488 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
2489 generator.generate();
2490
2491 destroyData();
2492}
2493
2494// ------------------------------ EvalNode -----------------------------
2495
2496EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2497 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2498{
2499}
2500
2501EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2502{
2503 return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
2504}
2505
2506RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2507{
2508 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2509
2510 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2511 generator.emitLoad(dstRegister.get(), jsUndefined());
2512 statementListEmitCode(children(), generator, dstRegister.get());
2513
2514 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2515 generator.emitEnd(dstRegister.get());
2516 return 0;
2517}
2518
2519void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
2520{
2521 ScopeChain scopeChain(scopeChainNode);
2522 JSGlobalObject* globalObject = scopeChain.globalObject();
2523
2524 m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
2525
2526 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2527 generator.generate();
2528
2529 // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
2530 // so the entire ScopeNodeData cannot be destoyed.
2531 children().clear();
2532}
2533
2534EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
2535{
2536 ASSERT(!m_code);
2537
2538 ScopeChain scopeChain(scopeChainNode);
2539 JSGlobalObject* globalObject = scopeChain.globalObject();
2540
2541 m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
2542
2543 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2544 generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
2545 generator.generate();
2546
2547 return *m_code;
2548}
2549
2550void EvalNode::mark()
2551{
2552 // We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that
2553 data()->mark();
2554}
2555
2556// ------------------------------ FunctionBodyNode -----------------------------
2557
2558FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
2559 : ScopeNode(globalData)
2560 , m_parameters(0)
2561 , m_parameterCount(0)
2562 , m_refCount(0)
2563{
2564}
2565
2566FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2567 : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
2568 , m_parameters(0)
2569 , m_parameterCount(0)
2570 , m_refCount(0)
2571{
2572}
2573
2574FunctionBodyNode::~FunctionBodyNode()
2575{
2576 ASSERT(!m_refCount);
2577 for (size_t i = 0; i < m_parameterCount; ++i)
2578 m_parameters[i].~Identifier();
2579 fastFree(m_parameters);
2580}
2581
2582void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
2583{
2584 Vector<Identifier> parameters;
2585 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
2586 parameters.append(parameter->ident());
2587 size_t count = parameters.size();
2588
2589 setSource(source);
2590 finishParsing(parameters.releaseBuffer(), count);
2591}
2592
2593void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
2594{
2595 ASSERT(!source().isNull());
2596 m_parameters = parameters;
2597 m_parameterCount = parameterCount;
2598}
2599
2600void FunctionBodyNode::mark()
2601{
2602 if (m_code)
2603 m_code->mark();
2604}
2605
2606FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
2607{
2608 return new FunctionBodyNode(globalData);
2609}
2610
2611FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2612{
2613 return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
2614}
2615
2616void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
2617{
2618 // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
2619 // calling Parser::parse<FunctionBodyNode>().
2620 if (!data())
2621 scopeChainNode->globalData->parser->reparseInPlace(scopeChainNode->globalData, this);
2622 ASSERT(data());
2623
2624 ScopeChain scopeChain(scopeChainNode);
2625 JSGlobalObject* globalObject = scopeChain.globalObject();
2626
2627 m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2628
2629 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2630 generator.generate();
2631
2632 destroyData();
2633}
2634
2635CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
2636{
2637 ASSERT(!m_code);
2638
2639 ScopeChain scopeChain(scopeChainNode);
2640 JSGlobalObject* globalObject = scopeChain.globalObject();
2641
2642 m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2643
2644 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2645 generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
2646 generator.generate();
2647
2648 return *m_code;
2649}
2650
2651RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2652{
2653 generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
2654 statementListEmitCode(children(), generator, generator.ignoredResult());
2655 if (children().size() && children().last()->isBlock()) {
2656 BlockNode* blockNode = static_cast<BlockNode*>(children().last().get());
2657 if (blockNode->children().size() && blockNode->children().last()->isReturnNode())
2658 return 0;
2659 }
2660
2661 RegisterID* r0 = generator.emitLoad(0, jsUndefined());
2662 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2663 generator.emitReturn(r0);
2664 return 0;
2665}
2666
2667UString FunctionBodyNode::paramString() const
2668{
2669 UString s("");
2670 for (size_t pos = 0; pos < m_parameterCount; ++pos) {
2671 if (!s.isEmpty())
2672 s += ", ";
2673 s += parameters()[pos].ustring();
2674 }
2675
2676 return s;
2677}
2678
2679Identifier* FunctionBodyNode::copyParameters()
2680{
2681 Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
2682 VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
2683 return parameters;
2684}
2685
2686// ------------------------------ FuncDeclNode ---------------------------------
2687
2688FuncDeclNode::~FuncDeclNode()
2689{
2690 NodeReleaser::releaseAllNodes(this);
2691}
2692
2693void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
2694{
2695 releaser.release(m_parameter);
2696 releaser.release(m_body);
2697}
2698
2699JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2700{
2701 return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2702}
2703
2704RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2705{
2706 if (dst == generator.ignoredResult())
2707 dst = 0;
2708 return dst;
2709}
2710
2711// ------------------------------ FuncExprNode ---------------------------------
2712
2713FuncExprNode::~FuncExprNode()
2714{
2715 NodeReleaser::releaseAllNodes(this);
2716}
2717
2718void FuncExprNode::releaseNodes(NodeReleaser& releaser)
2719{
2720 releaser.release(m_parameter);
2721 releaser.release(m_body);
2722}
2723
2724RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2725{
2726 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2727}
2728
2729JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2730{
2731 JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2732
2733 /*
2734 The Identifier in a FunctionExpression can be referenced from inside
2735 the FunctionExpression's FunctionBody to allow the function to call
2736 itself recursively. However, unlike in a FunctionDeclaration, the
2737 Identifier in a FunctionExpression cannot be referenced from and
2738 does not affect the scope enclosing the FunctionExpression.
2739 */
2740
2741 if (!m_ident.isNull()) {
2742 JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete);
2743 func->scope().push(functionScopeObject);
2744 }
2745
2746 return func;
2747}
2748
2749} // namespace JSC
Note: See TracBrowser for help on using the repository browser.