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