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

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

2008-12-12 Cameron Zwarich <[email protected]>

Reviewed by Sam Weinig.

Bug 22828: Do not inspect bytecode instruction stream for op_get_by_id exception information
<https://bugs.webkit.org/show_bug.cgi?id=22828>

In order to remove the bytecode instruction stream after generating
native code, all inspection of bytecode instructions at runtime must
be removed. One particular instance of this is the special handling of
exceptions thrown by the op_get_by_id emitted directly before an
op_construct or an op_instanceof. This patch moves that information to
an auxiliary data structure in CodeBlock.

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