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

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

2008-11-20 Sam Weinig <[email protected]>

Reviewed by Darin Adler.

Patch for https://bugs.webkit.org/show_bug.cgi?id=22385
<rdar://problem/6390179>
Lazily reparse FunctionBodyNodes on first execution.

  • Saves 57MB on Membuster head.
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::generate): Remove vector shrinking since this is now handled by destroying the ScopeNodeData after generation.
  • parser/Grammar.y: Add alternate NoNode version of the grammar that does not create nodes. This is used to lazily create FunctionBodyNodes on first execution.
  • parser/Lexer.cpp: (JSC::Lexer::setCode): Fix bug where on reparse, the Lexer was confused about what position and length meant. Position is the current position in the original data buffer (important for getting correct line/column information) and length the end offset in the original buffer.
  • parser/Lexer.h: (JSC::Lexer::sourceCode): Positions are relative to the beginning of the buffer.
  • parser/Nodes.cpp: (JSC::ScopeNodeData::ScopeNodeData): Move initialization of ScopeNode data here. (JSC::ScopeNode::ScopeNode): Add constructor that only sets the JSGlobalData for FunctionBodyNode stubs. (JSC::ScopeNode::~ScopeNode): Release m_children now that we don't inherit from BlockNode. (JSC::ScopeNode::releaseNodes): Ditto. (JSC::EvalNode::generateBytecode): Only shrink m_children, as we need to keep around the rest of the data. (JSC::FunctionBodyNode::FunctionBodyNode): Add constructor that only sets the JSGlobalData. (JSC::FunctionBodyNode::create): Ditto. (JSC::FunctionBodyNode::generateBytecode): If we don't have the data, do a reparse to construct it. Then after generation, destroy the data. (JSC::ProgramNode::generateBytecode): After generation, destroy the AST data.
  • parser/Nodes.h: (JSC::ExpressionNode::): Add isFuncExprNode for FunctionConstructor. (JSC::StatementNode::): Add isExprStatementNode for FunctionConstructor. (JSC::ExprStatementNode::): Ditto. (JSC::ExprStatementNode::expr): Add accessor for FunctionConstructor. (JSC::FuncExprNode::): Add isFuncExprNode for FunctionConstructor

(JSC::ScopeNode::adoptData): Adopts a ScopeNodeData.
(JSC::ScopeNode::data): Accessor for ScopeNodeData.
(JSC::ScopeNode::destroyData): Deletes the ScopeNodeData.
(JSC::ScopeNode::setFeatures): Added.
(JSC::ScopeNode::varStack): Added assert.
(JSC::ScopeNode::functionStack): Ditto.
(JSC::ScopeNode::children): Ditto.
(JSC::ScopeNode::neededConstants): Ditto.
Factor m_varStack, m_functionStack, m_children and m_numConstants into ScopeNodeData.

  • parser/Parser.cpp: (JSC::Parser::reparse): Reparse the SourceCode in the FunctionBodyNode and set set up the ScopeNodeData for it.
  • parser/Parser.h:
  • parser/SourceCode.h: (JSC::SourceCode::endOffset): Added for use in the lexer.
  • runtime/FunctionConstructor.cpp: (JSC::getFunctionBody): Assuming a ProgramNode with one FunctionExpression in it, get the FunctionBodyNode. Any issues signifies a parse failure in constructFunction. (JSC::constructFunction): Make parsing functions in the form new Function(""), easier by concatenating the strings together (with some glue) and parsing the function expression as a ProgramNode from which we can receive the FunctionBodyNode. This has the added benefit of not having special parsing code for the arguments and lazily constructing the FunctionBodyNode's AST on first execution.
  • runtime/Identifier.h: (JSC::operator!=): Added.
  • Property svn:eol-style set to native
File size: 92.4 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 == 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 == 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 == 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 == 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 == 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 == 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 == 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 == 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 == ignoredResult())
713 return 0;
714 return generator.emitToJSNumber(generator.finalDestination(dst), local);
715 }
716
717 if (dst == 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 == 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 == 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 == 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 == 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(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 == ignoredResult()) {
926 generator.emitNode(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 == 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 == 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 == ignoredResult()) {
965 generator.emitNode(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 == 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, m_expr->resultDescriptor());
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(), ResultType::unknown());
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(), ResultType::unknown());
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 RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
1168
1169 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1170 return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
1171}
1172
1173// ------------------------------ LogicalOpNode ----------------------------
1174
1175LogicalOpNode::~LogicalOpNode()
1176{
1177 NodeReleaser::releaseAllNodes(this);
1178}
1179
1180void LogicalOpNode::releaseNodes(NodeReleaser& releaser)
1181{
1182 releaser.release(m_expr1);
1183 releaser.release(m_expr2);
1184}
1185
1186RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1187{
1188 RefPtr<RegisterID> temp = generator.tempDestination(dst);
1189 RefPtr<Label> target = generator.newLabel();
1190
1191 generator.emitNode(temp.get(), m_expr1.get());
1192 if (m_operator == OpLogicalAnd)
1193 generator.emitJumpIfFalse(temp.get(), target.get());
1194 else
1195 generator.emitJumpIfTrue(temp.get(), target.get());
1196 generator.emitNode(temp.get(), m_expr2.get());
1197 generator.emitLabel(target.get());
1198
1199 return generator.moveToDestinationIfNeeded(dst, temp.get());
1200}
1201
1202// ------------------------------ ConditionalNode ------------------------------
1203
1204ConditionalNode::~ConditionalNode()
1205{
1206 NodeReleaser::releaseAllNodes(this);
1207}
1208
1209void ConditionalNode::releaseNodes(NodeReleaser& releaser)
1210{
1211 releaser.release(m_logical);
1212 releaser.release(m_expr1);
1213 releaser.release(m_expr2);
1214}
1215
1216RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1217{
1218 RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1219 RefPtr<Label> beforeElse = generator.newLabel();
1220 RefPtr<Label> afterElse = generator.newLabel();
1221
1222 RegisterID* cond = generator.emitNode(m_logical.get());
1223 generator.emitJumpIfFalse(cond, beforeElse.get());
1224
1225 generator.emitNode(newDst.get(), m_expr1.get());
1226 generator.emitJump(afterElse.get());
1227
1228 generator.emitLabel(beforeElse.get());
1229 generator.emitNode(newDst.get(), m_expr2.get());
1230
1231 generator.emitLabel(afterElse.get());
1232
1233 return newDst.get();
1234}
1235
1236// ------------------------------ ReadModifyResolveNode -----------------------------------
1237
1238ReadModifyResolveNode::~ReadModifyResolveNode()
1239{
1240 NodeReleaser::releaseAllNodes(this);
1241}
1242
1243void ReadModifyResolveNode::releaseNodes(NodeReleaser& releaser)
1244{
1245 releaser.release(m_right);
1246}
1247
1248// FIXME: should this be moved to be a method on BytecodeGenerator?
1249static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper, OperandTypes types)
1250{
1251 OpcodeID opcodeID;
1252 switch (oper) {
1253 case OpMultEq:
1254 opcodeID = op_mul;
1255 break;
1256 case OpDivEq:
1257 opcodeID = op_div;
1258 break;
1259 case OpPlusEq:
1260 opcodeID = op_add;
1261 break;
1262 case OpMinusEq:
1263 opcodeID = op_sub;
1264 break;
1265 case OpLShift:
1266 opcodeID = op_lshift;
1267 break;
1268 case OpRShift:
1269 opcodeID = op_rshift;
1270 break;
1271 case OpURShift:
1272 opcodeID = op_urshift;
1273 break;
1274 case OpAndEq:
1275 opcodeID = op_bitand;
1276 break;
1277 case OpXOrEq:
1278 opcodeID = op_bitxor;
1279 break;
1280 case OpOrEq:
1281 opcodeID = op_bitor;
1282 break;
1283 case OpModEq:
1284 opcodeID = op_mod;
1285 break;
1286 default:
1287 ASSERT_NOT_REACHED();
1288 return dst;
1289 }
1290
1291 return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1292}
1293
1294RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1295{
1296 if (RegisterID* local = generator.registerFor(m_ident)) {
1297 if (generator.isLocalConstant(m_ident)) {
1298 RegisterID* src2 = generator.emitNode(m_right.get());
1299 return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1300 }
1301
1302 if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1303 RefPtr<RegisterID> result = generator.newTemporary();
1304 generator.emitMove(result.get(), local);
1305 RegisterID* src2 = generator.emitNode(m_right.get());
1306 emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1307 generator.emitMove(local, result.get());
1308 return generator.moveToDestinationIfNeeded(dst, result.get());
1309 }
1310
1311 RegisterID* src2 = generator.emitNode(m_right.get());
1312 RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1313 return generator.moveToDestinationIfNeeded(dst, result);
1314 }
1315
1316 int index = 0;
1317 size_t depth = 0;
1318 JSObject* globalObject = 0;
1319 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1320 RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
1321 RegisterID* src2 = generator.emitNode(m_right.get());
1322 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1323 generator.emitPutScopedVar(depth, index, result, globalObject);
1324 return result;
1325 }
1326
1327 RefPtr<RegisterID> src1 = generator.tempDestination(dst);
1328 generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
1329 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
1330 RegisterID* src2 = generator.emitNode(m_right.get());
1331 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1332 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1333 return generator.emitPutById(base.get(), m_ident, result);
1334}
1335
1336// ------------------------------ AssignResolveNode -----------------------------------
1337
1338AssignResolveNode::~AssignResolveNode()
1339{
1340 NodeReleaser::releaseAllNodes(this);
1341}
1342
1343void AssignResolveNode::releaseNodes(NodeReleaser& releaser)
1344{
1345 releaser.release(m_right);
1346}
1347
1348RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1349{
1350 if (RegisterID* local = generator.registerFor(m_ident)) {
1351 if (generator.isLocalConstant(m_ident))
1352 return generator.emitNode(dst, m_right.get());
1353
1354 RegisterID* result = generator.emitNode(local, m_right.get());
1355 return generator.moveToDestinationIfNeeded(dst, result);
1356 }
1357
1358 int index = 0;
1359 size_t depth = 0;
1360 JSObject* globalObject = 0;
1361 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1362 if (dst == ignoredResult())
1363 dst = 0;
1364 RegisterID* value = generator.emitNode(dst, m_right.get());
1365 generator.emitPutScopedVar(depth, index, value, globalObject);
1366 return value;
1367 }
1368
1369 RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1370 if (dst == ignoredResult())
1371 dst = 0;
1372 RegisterID* value = generator.emitNode(dst, m_right.get());
1373 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1374 return generator.emitPutById(base.get(), m_ident, value);
1375}
1376
1377// ------------------------------ AssignDotNode -----------------------------------
1378
1379AssignDotNode::~AssignDotNode()
1380{
1381 NodeReleaser::releaseAllNodes(this);
1382}
1383
1384void AssignDotNode::releaseNodes(NodeReleaser& releaser)
1385{
1386 releaser.release(m_base);
1387 releaser.release(m_right);
1388}
1389
1390RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1391{
1392 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1393 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1394 RegisterID* result = generator.emitNode(value.get(), m_right.get());
1395 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1396 generator.emitPutById(base.get(), m_ident, result);
1397 return generator.moveToDestinationIfNeeded(dst, result);
1398}
1399
1400// ------------------------------ ReadModifyDotNode -----------------------------------
1401
1402ReadModifyDotNode::~ReadModifyDotNode()
1403{
1404 NodeReleaser::releaseAllNodes(this);
1405}
1406
1407void ReadModifyDotNode::releaseNodes(NodeReleaser& releaser)
1408{
1409 releaser.release(m_base);
1410 releaser.release(m_right);
1411}
1412
1413RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1414{
1415 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1416
1417 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1418 RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1419 RegisterID* change = generator.emitNode(m_right.get());
1420 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1421
1422 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1423 return generator.emitPutById(base.get(), m_ident, updatedValue);
1424}
1425
1426// ------------------------------ AssignErrorNode -----------------------------------
1427
1428AssignErrorNode::~AssignErrorNode()
1429{
1430 NodeReleaser::releaseAllNodes(this);
1431}
1432
1433void AssignErrorNode::releaseNodes(NodeReleaser& releaser)
1434{
1435 releaser.release(m_left);
1436 releaser.release(m_right);
1437}
1438
1439RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1440{
1441 return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
1442}
1443
1444// ------------------------------ AssignBracketNode -----------------------------------
1445
1446AssignBracketNode::~AssignBracketNode()
1447{
1448 NodeReleaser::releaseAllNodes(this);
1449}
1450
1451void AssignBracketNode::releaseNodes(NodeReleaser& releaser)
1452{
1453 releaser.release(m_base);
1454 releaser.release(m_subscript);
1455 releaser.release(m_right);
1456}
1457
1458RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1459{
1460 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1461 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1462 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1463 RegisterID* result = generator.emitNode(value.get(), m_right.get());
1464
1465 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1466 generator.emitPutByVal(base.get(), property.get(), result);
1467 return generator.moveToDestinationIfNeeded(dst, result);
1468}
1469
1470// ------------------------------ ReadModifyBracketNode -----------------------------------
1471
1472ReadModifyBracketNode::~ReadModifyBracketNode()
1473{
1474 NodeReleaser::releaseAllNodes(this);
1475}
1476
1477void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser)
1478{
1479 releaser.release(m_base);
1480 releaser.release(m_subscript);
1481 releaser.release(m_right);
1482}
1483
1484RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1485{
1486 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1487 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1488
1489 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1490 RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1491 RegisterID* change = generator.emitNode(m_right.get());
1492 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1493
1494 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1495 generator.emitPutByVal(base.get(), property.get(), updatedValue);
1496
1497 return updatedValue;
1498}
1499
1500// ------------------------------ CommaNode ------------------------------------
1501
1502CommaNode::~CommaNode()
1503{
1504 NodeReleaser::releaseAllNodes(this);
1505}
1506
1507void CommaNode::releaseNodes(NodeReleaser& releaser)
1508{
1509 releaser.release(m_expr1);
1510 releaser.release(m_expr2);
1511}
1512
1513RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1514{
1515 generator.emitNode(ignoredResult(), m_expr1.get());
1516 return generator.emitNode(dst, m_expr2.get());
1517}
1518
1519// ------------------------------ ConstDeclNode ------------------------------------
1520
1521ConstDeclNode::~ConstDeclNode()
1522{
1523 NodeReleaser::releaseAllNodes(this);
1524}
1525
1526void ConstDeclNode::releaseNodes(NodeReleaser& releaser)
1527{
1528 releaser.release(m_next);
1529 releaser.release(m_init);
1530}
1531
1532ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
1533 : ExpressionNode(globalData)
1534 , m_ident(ident)
1535 , m_init(init)
1536{
1537}
1538
1539RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1540{
1541 if (RegisterID* local = generator.constRegisterFor(m_ident)) {
1542 if (!m_init)
1543 return local;
1544
1545 return generator.emitNode(local, m_init.get());
1546 }
1547
1548 // FIXME: While this code should only be hit in eval code, it will potentially
1549 // assign to the wrong base if m_ident exists in an intervening dynamic scope.
1550 RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1551 RegisterID* value = m_init ? generator.emitNode(m_init.get()) : generator.emitLoad(0, jsUndefined());
1552 return generator.emitPutById(base.get(), m_ident, value);
1553}
1554
1555RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1556{
1557 RegisterID* result = 0;
1558 for (ConstDeclNode* n = this; n; n = n->m_next.get())
1559 result = n->emitCodeSingle(generator);
1560
1561 return result;
1562}
1563
1564// ------------------------------ ConstStatementNode -----------------------------
1565
1566ConstStatementNode::~ConstStatementNode()
1567{
1568 NodeReleaser::releaseAllNodes(this);
1569}
1570
1571void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
1572{
1573 releaser.release(m_next);
1574}
1575
1576RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1577{
1578 return generator.emitNode(m_next.get());
1579}
1580
1581// ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1582
1583static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
1584{
1585 StatementVector::const_iterator end = statements.end();
1586 for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
1587 StatementNode* n = it->get();
1588 if (!n->isLoop())
1589 generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
1590 generator.emitNode(dst, n);
1591 }
1592 return 0;
1593}
1594
1595// ------------------------------ BlockNode ------------------------------------
1596
1597BlockNode::~BlockNode()
1598{
1599 NodeReleaser::releaseAllNodes(this);
1600}
1601
1602void BlockNode::releaseNodes(NodeReleaser& releaser)
1603{
1604 size_t size = m_children.size();
1605 for (size_t i = 0; i < size; ++i)
1606 releaser.release(m_children[i]);
1607}
1608
1609BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
1610 : StatementNode(globalData)
1611{
1612 if (children)
1613 children->releaseContentsIntoVector(m_children);
1614}
1615
1616RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1617{
1618 return statementListEmitCode(m_children, generator, dst);
1619}
1620
1621// ------------------------------ EmptyStatementNode ---------------------------
1622
1623RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
1624{
1625 return dst;
1626}
1627
1628// ------------------------------ DebuggerStatementNode ---------------------------
1629
1630RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1631{
1632 generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1633 return dst;
1634}
1635
1636// ------------------------------ ExprStatementNode ----------------------------
1637
1638RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1639{
1640 ASSERT(m_expr);
1641 return generator.emitNode(dst, m_expr.get());
1642}
1643
1644// ------------------------------ VarStatementNode ----------------------------
1645
1646VarStatementNode::~VarStatementNode()
1647{
1648 NodeReleaser::releaseAllNodes(this);
1649}
1650
1651void VarStatementNode::releaseNodes(NodeReleaser& releaser)
1652{
1653 releaser.release(m_expr);
1654}
1655
1656RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1657{
1658 ASSERT(m_expr);
1659 return generator.emitNode(m_expr.get());
1660}
1661
1662// ------------------------------ IfNode ---------------------------------------
1663
1664IfNode::~IfNode()
1665{
1666 NodeReleaser::releaseAllNodes(this);
1667}
1668
1669void IfNode::releaseNodes(NodeReleaser& releaser)
1670{
1671 releaser.release(m_condition);
1672 releaser.release(m_ifBlock);
1673}
1674
1675RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1676{
1677 RefPtr<Label> afterThen = generator.newLabel();
1678
1679 RegisterID* cond = generator.emitNode(m_condition.get());
1680 generator.emitJumpIfFalse(cond, afterThen.get());
1681
1682 if (!m_ifBlock->isBlock())
1683 generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1684
1685 generator.emitNode(dst, m_ifBlock.get());
1686 generator.emitLabel(afterThen.get());
1687
1688 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1689 return 0;
1690}
1691
1692// ------------------------------ IfElseNode ---------------------------------------
1693
1694IfElseNode::~IfElseNode()
1695{
1696 NodeReleaser::releaseAllNodes(this);
1697}
1698
1699void IfElseNode::releaseNodes(NodeReleaser& releaser)
1700{
1701 releaser.release(m_elseBlock);
1702 IfNode::releaseNodes(releaser);
1703}
1704
1705RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1706{
1707 RefPtr<Label> beforeElse = generator.newLabel();
1708 RefPtr<Label> afterElse = generator.newLabel();
1709
1710 RegisterID* cond = generator.emitNode(m_condition.get());
1711 generator.emitJumpIfFalse(cond, beforeElse.get());
1712
1713 if (!m_ifBlock->isBlock())
1714 generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1715
1716 generator.emitNode(dst, m_ifBlock.get());
1717 generator.emitJump(afterElse.get());
1718
1719 generator.emitLabel(beforeElse.get());
1720
1721 if (!m_elseBlock->isBlock())
1722 generator.emitDebugHook(WillExecuteStatement, m_elseBlock->firstLine(), m_elseBlock->lastLine());
1723
1724 generator.emitNode(dst, m_elseBlock.get());
1725
1726 generator.emitLabel(afterElse.get());
1727
1728 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1729 return 0;
1730}
1731
1732// ------------------------------ DoWhileNode ----------------------------------
1733
1734DoWhileNode::~DoWhileNode()
1735{
1736 NodeReleaser::releaseAllNodes(this);
1737}
1738
1739void DoWhileNode::releaseNodes(NodeReleaser& releaser)
1740{
1741 releaser.release(m_statement);
1742 releaser.release(m_expr);
1743}
1744
1745RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1746{
1747 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1748
1749 RefPtr<Label> topOfLoop = generator.newLabel();
1750 generator.emitLabel(topOfLoop.get());
1751
1752 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1753
1754 if (!m_statement->isBlock())
1755 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1756
1757 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1758
1759 generator.emitLabel(scope->continueTarget());
1760 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1761 RegisterID* cond = generator.emitNode(m_expr.get());
1762 generator.emitJumpIfTrue(cond, topOfLoop.get());
1763
1764 generator.emitLabel(scope->breakTarget());
1765 return result.get();
1766}
1767
1768// ------------------------------ WhileNode ------------------------------------
1769
1770WhileNode::~WhileNode()
1771{
1772 NodeReleaser::releaseAllNodes(this);
1773}
1774
1775void WhileNode::releaseNodes(NodeReleaser& releaser)
1776{
1777 releaser.release(m_expr);
1778 releaser.release(m_statement);
1779}
1780
1781RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1782{
1783 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1784
1785 generator.emitJump(scope->continueTarget());
1786
1787 RefPtr<Label> topOfLoop = generator.newLabel();
1788 generator.emitLabel(topOfLoop.get());
1789
1790 if (!m_statement->isBlock())
1791 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1792
1793 generator.emitNode(dst, m_statement.get());
1794
1795 generator.emitLabel(scope->continueTarget());
1796 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1797 RegisterID* cond = generator.emitNode(m_expr.get());
1798 generator.emitJumpIfTrue(cond, topOfLoop.get());
1799
1800 generator.emitLabel(scope->breakTarget());
1801
1802 // FIXME: This should return the last statement executed so that it can be returned as a Completion
1803 return 0;
1804}
1805
1806// ------------------------------ ForNode --------------------------------------
1807
1808ForNode::~ForNode()
1809{
1810 NodeReleaser::releaseAllNodes(this);
1811}
1812
1813void ForNode::releaseNodes(NodeReleaser& releaser)
1814{
1815 releaser.release(m_expr1);
1816 releaser.release(m_expr2);
1817 releaser.release(m_expr3);
1818 releaser.release(m_statement);
1819}
1820
1821RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1822{
1823 if (dst == ignoredResult())
1824 dst = 0;
1825
1826 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1827
1828 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1829
1830 if (m_expr1)
1831 generator.emitNode(ignoredResult(), m_expr1.get());
1832
1833 RefPtr<Label> condition = generator.newLabel();
1834 generator.emitJump(condition.get());
1835
1836 RefPtr<Label> topOfLoop = generator.newLabel();
1837 generator.emitLabel(topOfLoop.get());
1838
1839 if (!m_statement->isBlock())
1840 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1841 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1842
1843 generator.emitLabel(scope->continueTarget());
1844 if (m_expr3)
1845 generator.emitNode(ignoredResult(), m_expr3.get());
1846
1847 generator.emitLabel(condition.get());
1848 if (m_expr2) {
1849 RegisterID* cond = generator.emitNode(m_expr2.get());
1850 generator.emitJumpIfTrue(cond, topOfLoop.get());
1851 } else
1852 generator.emitJump(topOfLoop.get());
1853
1854 generator.emitLabel(scope->breakTarget());
1855 return result.get();
1856}
1857
1858// ------------------------------ ForInNode ------------------------------------
1859
1860ForInNode::~ForInNode()
1861{
1862 NodeReleaser::releaseAllNodes(this);
1863}
1864
1865void ForInNode::releaseNodes(NodeReleaser& releaser)
1866{
1867 releaser.release(m_init);
1868 releaser.release(m_lexpr);
1869 releaser.release(m_expr);
1870 releaser.release(m_statement);
1871}
1872
1873ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
1874 : StatementNode(globalData)
1875 , m_init(0L)
1876 , m_lexpr(l)
1877 , m_expr(expr)
1878 , m_statement(statement)
1879 , m_identIsVarDecl(false)
1880{
1881}
1882
1883ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
1884 : StatementNode(globalData)
1885 , m_ident(ident)
1886 , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset))
1887 , m_expr(expr)
1888 , m_statement(statement)
1889 , m_identIsVarDecl(true)
1890{
1891 if (in) {
1892 AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true);
1893 node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
1894 m_init = node;
1895 }
1896 // for( var foo = bar in baz )
1897}
1898
1899RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1900{
1901 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1902
1903 if (!m_lexpr->isLocation())
1904 return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
1905
1906 RefPtr<Label> continueTarget = generator.newLabel();
1907
1908 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1909
1910 if (m_init)
1911 generator.emitNode(ignoredResult(), m_init.get());
1912 RegisterID* forInBase = generator.emitNode(m_expr.get());
1913 RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
1914 generator.emitJump(scope->continueTarget());
1915
1916 RefPtr<Label> loopStart = generator.newLabel();
1917 generator.emitLabel(loopStart.get());
1918
1919 RegisterID* propertyName;
1920 if (m_lexpr->isResolveNode()) {
1921 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
1922 propertyName = generator.registerFor(ident);
1923 if (!propertyName) {
1924 propertyName = generator.newTemporary();
1925 RefPtr<RegisterID> protect = propertyName;
1926 RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1927
1928 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1929 generator.emitPutById(base, ident, propertyName);
1930 }
1931 } else if (m_lexpr->isDotAccessorNode()) {
1932 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
1933 const Identifier& ident = assignNode->identifier();
1934 propertyName = generator.newTemporary();
1935 RefPtr<RegisterID> protect = propertyName;
1936 RegisterID* base = generator.emitNode(assignNode->base());
1937
1938 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1939 generator.emitPutById(base, ident, propertyName);
1940 } else {
1941 ASSERT(m_lexpr->isBracketAccessorNode());
1942 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
1943 propertyName = generator.newTemporary();
1944 RefPtr<RegisterID> protect = propertyName;
1945 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1946 RegisterID* subscript = generator.emitNode(assignNode->subscript());
1947
1948 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1949 generator.emitPutByVal(base.get(), subscript, propertyName);
1950 }
1951
1952 if (!m_statement->isBlock())
1953 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1954 generator.emitNode(dst, m_statement.get());
1955
1956 generator.emitLabel(scope->continueTarget());
1957 generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
1958 generator.emitLabel(scope->breakTarget());
1959 return dst;
1960}
1961
1962// ------------------------------ ContinueNode ---------------------------------
1963
1964// ECMA 12.7
1965RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1966{
1967 LabelScope* scope = generator.continueTarget(m_ident);
1968
1969 if (!scope)
1970 return m_ident.isEmpty()
1971 ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
1972 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1973
1974 generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1975 return dst;
1976}
1977
1978// ------------------------------ BreakNode ------------------------------------
1979
1980// ECMA 12.8
1981RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1982{
1983 LabelScope* scope = generator.breakTarget(m_ident);
1984
1985 if (!scope)
1986 return m_ident.isEmpty()
1987 ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
1988 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1989
1990 generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1991 return dst;
1992}
1993
1994// ------------------------------ ReturnNode -----------------------------------
1995
1996ReturnNode::~ReturnNode()
1997{
1998 NodeReleaser::releaseAllNodes(this);
1999}
2000
2001void ReturnNode::releaseNodes(NodeReleaser& releaser)
2002{
2003 releaser.release(m_value);
2004}
2005
2006RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2007{
2008 if (generator.codeType() != FunctionCode)
2009 return emitThrowError(generator, SyntaxError, "Invalid return statement.");
2010
2011 if (dst == ignoredResult())
2012 dst = 0;
2013 RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
2014 if (generator.scopeDepth()) {
2015 RefPtr<Label> l0 = generator.newLabel();
2016 generator.emitJumpScopes(l0.get(), 0);
2017 generator.emitLabel(l0.get());
2018 }
2019 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2020 return generator.emitReturn(r0);
2021}
2022
2023// ------------------------------ WithNode -------------------------------------
2024
2025WithNode::~WithNode()
2026{
2027 NodeReleaser::releaseAllNodes(this);
2028}
2029
2030void WithNode::releaseNodes(NodeReleaser& releaser)
2031{
2032 releaser.release(m_expr);
2033 releaser.release(m_statement);
2034}
2035
2036RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2037{
2038 RefPtr<RegisterID> scope = generator.emitNode(m_expr.get()); // scope must be protected until popped
2039 generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
2040 generator.emitPushScope(scope.get());
2041 RegisterID* result = generator.emitNode(dst, m_statement.get());
2042 generator.emitPopScope();
2043 return result;
2044}
2045
2046// ------------------------------ CaseClauseNode --------------------------------
2047
2048CaseClauseNode::~CaseClauseNode()
2049{
2050 NodeReleaser::releaseAllNodes(this);
2051}
2052
2053void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
2054{
2055 releaser.release(m_expr);
2056}
2057
2058// ------------------------------ ClauseListNode --------------------------------
2059
2060ClauseListNode::~ClauseListNode()
2061{
2062 NodeReleaser::releaseAllNodes(this);
2063}
2064
2065void ClauseListNode::releaseNodes(NodeReleaser& releaser)
2066{
2067 releaser.release(m_clause);
2068 releaser.release(m_next);
2069}
2070
2071// ------------------------------ CaseBlockNode --------------------------------
2072
2073CaseBlockNode::~CaseBlockNode()
2074{
2075 NodeReleaser::releaseAllNodes(this);
2076}
2077
2078void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
2079{
2080 releaser.release(m_list1);
2081 releaser.release(m_defaultClause);
2082 releaser.release(m_list2);
2083}
2084
2085enum SwitchKind {
2086 SwitchUnset = 0,
2087 SwitchNumber = 1,
2088 SwitchString = 2,
2089 SwitchNeither = 3
2090};
2091
2092static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2093{
2094 for (; list; list = list->getNext()) {
2095 ExpressionNode* clauseExpression = list->getClause()->expr();
2096 literalVector.append(clauseExpression);
2097 if (clauseExpression->isNumber()) {
2098 double value = static_cast<NumberNode*>(clauseExpression)->value();
2099 if ((typeForTable & ~SwitchNumber) || !JSImmediate::from(value)) {
2100 typeForTable = SwitchNeither;
2101 break;
2102 }
2103 int32_t intVal = static_cast<int32_t>(value);
2104 ASSERT(intVal == value);
2105 if (intVal < min_num)
2106 min_num = intVal;
2107 if (intVal > max_num)
2108 max_num = intVal;
2109 typeForTable = SwitchNumber;
2110 continue;
2111 }
2112 if (clauseExpression->isString()) {
2113 if (typeForTable & ~SwitchString) {
2114 typeForTable = SwitchNeither;
2115 break;
2116 }
2117 const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
2118 if (singleCharacterSwitch &= value.size() == 1) {
2119 int32_t intVal = value.rep()->data()[0];
2120 if (intVal < min_num)
2121 min_num = intVal;
2122 if (intVal > max_num)
2123 max_num = intVal;
2124 }
2125 typeForTable = SwitchString;
2126 continue;
2127 }
2128 typeForTable = SwitchNeither;
2129 break;
2130 }
2131}
2132
2133SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2134{
2135 SwitchKind typeForTable = SwitchUnset;
2136 bool singleCharacterSwitch = true;
2137
2138 processClauseList(m_list1.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2139 processClauseList(m_list2.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2140
2141 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2142 return SwitchInfo::SwitchNone;
2143
2144 if (typeForTable == SwitchNumber) {
2145 int32_t range = max_num - min_num;
2146 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2147 return SwitchInfo::SwitchImmediate;
2148 return SwitchInfo::SwitchNone;
2149 }
2150
2151 ASSERT(typeForTable == SwitchString);
2152
2153 if (singleCharacterSwitch) {
2154 int32_t range = max_num - min_num;
2155 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2156 return SwitchInfo::SwitchCharacter;
2157 }
2158
2159 return SwitchInfo::SwitchString;
2160}
2161
2162RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2163{
2164 RefPtr<Label> defaultLabel;
2165 Vector<RefPtr<Label>, 8> labelVector;
2166 Vector<ExpressionNode*, 8> literalVector;
2167 int32_t min_num = std::numeric_limits<int32_t>::max();
2168 int32_t max_num = std::numeric_limits<int32_t>::min();
2169 SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
2170
2171 if (switchType != SwitchInfo::SwitchNone) {
2172 // Prepare the various labels
2173 for (uint32_t i = 0; i < literalVector.size(); i++)
2174 labelVector.append(generator.newLabel());
2175 defaultLabel = generator.newLabel();
2176 generator.beginSwitch(switchExpression, switchType);
2177 } else {
2178 // Setup jumps
2179 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2180 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2181 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2182 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2183 labelVector.append(generator.newLabel());
2184 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2185 }
2186
2187 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2188 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2189 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2190 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2191 labelVector.append(generator.newLabel());
2192 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2193 }
2194 defaultLabel = generator.newLabel();
2195 generator.emitJump(defaultLabel.get());
2196 }
2197
2198 RegisterID* result = 0;
2199
2200 size_t i = 0;
2201 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2202 generator.emitLabel(labelVector[i++].get());
2203 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2204 }
2205
2206 if (m_defaultClause) {
2207 generator.emitLabel(defaultLabel.get());
2208 result = statementListEmitCode(m_defaultClause->children(), generator, dst);
2209 }
2210
2211 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2212 generator.emitLabel(labelVector[i++].get());
2213 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2214 }
2215 if (!m_defaultClause)
2216 generator.emitLabel(defaultLabel.get());
2217
2218 ASSERT(i == labelVector.size());
2219 if (switchType != SwitchInfo::SwitchNone) {
2220 ASSERT(labelVector.size() == literalVector.size());
2221 generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2222 }
2223 return result;
2224}
2225
2226// ------------------------------ SwitchNode -----------------------------------
2227
2228SwitchNode::~SwitchNode()
2229{
2230 NodeReleaser::releaseAllNodes(this);
2231}
2232
2233void SwitchNode::releaseNodes(NodeReleaser& releaser)
2234{
2235 releaser.release(m_expr);
2236 releaser.release(m_block);
2237}
2238
2239RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2240{
2241 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
2242
2243 RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2244 RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2245
2246 generator.emitLabel(scope->breakTarget());
2247 return r1;
2248}
2249
2250// ------------------------------ LabelNode ------------------------------------
2251
2252LabelNode::~LabelNode()
2253{
2254 NodeReleaser::releaseAllNodes(this);
2255}
2256
2257void LabelNode::releaseNodes(NodeReleaser& releaser)
2258{
2259 releaser.release(m_statement);
2260}
2261
2262RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2263{
2264 if (generator.breakTarget(m_name))
2265 return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
2266
2267 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2268 RegisterID* r0 = generator.emitNode(dst, m_statement.get());
2269
2270 generator.emitLabel(scope->breakTarget());
2271 return r0;
2272}
2273
2274// ------------------------------ ThrowNode ------------------------------------
2275
2276ThrowNode::~ThrowNode()
2277{
2278 NodeReleaser::releaseAllNodes(this);
2279}
2280
2281void ThrowNode::releaseNodes(NodeReleaser& releaser)
2282{
2283 releaser.release(m_expr);
2284}
2285
2286RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2287{
2288 if (dst == ignoredResult())
2289 dst = 0;
2290 RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
2291 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
2292 generator.emitThrow(expr.get());
2293 return dst;
2294}
2295
2296// ------------------------------ TryNode --------------------------------------
2297
2298TryNode::~TryNode()
2299{
2300 NodeReleaser::releaseAllNodes(this);
2301}
2302
2303void TryNode::releaseNodes(NodeReleaser& releaser)
2304{
2305 releaser.release(m_tryBlock);
2306 releaser.release(m_catchBlock);
2307 releaser.release(m_finallyBlock);
2308}
2309
2310RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2311{
2312 RefPtr<Label> tryStartLabel = generator.newLabel();
2313 RefPtr<Label> tryEndLabel = generator.newLabel();
2314 RefPtr<Label> finallyStart;
2315 RefPtr<RegisterID> finallyReturnAddr;
2316 if (m_finallyBlock) {
2317 finallyStart = generator.newLabel();
2318 finallyReturnAddr = generator.newTemporary();
2319 generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
2320 }
2321 generator.emitLabel(tryStartLabel.get());
2322 generator.emitNode(dst, m_tryBlock.get());
2323 generator.emitLabel(tryEndLabel.get());
2324
2325 if (m_catchBlock) {
2326 RefPtr<Label> handlerEndLabel = generator.newLabel();
2327 generator.emitJump(handlerEndLabel.get());
2328 RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
2329 generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
2330 generator.emitNode(dst, m_catchBlock.get());
2331 generator.emitPopScope();
2332 generator.emitLabel(handlerEndLabel.get());
2333 }
2334
2335 if (m_finallyBlock) {
2336 generator.popFinallyContext();
2337 // there may be important registers live at the time we jump
2338 // to a finally block (such as for a return or throw) so we
2339 // ref the highest register ever used as a conservative
2340 // approach to not clobbering anything important
2341 RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
2342 RefPtr<Label> finallyEndLabel = generator.newLabel();
2343 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2344 // Use a label to record the subtle fact that sret will return to the
2345 // next instruction. sret is the only way to jump without an explicit label.
2346 generator.emitLabel(generator.newLabel().get());
2347 generator.emitJump(finallyEndLabel.get());
2348
2349 // Finally block for exception path
2350 RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
2351 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2352 // Use a label to record the subtle fact that sret will return to the
2353 // next instruction. sret is the only way to jump without an explicit label.
2354 generator.emitLabel(generator.newLabel().get());
2355 generator.emitThrow(tempExceptionRegister.get());
2356
2357 // emit the finally block itself
2358 generator.emitLabel(finallyStart.get());
2359 generator.emitNode(dst, m_finallyBlock.get());
2360 generator.emitSubroutineReturn(finallyReturnAddr.get());
2361
2362 generator.emitLabel(finallyEndLabel.get());
2363 }
2364
2365 return dst;
2366}
2367
2368// ------------------------------ ParameterNode -----------------------------
2369
2370ParameterNode::~ParameterNode()
2371{
2372 NodeReleaser::releaseAllNodes(this);
2373}
2374
2375void ParameterNode::releaseNodes(NodeReleaser& releaser)
2376{
2377 releaser.release(m_next);
2378}
2379
2380// -----------------------------ScopeNodeData ---------------------------
2381
2382ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
2383 : m_numConstants(numConstants)
2384{
2385 if (varStack)
2386 m_varStack = *varStack;
2387 if (funcStack)
2388 m_functionStack = *funcStack;
2389 if (children)
2390 children->releaseContentsIntoVector(m_children);
2391}
2392
2393// ------------------------------ ScopeNode -----------------------------
2394
2395ScopeNode::ScopeNode(JSGlobalData* globalData)
2396 : StatementNode(globalData)
2397 , m_features(NoFeatures)
2398{
2399#if ENABLE(OPCODE_SAMPLING)
2400 globalData->interpreter->sampler()->notifyOfScope(this);
2401#endif
2402}
2403
2404ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
2405 : StatementNode(globalData)
2406 , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
2407 , m_features(features)
2408 , m_source(source)
2409{
2410#if ENABLE(OPCODE_SAMPLING)
2411 globalData->interpreter->sampler()->notifyOfScope(this);
2412#endif
2413}
2414
2415ScopeNode::~ScopeNode()
2416{
2417 NodeReleaser::releaseAllNodes(this);
2418}
2419
2420void ScopeNode::releaseNodes(NodeReleaser& releaser)
2421{
2422 if (!m_data)
2423 return;
2424 size_t size = m_data->m_children.size();
2425 for (size_t i = 0; i < size; ++i)
2426 releaser.release(m_data->m_children[i]);
2427}
2428
2429// ------------------------------ ProgramNode -----------------------------
2430
2431ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2432 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2433{
2434}
2435
2436ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2437{
2438 return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
2439}
2440
2441// ------------------------------ EvalNode -----------------------------
2442
2443EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2444 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2445{
2446}
2447
2448RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2449{
2450 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2451
2452 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2453 generator.emitLoad(dstRegister.get(), jsUndefined());
2454 statementListEmitCode(children(), generator, dstRegister.get());
2455
2456 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2457 generator.emitEnd(dstRegister.get());
2458 return 0;
2459}
2460
2461void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
2462{
2463 ScopeChain scopeChain(scopeChainNode);
2464 JSGlobalObject* globalObject = scopeChain.globalObject();
2465
2466 m_code.set(new EvalCodeBlock(this, globalObject, source().provider()));
2467
2468 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable, m_code.get());
2469 generator.generate();
2470
2471 // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
2472 // so the entire ScopeNodeData cannot be destoyed.
2473 children().clear();
2474}
2475
2476EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2477{
2478 return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
2479}
2480
2481// ------------------------------ FunctionBodyNode -----------------------------
2482
2483FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
2484 : ScopeNode(globalData)
2485 , m_parameters(0)
2486 , m_parameterCount(0)
2487 , m_refCount(0)
2488{
2489}
2490
2491FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2492 : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
2493 , m_parameters(0)
2494 , m_parameterCount(0)
2495 , m_refCount(0)
2496{
2497}
2498
2499FunctionBodyNode::~FunctionBodyNode()
2500{
2501 ASSERT(!m_refCount);
2502 fastFree(m_parameters);
2503}
2504
2505void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
2506{
2507 Vector<Identifier> parameters;
2508 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
2509 parameters.append(parameter->ident());
2510 size_t count = parameters.size();
2511
2512 setSource(source);
2513 finishParsing(parameters.releaseBuffer(), count);
2514}
2515
2516void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
2517{
2518 ASSERT(!source().isNull());
2519 m_parameters = parameters;
2520 m_parameterCount = parameterCount;
2521}
2522
2523void FunctionBodyNode::mark()
2524{
2525 if (m_code)
2526 m_code->mark();
2527}
2528
2529FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
2530{
2531 return new FunctionBodyNode(globalData);
2532}
2533
2534FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2535{
2536 return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
2537}
2538
2539void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
2540{
2541 // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
2542 // calling Parser::parse<FunctionBodyNode>().
2543 if (!data())
2544 scopeChainNode->globalData->parser->reparse(scopeChainNode->globalData, this);
2545 ASSERT(data());
2546
2547 ScopeChain scopeChain(scopeChainNode);
2548 JSGlobalObject* globalObject = scopeChain.globalObject();
2549
2550 m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2551
2552 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable, m_code.get());
2553 generator.generate();
2554
2555 destroyData();
2556}
2557
2558RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2559{
2560 generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
2561 statementListEmitCode(children(), generator, ignoredResult());
2562 if (!children().size() || !children().last()->isReturnNode()) {
2563 RegisterID* r0 = generator.emitLoad(0, jsUndefined());
2564 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2565 generator.emitReturn(r0);
2566 }
2567 return 0;
2568}
2569
2570RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2571{
2572 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2573
2574 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2575 generator.emitLoad(dstRegister.get(), jsUndefined());
2576 statementListEmitCode(children(), generator, dstRegister.get());
2577
2578 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2579 generator.emitEnd(dstRegister.get());
2580 return 0;
2581}
2582
2583void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
2584{
2585 ScopeChain scopeChain(scopeChainNode);
2586 JSGlobalObject* globalObject = scopeChain.globalObject();
2587
2588 m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
2589
2590 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
2591 generator.generate();
2592
2593 destroyData();
2594}
2595
2596UString FunctionBodyNode::paramString() const
2597{
2598 UString s("");
2599 for (size_t pos = 0; pos < m_parameterCount; ++pos) {
2600 if (!s.isEmpty())
2601 s += ", ";
2602 s += parameters()[pos].ustring();
2603 }
2604
2605 return s;
2606}
2607
2608Identifier* FunctionBodyNode::copyParameters()
2609{
2610 Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
2611 VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
2612 return parameters;
2613}
2614
2615// ------------------------------ FuncDeclNode ---------------------------------
2616
2617FuncDeclNode::~FuncDeclNode()
2618{
2619 NodeReleaser::releaseAllNodes(this);
2620}
2621
2622void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
2623{
2624 releaser.release(m_parameter);
2625 releaser.release(m_body);
2626}
2627
2628JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2629{
2630 return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2631}
2632
2633RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
2634{
2635 return dst;
2636}
2637
2638// ------------------------------ FuncExprNode ---------------------------------
2639
2640FuncExprNode::~FuncExprNode()
2641{
2642 NodeReleaser::releaseAllNodes(this);
2643}
2644
2645void FuncExprNode::releaseNodes(NodeReleaser& releaser)
2646{
2647 releaser.release(m_parameter);
2648 releaser.release(m_body);
2649}
2650
2651RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2652{
2653 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2654}
2655
2656JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2657{
2658 JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2659
2660 /*
2661 The Identifier in a FunctionExpression can be referenced from inside
2662 the FunctionExpression's FunctionBody to allow the function to call
2663 itself recursively. However, unlike in a FunctionDeclaration, the
2664 Identifier in a FunctionExpression cannot be referenced from and
2665 does not affect the scope enclosing the FunctionExpression.
2666 */
2667
2668 if (!m_ident.isNull()) {
2669 JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete);
2670 func->scope().push(functionScopeObject);
2671 }
2672
2673 return func;
2674}
2675
2676} // namespace JSC
Note: See TracBrowser for help on using the repository browser.