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