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

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

<https://bugs.webkit.org/show_bug.cgi?id=23049> [jsfunfuzz] With blocks do not correctly protect their scope object
<rdar://problem/6469742> Crash in JSC::TypeInfo::hasStandardGetOwnPropertySlot() running jsfunfuzz

Reviewed by Darin Adler

The problem that caused this was that with nodes were not correctly protecting
the final object that was placed in the scope chain. We correct this by forcing
the use of a temporary register (which stops us relying on a local register
protecting the scope) and changing the behaviour of op_push_scope so that it
will store the final scope object.

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