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