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 #ifndef QT_BUILD_SCRIPT_LIB
1429     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1430 #endif
1431     if (m_expr->hasConditionContextCodegen())
1432         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
1433     else {
1434         RegisterID* cond = generator.emitNode(m_expr);
1435         generator.emitJumpIfTrue(cond, topOfLoop.get());
1436     }
1437 
1438     generator.emitLabel(scope->breakTarget());
1439     return result.get();
1440 }
1441 
1442 // ------------------------------ WhileNode ------------------------------------
1443 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1444 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1445 {
1446     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1447 
1448 #ifdef QT_BUILD_SCRIPT_LIB
1449     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1450 #endif
1451     generator.emitJump(scope->continueTarget());
1452 
1453     RefPtr<Label> topOfLoop = generator.newLabel();
1454     generator.emitLabel(topOfLoop.get());
1455 
1456     generator.emitNode(dst, m_statement);
1457 
1458     generator.emitLabel(scope->continueTarget());
1459 #ifndef QT_BUILD_SCRIPT_LIB
1460     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1461 #endif
1462 
1463     if (m_expr->hasConditionContextCodegen())
1464         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
1465     else {
1466         RegisterID* cond = generator.emitNode(m_expr);
1467         generator.emitJumpIfTrue(cond, topOfLoop.get());
1468     }
1469 
1470     generator.emitLabel(scope->breakTarget());
1471 
1472     // FIXME: This should return the last statement executed so that it can be returned as a Completion
1473     return 0;
1474 }
1475 
1476 // ------------------------------ ForNode --------------------------------------
1477 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1478 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1479 {
1480     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1481 
1482     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1483 
1484     if (m_expr1)
1485         generator.emitNode(generator.ignoredResult(), m_expr1);
1486 
1487     RefPtr<Label> condition = generator.newLabel();
1488     generator.emitJump(condition.get());
1489 
1490     RefPtr<Label> topOfLoop = generator.newLabel();
1491     generator.emitLabel(topOfLoop.get());
1492 
1493     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
1494 
1495     generator.emitLabel(scope->continueTarget());
1496 #ifndef QT_BUILD_SCRIPT_LIB
1497     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1498 #endif
1499     if (m_expr3)
1500         generator.emitNode(generator.ignoredResult(), m_expr3);
1501 
1502     generator.emitLabel(condition.get());
1503     if (m_expr2) {
1504         if (m_expr2->hasConditionContextCodegen())
1505             generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), false);
1506         else {
1507             RegisterID* cond = generator.emitNode(m_expr2);
1508             generator.emitJumpIfTrue(cond, topOfLoop.get());
1509         }
1510     } else
1511         generator.emitJump(topOfLoop.get());
1512 
1513     generator.emitLabel(scope->breakTarget());
1514     return result.get();
1515 }
1516 
1517 // ------------------------------ ForInNode ------------------------------------
1518 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1519 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1520 {
1521     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1522 
1523     if (!m_lexpr->isLocation())
1524         return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
1525 
1526     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1527 
1528     if (m_init)
1529         generator.emitNode(generator.ignoredResult(), m_init);
1530 
1531     RefPtr<RegisterID> base = generator.newTemporary();
1532     generator.emitNode(base.get(), m_expr);
1533     RefPtr<RegisterID> i = generator.newTemporary();
1534     RefPtr<RegisterID> size = generator.newTemporary();
1535     RefPtr<RegisterID> expectedSubscript;
1536     RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget());
1537     generator.emitJump(scope->continueTarget());
1538 
1539     RefPtr<Label> loopStart = generator.newLabel();
1540     generator.emitLabel(loopStart.get());
1541 
1542     RegisterID* propertyName;
1543     bool optimizedForinAccess = false;
1544     if (m_lexpr->isResolveNode()) {
1545         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
1546         propertyName = generator.registerFor(ident);
1547         if (!propertyName) {
1548             propertyName = generator.newTemporary();
1549             RefPtr<RegisterID> protect = propertyName;
1550             RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1551 
1552             generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1553             generator.emitPutById(base, ident, propertyName);
1554         } else {
1555             expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName);
1556             generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName);
1557             optimizedForinAccess = true;
1558         }
1559     } else if (m_lexpr->isDotAccessorNode()) {
1560         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
1561         const Identifier& ident = assignNode->identifier();
1562         propertyName = generator.newTemporary();
1563         RefPtr<RegisterID> protect = propertyName;
1564         RegisterID* base = generator.emitNode(assignNode->base());
1565 
1566         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1567         generator.emitPutById(base, ident, propertyName);
1568     } else {
1569         ASSERT(m_lexpr->isBracketAccessorNode());
1570         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
1571         propertyName = generator.newTemporary();
1572         RefPtr<RegisterID> protect = propertyName;
1573         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1574         RegisterID* subscript = generator.emitNode(assignNode->subscript());
1575 
1576         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1577         generator.emitPutByVal(base.get(), subscript, propertyName);
1578     }
1579 
1580     generator.emitNode(dst, m_statement);
1581 
1582     if (optimizedForinAccess)
1583         generator.popOptimisedForIn();
1584 
1585     generator.emitLabel(scope->continueTarget());
1586     generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
1587 #ifndef QT_BUILD_SCRIPT_LIB
1588     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1589 #endif
1590     generator.emitLabel(scope->breakTarget());
1591     return dst;
1592 }
1593 
1594 // ------------------------------ ContinueNode ---------------------------------
1595 
1596 // ECMA 12.7
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1597 RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1598 {
1599     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1600 
1601     LabelScope* scope = generator.continueTarget(m_ident);
1602 
1603     if (!scope)
1604         return m_ident.isEmpty()
1605             ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
1606             : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1607 
1608     generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1609     return dst;
1610 }
1611 
1612 // ------------------------------ BreakNode ------------------------------------
1613 
1614 // ECMA 12.8
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1615 RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1616 {
1617     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1618 
1619     LabelScope* scope = generator.breakTarget(m_ident);
1620 
1621     if (!scope)
1622         return m_ident.isEmpty()
1623             ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
1624             : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1625 
1626     generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1627     return dst;
1628 }
1629 
1630 // ------------------------------ ReturnNode -----------------------------------
1631 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1632 RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1633 {
1634     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1635     if (generator.codeType() != FunctionCode)
1636         return emitThrowError(generator, SyntaxError, "Invalid return statement.");
1637 
1638     if (dst == generator.ignoredResult())
1639         dst = 0;
1640     RegisterID* r0 = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
1641     RefPtr<RegisterID> returnRegister;
1642     if (generator.scopeDepth()) {
1643         RefPtr<Label> l0 = generator.newLabel();
1644         if (generator.hasFinaliser() && !r0->isTemporary()) {
1645             returnRegister = generator.emitMove(generator.newTemporary(), r0);
1646             r0 = returnRegister.get();
1647         }
1648         generator.emitJumpScopes(l0.get(), 0);
1649         generator.emitLabel(l0.get());
1650     }
1651     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1652     return generator.emitReturn(r0);
1653 }
1654 
1655 // ------------------------------ WithNode -------------------------------------
1656 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1657 RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1658 {
1659     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1660 
1661     RefPtr<RegisterID> scope = generator.newTemporary();
1662     generator.emitNode(scope.get(), m_expr); // scope must be protected until popped
1663     generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
1664     generator.emitPushScope(scope.get());
1665     RegisterID* result = generator.emitNode(dst, m_statement);
1666     generator.emitPopScope();
1667     return result;
1668 }
1669 
1670 // ------------------------------ CaseClauseNode --------------------------------
1671 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1672 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1673 {
1674     if (m_statements)
1675         m_statements->emitBytecode(generator, dst);
1676 }
1677 
1678 // ------------------------------ CaseBlockNode --------------------------------
1679 
1680 enum SwitchKind {
1681     SwitchUnset = 0,
1682     SwitchNumber = 1,
1683     SwitchString = 2,
1684     SwitchNeither = 3
1685 };
1686 
processClauseList(ClauseListNode * list,Vector<ExpressionNode *,8> & literalVector,SwitchKind & typeForTable,bool & singleCharacterSwitch,int32_t & min_num,int32_t & max_num)1687 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
1688 {
1689     for (; list; list = list->getNext()) {
1690         ExpressionNode* clauseExpression = list->getClause()->expr();
1691         literalVector.append(clauseExpression);
1692         if (clauseExpression->isNumber()) {
1693             double value = static_cast<NumberNode*>(clauseExpression)->value();
1694             int32_t intVal = static_cast<int32_t>(value);
1695             if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
1696                 typeForTable = SwitchNeither;
1697                 break;
1698             }
1699             if (intVal < min_num)
1700                 min_num = intVal;
1701             if (intVal > max_num)
1702                 max_num = intVal;
1703             typeForTable = SwitchNumber;
1704             continue;
1705         }
1706         if (clauseExpression->isString()) {
1707             if (typeForTable & ~SwitchString) {
1708                 typeForTable = SwitchNeither;
1709                 break;
1710             }
1711             const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
1712             if (singleCharacterSwitch &= value.size() == 1) {
1713                 int32_t intVal = value.rep()->data()[0];
1714                 if (intVal < min_num)
1715                     min_num = intVal;
1716                 if (intVal > max_num)
1717                     max_num = intVal;
1718             }
1719             typeForTable = SwitchString;
1720             continue;
1721         }
1722         typeForTable = SwitchNeither;
1723         break;
1724     }
1725 }
1726 
tryOptimizedSwitch(Vector<ExpressionNode *,8> & literalVector,int32_t & min_num,int32_t & max_num)1727 SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
1728 {
1729     SwitchKind typeForTable = SwitchUnset;
1730     bool singleCharacterSwitch = true;
1731 
1732     processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
1733     processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
1734 
1735     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
1736         return SwitchInfo::SwitchNone;
1737 
1738     if (typeForTable == SwitchNumber) {
1739         int32_t range = max_num - min_num;
1740         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
1741             return SwitchInfo::SwitchImmediate;
1742         return SwitchInfo::SwitchNone;
1743     }
1744 
1745     ASSERT(typeForTable == SwitchString);
1746 
1747     if (singleCharacterSwitch) {
1748         int32_t range = max_num - min_num;
1749         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
1750             return SwitchInfo::SwitchCharacter;
1751     }
1752 
1753     return SwitchInfo::SwitchString;
1754 }
1755 
emitBytecodeForBlock(BytecodeGenerator & generator,RegisterID * switchExpression,RegisterID * dst)1756 RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
1757 {
1758     RefPtr<Label> defaultLabel;
1759     Vector<RefPtr<Label>, 8> labelVector;
1760     Vector<ExpressionNode*, 8> literalVector;
1761     int32_t min_num = std::numeric_limits<int32_t>::max();
1762     int32_t max_num = std::numeric_limits<int32_t>::min();
1763     SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
1764 
1765     if (switchType != SwitchInfo::SwitchNone) {
1766         // Prepare the various labels
1767         for (uint32_t i = 0; i < literalVector.size(); i++)
1768             labelVector.append(generator.newLabel());
1769         defaultLabel = generator.newLabel();
1770         generator.beginSwitch(switchExpression, switchType);
1771     } else {
1772         // Setup jumps
1773         for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
1774             RefPtr<RegisterID> clauseVal = generator.newTemporary();
1775             generator.emitNode(clauseVal.get(), list->getClause()->expr());
1776             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
1777             labelVector.append(generator.newLabel());
1778             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
1779         }
1780 
1781         for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
1782             RefPtr<RegisterID> clauseVal = generator.newTemporary();
1783             generator.emitNode(clauseVal.get(), list->getClause()->expr());
1784             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
1785             labelVector.append(generator.newLabel());
1786             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
1787         }
1788         defaultLabel = generator.newLabel();
1789         generator.emitJump(defaultLabel.get());
1790     }
1791 
1792     RegisterID* result = 0;
1793 
1794     size_t i = 0;
1795     for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
1796         generator.emitLabel(labelVector[i++].get());
1797         list->getClause()->emitBytecode(generator, dst);
1798     }
1799 
1800     if (m_defaultClause) {
1801         generator.emitLabel(defaultLabel.get());
1802         m_defaultClause->emitBytecode(generator, dst);
1803     }
1804 
1805     for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
1806         generator.emitLabel(labelVector[i++].get());
1807         list->getClause()->emitBytecode(generator, dst);
1808     }
1809     if (!m_defaultClause)
1810         generator.emitLabel(defaultLabel.get());
1811 
1812     ASSERT(i == labelVector.size());
1813     if (switchType != SwitchInfo::SwitchNone) {
1814         ASSERT(labelVector.size() == literalVector.size());
1815         generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
1816     }
1817     return result;
1818 }
1819 
1820 // ------------------------------ SwitchNode -----------------------------------
1821 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1822 RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1823 {
1824     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1825 
1826     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
1827 
1828     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1829     RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
1830 
1831     generator.emitLabel(scope->breakTarget());
1832     return r1;
1833 }
1834 
1835 // ------------------------------ LabelNode ------------------------------------
1836 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1837 RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1838 {
1839     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1840 
1841     if (generator.breakTarget(m_name))
1842         return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
1843 
1844     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
1845     RegisterID* r0 = generator.emitNode(dst, m_statement);
1846 
1847     generator.emitLabel(scope->breakTarget());
1848     return r0;
1849 }
1850 
1851 // ------------------------------ ThrowNode ------------------------------------
1852 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1853 RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1854 {
1855     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1856 
1857     if (dst == generator.ignoredResult())
1858         dst = 0;
1859     RefPtr<RegisterID> expr = generator.emitNode(m_expr);
1860     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1861     generator.emitThrow(expr.get());
1862     return 0;
1863 }
1864 
1865 // ------------------------------ TryNode --------------------------------------
1866 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1867 RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1868 {
1869     // NOTE: The catch and finally blocks must be labeled explicitly, so the
1870     // optimizer knows they may be jumped to from anywhere.
1871 
1872 #ifndef QT_BUILD_SCRIPT_LIB
1873     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1874 #endif
1875 
1876     RefPtr<Label> tryStartLabel = generator.newLabel();
1877     RefPtr<Label> finallyStart;
1878     RefPtr<RegisterID> finallyReturnAddr;
1879     if (m_finallyBlock) {
1880         finallyStart = generator.newLabel();
1881         finallyReturnAddr = generator.newTemporary();
1882         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
1883     }
1884 
1885     generator.emitLabel(tryStartLabel.get());
1886     generator.emitNode(dst, m_tryBlock);
1887 
1888     if (m_catchBlock) {
1889         RefPtr<Label> catchEndLabel = generator.newLabel();
1890 
1891         // Normal path: jump over the catch block.
1892         generator.emitJump(catchEndLabel.get());
1893 
1894         // Uncaught exception path: the catch block.
1895         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
1896         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
1897         if (m_catchHasEval) {
1898             RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
1899             generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
1900             generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
1901             generator.emitPushScope(exceptionRegister.get());
1902         } else
1903             generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
1904         generator.emitNode(dst, m_catchBlock);
1905         generator.emitPopScope();
1906         generator.emitLabel(catchEndLabel.get());
1907     }
1908 
1909     if (m_finallyBlock) {
1910         generator.popFinallyContext();
1911         // there may be important registers live at the time we jump
1912         // to a finally block (such as for a return or throw) so we
1913         // ref the highest register ever used as a conservative
1914         // approach to not clobbering anything important
1915         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
1916         RefPtr<Label> finallyEndLabel = generator.newLabel();
1917 
1918         // Normal path: invoke the finally block, then jump over it.
1919         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1920         generator.emitJump(finallyEndLabel.get());
1921 
1922         // Uncaught exception path: invoke the finally block, then re-throw the exception.
1923         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
1924         RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
1925         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1926         generator.emitThrow(tempExceptionRegister.get());
1927 
1928         // The finally block.
1929         generator.emitLabel(finallyStart.get());
1930         generator.emitNode(dst, m_finallyBlock);
1931         generator.emitSubroutineReturn(finallyReturnAddr.get());
1932 
1933         generator.emitLabel(finallyEndLabel.get());
1934     }
1935 
1936     return dst;
1937 }
1938 
1939 // ------------------------------ ScopeNode -----------------------------
1940 
emitStatementsBytecode(BytecodeGenerator & generator,RegisterID * dst)1941 inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
1942 {
1943     if (m_data->m_statements)
1944         m_data->m_statements->emitBytecode(generator, dst);
1945 }
1946 
1947 // ------------------------------ ProgramNode -----------------------------
1948 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1949 RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1950 {
1951     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1952 
1953     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1954     generator.emitLoad(dstRegister.get(), jsUndefined());
1955     emitStatementsBytecode(generator, dstRegister.get());
1956 
1957     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1958     generator.emitEnd(dstRegister.get());
1959     return 0;
1960 }
1961 
1962 // ------------------------------ EvalNode -----------------------------
1963 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1964 RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1965 {
1966     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1967 
1968     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1969     generator.emitLoad(dstRegister.get(), jsUndefined());
1970     emitStatementsBytecode(generator, dstRegister.get());
1971 
1972     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1973     generator.emitEnd(dstRegister.get());
1974     return 0;
1975 }
1976 
1977 // ------------------------------ FunctionBodyNode -----------------------------
1978 
emitBytecode(BytecodeGenerator & generator,RegisterID *)1979 RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1980 {
1981     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
1982     emitStatementsBytecode(generator, generator.ignoredResult());
1983     StatementNode* singleStatement = this->singleStatement();
1984     if (singleStatement && singleStatement->isBlock()) {
1985         StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
1986         if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
1987             return 0;
1988     }
1989 
1990     RegisterID* r0 = generator.emitLoad(0, jsUndefined());
1991     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1992     generator.emitReturn(r0);
1993     return 0;
1994 }
1995 
1996 // ------------------------------ FuncDeclNode ---------------------------------
1997 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)1998 RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1999 {
2000     if (dst == generator.ignoredResult())
2001         dst = 0;
2002     return dst;
2003 }
2004 
2005 // ------------------------------ FuncExprNode ---------------------------------
2006 
emitBytecode(BytecodeGenerator & generator,RegisterID * dst)2007 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2008 {
2009     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2010 }
2011 
2012 } // namespace JSC
2013