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

Last change on this file since 43313 was 43313, checked in by Darin Adler, 16 years ago

2009-05-06 Darin Adler <Darin Adler>

Fixed assertion seen a lot!

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