• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 *  Copyright (C) 2007 Maks Orlovich
7 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8 *
9 *  This library is free software; you can redistribute it and/or
10 *  modify it under the terms of the GNU Library General Public
11 *  License as published by the Free Software Foundation; either
12 *  version 2 of the License, or (at your option) any later version.
13 *
14 *  This library is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 *  Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Library General Public License
20 *  along with this library; see the file COPYING.LIB.  If not, write to
21 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25 
26 #include "config.h"
27 #include "Nodes.h"
28 #include "NodeConstructors.h"
29 
30 #include "BytecodeGenerator.h"
31 #include "CallFrame.h"
32 #include "Debugger.h"
33 #include "JIT.h"
34 #include "JSFunction.h"
35 #include "JSGlobalObject.h"
36 #include "JSStaticScopeObject.h"
37 #include "LabelScope.h"
38 #include "Lexer.h"
39 #include "Operations.h"
40 #include "Parser.h"
41 #include "PropertyNameArray.h"
42 #include "RegExpObject.h"
43 #include "SamplingTool.h"
44 #include <wtf/Assertions.h>
45 #include <wtf/RefCountedLeakCounter.h>
46 #include <wtf/Threading.h>
47 
48 using namespace WTF;
49 
50 namespace JSC {
51 
52 /*
53     Details of the emitBytecode function.
54 
55     Return value: The register holding the production's value.
56              dst: An optional parameter specifying the most efficient destination at
57                   which to store the production's value. The callee must honor dst.
58 
59     The dst argument provides for a crude form of copy propagation. For example,
60 
61         x = 1
62 
63     becomes
64 
65         load r[x], 1
66 
67     instead of
68 
69         load r0, 1
70         mov r[x], r0
71 
72     because the assignment node, "x =", passes r[x] as dst to the number node, "1".
73 */
74 
75 // ------------------------------ ThrowableExpressionData --------------------------------
76 
substitute(UString & string,const UString & substring)77 static void substitute(UString& string, const UString& substring)
78 {
79     int position = string.find("%s");
80     ASSERT(position != -1);
81     string = makeString(string.substr(0, position), substring, string.substr(position + 2));
82 }
83 
emitThrowError(BytecodeGenerator & generator,ErrorType type,const char * message)84 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message)
85 {
86     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
87     RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
88     generator.emitThrow(exception);
89     return exception;
90 }
91 
emitThrowError(BytecodeGenerator & generator,ErrorType type,const char * messageTemplate,const UString & label)92 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const UString& label)
93 {
94     UString message = messageTemplate;
95     substitute(message, label);
96     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
97     RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
98     generator.emitThrow(exception);
99     return exception;
100 }
101 
emitThrowError(BytecodeGenerator & generator,ErrorType type,const char * messageTemplate,const Identifier & label)102 inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const Identifier& label)
103 {
104     return emitThrowError(generator, type, messageTemplate, label.ustring());
105 }
106 
107 // ------------------------------ NullNode -------------------------------------
108 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)109 RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
110 {
111     if (dst == generator.ignoredResult())
112         return 0;
113     return generator.emitLoad(dst, jsNull());
114 }
115 
116 // ------------------------------ BooleanNode ----------------------------------
117 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)118 RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
119 {
120     if (dst == generator.ignoredResult())
121         return 0;
122     return generator.emitLoad(dst, m_value);
123 }
124 
125 // ------------------------------ NumberNode -----------------------------------
126 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)127 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
128 {
129     if (dst == generator.ignoredResult())
130         return 0;
131     return generator.emitLoad(dst, m_value);
132 }
133 
134 // ------------------------------ StringNode -----------------------------------
135 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)136 RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
137 {
138     if (dst == generator.ignoredResult())
139         return 0;
140     return generator.emitLoad(dst, m_value);
141 }
142 
143 // ------------------------------ RegExpNode -----------------------------------
144 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)145 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
146 {
147     RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring());
148     if (!regExp->isValid())
149         return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage());
150     if (dst == generator.ignoredResult())
151         return 0;
152     return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
153 }
154 
155 // ------------------------------ ThisNode -------------------------------------
156 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)157 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
158 {
159     if (dst == generator.ignoredResult())
160         return 0;
161     return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
162 }
163 
164 // ------------------------------ ResolveNode ----------------------------------
165 
isPure(BytecodeGenerator & generator) const166 bool ResolveNode::isPure(BytecodeGenerator& generator) const
167 {
168     return generator.isLocal(m_ident);
169 }
170 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)171 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
172 {
173     if (RegisterID* local = generator.registerFor(m_ident)) {
174         if (dst == generator.ignoredResult())
175             return 0;
176         return generator.moveToDestinationIfNeeded(dst, local);
177     }
178 
179     generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0);
180     return generator.emitResolve(generator.finalDestination(dst), m_ident);
181 }
182 
183 // ------------------------------ ArrayNode ------------------------------------
184 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)185 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
186 {
187     // FIXME: Should we put all of this code into emitNewArray?
188 
189     unsigned length = 0;
190     ElementNode* firstPutElement;
191     for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
192         if (firstPutElement->elision())
193             break;
194         ++length;
195     }
196 
197     if (!firstPutElement && !m_elision)
198         return generator.emitNewArray(generator.finalDestination(dst), m_element);
199 
200     RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element);
201 
202     for (ElementNode* n = firstPutElement; n; n = n->next()) {
203         RegisterID* value = generator.emitNode(n->value());
204         length += n->elision();
205         generator.emitPutByIndex(array.get(), length++, value);
206     }
207 
208     if (m_elision) {
209         RegisterID* value = generator.emitLoad(0, jsNumber(generator.globalData(), m_elision + length));
210         generator.emitPutById(array.get(), generator.propertyNames().length, value);
211     }
212 
213     return generator.moveToDestinationIfNeeded(dst, array.get());
214 }
215 
isSimpleArray() const216 bool ArrayNode::isSimpleArray() const
217 {
218     if (m_elision || m_optional)
219         return false;
220     for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
221         if (ptr->elision())
222             return false;
223     }
224     return true;
225 }
226 
toArgumentList(JSGlobalData * globalData) const227 ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData) const
228 {
229     ASSERT(!m_elision && !m_optional);
230     ElementNode* ptr = m_element;
231     if (!ptr)
232         return 0;
233     ArgumentListNode* head = new (globalData) ArgumentListNode(globalData, ptr->value());
234     ArgumentListNode* tail = head;
235     ptr = ptr->next();
236     for (; ptr; ptr = ptr->next()) {
237         ASSERT(!ptr->elision());
238         tail = new (globalData) ArgumentListNode(globalData, tail, ptr->value());
239     }
240     return head;
241 }
242 
243 // ------------------------------ ObjectLiteralNode ----------------------------
244 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)245 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
246 {
247      if (!m_list) {
248          if (dst == generator.ignoredResult())
249              return 0;
250          return generator.emitNewObject(generator.finalDestination(dst));
251      }
252      return generator.emitNode(dst, m_list);
253 }
254 
255 // ------------------------------ PropertyListNode -----------------------------
256 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)257 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
258 {
259     RefPtr<RegisterID> newObj = generator.tempDestination(dst);
260 
261     generator.emitNewObject(newObj.get());
262 
263     for (PropertyListNode* p = this; p; p = p->m_next) {
264         RegisterID* value = generator.emitNode(p->m_node->m_assign);
265 
266         switch (p->m_node->m_type) {
267             case PropertyNode::Constant: {
268                 generator.emitPutById(newObj.get(), p->m_node->name(), value);
269                 break;
270             }
271             case PropertyNode::Getter: {
272                 generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
273                 break;
274             }
275             case PropertyNode::Setter: {
276                 generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
277                 break;
278             }
279             default:
280                 ASSERT_NOT_REACHED();
281         }
282     }
283 
284     return generator.moveToDestinationIfNeeded(dst, newObj.get());
285 }
286 
287 // ------------------------------ BracketAccessorNode --------------------------------
288 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)289 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
290 {
291     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
292     RegisterID* property = generator.emitNode(m_subscript);
293     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
294     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
295 }
296 
297 // ------------------------------ DotAccessorNode --------------------------------
298 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)299 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
300 {
301     RegisterID* base = generator.emitNode(m_base);
302     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
303     return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
304 }
305 
306 // ------------------------------ ArgumentListNode -----------------------------
307 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)308 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
309 {
310     ASSERT(m_expr);
311     return generator.emitNode(dst, m_expr);
312 }
313 
314 // ------------------------------ NewExprNode ----------------------------------
315 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)316 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
317 {
318     RefPtr<RegisterID> func = generator.emitNode(m_expr);
319     return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args, divot(), startOffset(), endOffset());
320 }
321 
322 // ------------------------------ EvalFunctionCallNode ----------------------------------
323 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)324 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
325 {
326     RefPtr<RegisterID> func = generator.tempDestination(dst);
327     RefPtr<RegisterID> thisRegister = generator.newTemporary();
328     generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
329     generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
330     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
331 }
332 
333 // ------------------------------ FunctionCallValueNode ----------------------------------
334 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)335 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
336 {
337     RefPtr<RegisterID> func = generator.emitNode(m_expr);
338     RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
339     return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
340 }
341 
342 // ------------------------------ FunctionCallResolveNode ----------------------------------
343 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)344 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
345 {
346     if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
347         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
348         return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
349     }
350 
351     int index = 0;
352     size_t depth = 0;
353     JSObject* globalObject = 0;
354     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
355         RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
356         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
357         return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
358     }
359 
360     RefPtr<RegisterID> func = generator.newTemporary();
361     RefPtr<RegisterID> thisRegister = generator.newTemporary();
362     int identifierStart = divot() - startOffset();
363     generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
364     generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident);
365     return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
366 }
367 
368 // ------------------------------ FunctionCallBracketNode ----------------------------------
369 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)370 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
371 {
372     RefPtr<RegisterID> base = generator.emitNode(m_base);
373     RegisterID* property = generator.emitNode(m_subscript);
374     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
375     RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
376     RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
377     return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
378 }
379 
380 // ------------------------------ FunctionCallDotNode ----------------------------------
381 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)382 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
383 {
384     RefPtr<RegisterID> function = generator.tempDestination(dst);
385     RefPtr<RegisterID> thisRegister = generator.newTemporary();
386     generator.emitNode(thisRegister.get(), m_base);
387     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
388     generator.emitMethodCheck();
389     generator.emitGetById(function.get(), thisRegister.get(), m_ident);
390     return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
391 }
392 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)393 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
394 {
395     RefPtr<Label> realCall = generator.newLabel();
396     RefPtr<Label> end = generator.newLabel();
397     RefPtr<RegisterID> base = generator.emitNode(m_base);
398     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
399     RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
400     RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
401     generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
402     {
403         RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
404         RefPtr<RegisterID> thisRegister = generator.newTemporary();
405         ArgumentListNode* oldList = m_args->m_listNode;
406         if (m_args->m_listNode && m_args->m_listNode->m_expr) {
407             generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
408             m_args->m_listNode = m_args->m_listNode->m_next;
409         } else
410             generator.emitLoad(thisRegister.get(), jsNull());
411 
412         generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
413         generator.emitJump(end.get());
414         m_args->m_listNode = oldList;
415     }
416     generator.emitLabel(realCall.get());
417     {
418         RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
419         generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
420     }
421     generator.emitLabel(end.get());
422     return finalDestination.get();
423 }
424 
areTrivialApplyArguments(ArgumentsNode * args)425 static bool areTrivialApplyArguments(ArgumentsNode* args)
426 {
427     return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
428         || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
429 }
430 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)431 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
432 {
433     // A few simple cases can be trivially handled as ordinary function calls.
434     // function.apply(), function.apply(arg) -> identical to function.call
435     // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
436     bool mayBeCall = areTrivialApplyArguments(m_args);
437 
438     RefPtr<Label> realCall = generator.newLabel();
439     RefPtr<Label> end = generator.newLabel();
440     RefPtr<RegisterID> base = generator.emitNode(m_base);
441     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
442     RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
443     RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
444     generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
445     {
446         if (mayBeCall) {
447             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
448             RefPtr<RegisterID> thisRegister = generator.newTemporary();
449             ArgumentListNode* oldList = m_args->m_listNode;
450             if (m_args->m_listNode && m_args->m_listNode->m_expr) {
451                 generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
452                 m_args->m_listNode = m_args->m_listNode->m_next;
453                 if (m_args->m_listNode) {
454                     ASSERT(m_args->m_listNode->m_expr->isSimpleArray());
455                     ASSERT(!m_args->m_listNode->m_next);
456                     m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_expr)->toArgumentList(generator.globalData());
457                 }
458             } else
459                 generator.emitLoad(thisRegister.get(), jsNull());
460             generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
461             m_args->m_listNode = oldList;
462         } else {
463             ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
464             RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
465             RefPtr<RegisterID> argsCountRegister = generator.newTemporary();
466             RefPtr<RegisterID> thisRegister = generator.newTemporary();
467             RefPtr<RegisterID> argsRegister = generator.newTemporary();
468             generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
469             ArgumentListNode* args = m_args->m_listNode->m_next;
470             bool isArgumentsApply = false;
471             if (args->m_expr->isResolveNode()) {
472                 ResolveNode* resolveNode = static_cast<ResolveNode*>(args->m_expr);
473                 isArgumentsApply = generator.willResolveToArguments(resolveNode->identifier());
474                 if (isArgumentsApply)
475                     generator.emitMove(argsRegister.get(), generator.uncheckedRegisterForArguments());
476             }
477             if (!isArgumentsApply)
478                 generator.emitNode(argsRegister.get(), args->m_expr);
479             while ((args = args->m_next))
480                 generator.emitNode(args->m_expr);
481 
482             generator.emitLoadVarargs(argsCountRegister.get(), argsRegister.get());
483             generator.emitCallVarargs(finalDestination.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset());
484         }
485         generator.emitJump(end.get());
486     }
487     generator.emitLabel(realCall.get());
488     {
489         RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
490         generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
491     }
492     generator.emitLabel(end.get());
493     return finalDestination.get();
494 }
495 
496 // ------------------------------ PostfixResolveNode ----------------------------------
497 
emitPreIncOrDec(BytecodeGenerator & generator,RegisterID * srcDst,Operator oper)498 static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
499 {
500     return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
501 }
502 
emitPostIncOrDec(BytecodeGenerator & generator,RegisterID * dst,RegisterID * srcDst,Operator oper)503 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
504 {
505     if (srcDst == dst)
506         return generator.emitToJSNumber(dst, srcDst);
507     return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
508 }
509 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)510 RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
511 {
512     if (RegisterID* local = generator.registerFor(m_ident)) {
513         if (generator.isLocalConstant(m_ident)) {
514             if (dst == generator.ignoredResult())
515                 return 0;
516             return generator.emitToJSNumber(generator.finalDestination(dst), local);
517         }
518 
519         if (dst == generator.ignoredResult())
520             return emitPreIncOrDec(generator, local, m_operator);
521         return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
522     }
523 
524     int index = 0;
525     size_t depth = 0;
526     JSObject* globalObject = 0;
527     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
528         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
529         RegisterID* oldValue;
530         if (dst == generator.ignoredResult()) {
531             oldValue = 0;
532             emitPreIncOrDec(generator, value.get(), m_operator);
533         } else {
534             oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
535         }
536         generator.emitPutScopedVar(depth, index, value.get(), globalObject);
537         return oldValue;
538     }
539 
540     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
541     RefPtr<RegisterID> value = generator.newTemporary();
542     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
543     RegisterID* oldValue;
544     if (dst == generator.ignoredResult()) {
545         oldValue = 0;
546         emitPreIncOrDec(generator, value.get(), m_operator);
547     } else {
548         oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
549     }
550     generator.emitPutById(base.get(), m_ident, value.get());
551     return oldValue;
552 }
553 
554 // ------------------------------ PostfixBracketNode ----------------------------------
555 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)556 RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
557 {
558     RefPtr<RegisterID> base = generator.emitNode(m_base);
559     RefPtr<RegisterID> property = generator.emitNode(m_subscript);
560 
561     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
562     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
563     RegisterID* oldValue;
564     if (dst == generator.ignoredResult()) {
565         oldValue = 0;
566         if (m_operator == OpPlusPlus)
567             generator.emitPreInc(value.get());
568         else
569             generator.emitPreDec(value.get());
570     } else {
571         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
572     }
573     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
574     generator.emitPutByVal(base.get(), property.get(), value.get());
575     return oldValue;
576 }
577 
578 // ------------------------------ PostfixDotNode ----------------------------------
579 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)580 RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
581 {
582     RefPtr<RegisterID> base = generator.emitNode(m_base);
583 
584     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
585     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
586     RegisterID* oldValue;
587     if (dst == generator.ignoredResult()) {
588         oldValue = 0;
589         if (m_operator == OpPlusPlus)
590             generator.emitPreInc(value.get());
591         else
592             generator.emitPreDec(value.get());
593     } else {
594         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
595     }
596     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
597     generator.emitPutById(base.get(), m_ident, value.get());
598     return oldValue;
599 }
600 
601 // ------------------------------ PostfixErrorNode -----------------------------------
602 
emitBytecode(BytecodeGenerator & generator,RegisterID *)603 RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
604 {
605     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus
606         ? "Postfix ++ operator applied to value that is not a reference."
607         : "Postfix -- operator applied to value that is not a reference.");
608 }
609 
610 // ------------------------------ DeleteResolveNode -----------------------------------
611 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)612 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
613 {
614     if (generator.registerFor(m_ident))
615         return generator.emitLoad(generator.finalDestination(dst), false);
616 
617     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
618     RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
619     return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
620 }
621 
622 // ------------------------------ DeleteBracketNode -----------------------------------
623 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)624 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
625 {
626     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
627     RegisterID* r1 = generator.emitNode(m_subscript);
628 
629     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
630     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
631 }
632 
633 // ------------------------------ DeleteDotNode -----------------------------------
634 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)635 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
636 {
637     RegisterID* r0 = generator.emitNode(m_base);
638 
639     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
640     return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
641 }
642 
643 // ------------------------------ DeleteValueNode -----------------------------------
644 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)645 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
646 {
647     generator.emitNode(generator.ignoredResult(), m_expr);
648 
649     // delete on a non-location expression ignores the value and returns true
650     return generator.emitLoad(generator.finalDestination(dst), true);
651 }
652 
653 // ------------------------------ VoidNode -------------------------------------
654 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)655 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
656 {
657     if (dst == generator.ignoredResult()) {
658         generator.emitNode(generator.ignoredResult(), m_expr);
659         return 0;
660     }
661     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
662     return generator.emitLoad(dst, jsUndefined());
663 }
664 
665 // ------------------------------ TypeOfValueNode -----------------------------------
666 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)667 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
668 {
669     if (RegisterID* local = generator.registerFor(m_ident)) {
670         if (dst == generator.ignoredResult())
671             return 0;
672         return generator.emitTypeOf(generator.finalDestination(dst), local);
673     }
674 
675     RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
676     generator.emitGetById(scratch.get(), scratch.get(), m_ident);
677     if (dst == generator.ignoredResult())
678         return 0;
679     return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
680 }
681 
682 // ------------------------------ TypeOfValueNode -----------------------------------
683 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)684 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
685 {
686     if (dst == generator.ignoredResult()) {
687         generator.emitNode(generator.ignoredResult(), m_expr);
688         return 0;
689     }
690     RefPtr<RegisterID> src = generator.emitNode(m_expr);
691     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
692 }
693 
694 // ------------------------------ PrefixResolveNode ----------------------------------
695 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)696 RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
697 {
698     if (RegisterID* local = generator.registerFor(m_ident)) {
699         if (generator.isLocalConstant(m_ident)) {
700             if (dst == generator.ignoredResult())
701                 return 0;
702             RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
703             return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
704         }
705 
706         emitPreIncOrDec(generator, local, m_operator);
707         return generator.moveToDestinationIfNeeded(dst, local);
708     }
709 
710     int index = 0;
711     size_t depth = 0;
712     JSObject* globalObject = 0;
713     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
714         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
715         emitPreIncOrDec(generator, propDst.get(), m_operator);
716         generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
717         return generator.moveToDestinationIfNeeded(dst, propDst.get());
718     }
719 
720     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
721     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
722     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
723     emitPreIncOrDec(generator, propDst.get(), m_operator);
724     generator.emitPutById(base.get(), m_ident, propDst.get());
725     return generator.moveToDestinationIfNeeded(dst, propDst.get());
726 }
727 
728 // ------------------------------ PrefixBracketNode ----------------------------------
729 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)730 RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
731 {
732     RefPtr<RegisterID> base = generator.emitNode(m_base);
733     RefPtr<RegisterID> property = generator.emitNode(m_subscript);
734     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
735 
736     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
737     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
738     if (m_operator == OpPlusPlus)
739         generator.emitPreInc(value);
740     else
741         generator.emitPreDec(value);
742     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
743     generator.emitPutByVal(base.get(), property.get(), value);
744     return generator.moveToDestinationIfNeeded(dst, propDst.get());
745 }
746 
747 // ------------------------------ PrefixDotNode ----------------------------------
748 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)749 RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
750 {
751     RefPtr<RegisterID> base = generator.emitNode(m_base);
752     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
753 
754     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
755     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
756     if (m_operator == OpPlusPlus)
757         generator.emitPreInc(value);
758     else
759         generator.emitPreDec(value);
760     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
761     generator.emitPutById(base.get(), m_ident, value);
762     return generator.moveToDestinationIfNeeded(dst, propDst.get());
763 }
764 
765 // ------------------------------ PrefixErrorNode -----------------------------------
766 
emitBytecode(BytecodeGenerator & generator,RegisterID *)767 RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
768 {
769     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus
770         ? "Prefix ++ operator applied to value that is not a reference."
771         : "Prefix -- operator applied to value that is not a reference.");
772 }
773 
774 // ------------------------------ Unary Operation Nodes -----------------------------------
775 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)776 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
777 {
778     RegisterID* src = generator.emitNode(m_expr);
779     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
780 }
781 
782 
783 // ------------------------------ LogicalNotNode -----------------------------------
784 
emitBytecodeInConditionContext(BytecodeGenerator & generator,Label * trueTarget,Label * falseTarget,bool fallThroughMeansTrue)785 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
786 {
787     ASSERT(expr()->hasConditionContextCodegen());
788 
789     // reverse the true and false targets
790     generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, !fallThroughMeansTrue);
791 }
792 
793 
794 // ------------------------------ Binary Operation Nodes -----------------------------------
795 
796 // BinaryOpNode::emitStrcat:
797 //
798 // This node generates an op_strcat operation.  This opcode can handle concatenation of three or
799 // more values, where we can determine a set of separate op_add operations would be operating on
800 // string values.
801 //
802 // This function expects to be operating on a graph of AST nodes looking something like this:
803 //
804 //     (a)...     (b)
805 //          \   /
806 //           (+)     (c)
807 //              \   /
808 //      [d]     ((+))
809 //         \    /
810 //          [+=]
811 //
812 // The assignment operation is optional, if it exists the register holding the value on the
813 // lefthand side of the assignment should be passing as the optional 'lhs' argument.
814 //
815 // The method should be called on the node at the root of the tree of regular binary add
816 // operations (marked in the diagram with a double set of parentheses).  This node must
817 // be performing a string concatenation (determined by statically detecting that at least
818 // one child must be a string).
819 //
820 // Since the minimum number of values being concatenated together is expected to be 3, if
821 // a lhs to a concatenating assignment is not provided then the  root add should have at
822 // least one left child that is also an add that can be determined to be operating on strings.
823 //
emitStrcat(BytecodeGenerator & generator,RegisterID * dst,RegisterID * lhs,ReadModifyResolveNode * emitExpressionInfoForMe)824 RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
825 {
826     ASSERT(isAdd());
827     ASSERT(resultDescriptor().definitelyIsString());
828 
829     // Create a list of expressions for all the adds in the tree of nodes we can convert into
830     // a string concatenation.  The rightmost node (c) is added first.  The rightmost node is
831     // added first, and the leftmost child is never added, so the vector produced for the
832     // example above will be [ c, b ].
833     Vector<ExpressionNode*, 16> reverseExpressionList;
834     reverseExpressionList.append(m_expr2);
835 
836     // Examine the left child of the add.  So long as this is a string add, add its right-child
837     // to the list, and keep processing along the left fork.
838     ExpressionNode* leftMostAddChild = m_expr1;
839     while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
840         reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
841         leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
842     }
843 
844     Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
845 
846     // If there is an assignment, allocate a temporary to hold the lhs after conversion.
847     // We could possibly avoid this (the lhs is converted last anyway, we could let the
848     // op_strcat node handle its conversion if required).
849     if (lhs)
850         temporaryRegisters.append(generator.newTemporary());
851 
852     // Emit code for the leftmost node ((a) in the example).
853     temporaryRegisters.append(generator.newTemporary());
854     RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
855     generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
856 
857     // Note on ordering of conversions:
858     //
859     // We maintain the same ordering of conversions as we would see if the concatenations
860     // was performed as a sequence of adds (otherwise this optimization could change
861     // behaviour should an object have been provided a valueOf or toString method).
862     //
863     // Considering the above example, the sequnce of execution is:
864     //     * evaluate operand (a)
865     //     * evaluate operand (b)
866     //     * convert (a) to primitive   <-  (this would be triggered by the first add)
867     //     * convert (b) to primitive   <-  (ditto)
868     //     * evaluate operand (c)
869     //     * convert (c) to primitive   <-  (this would be triggered by the second add)
870     // And optionally, if there is an assignment:
871     //     * convert (d) to primitive   <-  (this would be triggered by the assigning addition)
872     //
873     // As such we do not plant an op to convert the leftmost child now.  Instead, use
874     // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
875     // once the second node has been generated.  However, if the leftmost child is an
876     // immediate we can trivially determine that no conversion will be required.
877     // If this is the case
878     if (leftMostAddChild->isString())
879         leftMostAddChildTempRegister = 0;
880 
881     while (reverseExpressionList.size()) {
882         ExpressionNode* node = reverseExpressionList.last();
883         reverseExpressionList.removeLast();
884 
885         // Emit the code for the current node.
886         temporaryRegisters.append(generator.newTemporary());
887         generator.emitNode(temporaryRegisters.last().get(), node);
888 
889         // On the first iteration of this loop, when we first reach this point we have just
890         // generated the second node, which means it is time to convert the leftmost operand.
891         if (leftMostAddChildTempRegister) {
892             generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
893             leftMostAddChildTempRegister = 0; // Only do this once.
894         }
895         // Plant a conversion for this node, if necessary.
896         if (!node->isString())
897             generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
898     }
899     ASSERT(temporaryRegisters.size() >= 3);
900 
901     // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
902     // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
903     if (emitExpressionInfoForMe)
904         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
905 
906     // If there is an assignment convert the lhs now.  This will also copy lhs to
907     // the temporary register we allocated for it.
908     if (lhs)
909         generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
910 
911     return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
912 }
913 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)914 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
915 {
916     OpcodeID opcodeID = this->opcodeID();
917 
918     if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString())
919         return emitStrcat(generator, dst);
920 
921     if (opcodeID == op_neq) {
922         if (m_expr1->isNull() || m_expr2->isNull()) {
923             RefPtr<RegisterID> src = generator.tempDestination(dst);
924             generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
925             return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
926         }
927     }
928 
929     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
930     RegisterID* src2 = generator.emitNode(m_expr2);
931     return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
932 }
933 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)934 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
935 {
936     if (m_expr1->isNull() || m_expr2->isNull()) {
937         RefPtr<RegisterID> src = generator.tempDestination(dst);
938         generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
939         return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
940     }
941 
942     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
943     RegisterID* src2 = generator.emitNode(m_expr2);
944     return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
945 }
946 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)947 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
948 {
949     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
950     RegisterID* src2 = generator.emitNode(m_expr2);
951     return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
952 }
953 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)954 RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
955 {
956     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
957     RegisterID* src2 = generator.emitNode(m_expr2);
958     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
959 }
960 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)961 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
962 {
963     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
964     RegisterID* src2 = generator.emitNode(m_expr2);
965     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
966     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
967 }
968 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)969 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
970 {
971     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
972     RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
973 
974     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
975     generator.emitGetByIdExceptionInfo(op_instanceof);
976     RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
977 
978     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
979     return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
980 }
981 
982 // ------------------------------ LogicalOpNode ----------------------------
983 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)984 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
985 {
986     RefPtr<RegisterID> temp = generator.tempDestination(dst);
987     RefPtr<Label> target = generator.newLabel();
988 
989     generator.emitNode(temp.get(), m_expr1);
990     if (m_operator == OpLogicalAnd)
991         generator.emitJumpIfFalse(temp.get(), target.get());
992     else
993         generator.emitJumpIfTrue(temp.get(), target.get());
994     generator.emitNode(temp.get(), m_expr2);
995     generator.emitLabel(target.get());
996 
997     return generator.moveToDestinationIfNeeded(dst, temp.get());
998 }
999 
emitBytecodeInConditionContext(BytecodeGenerator & generator,Label * trueTarget,Label * falseTarget,bool fallThroughMeansTrue)1000 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
1001 {
1002     if (m_expr1->hasConditionContextCodegen()) {
1003         RefPtr<Label> afterExpr1 = generator.newLabel();
1004         if (m_operator == OpLogicalAnd)
1005             generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, true);
1006         else
1007             generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), false);
1008         generator.emitLabel(afterExpr1.get());
1009     } else {
1010         RegisterID* temp = generator.emitNode(m_expr1);
1011         if (m_operator == OpLogicalAnd)
1012             generator.emitJumpIfFalse(temp, falseTarget);
1013         else
1014             generator.emitJumpIfTrue(temp, trueTarget);
1015     }
1016 
1017     if (m_expr2->hasConditionContextCodegen())
1018         generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMeansTrue);
1019     else {
1020         RegisterID* temp = generator.emitNode(m_expr2);
1021         if (fallThroughMeansTrue)
1022             generator.emitJumpIfFalse(temp, falseTarget);
1023         else
1024             generator.emitJumpIfTrue(temp, trueTarget);
1025     }
1026 }
1027 
1028 // ------------------------------ ConditionalNode ------------------------------
1029 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1030 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1031 {
1032     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1033     RefPtr<Label> beforeElse = generator.newLabel();
1034     RefPtr<Label> afterElse = generator.newLabel();
1035 
1036     if (m_logical->hasConditionContextCodegen()) {
1037         RefPtr<Label> beforeThen = generator.newLabel();
1038         generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), true);
1039         generator.emitLabel(beforeThen.get());
1040     } else {
1041         RegisterID* cond = generator.emitNode(m_logical);
1042         generator.emitJumpIfFalse(cond, beforeElse.get());
1043     }
1044 
1045     generator.emitNode(newDst.get(), m_expr1);
1046     generator.emitJump(afterElse.get());
1047 
1048     generator.emitLabel(beforeElse.get());
1049     generator.emitNode(newDst.get(), m_expr2);
1050 
1051     generator.emitLabel(afterElse.get());
1052 
1053     return newDst.get();
1054 }
1055 
1056 // ------------------------------ ReadModifyResolveNode -----------------------------------
1057 
1058 // FIXME: should this be moved to be a method on BytecodeGenerator?
emitReadModifyAssignment(BytecodeGenerator & generator,RegisterID * dst,RegisterID * src1,ExpressionNode * m_right,Operator oper,OperandTypes types,ReadModifyResolveNode * emitExpressionInfoForMe=0)1059 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
1060 {
1061     OpcodeID opcodeID;
1062     switch (oper) {
1063         case OpMultEq:
1064             opcodeID = op_mul;
1065             break;
1066         case OpDivEq:
1067             opcodeID = op_div;
1068             break;
1069         case OpPlusEq:
1070             if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
1071                 return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
1072             opcodeID = op_add;
1073             break;
1074         case OpMinusEq:
1075             opcodeID = op_sub;
1076             break;
1077         case OpLShift:
1078             opcodeID = op_lshift;
1079             break;
1080         case OpRShift:
1081             opcodeID = op_rshift;
1082             break;
1083         case OpURShift:
1084             opcodeID = op_urshift;
1085             break;
1086         case OpAndEq:
1087             opcodeID = op_bitand;
1088             break;
1089         case OpXOrEq:
1090             opcodeID = op_bitxor;
1091             break;
1092         case OpOrEq:
1093             opcodeID = op_bitor;
1094             break;
1095         case OpModEq:
1096             opcodeID = op_mod;
1097             break;
1098         default:
1099             ASSERT_NOT_REACHED();
1100             return dst;
1101     }
1102 
1103     RegisterID* src2 = generator.emitNode(m_right);
1104 
1105     // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1106     // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1107     if (emitExpressionInfoForMe)
1108         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
1109 
1110     return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1111 }
1112 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1113 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1114 {
1115     if (RegisterID* local = generator.registerFor(m_ident)) {
1116         if (generator.isLocalConstant(m_ident)) {
1117             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1118         }
1119 
1120         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1121             RefPtr<RegisterID> result = generator.newTemporary();
1122             generator.emitMove(result.get(), local);
1123             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1124             generator.emitMove(local, result.get());
1125             return generator.moveToDestinationIfNeeded(dst, result.get());
1126         }
1127 
1128         RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1129         return generator.moveToDestinationIfNeeded(dst, result);
1130     }
1131 
1132     int index = 0;
1133     size_t depth = 0;
1134     JSObject* globalObject = 0;
1135     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1136         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
1137         RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1138         generator.emitPutScopedVar(depth, index, result, globalObject);
1139         return result;
1140     }
1141 
1142     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
1143     generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
1144     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
1145     RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
1146     return generator.emitPutById(base.get(), m_ident, result);
1147 }
1148 
1149 // ------------------------------ AssignResolveNode -----------------------------------
1150 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1151 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1152 {
1153     if (RegisterID* local = generator.registerFor(m_ident)) {
1154         if (generator.isLocalConstant(m_ident))
1155             return generator.emitNode(dst, m_right);
1156 
1157         RegisterID* result = generator.emitNode(local, m_right);
1158         return generator.moveToDestinationIfNeeded(dst, result);
1159     }
1160 
1161     int index = 0;
1162     size_t depth = 0;
1163     JSObject* globalObject = 0;
1164     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1165         if (dst == generator.ignoredResult())
1166             dst = 0;
1167         RegisterID* value = generator.emitNode(dst, m_right);
1168         generator.emitPutScopedVar(depth, index, value, globalObject);
1169         return value;
1170     }
1171 
1172     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1173     if (dst == generator.ignoredResult())
1174         dst = 0;
1175     RegisterID* value = generator.emitNode(dst, m_right);
1176     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1177     return generator.emitPutById(base.get(), m_ident, value);
1178 }
1179 
1180 // ------------------------------ AssignDotNode -----------------------------------
1181 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1182 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1183 {
1184     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1185     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1186     RegisterID* result = generator.emitNode(value.get(), m_right);
1187     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1188     generator.emitPutById(base.get(), m_ident, result);
1189     return generator.moveToDestinationIfNeeded(dst, result);
1190 }
1191 
1192 // ------------------------------ ReadModifyDotNode -----------------------------------
1193 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1194 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1195 {
1196     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1197 
1198     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1199     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1200     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1201 
1202     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1203     return generator.emitPutById(base.get(), m_ident, updatedValue);
1204 }
1205 
1206 // ------------------------------ AssignErrorNode -----------------------------------
1207 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1208 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1209 {
1210     return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
1211 }
1212 
1213 // ------------------------------ AssignBracketNode -----------------------------------
1214 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1215 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1216 {
1217     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1218     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
1219     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1220     RegisterID* result = generator.emitNode(value.get(), m_right);
1221 
1222     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1223     generator.emitPutByVal(base.get(), property.get(), result);
1224     return generator.moveToDestinationIfNeeded(dst, result);
1225 }
1226 
1227 // ------------------------------ ReadModifyBracketNode -----------------------------------
1228 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1229 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1230 {
1231     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1232     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
1233 
1234     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1235     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1236     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1237 
1238     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1239     generator.emitPutByVal(base.get(), property.get(), updatedValue);
1240 
1241     return updatedValue;
1242 }
1243 
1244 // ------------------------------ CommaNode ------------------------------------
1245 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1246 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1247 {
1248     ASSERT(m_expressions.size() > 1);
1249     for (size_t i = 0; i < m_expressions.size() - 1; i++)
1250         generator.emitNode(generator.ignoredResult(), m_expressions[i]);
1251     return generator.emitNode(dst, m_expressions.last());
1252 }
1253 
1254 // ------------------------------ ConstDeclNode ------------------------------------
1255 
emitCodeSingle(BytecodeGenerator & generator)1256 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1257 {
1258     if (RegisterID* local = generator.constRegisterFor(m_ident)) {
1259         if (!m_init)
1260             return local;
1261 
1262         return generator.emitNode(local, m_init);
1263     }
1264 
1265     if (generator.codeType() != EvalCode) {
1266         if (m_init)
1267             return generator.emitNode(m_init);
1268         else
1269             return generator.emitResolve(generator.newTemporary(), m_ident);
1270     }
1271     // FIXME: While this code should only be hit in eval code, it will potentially
1272     // assign to the wrong base if m_ident exists in an intervening dynamic scope.
1273     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1274     RegisterID* value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
1275     return generator.emitPutById(base.get(), m_ident, value);
1276 }
1277 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1278 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1279 {
1280     RegisterID* result = 0;
1281     for (ConstDeclNode* n = this; n; n = n->m_next)
1282         result = n->emitCodeSingle(generator);
1283 
1284     return result;
1285 }
1286 
1287 // ------------------------------ ConstStatementNode -----------------------------
1288 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1289 RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1290 {
1291     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1292     return generator.emitNode(m_next);
1293 }
1294 
1295 // ------------------------------ SourceElements -------------------------------
1296 
1297 
lastStatement() const1298 inline StatementNode* SourceElements::lastStatement() const
1299 {
1300     size_t size = m_statements.size();
1301     return size ? m_statements[size - 1] : 0;
1302 }
1303 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1304 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1305 {
1306     size_t size = m_statements.size();
1307     for (size_t i = 0; i < size; ++i)
1308         generator.emitNode(dst, m_statements[i]);
1309 }
1310 
1311 // ------------------------------ BlockNode ------------------------------------
1312 
lastStatement() const1313 inline StatementNode* BlockNode::lastStatement() const
1314 {
1315     return m_statements ? m_statements->lastStatement() : 0;
1316 }
1317 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1318 RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1319 {
1320     if (m_statements)
1321         m_statements->emitBytecode(generator, dst);
1322     return 0;
1323 }
1324 
1325 // ------------------------------ EmptyStatementNode ---------------------------
1326 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1327 RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1328 {
1329     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1330     return dst;
1331 }
1332 
1333 // ------------------------------ DebuggerStatementNode ---------------------------
1334 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1335 RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1336 {
1337     generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1338     return dst;
1339 }
1340 
1341 // ------------------------------ ExprStatementNode ----------------------------
1342 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1343 RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1344 {
1345     ASSERT(m_expr);
1346     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1347     return generator.emitNode(dst, m_expr);
1348 }
1349 
1350 // ------------------------------ VarStatementNode ----------------------------
1351 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1352 RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1353 {
1354     ASSERT(m_expr);
1355     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1356     return generator.emitNode(m_expr);
1357 }
1358 
1359 // ------------------------------ IfNode ---------------------------------------
1360 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1361 RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1362 {
1363     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1364 
1365     RefPtr<Label> afterThen = generator.newLabel();
1366 
1367     if (m_condition->hasConditionContextCodegen()) {
1368         RefPtr<Label> beforeThen = generator.newLabel();
1369         generator.emitNodeInConditionContext(m_condition, beforeThen.get(), afterThen.get(), true);
1370         generator.emitLabel(beforeThen.get());
1371     } else {
1372         RegisterID* cond = generator.emitNode(m_condition);
1373         generator.emitJumpIfFalse(cond, afterThen.get());
1374     }
1375 
1376     generator.emitNode(dst, m_ifBlock);
1377     generator.emitLabel(afterThen.get());
1378 
1379     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1380     return 0;
1381 }
1382 
1383 // ------------------------------ IfElseNode ---------------------------------------
1384 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1385 RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1386 {
1387     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1388 
1389     RefPtr<Label> beforeElse = generator.newLabel();
1390     RefPtr<Label> afterElse = generator.newLabel();
1391 
1392     if (m_condition->hasConditionContextCodegen()) {
1393         RefPtr<Label> beforeThen = generator.newLabel();
1394         generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), true);
1395         generator.emitLabel(beforeThen.get());
1396     } else {
1397         RegisterID* cond = generator.emitNode(m_condition);
1398         generator.emitJumpIfFalse(cond, beforeElse.get());
1399     }
1400 
1401     generator.emitNode(dst, m_ifBlock);
1402     generator.emitJump(afterElse.get());
1403 
1404     generator.emitLabel(beforeElse.get());
1405 
1406     generator.emitNode(dst, m_elseBlock);
1407 
1408     generator.emitLabel(afterElse.get());
1409 
1410     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1411     return 0;
1412 }
1413 
1414 // ------------------------------ DoWhileNode ----------------------------------
1415 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1416 RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1417 {
1418     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1419 
1420     RefPtr<Label> topOfLoop = generator.newLabel();
1421     generator.emitLabel(topOfLoop.get());
1422 
1423     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1424 
1425     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
1426 
1427     generator.emitLabel(scope->continueTarget());
1428     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1429     if (m_expr->hasConditionContextCodegen())
1430         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
1431     else {
1432         RegisterID* cond = generator.emitNode(m_expr);
1433         generator.emitJumpIfTrue(cond, topOfLoop.get());
1434     }
1435 
1436     generator.emitLabel(scope->breakTarget());
1437     return result.get();
1438 }
1439 
1440 // ------------------------------ WhileNode ------------------------------------
1441 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1442 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1443 {
1444     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1445 
1446     generator.emitJump(scope->continueTarget());
1447 
1448     RefPtr<Label> topOfLoop = generator.newLabel();
1449     generator.emitLabel(topOfLoop.get());
1450 
1451     generator.emitNode(dst, m_statement);
1452 
1453     generator.emitLabel(scope->continueTarget());
1454     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1455 
1456     if (m_expr->hasConditionContextCodegen())
1457         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
1458     else {
1459         RegisterID* cond = generator.emitNode(m_expr);
1460         generator.emitJumpIfTrue(cond, topOfLoop.get());
1461     }
1462 
1463     generator.emitLabel(scope->breakTarget());
1464 
1465     // FIXME: This should return the last statement executed so that it can be returned as a Completion
1466     return 0;
1467 }
1468 
1469 // ------------------------------ ForNode --------------------------------------
1470 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1471 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1472 {
1473     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1474 
1475     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1476 
1477     if (m_expr1)
1478         generator.emitNode(generator.ignoredResult(), m_expr1);
1479 
1480     RefPtr<Label> condition = generator.newLabel();
1481     generator.emitJump(condition.get());
1482 
1483     RefPtr<Label> topOfLoop = generator.newLabel();
1484     generator.emitLabel(topOfLoop.get());
1485 
1486     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
1487 
1488     generator.emitLabel(scope->continueTarget());
1489     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1490     if (m_expr3)
1491         generator.emitNode(generator.ignoredResult(), m_expr3);
1492 
1493     generator.emitLabel(condition.get());
1494     if (m_expr2) {
1495         if (m_expr2->hasConditionContextCodegen())
1496             generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), false);
1497         else {
1498             RegisterID* cond = generator.emitNode(m_expr2);
1499             generator.emitJumpIfTrue(cond, topOfLoop.get());
1500         }
1501     } else
1502         generator.emitJump(topOfLoop.get());
1503 
1504     generator.emitLabel(scope->breakTarget());
1505     return result.get();
1506 }
1507 
1508 // ------------------------------ ForInNode ------------------------------------
1509 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1510 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1511 {
1512     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1513 
1514     if (!m_lexpr->isLocation())
1515         return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
1516 
1517     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1518 
1519     if (m_init)
1520         generator.emitNode(generator.ignoredResult(), m_init);
1521 
1522     RefPtr<RegisterID> base = generator.newTemporary();
1523     generator.emitNode(base.get(), m_expr);
1524     RefPtr<RegisterID> i = generator.newTemporary();
1525     RefPtr<RegisterID> size = generator.newTemporary();
1526     RefPtr<RegisterID> expectedSubscript;
1527     RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget());
1528     generator.emitJump(scope->continueTarget());
1529 
1530     RefPtr<Label> loopStart = generator.newLabel();
1531     generator.emitLabel(loopStart.get());
1532 
1533     RegisterID* propertyName;
1534     bool optimizedForinAccess = false;
1535     if (m_lexpr->isResolveNode()) {
1536         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
1537         propertyName = generator.registerFor(ident);
1538         if (!propertyName) {
1539             propertyName = generator.newTemporary();
1540             RefPtr<RegisterID> protect = propertyName;
1541             RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1542 
1543             generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1544             generator.emitPutById(base, ident, propertyName);
1545         } else {
1546             expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName);
1547             generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName);
1548             optimizedForinAccess = true;
1549         }
1550     } else if (m_lexpr->isDotAccessorNode()) {
1551         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
1552         const Identifier& ident = assignNode->identifier();
1553         propertyName = generator.newTemporary();
1554         RefPtr<RegisterID> protect = propertyName;
1555         RegisterID* base = generator.emitNode(assignNode->base());
1556 
1557         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1558         generator.emitPutById(base, ident, propertyName);
1559     } else {
1560         ASSERT(m_lexpr->isBracketAccessorNode());
1561         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
1562         propertyName = generator.newTemporary();
1563         RefPtr<RegisterID> protect = propertyName;
1564         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1565         RegisterID* subscript = generator.emitNode(assignNode->subscript());
1566 
1567         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1568         generator.emitPutByVal(base.get(), subscript, propertyName);
1569     }
1570 
1571     generator.emitNode(dst, m_statement);
1572 
1573     if (optimizedForinAccess)
1574         generator.popOptimisedForIn();
1575 
1576     generator.emitLabel(scope->continueTarget());
1577     generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
1578     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1579     generator.emitLabel(scope->breakTarget());
1580     return dst;
1581 }
1582 
1583 // ------------------------------ ContinueNode ---------------------------------
1584 
1585 // ECMA 12.7
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1586 RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1587 {
1588     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1589 
1590     LabelScope* scope = generator.continueTarget(m_ident);
1591 
1592     if (!scope)
1593         return m_ident.isEmpty()
1594             ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
1595             : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1596 
1597     generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1598     return dst;
1599 }
1600 
1601 // ------------------------------ BreakNode ------------------------------------
1602 
1603 // ECMA 12.8
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1604 RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1605 {
1606     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1607 
1608     LabelScope* scope = generator.breakTarget(m_ident);
1609 
1610     if (!scope)
1611         return m_ident.isEmpty()
1612             ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
1613             : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1614 
1615     generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1616     return dst;
1617 }
1618 
1619 // ------------------------------ ReturnNode -----------------------------------
1620 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1621 RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1622 {
1623     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1624     if (generator.codeType() != FunctionCode)
1625         return emitThrowError(generator, SyntaxError, "Invalid return statement.");
1626 
1627     if (dst == generator.ignoredResult())
1628         dst = 0;
1629     RegisterID* r0 = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
1630     RefPtr<RegisterID> returnRegister;
1631     if (generator.scopeDepth()) {
1632         RefPtr<Label> l0 = generator.newLabel();
1633         if (generator.hasFinaliser() && !r0->isTemporary()) {
1634             returnRegister = generator.emitMove(generator.newTemporary(), r0);
1635             r0 = returnRegister.get();
1636         }
1637         generator.emitJumpScopes(l0.get(), 0);
1638         generator.emitLabel(l0.get());
1639     }
1640     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1641     return generator.emitReturn(r0);
1642 }
1643 
1644 // ------------------------------ WithNode -------------------------------------
1645 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1646 RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1647 {
1648     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1649 
1650     RefPtr<RegisterID> scope = generator.newTemporary();
1651     generator.emitNode(scope.get(), m_expr); // scope must be protected until popped
1652     generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
1653     generator.emitPushScope(scope.get());
1654     RegisterID* result = generator.emitNode(dst, m_statement);
1655     generator.emitPopScope();
1656     return result;
1657 }
1658 
1659 // ------------------------------ CaseClauseNode --------------------------------
1660 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1661 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1662 {
1663     if (m_statements)
1664         m_statements->emitBytecode(generator, dst);
1665 }
1666 
1667 // ------------------------------ CaseBlockNode --------------------------------
1668 
1669 enum SwitchKind {
1670     SwitchUnset = 0,
1671     SwitchNumber = 1,
1672     SwitchString = 2,
1673     SwitchNeither = 3
1674 };
1675 
processClauseList(ClauseListNode * list,Vector<ExpressionNode *,8> & literalVector,SwitchKind & typeForTable,bool & singleCharacterSwitch,int32_t & min_num,int32_t & max_num)1676 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
1677 {
1678     for (; list; list = list->getNext()) {
1679         ExpressionNode* clauseExpression = list->getClause()->expr();
1680         literalVector.append(clauseExpression);
1681         if (clauseExpression->isNumber()) {
1682             double value = static_cast<NumberNode*>(clauseExpression)->value();
1683             int32_t intVal = static_cast<int32_t>(value);
1684             if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
1685                 typeForTable = SwitchNeither;
1686                 break;
1687             }
1688             if (intVal < min_num)
1689                 min_num = intVal;
1690             if (intVal > max_num)
1691                 max_num = intVal;
1692             typeForTable = SwitchNumber;
1693             continue;
1694         }
1695         if (clauseExpression->isString()) {
1696             if (typeForTable & ~SwitchString) {
1697                 typeForTable = SwitchNeither;
1698                 break;
1699             }
1700             const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
1701             if (singleCharacterSwitch &= value.size() == 1) {
1702                 int32_t intVal = value.rep()->data()[0];
1703                 if (intVal < min_num)
1704                     min_num = intVal;
1705                 if (intVal > max_num)
1706                     max_num = intVal;
1707             }
1708             typeForTable = SwitchString;
1709             continue;
1710         }
1711         typeForTable = SwitchNeither;
1712         break;
1713     }
1714 }
1715 
tryOptimizedSwitch(Vector<ExpressionNode *,8> & literalVector,int32_t & min_num,int32_t & max_num)1716 SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
1717 {
1718     SwitchKind typeForTable = SwitchUnset;
1719     bool singleCharacterSwitch = true;
1720 
1721     processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
1722     processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
1723 
1724     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
1725         return SwitchInfo::SwitchNone;
1726 
1727     if (typeForTable == SwitchNumber) {
1728         int32_t range = max_num - min_num;
1729         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
1730             return SwitchInfo::SwitchImmediate;
1731         return SwitchInfo::SwitchNone;
1732     }
1733 
1734     ASSERT(typeForTable == SwitchString);
1735 
1736     if (singleCharacterSwitch) {
1737         int32_t range = max_num - min_num;
1738         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
1739             return SwitchInfo::SwitchCharacter;
1740     }
1741 
1742     return SwitchInfo::SwitchString;
1743 }
1744 
emitBytecodeForBlock(BytecodeGenerator & generator,RegisterID * switchExpression,RegisterID * dst)1745 RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
1746 {
1747     RefPtr<Label> defaultLabel;
1748     Vector<RefPtr<Label>, 8> labelVector;
1749     Vector<ExpressionNode*, 8> literalVector;
1750     int32_t min_num = std::numeric_limits<int32_t>::max();
1751     int32_t max_num = std::numeric_limits<int32_t>::min();
1752     SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
1753 
1754     if (switchType != SwitchInfo::SwitchNone) {
1755         // Prepare the various labels
1756         for (uint32_t i = 0; i < literalVector.size(); i++)
1757             labelVector.append(generator.newLabel());
1758         defaultLabel = generator.newLabel();
1759         generator.beginSwitch(switchExpression, switchType);
1760     } else {
1761         // Setup jumps
1762         for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
1763             RefPtr<RegisterID> clauseVal = generator.newTemporary();
1764             generator.emitNode(clauseVal.get(), list->getClause()->expr());
1765             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
1766             labelVector.append(generator.newLabel());
1767             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
1768         }
1769 
1770         for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
1771             RefPtr<RegisterID> clauseVal = generator.newTemporary();
1772             generator.emitNode(clauseVal.get(), list->getClause()->expr());
1773             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
1774             labelVector.append(generator.newLabel());
1775             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
1776         }
1777         defaultLabel = generator.newLabel();
1778         generator.emitJump(defaultLabel.get());
1779     }
1780 
1781     RegisterID* result = 0;
1782 
1783     size_t i = 0;
1784     for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
1785         generator.emitLabel(labelVector[i++].get());
1786         list->getClause()->emitBytecode(generator, dst);
1787     }
1788 
1789     if (m_defaultClause) {
1790         generator.emitLabel(defaultLabel.get());
1791         m_defaultClause->emitBytecode(generator, dst);
1792     }
1793 
1794     for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
1795         generator.emitLabel(labelVector[i++].get());
1796         list->getClause()->emitBytecode(generator, dst);
1797     }
1798     if (!m_defaultClause)
1799         generator.emitLabel(defaultLabel.get());
1800 
1801     ASSERT(i == labelVector.size());
1802     if (switchType != SwitchInfo::SwitchNone) {
1803         ASSERT(labelVector.size() == literalVector.size());
1804         generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
1805     }
1806     return result;
1807 }
1808 
1809 // ------------------------------ SwitchNode -----------------------------------
1810 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1811 RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1812 {
1813     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1814 
1815     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
1816 
1817     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1818     RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
1819 
1820     generator.emitLabel(scope->breakTarget());
1821     return r1;
1822 }
1823 
1824 // ------------------------------ LabelNode ------------------------------------
1825 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1826 RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1827 {
1828     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1829 
1830     if (generator.breakTarget(m_name))
1831         return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
1832 
1833     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
1834     RegisterID* r0 = generator.emitNode(dst, m_statement);
1835 
1836     generator.emitLabel(scope->breakTarget());
1837     return r0;
1838 }
1839 
1840 // ------------------------------ ThrowNode ------------------------------------
1841 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1842 RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1843 {
1844     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1845 
1846     if (dst == generator.ignoredResult())
1847         dst = 0;
1848     RefPtr<RegisterID> expr = generator.emitNode(m_expr);
1849     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1850     generator.emitThrow(expr.get());
1851     return 0;
1852 }
1853 
1854 // ------------------------------ TryNode --------------------------------------
1855 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1856 RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1857 {
1858     // NOTE: The catch and finally blocks must be labeled explicitly, so the
1859     // optimizer knows they may be jumped to from anywhere.
1860 
1861     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1862 
1863     RefPtr<Label> tryStartLabel = generator.newLabel();
1864     RefPtr<Label> finallyStart;
1865     RefPtr<RegisterID> finallyReturnAddr;
1866     if (m_finallyBlock) {
1867         finallyStart = generator.newLabel();
1868         finallyReturnAddr = generator.newTemporary();
1869         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
1870     }
1871 
1872     generator.emitLabel(tryStartLabel.get());
1873     generator.emitNode(dst, m_tryBlock);
1874 
1875     if (m_catchBlock) {
1876         RefPtr<Label> catchEndLabel = generator.newLabel();
1877 
1878         // Normal path: jump over the catch block.
1879         generator.emitJump(catchEndLabel.get());
1880 
1881         // Uncaught exception path: the catch block.
1882         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
1883         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
1884         if (m_catchHasEval) {
1885             RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
1886             generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
1887             generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
1888             generator.emitPushScope(exceptionRegister.get());
1889         } else
1890             generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
1891         generator.emitNode(dst, m_catchBlock);
1892         generator.emitPopScope();
1893         generator.emitLabel(catchEndLabel.get());
1894     }
1895 
1896     if (m_finallyBlock) {
1897         generator.popFinallyContext();
1898         // there may be important registers live at the time we jump
1899         // to a finally block (such as for a return or throw) so we
1900         // ref the highest register ever used as a conservative
1901         // approach to not clobbering anything important
1902         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
1903         RefPtr<Label> finallyEndLabel = generator.newLabel();
1904 
1905         // Normal path: invoke the finally block, then jump over it.
1906         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1907         generator.emitJump(finallyEndLabel.get());
1908 
1909         // Uncaught exception path: invoke the finally block, then re-throw the exception.
1910         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
1911         RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
1912         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1913         generator.emitThrow(tempExceptionRegister.get());
1914 
1915         // The finally block.
1916         generator.emitLabel(finallyStart.get());
1917         generator.emitNode(dst, m_finallyBlock);
1918         generator.emitSubroutineReturn(finallyReturnAddr.get());
1919 
1920         generator.emitLabel(finallyEndLabel.get());
1921     }
1922 
1923     return dst;
1924 }
1925 
1926 // ------------------------------ ScopeNode -----------------------------
1927 
emitStatementsBytecode(BytecodeGenerator & generator,RegisterID * dst)1928 inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
1929 {
1930     if (m_data->m_statements)
1931         m_data->m_statements->emitBytecode(generator, dst);
1932 }
1933 
1934 // ------------------------------ ProgramNode -----------------------------
1935 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1936 RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1937 {
1938     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1939 
1940     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1941     generator.emitLoad(dstRegister.get(), jsUndefined());
1942     emitStatementsBytecode(generator, dstRegister.get());
1943 
1944     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1945     generator.emitEnd(dstRegister.get());
1946     return 0;
1947 }
1948 
1949 // ------------------------------ EvalNode -----------------------------
1950 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1951 RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1952 {
1953     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1954 
1955     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1956     generator.emitLoad(dstRegister.get(), jsUndefined());
1957     emitStatementsBytecode(generator, dstRegister.get());
1958 
1959     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1960     generator.emitEnd(dstRegister.get());
1961     return 0;
1962 }
1963 
1964 // ------------------------------ FunctionBodyNode -----------------------------
1965 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1966 RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1967 {
1968     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
1969     emitStatementsBytecode(generator, generator.ignoredResult());
1970     StatementNode* singleStatement = this->singleStatement();
1971     if (singleStatement && singleStatement->isBlock()) {
1972         StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
1973         if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
1974             return 0;
1975     }
1976 
1977     RegisterID* r0 = generator.emitLoad(0, jsUndefined());
1978     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1979     generator.emitReturn(r0);
1980     return 0;
1981 }
1982 
1983 // ------------------------------ FuncDeclNode ---------------------------------
1984 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1985 RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1986 {
1987     if (dst == generator.ignoredResult())
1988         dst = 0;
1989     return dst;
1990 }
1991 
1992 // ------------------------------ FuncExprNode ---------------------------------
1993 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1994 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1995 {
1996     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
1997 }
1998 
1999 } // namespace JSC
2000