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