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

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

[jsfunfuzz] Computed exception offset wrong when first instruction is attempt to resolve deleted eval
<https://bugs.webkit.org/show_bug.cgi?id=23062>

Reviewed by Gavin Barraclough.

This was caused by the expression information for the initial resolve of
eval not being emitted. If this resolve was the first instruction that
could throw an exception the information search would fail leading to an
assertion failure. If it was not the first throwable opcode the wrong
expression information would used.

Fix is simply to emit the expression info.

  • Property svn:eol-style set to native
File size: 93.0 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.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
591 generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
592 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
593}
594
595// ------------------------------ FunctionCallValueNode ----------------------------------
596
597FunctionCallValueNode::~FunctionCallValueNode()
598{
599 NodeReleaser::releaseAllNodes(this);
600}
601
602void FunctionCallValueNode::releaseNodes(NodeReleaser& releaser)
603{
604 releaser.release(m_expr);
605 releaser.release(m_args);
606}
607
608RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
609{
610 RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
611 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
612 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
613}
614
615// ------------------------------ FunctionCallResolveNode ----------------------------------
616
617FunctionCallResolveNode::~FunctionCallResolveNode()
618{
619 NodeReleaser::releaseAllNodes(this);
620}
621
622void FunctionCallResolveNode::releaseNodes(NodeReleaser& releaser)
623{
624 releaser.release(m_args);
625}
626
627RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
628{
629 if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
630 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
631 return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
632 }
633
634 int index = 0;
635 size_t depth = 0;
636 JSObject* globalObject = 0;
637 if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
638 RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
639 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
640 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
641 }
642
643 RefPtr<RegisterID> func = generator.tempDestination(dst);
644 RefPtr<RegisterID> thisRegister = generator.newTemporary();
645 int identifierStart = divot() - startOffset();
646 generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
647 generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
648 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
649}
650
651// ------------------------------ FunctionCallBracketNode ----------------------------------
652
653FunctionCallBracketNode::~FunctionCallBracketNode()
654{
655 NodeReleaser::releaseAllNodes(this);
656}
657
658void FunctionCallBracketNode::releaseNodes(NodeReleaser& releaser)
659{
660 releaser.release(m_base);
661 releaser.release(m_subscript);
662 releaser.release(m_args);
663}
664
665RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
666{
667 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
668 RegisterID* property = generator.emitNode(m_subscript.get());
669 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
670 RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
671 RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
672 return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
673}
674
675// ------------------------------ FunctionCallDotNode ----------------------------------
676
677FunctionCallDotNode::~FunctionCallDotNode()
678{
679 NodeReleaser::releaseAllNodes(this);
680}
681
682void FunctionCallDotNode::releaseNodes(NodeReleaser& releaser)
683{
684 releaser.release(m_base);
685 releaser.release(m_args);
686}
687
688RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
689{
690 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
691 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
692 RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
693 RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
694 return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
695}
696
697// ------------------------------ PostfixResolveNode ----------------------------------
698
699static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
700{
701 return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
702}
703
704static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
705{
706 return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
707}
708
709RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
710{
711 if (RegisterID* local = generator.registerFor(m_ident)) {
712 if (generator.isLocalConstant(m_ident)) {
713 if (dst == generator.ignoredResult())
714 return 0;
715 return generator.emitToJSNumber(generator.finalDestination(dst), local);
716 }
717
718 if (dst == generator.ignoredResult())
719 return emitPreIncOrDec(generator, local, m_operator);
720 return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
721 }
722
723 int index = 0;
724 size_t depth = 0;
725 JSObject* globalObject = 0;
726 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
727 RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
728 RegisterID* oldValue;
729 if (dst == generator.ignoredResult()) {
730 oldValue = 0;
731 emitPreIncOrDec(generator, value.get(), m_operator);
732 } else {
733 oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
734 }
735 generator.emitPutScopedVar(depth, index, value.get(), globalObject);
736 return oldValue;
737 }
738
739 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
740 RefPtr<RegisterID> value = generator.newTemporary();
741 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
742 RegisterID* oldValue;
743 if (dst == generator.ignoredResult()) {
744 oldValue = 0;
745 emitPreIncOrDec(generator, value.get(), m_operator);
746 } else {
747 oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
748 }
749 generator.emitPutById(base.get(), m_ident, value.get());
750 return oldValue;
751}
752
753// ------------------------------ PostfixBracketNode ----------------------------------
754
755PostfixBracketNode::~PostfixBracketNode()
756{
757 NodeReleaser::releaseAllNodes(this);
758}
759
760void PostfixBracketNode::releaseNodes(NodeReleaser& releaser)
761{
762 releaser.release(m_base);
763 releaser.release(m_subscript);
764}
765
766RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
767{
768 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
769 RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
770
771 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
772 RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
773 RegisterID* oldValue;
774 if (dst == generator.ignoredResult()) {
775 oldValue = 0;
776 if (m_operator == OpPlusPlus)
777 generator.emitPreInc(value.get());
778 else
779 generator.emitPreDec(value.get());
780 } else {
781 oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
782 }
783 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
784 generator.emitPutByVal(base.get(), property.get(), value.get());
785 return oldValue;
786}
787
788// ------------------------------ PostfixDotNode ----------------------------------
789
790PostfixDotNode::~PostfixDotNode()
791{
792 NodeReleaser::releaseAllNodes(this);
793}
794
795void PostfixDotNode::releaseNodes(NodeReleaser& releaser)
796{
797 releaser.release(m_base);
798}
799
800RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
801{
802 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
803
804 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
805 RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
806 RegisterID* oldValue;
807 if (dst == generator.ignoredResult()) {
808 oldValue = 0;
809 if (m_operator == OpPlusPlus)
810 generator.emitPreInc(value.get());
811 else
812 generator.emitPreDec(value.get());
813 } else {
814 oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
815 }
816 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
817 generator.emitPutById(base.get(), m_ident, value.get());
818 return oldValue;
819}
820
821// ------------------------------ PostfixErrorNode -----------------------------------
822
823PostfixErrorNode::~PostfixErrorNode()
824{
825 NodeReleaser::releaseAllNodes(this);
826}
827
828void PostfixErrorNode::releaseNodes(NodeReleaser& releaser)
829{
830 releaser.release(m_expr);
831}
832
833RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
834{
835 return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
836}
837
838// ------------------------------ DeleteResolveNode -----------------------------------
839
840RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
841{
842 if (generator.registerFor(m_ident))
843 return generator.emitUnexpectedLoad(generator.finalDestination(dst), false);
844
845 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
846 RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
847 return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
848}
849
850// ------------------------------ DeleteBracketNode -----------------------------------
851
852DeleteBracketNode::~DeleteBracketNode()
853{
854 NodeReleaser::releaseAllNodes(this);
855}
856
857void DeleteBracketNode::releaseNodes(NodeReleaser& releaser)
858{
859 releaser.release(m_base);
860 releaser.release(m_subscript);
861}
862
863RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
864{
865 RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
866 RegisterID* r1 = generator.emitNode(m_subscript.get());
867
868 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
869 return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
870}
871
872// ------------------------------ DeleteDotNode -----------------------------------
873
874DeleteDotNode::~DeleteDotNode()
875{
876 NodeReleaser::releaseAllNodes(this);
877}
878
879void DeleteDotNode::releaseNodes(NodeReleaser& releaser)
880{
881 releaser.release(m_base);
882}
883
884RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
885{
886 RegisterID* r0 = generator.emitNode(m_base.get());
887
888 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
889 return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
890}
891
892// ------------------------------ DeleteValueNode -----------------------------------
893
894DeleteValueNode::~DeleteValueNode()
895{
896 NodeReleaser::releaseAllNodes(this);
897}
898
899void DeleteValueNode::releaseNodes(NodeReleaser& releaser)
900{
901 releaser.release(m_expr);
902}
903
904RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
905{
906 generator.emitNode(generator.ignoredResult(), m_expr.get());
907
908 // delete on a non-location expression ignores the value and returns true
909 return generator.emitUnexpectedLoad(generator.finalDestination(dst), true);
910}
911
912// ------------------------------ VoidNode -------------------------------------
913
914VoidNode::~VoidNode()
915{
916 NodeReleaser::releaseAllNodes(this);
917}
918
919void VoidNode::releaseNodes(NodeReleaser& releaser)
920{
921 releaser.release(m_expr);
922}
923
924RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
925{
926 if (dst == generator.ignoredResult()) {
927 generator.emitNode(generator.ignoredResult(), m_expr.get());
928 return 0;
929 }
930 RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
931 return generator.emitLoad(dst, jsUndefined());
932}
933
934// ------------------------------ TypeOfValueNode -----------------------------------
935
936RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
937{
938 if (RegisterID* local = generator.registerFor(m_ident)) {
939 if (dst == generator.ignoredResult())
940 return 0;
941 return generator.emitTypeOf(generator.finalDestination(dst), local);
942 }
943
944 RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
945 generator.emitGetById(scratch.get(), scratch.get(), m_ident);
946 if (dst == generator.ignoredResult())
947 return 0;
948 return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
949}
950
951// ------------------------------ TypeOfValueNode -----------------------------------
952
953TypeOfValueNode::~TypeOfValueNode()
954{
955 NodeReleaser::releaseAllNodes(this);
956}
957
958void TypeOfValueNode::releaseNodes(NodeReleaser& releaser)
959{
960 releaser.release(m_expr);
961}
962
963RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
964{
965 if (dst == generator.ignoredResult()) {
966 generator.emitNode(generator.ignoredResult(), m_expr.get());
967 return 0;
968 }
969 RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
970 return generator.emitTypeOf(generator.finalDestination(dst), src.get());
971}
972
973// ------------------------------ PrefixResolveNode ----------------------------------
974
975RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
976{
977 if (RegisterID* local = generator.registerFor(m_ident)) {
978 if (generator.isLocalConstant(m_ident)) {
979 if (dst == generator.ignoredResult())
980 return 0;
981 RefPtr<RegisterID> r0 = generator.emitUnexpectedLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
982 return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
983 }
984
985 emitPreIncOrDec(generator, local, m_operator);
986 return generator.moveToDestinationIfNeeded(dst, local);
987 }
988
989 int index = 0;
990 size_t depth = 0;
991 JSObject* globalObject = 0;
992 if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
993 RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
994 emitPreIncOrDec(generator, propDst.get(), m_operator);
995 generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
996 return generator.moveToDestinationIfNeeded(dst, propDst.get());
997 }
998
999 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1000 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1001 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
1002 emitPreIncOrDec(generator, propDst.get(), m_operator);
1003 generator.emitPutById(base.get(), m_ident, propDst.get());
1004 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1005}
1006
1007// ------------------------------ PrefixBracketNode ----------------------------------
1008
1009PrefixBracketNode::~PrefixBracketNode()
1010{
1011 NodeReleaser::releaseAllNodes(this);
1012}
1013
1014void PrefixBracketNode::releaseNodes(NodeReleaser& releaser)
1015{
1016 releaser.release(m_base);
1017 releaser.release(m_subscript);
1018}
1019
1020RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1021{
1022 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1023 RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
1024 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1025
1026 generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
1027 RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1028 if (m_operator == OpPlusPlus)
1029 generator.emitPreInc(value);
1030 else
1031 generator.emitPreDec(value);
1032 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1033 generator.emitPutByVal(base.get(), property.get(), value);
1034 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1035}
1036
1037// ------------------------------ PrefixDotNode ----------------------------------
1038
1039PrefixDotNode::~PrefixDotNode()
1040{
1041 NodeReleaser::releaseAllNodes(this);
1042}
1043
1044void PrefixDotNode::releaseNodes(NodeReleaser& releaser)
1045{
1046 releaser.release(m_base);
1047}
1048
1049RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1050{
1051 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1052 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1053
1054 generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
1055 RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
1056 if (m_operator == OpPlusPlus)
1057 generator.emitPreInc(value);
1058 else
1059 generator.emitPreDec(value);
1060 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1061 generator.emitPutById(base.get(), m_ident, value);
1062 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1063}
1064
1065// ------------------------------ PrefixErrorNode -----------------------------------
1066
1067PrefixErrorNode::~PrefixErrorNode()
1068{
1069 NodeReleaser::releaseAllNodes(this);
1070}
1071
1072void PrefixErrorNode::releaseNodes(NodeReleaser& releaser)
1073{
1074 releaser.release(m_expr);
1075}
1076
1077RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1078{
1079 return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
1080}
1081
1082// ------------------------------ Unary Operation Nodes -----------------------------------
1083
1084UnaryOpNode::~UnaryOpNode()
1085{
1086 NodeReleaser::releaseAllNodes(this);
1087}
1088
1089void UnaryOpNode::releaseNodes(NodeReleaser& releaser)
1090{
1091 releaser.release(m_expr);
1092}
1093
1094RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1095{
1096 RegisterID* src = generator.emitNode(m_expr.get());
1097 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
1098}
1099
1100// ------------------------------ Binary Operation Nodes -----------------------------------
1101
1102BinaryOpNode::~BinaryOpNode()
1103{
1104 NodeReleaser::releaseAllNodes(this);
1105}
1106
1107void BinaryOpNode::releaseNodes(NodeReleaser& releaser)
1108{
1109 releaser.release(m_expr1);
1110 releaser.release(m_expr2);
1111}
1112
1113RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1114{
1115 OpcodeID opcodeID = this->opcodeID();
1116 if (opcodeID == op_neq) {
1117 if (m_expr1->isNull() || m_expr2->isNull()) {
1118 RefPtr<RegisterID> src = generator.tempDestination(dst);
1119 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
1120 return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
1121 }
1122 }
1123
1124 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1125 RegisterID* src2 = generator.emitNode(m_expr2.get());
1126 return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1127}
1128
1129RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1130{
1131 if (m_expr1->isNull() || m_expr2->isNull()) {
1132 RefPtr<RegisterID> src = generator.tempDestination(dst);
1133 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
1134 return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
1135 }
1136
1137 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1138 RegisterID* src2 = generator.emitNode(m_expr2.get());
1139 return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
1140}
1141
1142RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1143{
1144 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1145 RegisterID* src2 = generator.emitNode(m_expr2.get());
1146 return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
1147}
1148
1149RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1150{
1151 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1152 RegisterID* src2 = generator.emitNode(m_expr2.get());
1153 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
1154}
1155
1156RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1157{
1158 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1159 RegisterID* src2 = generator.emitNode(m_expr2.get());
1160 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1161 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1162}
1163
1164RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1165{
1166 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1167 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2.get());
1168
1169 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1170 generator.emitGetByIdExceptionInfo(op_instanceof);
1171 RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
1172
1173 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1174 return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
1175}
1176
1177// ------------------------------ LogicalOpNode ----------------------------
1178
1179LogicalOpNode::~LogicalOpNode()
1180{
1181 NodeReleaser::releaseAllNodes(this);
1182}
1183
1184void LogicalOpNode::releaseNodes(NodeReleaser& releaser)
1185{
1186 releaser.release(m_expr1);
1187 releaser.release(m_expr2);
1188}
1189
1190RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1191{
1192 RefPtr<RegisterID> temp = generator.tempDestination(dst);
1193 RefPtr<Label> target = generator.newLabel();
1194
1195 generator.emitNode(temp.get(), m_expr1.get());
1196 if (m_operator == OpLogicalAnd)
1197 generator.emitJumpIfFalse(temp.get(), target.get());
1198 else
1199 generator.emitJumpIfTrue(temp.get(), target.get());
1200 generator.emitNode(temp.get(), m_expr2.get());
1201 generator.emitLabel(target.get());
1202
1203 return generator.moveToDestinationIfNeeded(dst, temp.get());
1204}
1205
1206// ------------------------------ ConditionalNode ------------------------------
1207
1208ConditionalNode::~ConditionalNode()
1209{
1210 NodeReleaser::releaseAllNodes(this);
1211}
1212
1213void ConditionalNode::releaseNodes(NodeReleaser& releaser)
1214{
1215 releaser.release(m_logical);
1216 releaser.release(m_expr1);
1217 releaser.release(m_expr2);
1218}
1219
1220RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1221{
1222 RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1223 RefPtr<Label> beforeElse = generator.newLabel();
1224 RefPtr<Label> afterElse = generator.newLabel();
1225
1226 RegisterID* cond = generator.emitNode(m_logical.get());
1227 generator.emitJumpIfFalse(cond, beforeElse.get());
1228
1229 generator.emitNode(newDst.get(), m_expr1.get());
1230 generator.emitJump(afterElse.get());
1231
1232 generator.emitLabel(beforeElse.get());
1233 generator.emitNode(newDst.get(), m_expr2.get());
1234
1235 generator.emitLabel(afterElse.get());
1236
1237 return newDst.get();
1238}
1239
1240// ------------------------------ ReadModifyResolveNode -----------------------------------
1241
1242ReadModifyResolveNode::~ReadModifyResolveNode()
1243{
1244 NodeReleaser::releaseAllNodes(this);
1245}
1246
1247void ReadModifyResolveNode::releaseNodes(NodeReleaser& releaser)
1248{
1249 releaser.release(m_right);
1250}
1251
1252// FIXME: should this be moved to be a method on BytecodeGenerator?
1253static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper, OperandTypes types)
1254{
1255 OpcodeID opcodeID;
1256 switch (oper) {
1257 case OpMultEq:
1258 opcodeID = op_mul;
1259 break;
1260 case OpDivEq:
1261 opcodeID = op_div;
1262 break;
1263 case OpPlusEq:
1264 opcodeID = op_add;
1265 break;
1266 case OpMinusEq:
1267 opcodeID = op_sub;
1268 break;
1269 case OpLShift:
1270 opcodeID = op_lshift;
1271 break;
1272 case OpRShift:
1273 opcodeID = op_rshift;
1274 break;
1275 case OpURShift:
1276 opcodeID = op_urshift;
1277 break;
1278 case OpAndEq:
1279 opcodeID = op_bitand;
1280 break;
1281 case OpXOrEq:
1282 opcodeID = op_bitxor;
1283 break;
1284 case OpOrEq:
1285 opcodeID = op_bitor;
1286 break;
1287 case OpModEq:
1288 opcodeID = op_mod;
1289 break;
1290 default:
1291 ASSERT_NOT_REACHED();
1292 return dst;
1293 }
1294
1295 return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1296}
1297
1298RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1299{
1300 if (RegisterID* local = generator.registerFor(m_ident)) {
1301 if (generator.isLocalConstant(m_ident)) {
1302 RegisterID* src2 = generator.emitNode(m_right.get());
1303 return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1304 }
1305
1306 if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1307 RefPtr<RegisterID> result = generator.newTemporary();
1308 generator.emitMove(result.get(), local);
1309 RegisterID* src2 = generator.emitNode(m_right.get());
1310 emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1311 generator.emitMove(local, result.get());
1312 return generator.moveToDestinationIfNeeded(dst, result.get());
1313 }
1314
1315 RegisterID* src2 = generator.emitNode(m_right.get());
1316 RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1317 return generator.moveToDestinationIfNeeded(dst, result);
1318 }
1319
1320 int index = 0;
1321 size_t depth = 0;
1322 JSObject* globalObject = 0;
1323 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1324 RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
1325 RegisterID* src2 = generator.emitNode(m_right.get());
1326 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1327 generator.emitPutScopedVar(depth, index, result, globalObject);
1328 return result;
1329 }
1330
1331 RefPtr<RegisterID> src1 = generator.tempDestination(dst);
1332 generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
1333 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
1334 RegisterID* src2 = generator.emitNode(m_right.get());
1335 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1336 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1337 return generator.emitPutById(base.get(), m_ident, result);
1338}
1339
1340// ------------------------------ AssignResolveNode -----------------------------------
1341
1342AssignResolveNode::~AssignResolveNode()
1343{
1344 NodeReleaser::releaseAllNodes(this);
1345}
1346
1347void AssignResolveNode::releaseNodes(NodeReleaser& releaser)
1348{
1349 releaser.release(m_right);
1350}
1351
1352RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1353{
1354 if (RegisterID* local = generator.registerFor(m_ident)) {
1355 if (generator.isLocalConstant(m_ident))
1356 return generator.emitNode(dst, m_right.get());
1357
1358 RegisterID* result = generator.emitNode(local, m_right.get());
1359 return generator.moveToDestinationIfNeeded(dst, result);
1360 }
1361
1362 int index = 0;
1363 size_t depth = 0;
1364 JSObject* globalObject = 0;
1365 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1366 if (dst == generator.ignoredResult())
1367 dst = 0;
1368 RegisterID* value = generator.emitNode(dst, m_right.get());
1369 generator.emitPutScopedVar(depth, index, value, globalObject);
1370 return value;
1371 }
1372
1373 RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1374 if (dst == generator.ignoredResult())
1375 dst = 0;
1376 RegisterID* value = generator.emitNode(dst, m_right.get());
1377 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1378 return generator.emitPutById(base.get(), m_ident, value);
1379}
1380
1381// ------------------------------ AssignDotNode -----------------------------------
1382
1383AssignDotNode::~AssignDotNode()
1384{
1385 NodeReleaser::releaseAllNodes(this);
1386}
1387
1388void AssignDotNode::releaseNodes(NodeReleaser& releaser)
1389{
1390 releaser.release(m_base);
1391 releaser.release(m_right);
1392}
1393
1394RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1395{
1396 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1397 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1398 RegisterID* result = generator.emitNode(value.get(), m_right.get());
1399 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1400 generator.emitPutById(base.get(), m_ident, result);
1401 return generator.moveToDestinationIfNeeded(dst, result);
1402}
1403
1404// ------------------------------ ReadModifyDotNode -----------------------------------
1405
1406ReadModifyDotNode::~ReadModifyDotNode()
1407{
1408 NodeReleaser::releaseAllNodes(this);
1409}
1410
1411void ReadModifyDotNode::releaseNodes(NodeReleaser& releaser)
1412{
1413 releaser.release(m_base);
1414 releaser.release(m_right);
1415}
1416
1417RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1418{
1419 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1420
1421 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1422 RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1423 RegisterID* change = generator.emitNode(m_right.get());
1424 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1425
1426 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1427 return generator.emitPutById(base.get(), m_ident, updatedValue);
1428}
1429
1430// ------------------------------ AssignErrorNode -----------------------------------
1431
1432AssignErrorNode::~AssignErrorNode()
1433{
1434 NodeReleaser::releaseAllNodes(this);
1435}
1436
1437void AssignErrorNode::releaseNodes(NodeReleaser& releaser)
1438{
1439 releaser.release(m_left);
1440 releaser.release(m_right);
1441}
1442
1443RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1444{
1445 return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
1446}
1447
1448// ------------------------------ AssignBracketNode -----------------------------------
1449
1450AssignBracketNode::~AssignBracketNode()
1451{
1452 NodeReleaser::releaseAllNodes(this);
1453}
1454
1455void AssignBracketNode::releaseNodes(NodeReleaser& releaser)
1456{
1457 releaser.release(m_base);
1458 releaser.release(m_subscript);
1459 releaser.release(m_right);
1460}
1461
1462RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1463{
1464 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1465 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1466 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1467 RegisterID* result = generator.emitNode(value.get(), m_right.get());
1468
1469 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1470 generator.emitPutByVal(base.get(), property.get(), result);
1471 return generator.moveToDestinationIfNeeded(dst, result);
1472}
1473
1474// ------------------------------ ReadModifyBracketNode -----------------------------------
1475
1476ReadModifyBracketNode::~ReadModifyBracketNode()
1477{
1478 NodeReleaser::releaseAllNodes(this);
1479}
1480
1481void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser)
1482{
1483 releaser.release(m_base);
1484 releaser.release(m_subscript);
1485 releaser.release(m_right);
1486}
1487
1488RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1489{
1490 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1491 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1492
1493 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1494 RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1495 RegisterID* change = generator.emitNode(m_right.get());
1496 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1497
1498 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1499 generator.emitPutByVal(base.get(), property.get(), updatedValue);
1500
1501 return updatedValue;
1502}
1503
1504// ------------------------------ CommaNode ------------------------------------
1505
1506CommaNode::~CommaNode()
1507{
1508 NodeReleaser::releaseAllNodes(this);
1509}
1510
1511void CommaNode::releaseNodes(NodeReleaser& releaser)
1512{
1513 releaser.release(m_expr1);
1514 releaser.release(m_expr2);
1515}
1516
1517RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1518{
1519 generator.emitNode(generator.ignoredResult(), m_expr1.get());
1520 return generator.emitNode(dst, m_expr2.get());
1521}
1522
1523// ------------------------------ ConstDeclNode ------------------------------------
1524
1525ConstDeclNode::~ConstDeclNode()
1526{
1527 NodeReleaser::releaseAllNodes(this);
1528}
1529
1530void ConstDeclNode::releaseNodes(NodeReleaser& releaser)
1531{
1532 releaser.release(m_next);
1533 releaser.release(m_init);
1534}
1535
1536ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
1537 : ExpressionNode(globalData)
1538 , m_ident(ident)
1539 , m_init(init)
1540{
1541}
1542
1543RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1544{
1545 if (RegisterID* local = generator.constRegisterFor(m_ident)) {
1546 if (!m_init)
1547 return local;
1548
1549 return generator.emitNode(local, m_init.get());
1550 }
1551
1552 // FIXME: While this code should only be hit in eval code, it will potentially
1553 // assign to the wrong base if m_ident exists in an intervening dynamic scope.
1554 RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1555 RegisterID* value = m_init ? generator.emitNode(m_init.get()) : generator.emitLoad(0, jsUndefined());
1556 return generator.emitPutById(base.get(), m_ident, value);
1557}
1558
1559RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1560{
1561 RegisterID* result = 0;
1562 for (ConstDeclNode* n = this; n; n = n->m_next.get())
1563 result = n->emitCodeSingle(generator);
1564
1565 return result;
1566}
1567
1568// ------------------------------ ConstStatementNode -----------------------------
1569
1570ConstStatementNode::~ConstStatementNode()
1571{
1572 NodeReleaser::releaseAllNodes(this);
1573}
1574
1575void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
1576{
1577 releaser.release(m_next);
1578}
1579
1580RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1581{
1582 return generator.emitNode(m_next.get());
1583}
1584
1585// ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1586
1587static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
1588{
1589 StatementVector::const_iterator end = statements.end();
1590 for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
1591 StatementNode* n = it->get();
1592 if (!n->isLoop())
1593 generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
1594 generator.emitNode(dst, n);
1595 }
1596 return 0;
1597}
1598
1599// ------------------------------ BlockNode ------------------------------------
1600
1601BlockNode::~BlockNode()
1602{
1603 NodeReleaser::releaseAllNodes(this);
1604}
1605
1606void BlockNode::releaseNodes(NodeReleaser& releaser)
1607{
1608 size_t size = m_children.size();
1609 for (size_t i = 0; i < size; ++i)
1610 releaser.release(m_children[i]);
1611}
1612
1613BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
1614 : StatementNode(globalData)
1615{
1616 if (children)
1617 children->releaseContentsIntoVector(m_children);
1618}
1619
1620RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1621{
1622 return statementListEmitCode(m_children, generator, dst);
1623}
1624
1625// ------------------------------ EmptyStatementNode ---------------------------
1626
1627RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
1628{
1629 return dst;
1630}
1631
1632// ------------------------------ DebuggerStatementNode ---------------------------
1633
1634RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1635{
1636 generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1637 return dst;
1638}
1639
1640// ------------------------------ ExprStatementNode ----------------------------
1641
1642RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1643{
1644 ASSERT(m_expr);
1645 return generator.emitNode(dst, m_expr.get());
1646}
1647
1648// ------------------------------ VarStatementNode ----------------------------
1649
1650VarStatementNode::~VarStatementNode()
1651{
1652 NodeReleaser::releaseAllNodes(this);
1653}
1654
1655void VarStatementNode::releaseNodes(NodeReleaser& releaser)
1656{
1657 releaser.release(m_expr);
1658}
1659
1660RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1661{
1662 ASSERT(m_expr);
1663 return generator.emitNode(m_expr.get());
1664}
1665
1666// ------------------------------ IfNode ---------------------------------------
1667
1668IfNode::~IfNode()
1669{
1670 NodeReleaser::releaseAllNodes(this);
1671}
1672
1673void IfNode::releaseNodes(NodeReleaser& releaser)
1674{
1675 releaser.release(m_condition);
1676 releaser.release(m_ifBlock);
1677}
1678
1679RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1680{
1681 RefPtr<Label> afterThen = generator.newLabel();
1682
1683 RegisterID* cond = generator.emitNode(m_condition.get());
1684 generator.emitJumpIfFalse(cond, afterThen.get());
1685
1686 if (!m_ifBlock->isBlock())
1687 generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1688
1689 generator.emitNode(dst, m_ifBlock.get());
1690 generator.emitLabel(afterThen.get());
1691
1692 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1693 return 0;
1694}
1695
1696// ------------------------------ IfElseNode ---------------------------------------
1697
1698IfElseNode::~IfElseNode()
1699{
1700 NodeReleaser::releaseAllNodes(this);
1701}
1702
1703void IfElseNode::releaseNodes(NodeReleaser& releaser)
1704{
1705 releaser.release(m_elseBlock);
1706 IfNode::releaseNodes(releaser);
1707}
1708
1709RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1710{
1711 RefPtr<Label> beforeElse = generator.newLabel();
1712 RefPtr<Label> afterElse = generator.newLabel();
1713
1714 RegisterID* cond = generator.emitNode(m_condition.get());
1715 generator.emitJumpIfFalse(cond, beforeElse.get());
1716
1717 if (!m_ifBlock->isBlock())
1718 generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1719
1720 generator.emitNode(dst, m_ifBlock.get());
1721 generator.emitJump(afterElse.get());
1722
1723 generator.emitLabel(beforeElse.get());
1724
1725 if (!m_elseBlock->isBlock())
1726 generator.emitDebugHook(WillExecuteStatement, m_elseBlock->firstLine(), m_elseBlock->lastLine());
1727
1728 generator.emitNode(dst, m_elseBlock.get());
1729
1730 generator.emitLabel(afterElse.get());
1731
1732 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1733 return 0;
1734}
1735
1736// ------------------------------ DoWhileNode ----------------------------------
1737
1738DoWhileNode::~DoWhileNode()
1739{
1740 NodeReleaser::releaseAllNodes(this);
1741}
1742
1743void DoWhileNode::releaseNodes(NodeReleaser& releaser)
1744{
1745 releaser.release(m_statement);
1746 releaser.release(m_expr);
1747}
1748
1749RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1750{
1751 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1752
1753 RefPtr<Label> topOfLoop = generator.newLabel();
1754 generator.emitLabel(topOfLoop.get());
1755
1756 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1757
1758 if (!m_statement->isBlock())
1759 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1760
1761 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1762
1763 generator.emitLabel(scope->continueTarget());
1764 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1765 RegisterID* cond = generator.emitNode(m_expr.get());
1766 generator.emitJumpIfTrue(cond, topOfLoop.get());
1767
1768 generator.emitLabel(scope->breakTarget());
1769 return result.get();
1770}
1771
1772// ------------------------------ WhileNode ------------------------------------
1773
1774WhileNode::~WhileNode()
1775{
1776 NodeReleaser::releaseAllNodes(this);
1777}
1778
1779void WhileNode::releaseNodes(NodeReleaser& releaser)
1780{
1781 releaser.release(m_expr);
1782 releaser.release(m_statement);
1783}
1784
1785RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1786{
1787 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1788
1789 generator.emitJump(scope->continueTarget());
1790
1791 RefPtr<Label> topOfLoop = generator.newLabel();
1792 generator.emitLabel(topOfLoop.get());
1793
1794 if (!m_statement->isBlock())
1795 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1796
1797 generator.emitNode(dst, m_statement.get());
1798
1799 generator.emitLabel(scope->continueTarget());
1800 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1801 RegisterID* cond = generator.emitNode(m_expr.get());
1802 generator.emitJumpIfTrue(cond, topOfLoop.get());
1803
1804 generator.emitLabel(scope->breakTarget());
1805
1806 // FIXME: This should return the last statement executed so that it can be returned as a Completion
1807 return 0;
1808}
1809
1810// ------------------------------ ForNode --------------------------------------
1811
1812ForNode::~ForNode()
1813{
1814 NodeReleaser::releaseAllNodes(this);
1815}
1816
1817void ForNode::releaseNodes(NodeReleaser& releaser)
1818{
1819 releaser.release(m_expr1);
1820 releaser.release(m_expr2);
1821 releaser.release(m_expr3);
1822 releaser.release(m_statement);
1823}
1824
1825RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1826{
1827 if (dst == generator.ignoredResult())
1828 dst = 0;
1829
1830 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1831
1832 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1833
1834 if (m_expr1)
1835 generator.emitNode(generator.ignoredResult(), m_expr1.get());
1836
1837 RefPtr<Label> condition = generator.newLabel();
1838 generator.emitJump(condition.get());
1839
1840 RefPtr<Label> topOfLoop = generator.newLabel();
1841 generator.emitLabel(topOfLoop.get());
1842
1843 if (!m_statement->isBlock())
1844 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1845 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1846
1847 generator.emitLabel(scope->continueTarget());
1848 if (m_expr3)
1849 generator.emitNode(generator.ignoredResult(), m_expr3.get());
1850
1851 generator.emitLabel(condition.get());
1852 if (m_expr2) {
1853 RegisterID* cond = generator.emitNode(m_expr2.get());
1854 generator.emitJumpIfTrue(cond, topOfLoop.get());
1855 } else
1856 generator.emitJump(topOfLoop.get());
1857
1858 generator.emitLabel(scope->breakTarget());
1859 return result.get();
1860}
1861
1862// ------------------------------ ForInNode ------------------------------------
1863
1864ForInNode::~ForInNode()
1865{
1866 NodeReleaser::releaseAllNodes(this);
1867}
1868
1869void ForInNode::releaseNodes(NodeReleaser& releaser)
1870{
1871 releaser.release(m_init);
1872 releaser.release(m_lexpr);
1873 releaser.release(m_expr);
1874 releaser.release(m_statement);
1875}
1876
1877ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
1878 : StatementNode(globalData)
1879 , m_init(0L)
1880 , m_lexpr(l)
1881 , m_expr(expr)
1882 , m_statement(statement)
1883 , m_identIsVarDecl(false)
1884{
1885}
1886
1887ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
1888 : StatementNode(globalData)
1889 , m_ident(ident)
1890 , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset))
1891 , m_expr(expr)
1892 , m_statement(statement)
1893 , m_identIsVarDecl(true)
1894{
1895 if (in) {
1896 AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true);
1897 node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
1898 m_init = node;
1899 }
1900 // for( var foo = bar in baz )
1901}
1902
1903RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1904{
1905 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1906
1907 if (!m_lexpr->isLocation())
1908 return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
1909
1910 RefPtr<Label> continueTarget = generator.newLabel();
1911
1912 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1913
1914 if (m_init)
1915 generator.emitNode(generator.ignoredResult(), m_init.get());
1916 RegisterID* forInBase = generator.emitNode(m_expr.get());
1917 RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
1918 generator.emitJump(scope->continueTarget());
1919
1920 RefPtr<Label> loopStart = generator.newLabel();
1921 generator.emitLabel(loopStart.get());
1922
1923 RegisterID* propertyName;
1924 if (m_lexpr->isResolveNode()) {
1925 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
1926 propertyName = generator.registerFor(ident);
1927 if (!propertyName) {
1928 propertyName = generator.newTemporary();
1929 RefPtr<RegisterID> protect = propertyName;
1930 RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1931
1932 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1933 generator.emitPutById(base, ident, propertyName);
1934 }
1935 } else if (m_lexpr->isDotAccessorNode()) {
1936 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
1937 const Identifier& ident = assignNode->identifier();
1938 propertyName = generator.newTemporary();
1939 RefPtr<RegisterID> protect = propertyName;
1940 RegisterID* base = generator.emitNode(assignNode->base());
1941
1942 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1943 generator.emitPutById(base, ident, propertyName);
1944 } else {
1945 ASSERT(m_lexpr->isBracketAccessorNode());
1946 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
1947 propertyName = generator.newTemporary();
1948 RefPtr<RegisterID> protect = propertyName;
1949 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1950 RegisterID* subscript = generator.emitNode(assignNode->subscript());
1951
1952 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1953 generator.emitPutByVal(base.get(), subscript, propertyName);
1954 }
1955
1956 if (!m_statement->isBlock())
1957 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1958 generator.emitNode(dst, m_statement.get());
1959
1960 generator.emitLabel(scope->continueTarget());
1961 generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
1962 generator.emitLabel(scope->breakTarget());
1963 return dst;
1964}
1965
1966// ------------------------------ ContinueNode ---------------------------------
1967
1968// ECMA 12.7
1969RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1970{
1971 LabelScope* scope = generator.continueTarget(m_ident);
1972
1973 if (!scope)
1974 return m_ident.isEmpty()
1975 ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
1976 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1977
1978 generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1979 return dst;
1980}
1981
1982// ------------------------------ BreakNode ------------------------------------
1983
1984// ECMA 12.8
1985RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1986{
1987 LabelScope* scope = generator.breakTarget(m_ident);
1988
1989 if (!scope)
1990 return m_ident.isEmpty()
1991 ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
1992 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1993
1994 generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1995 return dst;
1996}
1997
1998// ------------------------------ ReturnNode -----------------------------------
1999
2000ReturnNode::~ReturnNode()
2001{
2002 NodeReleaser::releaseAllNodes(this);
2003}
2004
2005void ReturnNode::releaseNodes(NodeReleaser& releaser)
2006{
2007 releaser.release(m_value);
2008}
2009
2010RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2011{
2012 if (generator.codeType() != FunctionCode)
2013 return emitThrowError(generator, SyntaxError, "Invalid return statement.");
2014
2015 if (dst == generator.ignoredResult())
2016 dst = 0;
2017 RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
2018 if (generator.scopeDepth()) {
2019 RefPtr<Label> l0 = generator.newLabel();
2020 generator.emitJumpScopes(l0.get(), 0);
2021 generator.emitLabel(l0.get());
2022 }
2023 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2024 return generator.emitReturn(r0);
2025}
2026
2027// ------------------------------ WithNode -------------------------------------
2028
2029WithNode::~WithNode()
2030{
2031 NodeReleaser::releaseAllNodes(this);
2032}
2033
2034void WithNode::releaseNodes(NodeReleaser& releaser)
2035{
2036 releaser.release(m_expr);
2037 releaser.release(m_statement);
2038}
2039
2040RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2041{
2042 RefPtr<RegisterID> scope = generator.newTemporary();
2043 generator.emitNode(scope.get(), m_expr.get()); // scope must be protected until popped
2044 generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
2045 generator.emitPushScope(scope.get());
2046 RegisterID* result = generator.emitNode(dst, m_statement.get());
2047 generator.emitPopScope();
2048 return result;
2049}
2050
2051// ------------------------------ CaseClauseNode --------------------------------
2052
2053CaseClauseNode::~CaseClauseNode()
2054{
2055 NodeReleaser::releaseAllNodes(this);
2056}
2057
2058void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
2059{
2060 releaser.release(m_expr);
2061}
2062
2063// ------------------------------ ClauseListNode --------------------------------
2064
2065ClauseListNode::~ClauseListNode()
2066{
2067 NodeReleaser::releaseAllNodes(this);
2068}
2069
2070void ClauseListNode::releaseNodes(NodeReleaser& releaser)
2071{
2072 releaser.release(m_clause);
2073 releaser.release(m_next);
2074}
2075
2076// ------------------------------ CaseBlockNode --------------------------------
2077
2078CaseBlockNode::~CaseBlockNode()
2079{
2080 NodeReleaser::releaseAllNodes(this);
2081}
2082
2083void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
2084{
2085 releaser.release(m_list1);
2086 releaser.release(m_defaultClause);
2087 releaser.release(m_list2);
2088}
2089
2090enum SwitchKind {
2091 SwitchUnset = 0,
2092 SwitchNumber = 1,
2093 SwitchString = 2,
2094 SwitchNeither = 3
2095};
2096
2097static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2098{
2099 for (; list; list = list->getNext()) {
2100 ExpressionNode* clauseExpression = list->getClause()->expr();
2101 literalVector.append(clauseExpression);
2102 if (clauseExpression->isNumber()) {
2103 double value = static_cast<NumberNode*>(clauseExpression)->value();
2104 if ((typeForTable & ~SwitchNumber) || !JSImmediate::from(value)) {
2105 typeForTable = SwitchNeither;
2106 break;
2107 }
2108 int32_t intVal = static_cast<int32_t>(value);
2109 ASSERT(intVal == value);
2110 if (intVal < min_num)
2111 min_num = intVal;
2112 if (intVal > max_num)
2113 max_num = intVal;
2114 typeForTable = SwitchNumber;
2115 continue;
2116 }
2117 if (clauseExpression->isString()) {
2118 if (typeForTable & ~SwitchString) {
2119 typeForTable = SwitchNeither;
2120 break;
2121 }
2122 const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
2123 if (singleCharacterSwitch &= value.size() == 1) {
2124 int32_t intVal = value.rep()->data()[0];
2125 if (intVal < min_num)
2126 min_num = intVal;
2127 if (intVal > max_num)
2128 max_num = intVal;
2129 }
2130 typeForTable = SwitchString;
2131 continue;
2132 }
2133 typeForTable = SwitchNeither;
2134 break;
2135 }
2136}
2137
2138SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2139{
2140 SwitchKind typeForTable = SwitchUnset;
2141 bool singleCharacterSwitch = true;
2142
2143 processClauseList(m_list1.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2144 processClauseList(m_list2.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2145
2146 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2147 return SwitchInfo::SwitchNone;
2148
2149 if (typeForTable == SwitchNumber) {
2150 int32_t range = max_num - min_num;
2151 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2152 return SwitchInfo::SwitchImmediate;
2153 return SwitchInfo::SwitchNone;
2154 }
2155
2156 ASSERT(typeForTable == SwitchString);
2157
2158 if (singleCharacterSwitch) {
2159 int32_t range = max_num - min_num;
2160 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2161 return SwitchInfo::SwitchCharacter;
2162 }
2163
2164 return SwitchInfo::SwitchString;
2165}
2166
2167RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2168{
2169 RefPtr<Label> defaultLabel;
2170 Vector<RefPtr<Label>, 8> labelVector;
2171 Vector<ExpressionNode*, 8> literalVector;
2172 int32_t min_num = std::numeric_limits<int32_t>::max();
2173 int32_t max_num = std::numeric_limits<int32_t>::min();
2174 SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
2175
2176 if (switchType != SwitchInfo::SwitchNone) {
2177 // Prepare the various labels
2178 for (uint32_t i = 0; i < literalVector.size(); i++)
2179 labelVector.append(generator.newLabel());
2180 defaultLabel = generator.newLabel();
2181 generator.beginSwitch(switchExpression, switchType);
2182 } else {
2183 // Setup jumps
2184 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2185 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2186 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2187 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2188 labelVector.append(generator.newLabel());
2189 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2190 }
2191
2192 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2193 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2194 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2195 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2196 labelVector.append(generator.newLabel());
2197 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2198 }
2199 defaultLabel = generator.newLabel();
2200 generator.emitJump(defaultLabel.get());
2201 }
2202
2203 RegisterID* result = 0;
2204
2205 size_t i = 0;
2206 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2207 generator.emitLabel(labelVector[i++].get());
2208 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2209 }
2210
2211 if (m_defaultClause) {
2212 generator.emitLabel(defaultLabel.get());
2213 result = statementListEmitCode(m_defaultClause->children(), generator, dst);
2214 }
2215
2216 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2217 generator.emitLabel(labelVector[i++].get());
2218 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2219 }
2220 if (!m_defaultClause)
2221 generator.emitLabel(defaultLabel.get());
2222
2223 ASSERT(i == labelVector.size());
2224 if (switchType != SwitchInfo::SwitchNone) {
2225 ASSERT(labelVector.size() == literalVector.size());
2226 generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2227 }
2228 return result;
2229}
2230
2231// ------------------------------ SwitchNode -----------------------------------
2232
2233SwitchNode::~SwitchNode()
2234{
2235 NodeReleaser::releaseAllNodes(this);
2236}
2237
2238void SwitchNode::releaseNodes(NodeReleaser& releaser)
2239{
2240 releaser.release(m_expr);
2241 releaser.release(m_block);
2242}
2243
2244RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2245{
2246 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
2247
2248 RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2249 RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2250
2251 generator.emitLabel(scope->breakTarget());
2252 return r1;
2253}
2254
2255// ------------------------------ LabelNode ------------------------------------
2256
2257LabelNode::~LabelNode()
2258{
2259 NodeReleaser::releaseAllNodes(this);
2260}
2261
2262void LabelNode::releaseNodes(NodeReleaser& releaser)
2263{
2264 releaser.release(m_statement);
2265}
2266
2267RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2268{
2269 if (generator.breakTarget(m_name))
2270 return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
2271
2272 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2273 RegisterID* r0 = generator.emitNode(dst, m_statement.get());
2274
2275 generator.emitLabel(scope->breakTarget());
2276 return r0;
2277}
2278
2279// ------------------------------ ThrowNode ------------------------------------
2280
2281ThrowNode::~ThrowNode()
2282{
2283 NodeReleaser::releaseAllNodes(this);
2284}
2285
2286void ThrowNode::releaseNodes(NodeReleaser& releaser)
2287{
2288 releaser.release(m_expr);
2289}
2290
2291RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2292{
2293 if (dst == generator.ignoredResult())
2294 dst = 0;
2295 RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
2296 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
2297 generator.emitThrow(expr.get());
2298 return dst;
2299}
2300
2301// ------------------------------ TryNode --------------------------------------
2302
2303TryNode::~TryNode()
2304{
2305 NodeReleaser::releaseAllNodes(this);
2306}
2307
2308void TryNode::releaseNodes(NodeReleaser& releaser)
2309{
2310 releaser.release(m_tryBlock);
2311 releaser.release(m_catchBlock);
2312 releaser.release(m_finallyBlock);
2313}
2314
2315RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2316{
2317 RefPtr<Label> tryStartLabel = generator.newLabel();
2318 RefPtr<Label> tryEndLabel = generator.newLabel();
2319 RefPtr<Label> finallyStart;
2320 RefPtr<RegisterID> finallyReturnAddr;
2321 if (m_finallyBlock) {
2322 finallyStart = generator.newLabel();
2323 finallyReturnAddr = generator.newTemporary();
2324 generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
2325 }
2326 generator.emitLabel(tryStartLabel.get());
2327 generator.emitNode(dst, m_tryBlock.get());
2328 generator.emitLabel(tryEndLabel.get());
2329
2330 if (m_catchBlock) {
2331 RefPtr<Label> handlerEndLabel = generator.newLabel();
2332 generator.emitJump(handlerEndLabel.get());
2333 RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
2334 generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
2335 generator.emitNode(dst, m_catchBlock.get());
2336 generator.emitPopScope();
2337 generator.emitLabel(handlerEndLabel.get());
2338 }
2339
2340 if (m_finallyBlock) {
2341 generator.popFinallyContext();
2342 // there may be important registers live at the time we jump
2343 // to a finally block (such as for a return or throw) so we
2344 // ref the highest register ever used as a conservative
2345 // approach to not clobbering anything important
2346 RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
2347 RefPtr<Label> finallyEndLabel = generator.newLabel();
2348 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2349 // Use a label to record the subtle fact that sret will return to the
2350 // next instruction. sret is the only way to jump without an explicit label.
2351 generator.emitLabel(generator.newLabel().get());
2352 generator.emitJump(finallyEndLabel.get());
2353
2354 // Finally block for exception path
2355 RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
2356 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2357 // Use a label to record the subtle fact that sret will return to the
2358 // next instruction. sret is the only way to jump without an explicit label.
2359 generator.emitLabel(generator.newLabel().get());
2360 generator.emitThrow(tempExceptionRegister.get());
2361
2362 // emit the finally block itself
2363 generator.emitLabel(finallyStart.get());
2364 generator.emitNode(dst, m_finallyBlock.get());
2365 generator.emitSubroutineReturn(finallyReturnAddr.get());
2366
2367 generator.emitLabel(finallyEndLabel.get());
2368 }
2369
2370 return dst;
2371}
2372
2373// ------------------------------ ParameterNode -----------------------------
2374
2375ParameterNode::~ParameterNode()
2376{
2377 NodeReleaser::releaseAllNodes(this);
2378}
2379
2380void ParameterNode::releaseNodes(NodeReleaser& releaser)
2381{
2382 releaser.release(m_next);
2383}
2384
2385// -----------------------------ScopeNodeData ---------------------------
2386
2387ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
2388 : m_numConstants(numConstants)
2389{
2390 if (varStack)
2391 m_varStack = *varStack;
2392 if (funcStack)
2393 m_functionStack = *funcStack;
2394 if (children)
2395 children->releaseContentsIntoVector(m_children);
2396}
2397
2398// ------------------------------ ScopeNode -----------------------------
2399
2400ScopeNode::ScopeNode(JSGlobalData* globalData)
2401 : StatementNode(globalData)
2402 , m_features(NoFeatures)
2403{
2404#if ENABLE(OPCODE_SAMPLING)
2405 globalData->interpreter->sampler()->notifyOfScope(this);
2406#endif
2407}
2408
2409ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
2410 : StatementNode(globalData)
2411 , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
2412 , m_features(features)
2413 , m_source(source)
2414{
2415#if ENABLE(OPCODE_SAMPLING)
2416 globalData->interpreter->sampler()->notifyOfScope(this);
2417#endif
2418}
2419
2420ScopeNode::~ScopeNode()
2421{
2422 NodeReleaser::releaseAllNodes(this);
2423}
2424
2425void ScopeNode::releaseNodes(NodeReleaser& releaser)
2426{
2427 if (!m_data)
2428 return;
2429 size_t size = m_data->m_children.size();
2430 for (size_t i = 0; i < size; ++i)
2431 releaser.release(m_data->m_children[i]);
2432}
2433
2434// ------------------------------ ProgramNode -----------------------------
2435
2436ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2437 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2438{
2439}
2440
2441ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2442{
2443 return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
2444}
2445
2446// ------------------------------ EvalNode -----------------------------
2447
2448EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2449 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2450{
2451}
2452
2453RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2454{
2455 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2456
2457 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2458 generator.emitLoad(dstRegister.get(), jsUndefined());
2459 statementListEmitCode(children(), generator, dstRegister.get());
2460
2461 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2462 generator.emitEnd(dstRegister.get());
2463 return 0;
2464}
2465
2466void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
2467{
2468 ScopeChain scopeChain(scopeChainNode);
2469 JSGlobalObject* globalObject = scopeChain.globalObject();
2470
2471 m_code.set(new EvalCodeBlock(this, globalObject, source().provider()));
2472
2473 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2474 generator.generate();
2475
2476 // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
2477 // so the entire ScopeNodeData cannot be destoyed.
2478 children().clear();
2479}
2480
2481EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2482{
2483 return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
2484}
2485
2486// ------------------------------ FunctionBodyNode -----------------------------
2487
2488FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
2489 : ScopeNode(globalData)
2490 , m_parameters(0)
2491 , m_parameterCount(0)
2492 , m_refCount(0)
2493{
2494}
2495
2496FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2497 : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
2498 , m_parameters(0)
2499 , m_parameterCount(0)
2500 , m_refCount(0)
2501{
2502}
2503
2504FunctionBodyNode::~FunctionBodyNode()
2505{
2506 ASSERT(!m_refCount);
2507 fastFree(m_parameters);
2508}
2509
2510void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
2511{
2512 Vector<Identifier> parameters;
2513 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
2514 parameters.append(parameter->ident());
2515 size_t count = parameters.size();
2516
2517 setSource(source);
2518 finishParsing(parameters.releaseBuffer(), count);
2519}
2520
2521void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
2522{
2523 ASSERT(!source().isNull());
2524 m_parameters = parameters;
2525 m_parameterCount = parameterCount;
2526}
2527
2528void FunctionBodyNode::mark()
2529{
2530 if (m_code)
2531 m_code->mark();
2532}
2533
2534FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
2535{
2536 return new FunctionBodyNode(globalData);
2537}
2538
2539FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2540{
2541 return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
2542}
2543
2544void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
2545{
2546 // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
2547 // calling Parser::parse<FunctionBodyNode>().
2548 if (!data())
2549 scopeChainNode->globalData->parser->reparse(scopeChainNode->globalData, this);
2550 ASSERT(data());
2551
2552 ScopeChain scopeChain(scopeChainNode);
2553 JSGlobalObject* globalObject = scopeChain.globalObject();
2554
2555 m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2556
2557 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2558 generator.generate();
2559
2560 destroyData();
2561}
2562
2563RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2564{
2565 generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
2566 statementListEmitCode(children(), generator, generator.ignoredResult());
2567 if (!children().size() || !children().last()->isReturnNode()) {
2568 RegisterID* r0 = generator.emitLoad(0, jsUndefined());
2569 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2570 generator.emitReturn(r0);
2571 }
2572 return 0;
2573}
2574
2575RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2576{
2577 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2578
2579 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2580 generator.emitLoad(dstRegister.get(), jsUndefined());
2581 statementListEmitCode(children(), generator, dstRegister.get());
2582
2583 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2584 generator.emitEnd(dstRegister.get());
2585 return 0;
2586}
2587
2588void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
2589{
2590 ScopeChain scopeChain(scopeChainNode);
2591 JSGlobalObject* globalObject = scopeChain.globalObject();
2592
2593 m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
2594
2595 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
2596 generator.generate();
2597
2598 destroyData();
2599}
2600
2601UString FunctionBodyNode::paramString() const
2602{
2603 UString s("");
2604 for (size_t pos = 0; pos < m_parameterCount; ++pos) {
2605 if (!s.isEmpty())
2606 s += ", ";
2607 s += parameters()[pos].ustring();
2608 }
2609
2610 return s;
2611}
2612
2613Identifier* FunctionBodyNode::copyParameters()
2614{
2615 Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
2616 VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
2617 return parameters;
2618}
2619
2620// ------------------------------ FuncDeclNode ---------------------------------
2621
2622FuncDeclNode::~FuncDeclNode()
2623{
2624 NodeReleaser::releaseAllNodes(this);
2625}
2626
2627void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
2628{
2629 releaser.release(m_parameter);
2630 releaser.release(m_body);
2631}
2632
2633JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2634{
2635 return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2636}
2637
2638RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2639{
2640 if (dst == generator.ignoredResult())
2641 dst = 0;
2642 return dst;
2643}
2644
2645// ------------------------------ FuncExprNode ---------------------------------
2646
2647FuncExprNode::~FuncExprNode()
2648{
2649 NodeReleaser::releaseAllNodes(this);
2650}
2651
2652void FuncExprNode::releaseNodes(NodeReleaser& releaser)
2653{
2654 releaser.release(m_parameter);
2655 releaser.release(m_body);
2656}
2657
2658RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2659{
2660 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2661}
2662
2663JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2664{
2665 JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2666
2667 /*
2668 The Identifier in a FunctionExpression can be referenced from inside
2669 the FunctionExpression's FunctionBody to allow the function to call
2670 itself recursively. However, unlike in a FunctionDeclaration, the
2671 Identifier in a FunctionExpression cannot be referenced from and
2672 does not affect the scope enclosing the FunctionExpression.
2673 */
2674
2675 if (!m_ident.isNull()) {
2676 JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete);
2677 func->scope().push(functionScopeObject);
2678 }
2679
2680 return func;
2681}
2682
2683} // namespace JSC
Note: See TracBrowser for help on using the repository browser.