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

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

2009-05-05 Sam Weinig <[email protected]>

Try to fix Windows build.

Move Node constructor to the .cpp file.

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