]> git.saurik.com Git - apple/javascriptcore.git/blob - bytecompiler/NodesCodegen.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecompiler / NodesCodegen.cpp
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, 2012, 2013, 2015 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 * Copyright (C) 2012 Igalia, S.L.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24 *
25 */
26
27 #include "config.h"
28 #include "Nodes.h"
29 #include "NodeConstructors.h"
30
31 #include "BuiltinNames.h"
32 #include "BytecodeGenerator.h"
33 #include "CallFrame.h"
34 #include "Debugger.h"
35 #include "JIT.h"
36 #include "JSFunction.h"
37 #include "JSGlobalObject.h"
38 #include "JSNameScope.h"
39 #include "JSONObject.h"
40 #include "LabelScope.h"
41 #include "Lexer.h"
42 #include "JSCInlines.h"
43 #include "JSTemplateRegistryKey.h"
44 #include "Parser.h"
45 #include "PropertyNameArray.h"
46 #include "RegExpCache.h"
47 #include "RegExpObject.h"
48 #include "SamplingTool.h"
49 #include "StackAlignment.h"
50 #include "TemplateRegistryKey.h"
51 #include <wtf/Assertions.h>
52 #include <wtf/RefCountedLeakCounter.h>
53 #include <wtf/Threading.h>
54
55 using namespace WTF;
56
57 namespace JSC {
58
59 /*
60 Details of the emitBytecode function.
61
62 Return value: The register holding the production's value.
63 dst: An optional parameter specifying the most efficient destination at
64 which to store the production's value. The callee must honor dst.
65
66 The dst argument provides for a crude form of copy propagation. For example,
67
68 x = 1
69
70 becomes
71
72 load r[x], 1
73
74 instead of
75
76 load r0, 1
77 mov r[x], r0
78
79 because the assignment node, "x =", passes r[x] as dst to the number node, "1".
80 */
81
82 void ExpressionNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
83 {
84 RegisterID* result = generator.emitNode(this);
85 if (fallThroughMode == FallThroughMeansTrue)
86 generator.emitJumpIfFalse(result, falseTarget);
87 else
88 generator.emitJumpIfTrue(result, trueTarget);
89 }
90
91 // ------------------------------ ThrowableExpressionData --------------------------------
92
93 RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message)
94 {
95 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
96 generator.emitThrowReferenceError(message);
97 return generator.newTemporary();
98 }
99
100 // ------------------------------ ConstantNode ----------------------------------
101
102 void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
103 {
104 TriState value = jsValue(generator).pureToBoolean();
105 if (value == MixedTriState)
106 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
107 else if (value == TrueTriState && fallThroughMode == FallThroughMeansFalse)
108 generator.emitJump(trueTarget);
109 else if (value == FalseTriState && fallThroughMode == FallThroughMeansTrue)
110 generator.emitJump(falseTarget);
111
112 // All other cases are unconditional fall-throughs, like "if (true)".
113 }
114
115 RegisterID* ConstantNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
116 {
117 if (dst == generator.ignoredResult())
118 return 0;
119 return generator.emitLoad(dst, jsValue(generator));
120 }
121
122 JSValue StringNode::jsValue(BytecodeGenerator& generator) const
123 {
124 return generator.addStringConstant(m_value);
125 }
126
127 // ------------------------------ NumberNode ----------------------------------
128
129 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
130 {
131 if (dst == generator.ignoredResult())
132 return nullptr;
133 return generator.emitLoad(dst, jsValue(generator), isIntegerNode() ? SourceCodeRepresentation::Integer : SourceCodeRepresentation::Double);
134 }
135
136 // ------------------------------ RegExpNode -----------------------------------
137
138 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
139 {
140 if (dst == generator.ignoredResult())
141 return 0;
142 return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string())));
143 }
144
145 // ------------------------------ ThisNode -------------------------------------
146
147 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
148 {
149 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived)
150 generator.emitTDZCheck(generator.thisRegister());
151
152 if (dst == generator.ignoredResult())
153 return 0;
154
155 RegisterID* result = generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
156 if (generator.vm()->typeProfiler()) {
157 generator.emitProfileType(generator.thisRegister(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
158 static const unsigned thisLength = 4;
159 generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + thisLength, -1));
160 }
161 return result;
162 }
163
164 // ------------------------------ SuperNode -------------------------------------
165
166 RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
167 {
168 if (dst == generator.ignoredResult())
169 return 0;
170
171 RegisterID callee;
172 callee.setIndex(JSStack::Callee);
173
174 RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
175 RefPtr<RegisterID> protoParent = generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
176 return generator.emitGetById(generator.finalDestination(dst), protoParent.get(), generator.propertyNames().constructor);
177 }
178
179 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator)
180 {
181 RegisterID callee;
182 callee.setIndex(JSStack::Callee);
183
184 RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
185 return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
186 }
187
188 // ------------------------------ ResolveNode ----------------------------------
189
190 bool ResolveNode::isPure(BytecodeGenerator& generator) const
191 {
192 return generator.variable(m_ident).offset().isStack();
193 }
194
195 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
196 {
197 Variable var = generator.variable(m_ident);
198 if (RegisterID* local = var.local()) {
199 if (dst == generator.ignoredResult())
200 return nullptr;
201 if (generator.vm()->typeProfiler()) {
202 generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
203 generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
204 }
205 return generator.moveToDestinationIfNeeded(dst, local);
206 }
207
208 JSTextPosition divot = m_start + m_ident.length();
209 generator.emitExpressionInfo(divot, m_start, divot);
210 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
211 RegisterID* finalDest = generator.finalDestination(dst);
212 RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
213 if (generator.vm()->typeProfiler()) {
214 generator.emitProfileType(finalDest, var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
215 generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
216 }
217 return result;
218 }
219
220 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
221 // ------------------------------ TemplateStringNode -----------------------------------
222
223 RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
224 {
225 if (dst == generator.ignoredResult())
226 return nullptr;
227 return generator.emitLoad(dst, JSValue(generator.addStringConstant(cooked())));
228 }
229
230 // ------------------------------ TemplateLiteralNode -----------------------------------
231
232 RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
233 {
234 if (!m_templateExpressions) {
235 TemplateStringNode* templateString = m_templateStrings->value();
236 ASSERT_WITH_MESSAGE(!m_templateStrings->next(), "Only one template element exists because there's no expression in a given template literal.");
237 return generator.emitNode(dst, templateString);
238 }
239
240 Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
241
242 TemplateStringListNode* templateString = m_templateStrings;
243 TemplateExpressionListNode* templateExpression = m_templateExpressions;
244 for (; templateExpression; templateExpression = templateExpression->next(), templateString = templateString->next()) {
245 // Evaluate TemplateString.
246 if (!templateString->value()->cooked().isEmpty()) {
247 temporaryRegisters.append(generator.newTemporary());
248 generator.emitNode(temporaryRegisters.last().get(), templateString->value());
249 }
250
251 // Evaluate Expression.
252 temporaryRegisters.append(generator.newTemporary());
253 generator.emitNode(temporaryRegisters.last().get(), templateExpression->value());
254 generator.emitToString(temporaryRegisters.last().get(), temporaryRegisters.last().get());
255 }
256
257 // Evaluate tail TemplateString.
258 if (!templateString->value()->cooked().isEmpty()) {
259 temporaryRegisters.append(generator.newTemporary());
260 generator.emitNode(temporaryRegisters.last().get(), templateString->value());
261 }
262
263 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
264 }
265
266 // ------------------------------ TaggedTemplateNode -----------------------------------
267
268 RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
269 {
270 ExpectedFunction expectedFunction = NoExpectedFunction;
271 RefPtr<RegisterID> tag = nullptr;
272 RefPtr<RegisterID> base = nullptr;
273 if (!m_tag->isLocation()) {
274 tag = generator.newTemporary();
275 tag = generator.emitNode(tag.get(), m_tag);
276 } else if (m_tag->isResolveNode()) {
277 ResolveNode* resolve = static_cast<ResolveNode*>(m_tag);
278 const Identifier& identifier = resolve->identifier();
279 expectedFunction = generator.expectedFunctionForIdentifier(identifier);
280
281 Variable var = generator.variable(identifier);
282 if (RegisterID* local = var.local())
283 tag = generator.emitMove(generator.newTemporary(), local);
284 else {
285 tag = generator.newTemporary();
286 base = generator.newTemporary();
287
288 JSTextPosition newDivot = divotStart() + identifier.length();
289 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
290 generator.moveToDestinationIfNeeded(base.get(), generator.emitResolveScope(base.get(), var));
291 generator.emitGetFromScope(tag.get(), base.get(), var, ThrowIfNotFound);
292 }
293 } else if (m_tag->isBracketAccessorNode()) {
294 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(m_tag);
295 base = generator.newTemporary();
296 base = generator.emitNode(base.get(), bracket->base());
297 RefPtr<RegisterID> property = generator.emitNode(bracket->subscript());
298 tag = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
299 } else {
300 ASSERT(m_tag->isDotAccessorNode());
301 DotAccessorNode* dot = static_cast<DotAccessorNode*>(m_tag);
302 base = generator.newTemporary();
303 base = generator.emitNode(base.get(), dot->base());
304 tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
305 }
306
307 RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(generator.newTemporary(), this);
308
309 unsigned expressionsCount = 0;
310 for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
311 ++expressionsCount;
312
313 CallArguments callArguments(generator, nullptr, 1 + expressionsCount);
314 if (base)
315 generator.emitMove(callArguments.thisRegister(), base.get());
316 else
317 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
318
319 unsigned argumentIndex = 0;
320 generator.emitMove(callArguments.argumentRegister(argumentIndex++), templateObject.get());
321 for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
322 generator.emitNode(callArguments.argumentRegister(argumentIndex++), templateExpression->value());
323
324 return generator.emitCall(generator.finalDestination(dst, tag.get()), tag.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
325 }
326 #endif
327
328 // ------------------------------ ArrayNode ------------------------------------
329
330 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
331 {
332 // FIXME: Should we put all of this code into emitNewArray?
333
334 unsigned length = 0;
335 ElementNode* firstPutElement;
336 for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
337 if (firstPutElement->elision() || firstPutElement->value()->isSpreadExpression())
338 break;
339 ++length;
340 }
341
342 if (!firstPutElement && !m_elision)
343 return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
344
345 RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
346 ElementNode* n = firstPutElement;
347 for (; n; n = n->next()) {
348 if (n->value()->isSpreadExpression())
349 goto handleSpread;
350 RegisterID* value = generator.emitNode(n->value());
351 length += n->elision();
352 generator.emitPutByIndex(array.get(), length++, value);
353 }
354
355 if (m_elision) {
356 RegisterID* value = generator.emitLoad(0, jsNumber(m_elision + length));
357 generator.emitPutById(array.get(), generator.propertyNames().length, value);
358 }
359
360 return generator.moveToDestinationIfNeeded(dst, array.get());
361
362 handleSpread:
363 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(length));
364 auto spreader = [this, array, index](BytecodeGenerator& generator, RegisterID* value)
365 {
366 generator.emitDirectPutByVal(array.get(), index.get(), value);
367 generator.emitInc(index.get());
368 };
369 for (; n; n = n->next()) {
370 if (n->elision())
371 generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(n->elision())), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
372 if (n->value()->isSpreadExpression()) {
373 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(n->value());
374 generator.emitEnumeration(spread, spread->expression(), spreader);
375 } else {
376 generator.emitDirectPutByVal(array.get(), index.get(), generator.emitNode(n->value()));
377 generator.emitInc(index.get());
378 }
379 }
380
381 if (m_elision) {
382 generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(m_elision)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
383 generator.emitPutById(array.get(), generator.propertyNames().length, index.get());
384 }
385 return generator.moveToDestinationIfNeeded(dst, array.get());
386 }
387
388 bool ArrayNode::isSimpleArray() const
389 {
390 if (m_elision || m_optional)
391 return false;
392 for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
393 if (ptr->elision())
394 return false;
395 }
396 return true;
397 }
398
399 ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNumber, int startPosition) const
400 {
401 ASSERT(!m_elision && !m_optional);
402 ElementNode* ptr = m_element;
403 if (!ptr)
404 return 0;
405 JSTokenLocation location;
406 location.line = lineNumber;
407 location.startOffset = startPosition;
408 ArgumentListNode* head = new (parserArena) ArgumentListNode(location, ptr->value());
409 ArgumentListNode* tail = head;
410 ptr = ptr->next();
411 for (; ptr; ptr = ptr->next()) {
412 ASSERT(!ptr->elision());
413 tail = new (parserArena) ArgumentListNode(location, tail, ptr->value());
414 }
415 return head;
416 }
417
418 // ------------------------------ ObjectLiteralNode ----------------------------
419
420 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
421 {
422 if (!m_list) {
423 if (dst == generator.ignoredResult())
424 return 0;
425 return generator.emitNewObject(generator.finalDestination(dst));
426 }
427 RefPtr<RegisterID> newObj = generator.emitNewObject(generator.tempDestination(dst));
428 generator.emitNode(newObj.get(), m_list);
429 return generator.moveToDestinationIfNeeded(dst, newObj.get());
430 }
431
432 // ------------------------------ PropertyListNode -----------------------------
433
434 static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject)
435 {
436 generator.emitPutById(function, generator.propertyNames().homeObjectPrivateName, homeObject);
437 }
438
439 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
440 {
441 // Fast case: this loop just handles regular value properties.
442 PropertyListNode* p = this;
443 for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next)
444 emitPutConstantProperty(generator, dst, *p->m_node);
445
446 // Were there any get/set properties?
447 if (p) {
448 // Build a list of getter/setter pairs to try to put them at the same time. If we encounter
449 // a computed property, just emit everything as that may override previous values.
450 bool hasComputedProperty = false;
451
452 typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
453 typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;
454 GetterSetterMap map;
455
456 // Build a map, pairing get/set values together.
457 for (PropertyListNode* q = p; q; q = q->m_next) {
458 PropertyNode* node = q->m_node;
459 if (node->m_type & PropertyNode::Computed) {
460 hasComputedProperty = true;
461 break;
462 }
463 if (node->m_type & PropertyNode::Constant)
464 continue;
465
466 // Duplicates are possible.
467 GetterSetterPair pair(node, static_cast<PropertyNode*>(nullptr));
468 GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair);
469 if (!result.isNewEntry) {
470 if (result.iterator->value.first->m_type == node->m_type)
471 result.iterator->value.first = node;
472 else
473 result.iterator->value.second = node;
474 }
475 }
476
477 // Iterate over the remaining properties in the list.
478 for (; p; p = p->m_next) {
479 PropertyNode* node = p->m_node;
480
481 // Handle regular values.
482 if (node->m_type & PropertyNode::Constant) {
483 emitPutConstantProperty(generator, dst, *node);
484 continue;
485 }
486
487 RegisterID* value = generator.emitNode(node->m_assign);
488 bool isClassProperty = node->needsSuperBinding();
489 if (isClassProperty)
490 emitPutHomeObject(generator, value, dst);
491
492 ASSERT(node->m_type & (PropertyNode::Getter | PropertyNode::Setter));
493
494 // This is a get/set property which may be overridden by a computed property later.
495 if (hasComputedProperty) {
496 if (node->m_type & PropertyNode::Getter)
497 generator.emitPutGetterById(dst, *node->name(), value);
498 else
499 generator.emitPutSetterById(dst, *node->name(), value);
500 continue;
501 }
502
503 // This is a get/set property pair.
504 GetterSetterMap::iterator it = map.find(node->name()->impl());
505 ASSERT(it != map.end());
506 GetterSetterPair& pair = it->value;
507
508 // Was this already generated as a part of its partner?
509 if (pair.second == node)
510 continue;
511
512 // Generate the paired node now.
513 RefPtr<RegisterID> getterReg;
514 RefPtr<RegisterID> setterReg;
515 RegisterID* secondReg = nullptr;
516
517 if (node->m_type & PropertyNode::Getter) {
518 getterReg = value;
519 if (pair.second) {
520 ASSERT(pair.second->m_type & PropertyNode::Setter);
521 setterReg = generator.emitNode(pair.second->m_assign);
522 secondReg = setterReg.get();
523 } else {
524 setterReg = generator.newTemporary();
525 generator.emitLoad(setterReg.get(), jsUndefined());
526 }
527 } else {
528 ASSERT(node->m_type & PropertyNode::Setter);
529 setterReg = value;
530 if (pair.second) {
531 ASSERT(pair.second->m_type & PropertyNode::Getter);
532 getterReg = generator.emitNode(pair.second->m_assign);
533 secondReg = getterReg.get();
534 } else {
535 getterReg = generator.newTemporary();
536 generator.emitLoad(getterReg.get(), jsUndefined());
537 }
538 }
539
540 ASSERT(!pair.second || isClassProperty == pair.second->needsSuperBinding());
541 if (isClassProperty && pair.second)
542 emitPutHomeObject(generator, secondReg, dst);
543
544 if (isClassProperty) {
545 RefPtr<RegisterID> propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node->name());
546 generator.emitCallDefineProperty(dst, propertyNameRegister.get(),
547 nullptr, getterReg.get(), setterReg.get(), BytecodeGenerator::PropertyConfigurable, m_position);
548 } else
549 generator.emitPutGetterSetter(dst, *node->name(), getterReg.get(), setterReg.get());
550 }
551 }
552
553 return dst;
554 }
555
556 void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node)
557 {
558 RefPtr<RegisterID> value = generator.emitNode(node.m_assign);
559 if (node.needsSuperBinding()) {
560 emitPutHomeObject(generator, value.get(), newObj);
561
562 RefPtr<RegisterID> propertyNameRegister;
563 if (node.name())
564 propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node.name());
565 else
566 propertyNameRegister = generator.emitNode(node.m_expression);
567
568 generator.emitCallDefineProperty(newObj, propertyNameRegister.get(),
569 value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
570 return;
571 }
572 if (const auto* identifier = node.name()) {
573 Optional<uint32_t> optionalIndex = parseIndex(*identifier);
574 if (!optionalIndex) {
575 generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType());
576 return;
577 }
578
579 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value()));
580 generator.emitDirectPutByVal(newObj, index.get(), value.get());
581 return;
582 }
583 RefPtr<RegisterID> propertyName = generator.emitNode(node.m_expression);
584 generator.emitDirectPutByVal(newObj, propertyName.get(), value.get());
585 }
586
587 // ------------------------------ BracketAccessorNode --------------------------------
588
589 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
590 {
591 if (m_base->isSuperNode()) {
592 // FIXME: Should we generate the profiler info?
593 if (m_subscript->isString()) {
594 const Identifier& id = static_cast<StringNode*>(m_subscript)->value();
595 return generator.emitGetById(generator.finalDestination(dst), emitSuperBaseForCallee(generator), id);
596 }
597 return generator.emitGetByVal(generator.finalDestination(dst), emitSuperBaseForCallee(generator), generator.emitNode(m_subscript));
598 }
599
600 RegisterID* ret;
601 RegisterID* finalDest = generator.finalDestination(dst);
602
603 if (m_subscript->isString()) {
604 RefPtr<RegisterID> base = generator.emitNode(m_base);
605 ret = generator.emitGetById(finalDest, base.get(), static_cast<StringNode*>(m_subscript)->value());
606 } else {
607 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
608 RegisterID* property = generator.emitNode(m_subscript);
609 ret = generator.emitGetByVal(finalDest, base.get(), property);
610 }
611
612 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
613
614 if (generator.vm()->typeProfiler()) {
615 generator.emitProfileType(finalDest, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
616 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
617 }
618 return ret;
619 }
620
621 // ------------------------------ DotAccessorNode --------------------------------
622
623 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
624 {
625 RefPtr<RegisterID> base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
626 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
627 RegisterID* finalDest = generator.finalDestination(dst);
628 RegisterID* ret = generator.emitGetById(finalDest, base.get(), m_ident);
629 if (generator.vm()->typeProfiler()) {
630 generator.emitProfileType(finalDest, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
631 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
632 }
633 return ret;
634 }
635
636 // ------------------------------ ArgumentListNode -----------------------------
637
638 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
639 {
640 ASSERT(m_expr);
641 return generator.emitNode(dst, m_expr);
642 }
643
644 // ------------------------------ NewExprNode ----------------------------------
645
646 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
647 {
648 ExpectedFunction expectedFunction;
649 if (m_expr->isResolveNode())
650 expectedFunction = generator.expectedFunctionForIdentifier(static_cast<ResolveNode*>(m_expr)->identifier());
651 else
652 expectedFunction = NoExpectedFunction;
653 RefPtr<RegisterID> func = generator.emitNode(m_expr);
654 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
655 CallArguments callArguments(generator, m_args);
656 generator.emitMove(callArguments.thisRegister(), func.get());
657 return generator.emitConstruct(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
658 }
659
660 CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode, unsigned additionalArguments)
661 : m_argumentsNode(argumentsNode)
662 , m_padding(0)
663 {
664 if (generator.shouldEmitProfileHooks())
665 m_profileHookRegister = generator.newTemporary();
666
667 size_t argumentCountIncludingThis = 1 + additionalArguments; // 'this' register.
668 if (argumentsNode) {
669 for (ArgumentListNode* node = argumentsNode->m_listNode; node; node = node->m_next)
670 ++argumentCountIncludingThis;
671 }
672
673 m_argv.grow(argumentCountIncludingThis);
674 for (int i = argumentCountIncludingThis - 1; i >= 0; --i) {
675 m_argv[i] = generator.newTemporary();
676 ASSERT(static_cast<size_t>(i) == m_argv.size() - 1 || m_argv[i]->index() == m_argv[i + 1]->index() - 1);
677 }
678
679 while (stackOffset() % stackAlignmentRegisters()) {
680 m_argv.insert(0, generator.newTemporary());
681 m_padding++;
682 }
683 }
684
685 // ------------------------------ EvalFunctionCallNode ----------------------------------
686
687 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
688 {
689 Variable var = generator.variable(generator.propertyNames().eval);
690 if (RegisterID* local = var.local()) {
691 RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
692 CallArguments callArguments(generator, m_args);
693 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
694 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
695 }
696
697 RefPtr<RegisterID> func = generator.newTemporary();
698 CallArguments callArguments(generator, m_args);
699 JSTextPosition newDivot = divotStart() + 4;
700 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
701 generator.moveToDestinationIfNeeded(
702 callArguments.thisRegister(),
703 generator.emitResolveScope(callArguments.thisRegister(), var));
704 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
705 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
706 }
707
708 // ------------------------------ FunctionCallValueNode ----------------------------------
709
710 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
711 {
712 RefPtr<RegisterID> func = generator.emitNode(m_expr);
713 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
714 CallArguments callArguments(generator, m_args);
715 if (m_expr->isSuperNode()) {
716 ASSERT(generator.isConstructor());
717 ASSERT(generator.constructorKind() == ConstructorKind::Derived);
718 generator.emitMove(callArguments.thisRegister(), generator.newTarget());
719 RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
720 generator.emitMove(generator.thisRegister(), ret);
721 return ret;
722 }
723 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
724 RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
725 if (generator.vm()->typeProfiler()) {
726 generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
727 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
728 }
729 return ret;
730 }
731
732 // ------------------------------ FunctionCallResolveNode ----------------------------------
733
734 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
735 {
736 ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
737
738 Variable var = generator.variable(m_ident);
739 if (RegisterID* local = var.local()) {
740 RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
741 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
742 CallArguments callArguments(generator, m_args);
743 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
744 // This passes NoExpectedFunction because we expect that if the function is in a
745 // local variable, then it's not one of our built-in constructors.
746 RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
747 if (generator.vm()->typeProfiler()) {
748 generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
749 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
750 }
751 return ret;
752 }
753
754 RefPtr<RegisterID> func = generator.newTemporary();
755 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
756 CallArguments callArguments(generator, m_args);
757
758 JSTextPosition newDivot = divotStart() + m_ident.length();
759 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
760 generator.moveToDestinationIfNeeded(
761 callArguments.thisRegister(),
762 generator.emitResolveScope(callArguments.thisRegister(), var));
763 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
764 RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
765 if (generator.vm()->typeProfiler()) {
766 generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
767 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
768 }
769 return ret;
770 }
771
772 // ------------------------------ BytecodeIntrinsicNode ----------------------------------
773
774 RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
775 {
776 return (this->*m_emitter)(generator, dst);
777 }
778
779 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst)
780 {
781 ArgumentListNode* node = m_args->m_listNode;
782 RefPtr<RegisterID> base = generator.emitNode(node);
783 node = node->m_next;
784 RefPtr<RegisterID> index = generator.emitNode(node);
785 node = node->m_next;
786 RefPtr<RegisterID> value = generator.emitNode(node);
787
788 ASSERT(!node->m_next);
789
790 return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
791 }
792
793 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
794 {
795 ArgumentListNode* node = m_args->m_listNode;
796 RefPtr<RegisterID> src = generator.emitNode(node);
797 ASSERT(!node->m_next);
798
799 return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
800 }
801
802 // ------------------------------ FunctionCallBracketNode ----------------------------------
803
804 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
805 {
806 bool baseIsSuper = m_base->isSuperNode();
807 bool subscriptIsString = m_subscript->isString();
808
809 RefPtr<RegisterID> base;
810 if (baseIsSuper)
811 base = emitSuperBaseForCallee(generator);
812 else {
813 if (subscriptIsString)
814 base = generator.emitNode(m_base);
815 else
816 base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
817 }
818
819 RefPtr<RegisterID> function;
820 if (subscriptIsString) {
821 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
822 function = generator.emitGetById(generator.tempDestination(dst), base.get(), static_cast<StringNode*>(m_subscript)->value());
823 } else {
824 RefPtr<RegisterID> property = generator.emitNode(m_subscript);
825 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
826 function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
827 }
828
829 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
830 CallArguments callArguments(generator, m_args);
831 if (baseIsSuper)
832 generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
833 else
834 generator.emitMove(callArguments.thisRegister(), base.get());
835 RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
836 if (generator.vm()->typeProfiler()) {
837 generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
838 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
839 }
840 return ret;
841 }
842
843 // ------------------------------ FunctionCallDotNode ----------------------------------
844
845 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
846 {
847 RefPtr<RegisterID> function = generator.tempDestination(dst);
848 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
849 CallArguments callArguments(generator, m_args);
850 bool baseIsSuper = m_base->isSuperNode();
851 if (baseIsSuper)
852 generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
853 else
854 generator.emitNode(callArguments.thisRegister(), m_base);
855 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
856 generator.emitGetById(function.get(), baseIsSuper ? emitSuperBaseForCallee(generator) : callArguments.thisRegister(), m_ident);
857 RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
858 if (generator.vm()->typeProfiler()) {
859 generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
860 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
861 }
862 return ret;
863 }
864
865 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
866 {
867 RefPtr<Label> realCall = generator.newLabel();
868 RefPtr<Label> end = generator.newLabel();
869 RefPtr<RegisterID> base = generator.emitNode(m_base);
870 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
871 RefPtr<RegisterID> function;
872 bool emitCallCheck = !generator.isBuiltinFunction();
873 if (emitCallCheck) {
874 function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().callPublicName());
875 generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
876 }
877 RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
878 {
879 if (m_args->m_listNode && m_args->m_listNode->m_expr && m_args->m_listNode->m_expr->isSpreadExpression()) {
880 RefPtr<RegisterID> profileHookRegister;
881 if (generator.shouldEmitProfileHooks())
882 profileHookRegister = generator.newTemporary();
883 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
884 ExpressionNode* subject = spread->expression();
885 RefPtr<RegisterID> argumentsRegister;
886 argumentsRegister = generator.emitNode(subject);
887 generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
888 RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
889 generator.emitCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
890 } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
891 ArgumentListNode* oldList = m_args->m_listNode;
892 m_args->m_listNode = m_args->m_listNode->m_next;
893
894 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
895 CallArguments callArguments(generator, m_args);
896 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
897 generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
898 m_args->m_listNode = oldList;
899 } else {
900 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
901 CallArguments callArguments(generator, m_args);
902 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
903 generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
904 }
905 }
906 if (emitCallCheck) {
907 generator.emitJump(end.get());
908 generator.emitLabel(realCall.get());
909 {
910 CallArguments callArguments(generator, m_args);
911 generator.emitMove(callArguments.thisRegister(), base.get());
912 generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
913 }
914 generator.emitLabel(end.get());
915 }
916 if (generator.vm()->typeProfiler()) {
917 generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
918 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
919 }
920 return returnValue.get();
921 }
922
923 static bool areTrivialApplyArguments(ArgumentsNode* args)
924 {
925 return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
926 || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
927 }
928
929 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
930 {
931 // A few simple cases can be trivially handled as ordinary function calls.
932 // function.apply(), function.apply(arg) -> identical to function.call
933 // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
934 bool mayBeCall = areTrivialApplyArguments(m_args);
935
936 RefPtr<Label> realCall = generator.newLabel();
937 RefPtr<Label> end = generator.newLabel();
938 RefPtr<RegisterID> base = generator.emitNode(m_base);
939 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
940 RefPtr<RegisterID> function;
941 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
942 bool emitCallCheck = !generator.isBuiltinFunction();
943 if (emitCallCheck) {
944 function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().applyPublicName());
945 generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
946 }
947 if (mayBeCall) {
948 if (m_args->m_listNode && m_args->m_listNode->m_expr) {
949 ArgumentListNode* oldList = m_args->m_listNode;
950 if (m_args->m_listNode->m_expr->isSpreadExpression()) {
951 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
952 RefPtr<RegisterID> profileHookRegister;
953 if (generator.shouldEmitProfileHooks())
954 profileHookRegister = generator.newTemporary();
955 RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
956 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(0));
957 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
958 RefPtr<RegisterID> argumentsRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
959
960 auto extractor = [&thisRegister, &argumentsRegister, &index](BytecodeGenerator& generator, RegisterID* value)
961 {
962 RefPtr<Label> haveThis = generator.newLabel();
963 RefPtr<Label> end = generator.newLabel();
964 RefPtr<RegisterID> compareResult = generator.newTemporary();
965 RefPtr<RegisterID> indexZeroCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(0)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
966 generator.emitJumpIfFalse(indexZeroCompareResult.get(), haveThis.get());
967 generator.emitMove(thisRegister.get(), value);
968 generator.emitLoad(index.get(), jsNumber(1));
969 generator.emitJump(end.get());
970 generator.emitLabel(haveThis.get());
971 RefPtr<RegisterID> indexOneCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(1)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
972 generator.emitJumpIfFalse(indexOneCompareResult.get(), end.get());
973 generator.emitMove(argumentsRegister.get(), value);
974 generator.emitLoad(index.get(), jsNumber(2));
975 generator.emitLabel(end.get());
976 };
977 generator.emitEnumeration(this, spread->expression(), extractor);
978 generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
979 } else if (m_args->m_listNode->m_next) {
980 ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
981 ASSERT(!m_args->m_listNode->m_next->m_next);
982 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.parserArena(), 0, 0);
983 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
984 CallArguments callArguments(generator, m_args);
985 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
986 generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
987 } else {
988 m_args->m_listNode = m_args->m_listNode->m_next;
989 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
990 CallArguments callArguments(generator, m_args);
991 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
992 generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
993 }
994 m_args->m_listNode = oldList;
995 } else {
996 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
997 CallArguments callArguments(generator, m_args);
998 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
999 generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1000 }
1001 } else {
1002 ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
1003 RefPtr<RegisterID> profileHookRegister;
1004 if (generator.shouldEmitProfileHooks())
1005 profileHookRegister = generator.newTemporary();
1006 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1007 RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
1008 RefPtr<RegisterID> argsRegister;
1009 ArgumentListNode* args = m_args->m_listNode->m_next;
1010 argsRegister = generator.emitNode(args->m_expr);
1011
1012 // Function.prototype.apply ignores extra arguments, but we still
1013 // need to evaluate them for side effects.
1014 while ((args = args->m_next))
1015 generator.emitNode(args->m_expr);
1016
1017 generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
1018 }
1019 if (emitCallCheck) {
1020 generator.emitJump(end.get());
1021 generator.emitLabel(realCall.get());
1022 CallArguments callArguments(generator, m_args);
1023 generator.emitMove(callArguments.thisRegister(), base.get());
1024 generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1025 generator.emitLabel(end.get());
1026 }
1027 if (generator.vm()->typeProfiler()) {
1028 generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1029 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1030 }
1031 return returnValue.get();
1032 }
1033
1034 // ------------------------------ PostfixNode ----------------------------------
1035
1036 static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
1037 {
1038 return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
1039 }
1040
1041 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
1042 {
1043 if (dst == srcDst)
1044 return generator.emitToNumber(generator.finalDestination(dst), srcDst);
1045 RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
1046 emitIncOrDec(generator, srcDst, oper);
1047 return generator.moveToDestinationIfNeeded(dst, tmp.get());
1048 }
1049
1050 RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1051 {
1052 if (dst == generator.ignoredResult())
1053 return PrefixNode::emitResolve(generator, dst);
1054
1055 ASSERT(m_expr->isResolveNode());
1056 ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1057 const Identifier& ident = resolve->identifier();
1058
1059 Variable var = generator.variable(ident);
1060 if (RegisterID* local = var.local()) {
1061 RefPtr<RegisterID> localReg = local;
1062 if (var.isReadOnly()) {
1063 generator.emitReadOnlyExceptionIfNeeded();
1064 localReg = generator.emitMove(generator.tempDestination(dst), local);
1065 } else if (generator.vm()->typeProfiler()) {
1066 RefPtr<RegisterID> tempDst = generator.finalDestination(dst);
1067 ASSERT(dst != localReg);
1068 RefPtr<RegisterID> tempDstSrc = generator.newTemporary();
1069 generator.emitToNumber(tempDst.get(), localReg.get());
1070 generator.emitMove(tempDstSrc.get(), localReg.get());
1071 emitIncOrDec(generator, tempDstSrc.get(), m_operator);
1072 generator.emitMove(localReg.get(), tempDstSrc.get());
1073 if (generator.vm()->typeProfiler())
1074 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1075 return tempDst.get();
1076 }
1077 return emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
1078 }
1079
1080 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1081 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1082 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1083 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
1084 generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
1085 if (generator.vm()->typeProfiler()) {
1086 generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
1087 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1088 }
1089
1090 return oldValue.get();
1091 }
1092
1093 RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1094 {
1095 if (dst == generator.ignoredResult())
1096 return PrefixNode::emitBracket(generator, dst);
1097
1098 ASSERT(m_expr->isBracketAccessorNode());
1099 BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1100 ExpressionNode* baseNode = bracketAccessor->base();
1101 ExpressionNode* subscript = bracketAccessor->subscript();
1102
1103 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1104 RefPtr<RegisterID> property = generator.emitNode(subscript);
1105
1106 generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1107 RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1108 RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1109 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1110 generator.emitPutByVal(base.get(), property.get(), value.get());
1111 if (generator.vm()->typeProfiler()) {
1112 generator.emitProfileType(value.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1113 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1114 }
1115 return generator.moveToDestinationIfNeeded(dst, oldValue);
1116 }
1117
1118 RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1119 {
1120 if (dst == generator.ignoredResult())
1121 return PrefixNode::emitDot(generator, dst);
1122
1123 ASSERT(m_expr->isDotAccessorNode());
1124 DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1125 ExpressionNode* baseNode = dotAccessor->base();
1126 const Identifier& ident = dotAccessor->identifier();
1127
1128 RefPtr<RegisterID> base = generator.emitNode(baseNode);
1129
1130 generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1131 RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
1132 RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1133 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1134 generator.emitPutById(base.get(), ident, value.get());
1135 if (generator.vm()->typeProfiler()) {
1136 generator.emitProfileType(value.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1137 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1138 }
1139 return generator.moveToDestinationIfNeeded(dst, oldValue);
1140 }
1141
1142 RegisterID* PostfixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1143 {
1144 if (m_expr->isResolveNode())
1145 return emitResolve(generator, dst);
1146
1147 if (m_expr->isBracketAccessorNode())
1148 return emitBracket(generator, dst);
1149
1150 if (m_expr->isDotAccessorNode())
1151 return emitDot(generator, dst);
1152
1153 return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1154 ? ASCIILiteral("Postfix ++ operator applied to value that is not a reference.")
1155 : ASCIILiteral("Postfix -- operator applied to value that is not a reference."));
1156 }
1157
1158 // ------------------------------ DeleteResolveNode -----------------------------------
1159
1160 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1161 {
1162 Variable var = generator.variable(m_ident);
1163 if (var.local())
1164 return generator.emitLoad(generator.finalDestination(dst), false);
1165
1166 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1167 RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
1168 return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
1169 }
1170
1171 // ------------------------------ DeleteBracketNode -----------------------------------
1172
1173 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1174 {
1175 RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1176 RefPtr<RegisterID> r1 = generator.emitNode(m_subscript);
1177
1178 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1179 if (m_base->isSuperNode())
1180 return emitThrowReferenceError(generator, "Cannot delete a super property");
1181 return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
1182 }
1183
1184 // ------------------------------ DeleteDotNode -----------------------------------
1185
1186 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1187 {
1188 RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1189
1190 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1191 if (m_base->isSuperNode())
1192 return emitThrowReferenceError(generator, "Cannot delete a super property");
1193 return generator.emitDeleteById(generator.finalDestination(dst), r0.get(), m_ident);
1194 }
1195
1196 // ------------------------------ DeleteValueNode -----------------------------------
1197
1198 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1199 {
1200 generator.emitNode(generator.ignoredResult(), m_expr);
1201
1202 // delete on a non-location expression ignores the value and returns true
1203 return generator.emitLoad(generator.finalDestination(dst), true);
1204 }
1205
1206 // ------------------------------ VoidNode -------------------------------------
1207
1208 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1209 {
1210 if (dst == generator.ignoredResult()) {
1211 generator.emitNode(generator.ignoredResult(), m_expr);
1212 return 0;
1213 }
1214 RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1215 return generator.emitLoad(dst, jsUndefined());
1216 }
1217
1218 // ------------------------------ TypeOfResolveNode -----------------------------------
1219
1220 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1221 {
1222 Variable var = generator.variable(m_ident);
1223 if (RegisterID* local = var.local()) {
1224 if (dst == generator.ignoredResult())
1225 return 0;
1226 return generator.emitTypeOf(generator.finalDestination(dst), local);
1227 }
1228
1229 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1230 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
1231 if (dst == generator.ignoredResult())
1232 return 0;
1233 return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
1234 }
1235
1236 // ------------------------------ TypeOfValueNode -----------------------------------
1237
1238 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1239 {
1240 if (dst == generator.ignoredResult()) {
1241 generator.emitNode(generator.ignoredResult(), m_expr);
1242 return 0;
1243 }
1244 RefPtr<RegisterID> src = generator.emitNode(m_expr);
1245 return generator.emitTypeOf(generator.finalDestination(dst), src.get());
1246 }
1247
1248 // ------------------------------ PrefixNode ----------------------------------
1249
1250 RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1251 {
1252 ASSERT(m_expr->isResolveNode());
1253 ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1254 const Identifier& ident = resolve->identifier();
1255
1256 Variable var = generator.variable(ident);
1257 if (RegisterID* local = var.local()) {
1258 RefPtr<RegisterID> localReg = local;
1259 if (var.isReadOnly()) {
1260 generator.emitReadOnlyExceptionIfNeeded();
1261 localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
1262 } else if (generator.vm()->typeProfiler()) {
1263 RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1264 generator.emitMove(tempDst.get(), localReg.get());
1265 emitIncOrDec(generator, tempDst.get(), m_operator);
1266 generator.emitMove(localReg.get(), tempDst.get());
1267 if (generator.vm()->typeProfiler())
1268 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1269 return generator.moveToDestinationIfNeeded(dst, tempDst.get());
1270 }
1271 emitIncOrDec(generator, localReg.get(), m_operator);
1272 return generator.moveToDestinationIfNeeded(dst, localReg.get());
1273 }
1274
1275 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1276 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1277 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1278 emitIncOrDec(generator, value.get(), m_operator);
1279 generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
1280 if (generator.vm()->typeProfiler()) {
1281 generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
1282 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1283 }
1284 return generator.moveToDestinationIfNeeded(dst, value.get());
1285 }
1286
1287 RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1288 {
1289 ASSERT(m_expr->isBracketAccessorNode());
1290 BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1291 ExpressionNode* baseNode = bracketAccessor->base();
1292 ExpressionNode* subscript = bracketAccessor->subscript();
1293
1294 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1295 RefPtr<RegisterID> property = generator.emitNode(subscript);
1296 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1297
1298 generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1299 RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1300 emitIncOrDec(generator, value, m_operator);
1301 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1302 generator.emitPutByVal(base.get(), property.get(), value);
1303 if (generator.vm()->typeProfiler()) {
1304 generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1305 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1306 }
1307 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1308 }
1309
1310 RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1311 {
1312 ASSERT(m_expr->isDotAccessorNode());
1313 DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1314 ExpressionNode* baseNode = dotAccessor->base();
1315 const Identifier& ident = dotAccessor->identifier();
1316
1317 RefPtr<RegisterID> base = generator.emitNode(baseNode);
1318 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1319
1320 generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1321 RegisterID* value = generator.emitGetById(propDst.get(), base.get(), ident);
1322 emitIncOrDec(generator, value, m_operator);
1323 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1324 generator.emitPutById(base.get(), ident, value);
1325 if (generator.vm()->typeProfiler()) {
1326 generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1327 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1328 }
1329 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1330 }
1331
1332 RegisterID* PrefixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1333 {
1334 if (m_expr->isResolveNode())
1335 return emitResolve(generator, dst);
1336
1337 if (m_expr->isBracketAccessorNode())
1338 return emitBracket(generator, dst);
1339
1340 if (m_expr->isDotAccessorNode())
1341 return emitDot(generator, dst);
1342
1343 return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1344 ? ASCIILiteral("Prefix ++ operator applied to value that is not a reference.")
1345 : ASCIILiteral("Prefix -- operator applied to value that is not a reference."));
1346 }
1347
1348 // ------------------------------ Unary Operation Nodes -----------------------------------
1349
1350 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1351 {
1352 RefPtr<RegisterID> src = generator.emitNode(m_expr);
1353 generator.emitExpressionInfo(position(), position(), position());
1354 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get());
1355 }
1356
1357 // ------------------------------ BitwiseNotNode -----------------------------------
1358
1359 RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1360 {
1361 RefPtr<RegisterID> src2 = generator.emitLoad(generator.newTemporary(), jsNumber(-1));
1362 RefPtr<RegisterID> src1 = generator.emitNode(m_expr);
1363 return generator.emitBinaryOp(op_bitxor, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr->resultDescriptor(), ResultType::numberTypeIsInt32()));
1364 }
1365
1366 // ------------------------------ LogicalNotNode -----------------------------------
1367
1368 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1369 {
1370 // reverse the true and false targets
1371 generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode));
1372 }
1373
1374
1375 // ------------------------------ Binary Operation Nodes -----------------------------------
1376
1377 // BinaryOpNode::emitStrcat:
1378 //
1379 // This node generates an op_strcat operation. This opcode can handle concatenation of three or
1380 // more values, where we can determine a set of separate op_add operations would be operating on
1381 // string values.
1382 //
1383 // This function expects to be operating on a graph of AST nodes looking something like this:
1384 //
1385 // (a)... (b)
1386 // \ /
1387 // (+) (c)
1388 // \ /
1389 // [d] ((+))
1390 // \ /
1391 // [+=]
1392 //
1393 // The assignment operation is optional, if it exists the register holding the value on the
1394 // lefthand side of the assignment should be passing as the optional 'lhs' argument.
1395 //
1396 // The method should be called on the node at the root of the tree of regular binary add
1397 // operations (marked in the diagram with a double set of parentheses). This node must
1398 // be performing a string concatenation (determined by statically detecting that at least
1399 // one child must be a string).
1400 //
1401 // Since the minimum number of values being concatenated together is expected to be 3, if
1402 // a lhs to a concatenating assignment is not provided then the root add should have at
1403 // least one left child that is also an add that can be determined to be operating on strings.
1404 //
1405 RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
1406 {
1407 ASSERT(isAdd());
1408 ASSERT(resultDescriptor().definitelyIsString());
1409
1410 // Create a list of expressions for all the adds in the tree of nodes we can convert into
1411 // a string concatenation. The rightmost node (c) is added first. The rightmost node is
1412 // added first, and the leftmost child is never added, so the vector produced for the
1413 // example above will be [ c, b ].
1414 Vector<ExpressionNode*, 16> reverseExpressionList;
1415 reverseExpressionList.append(m_expr2);
1416
1417 // Examine the left child of the add. So long as this is a string add, add its right-child
1418 // to the list, and keep processing along the left fork.
1419 ExpressionNode* leftMostAddChild = m_expr1;
1420 while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
1421 reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
1422 leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
1423 }
1424
1425 Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
1426
1427 // If there is an assignment, allocate a temporary to hold the lhs after conversion.
1428 // We could possibly avoid this (the lhs is converted last anyway, we could let the
1429 // op_strcat node handle its conversion if required).
1430 if (lhs)
1431 temporaryRegisters.append(generator.newTemporary());
1432
1433 // Emit code for the leftmost node ((a) in the example).
1434 temporaryRegisters.append(generator.newTemporary());
1435 RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
1436 generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
1437
1438 // Note on ordering of conversions:
1439 //
1440 // We maintain the same ordering of conversions as we would see if the concatenations
1441 // was performed as a sequence of adds (otherwise this optimization could change
1442 // behaviour should an object have been provided a valueOf or toString method).
1443 //
1444 // Considering the above example, the sequnce of execution is:
1445 // * evaluate operand (a)
1446 // * evaluate operand (b)
1447 // * convert (a) to primitive <- (this would be triggered by the first add)
1448 // * convert (b) to primitive <- (ditto)
1449 // * evaluate operand (c)
1450 // * convert (c) to primitive <- (this would be triggered by the second add)
1451 // And optionally, if there is an assignment:
1452 // * convert (d) to primitive <- (this would be triggered by the assigning addition)
1453 //
1454 // As such we do not plant an op to convert the leftmost child now. Instead, use
1455 // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
1456 // once the second node has been generated. However, if the leftmost child is an
1457 // immediate we can trivially determine that no conversion will be required.
1458 // If this is the case
1459 if (leftMostAddChild->isString())
1460 leftMostAddChildTempRegister = 0;
1461
1462 while (reverseExpressionList.size()) {
1463 ExpressionNode* node = reverseExpressionList.last();
1464 reverseExpressionList.removeLast();
1465
1466 // Emit the code for the current node.
1467 temporaryRegisters.append(generator.newTemporary());
1468 generator.emitNode(temporaryRegisters.last().get(), node);
1469
1470 // On the first iteration of this loop, when we first reach this point we have just
1471 // generated the second node, which means it is time to convert the leftmost operand.
1472 if (leftMostAddChildTempRegister) {
1473 generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
1474 leftMostAddChildTempRegister = 0; // Only do this once.
1475 }
1476 // Plant a conversion for this node, if necessary.
1477 if (!node->isString())
1478 generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
1479 }
1480 ASSERT(temporaryRegisters.size() >= 3);
1481
1482 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1483 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1484 if (emitExpressionInfoForMe)
1485 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1486 // If there is an assignment convert the lhs now. This will also copy lhs to
1487 // the temporary register we allocated for it.
1488 if (lhs)
1489 generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
1490
1491 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
1492 }
1493
1494 void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1495 {
1496 TriState branchCondition;
1497 ExpressionNode* branchExpression;
1498 tryFoldToBranch(generator, branchCondition, branchExpression);
1499
1500 if (branchCondition == MixedTriState)
1501 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
1502 else if (branchCondition == TrueTriState)
1503 generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode);
1504 else
1505 generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode));
1506 }
1507
1508 static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant)
1509 {
1510 ResultType expressionType = branchExpression->resultDescriptor();
1511
1512 if (expressionType.definitelyIsBoolean() && constant.isBoolean())
1513 return true;
1514 else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1))
1515 return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch.
1516 else if (expressionType.isInt32() && constant.isInt32() && constant.asInt32() == 0)
1517 return true;
1518
1519 return false;
1520 }
1521
1522 void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression)
1523 {
1524 branchCondition = MixedTriState;
1525 branchExpression = 0;
1526
1527 ConstantNode* constant = 0;
1528 if (m_expr1->isConstant()) {
1529 constant = static_cast<ConstantNode*>(m_expr1);
1530 branchExpression = m_expr2;
1531 } else if (m_expr2->isConstant()) {
1532 constant = static_cast<ConstantNode*>(m_expr2);
1533 branchExpression = m_expr1;
1534 }
1535
1536 if (!constant)
1537 return;
1538 ASSERT(branchExpression);
1539
1540 OpcodeID opcodeID = this->opcodeID();
1541 JSValue value = constant->jsValue(generator);
1542 bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
1543 if (!canFoldToBranch)
1544 return;
1545
1546 if (opcodeID == op_eq || opcodeID == op_stricteq)
1547 branchCondition = triState(value.pureToBoolean());
1548 else if (opcodeID == op_neq || opcodeID == op_nstricteq)
1549 branchCondition = triState(!value.pureToBoolean());
1550 }
1551
1552 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1553 {
1554 OpcodeID opcodeID = this->opcodeID();
1555
1556 if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString()) {
1557 generator.emitExpressionInfo(position(), position(), position());
1558 return emitStrcat(generator, dst);
1559 }
1560
1561 if (opcodeID == op_neq) {
1562 if (m_expr1->isNull() || m_expr2->isNull()) {
1563 RefPtr<RegisterID> src = generator.tempDestination(dst);
1564 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1565 return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
1566 }
1567 }
1568
1569 ExpressionNode* left = m_expr1;
1570 ExpressionNode* right = m_expr2;
1571 if (opcodeID == op_neq || opcodeID == op_nstricteq) {
1572 if (left->isString())
1573 std::swap(left, right);
1574 }
1575
1576 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
1577 bool wasTypeof = generator.lastOpcodeID() == op_typeof;
1578 RefPtr<RegisterID> src2 = generator.emitNode(right);
1579 generator.emitExpressionInfo(position(), position(), position());
1580 if (wasTypeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
1581 RefPtr<RegisterID> tmp = generator.tempDestination(dst);
1582 if (opcodeID == op_neq)
1583 generator.emitEqualityOp(op_eq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
1584 else if (opcodeID == op_nstricteq)
1585 generator.emitEqualityOp(op_stricteq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
1586 else
1587 RELEASE_ASSERT_NOT_REACHED();
1588 return generator.emitUnaryOp(op_not, generator.finalDestination(dst, tmp.get()), tmp.get());
1589 }
1590 RegisterID* result = generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
1591 if (opcodeID == op_urshift && dst != generator.ignoredResult())
1592 return generator.emitUnaryOp(op_unsigned, result, result);
1593 return result;
1594 }
1595
1596 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1597 {
1598 if (m_expr1->isNull() || m_expr2->isNull()) {
1599 RefPtr<RegisterID> src = generator.tempDestination(dst);
1600 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1601 return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
1602 }
1603
1604 ExpressionNode* left = m_expr1;
1605 ExpressionNode* right = m_expr2;
1606 if (left->isString())
1607 std::swap(left, right);
1608
1609 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
1610 RefPtr<RegisterID> src2 = generator.emitNode(right);
1611 return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
1612 }
1613
1614 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1615 {
1616 ExpressionNode* left = m_expr1;
1617 ExpressionNode* right = m_expr2;
1618 if (left->isString())
1619 std::swap(left, right);
1620
1621 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
1622 RefPtr<RegisterID> src2 = generator.emitNode(right);
1623 return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
1624 }
1625
1626 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1627 {
1628 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
1629 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
1630 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1631 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1632 }
1633
1634 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1635 {
1636 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
1637 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
1638 RefPtr<RegisterID> prototype = generator.newTemporary();
1639 RefPtr<RegisterID> dstReg = generator.finalDestination(dst, src1.get());
1640 RefPtr<Label> target = generator.newLabel();
1641
1642 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1643 generator.emitCheckHasInstance(dstReg.get(), src1.get(), src2.get(), target.get());
1644
1645 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1646 generator.emitGetById(prototype.get(), src2.get(), generator.vm()->propertyNames->prototype);
1647
1648 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1649 RegisterID* result = generator.emitInstanceOf(dstReg.get(), src1.get(), prototype.get());
1650 generator.emitLabel(target.get());
1651 return result;
1652 }
1653
1654 // ------------------------------ LogicalOpNode ----------------------------
1655
1656 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1657 {
1658 RefPtr<RegisterID> temp = generator.tempDestination(dst);
1659 RefPtr<Label> target = generator.newLabel();
1660
1661 generator.emitNode(temp.get(), m_expr1);
1662 if (m_operator == OpLogicalAnd)
1663 generator.emitJumpIfFalse(temp.get(), target.get());
1664 else
1665 generator.emitJumpIfTrue(temp.get(), target.get());
1666 generator.emitNode(temp.get(), m_expr2);
1667 generator.emitLabel(target.get());
1668
1669 return generator.moveToDestinationIfNeeded(dst, temp.get());
1670 }
1671
1672 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1673 {
1674 RefPtr<Label> afterExpr1 = generator.newLabel();
1675 if (m_operator == OpLogicalAnd)
1676 generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, FallThroughMeansTrue);
1677 else
1678 generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), FallThroughMeansFalse);
1679 generator.emitLabel(afterExpr1.get());
1680
1681 generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMode);
1682 }
1683
1684 // ------------------------------ ConditionalNode ------------------------------
1685
1686 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1687 {
1688 RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1689 RefPtr<Label> beforeElse = generator.newLabel();
1690 RefPtr<Label> afterElse = generator.newLabel();
1691
1692 RefPtr<Label> beforeThen = generator.newLabel();
1693 generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
1694 generator.emitLabel(beforeThen.get());
1695
1696 generator.emitProfileControlFlow(m_expr1->startOffset());
1697 generator.emitNode(newDst.get(), m_expr1);
1698 generator.emitJump(afterElse.get());
1699
1700 generator.emitLabel(beforeElse.get());
1701 generator.emitProfileControlFlow(m_expr1->endOffset() + 1);
1702 generator.emitNode(newDst.get(), m_expr2);
1703
1704 generator.emitLabel(afterElse.get());
1705
1706 generator.emitProfileControlFlow(m_expr2->endOffset() + 1);
1707
1708 return newDst.get();
1709 }
1710
1711 // ------------------------------ ReadModifyResolveNode -----------------------------------
1712
1713 // FIXME: should this be moved to be a method on BytecodeGenerator?
1714 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
1715 {
1716 OpcodeID opcodeID;
1717 switch (oper) {
1718 case OpMultEq:
1719 opcodeID = op_mul;
1720 break;
1721 case OpDivEq:
1722 opcodeID = op_div;
1723 break;
1724 case OpPlusEq:
1725 if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
1726 return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
1727 opcodeID = op_add;
1728 break;
1729 case OpMinusEq:
1730 opcodeID = op_sub;
1731 break;
1732 case OpLShift:
1733 opcodeID = op_lshift;
1734 break;
1735 case OpRShift:
1736 opcodeID = op_rshift;
1737 break;
1738 case OpURShift:
1739 opcodeID = op_urshift;
1740 break;
1741 case OpAndEq:
1742 opcodeID = op_bitand;
1743 break;
1744 case OpXOrEq:
1745 opcodeID = op_bitxor;
1746 break;
1747 case OpOrEq:
1748 opcodeID = op_bitor;
1749 break;
1750 case OpModEq:
1751 opcodeID = op_mod;
1752 break;
1753 default:
1754 RELEASE_ASSERT_NOT_REACHED();
1755 return dst;
1756 }
1757
1758 RegisterID* src2 = generator.emitNode(m_right);
1759
1760 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1761 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1762 if (emitExpressionInfoForMe)
1763 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1764 RegisterID* result = generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1765 if (oper == OpURShift)
1766 return generator.emitUnaryOp(op_unsigned, result, result);
1767 return result;
1768 }
1769
1770 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1771 {
1772 JSTextPosition newDivot = divotStart() + m_ident.length();
1773 Variable var = generator.variable(m_ident);
1774 if (RegisterID* local = var.local()) {
1775 if (var.isReadOnly()) {
1776 generator.emitReadOnlyExceptionIfNeeded();
1777 return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1778 }
1779
1780 if (generator.vm()->typeProfiler()
1781 || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1782 RefPtr<RegisterID> result = generator.newTemporary();
1783 generator.emitMove(result.get(), local);
1784 emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1785 generator.emitMove(local, result.get());
1786 generator.invalidateForInContextForLocal(local);
1787 if (generator.vm()->typeProfiler())
1788 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1789 return generator.moveToDestinationIfNeeded(dst, result.get());
1790 }
1791
1792 RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1793 generator.invalidateForInContextForLocal(local);
1794 return generator.moveToDestinationIfNeeded(dst, result);
1795 }
1796
1797 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
1798 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1799 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1800 RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
1801 RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound);
1802 if (generator.vm()->typeProfiler()) {
1803 generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
1804 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1805 }
1806 return returnResult;
1807 }
1808
1809 // ------------------------------ AssignResolveNode -----------------------------------
1810
1811 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1812 {
1813 Variable var = generator.variable(m_ident);
1814 if (RegisterID* local = var.local()) {
1815 if (var.isReadOnly()) {
1816 generator.emitReadOnlyExceptionIfNeeded();
1817 return generator.emitNode(dst, m_right);
1818 }
1819 if (var.isSpecial() || generator.vm()->typeProfiler()) {
1820 RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1821 generator.emitNode(tempDst.get(), m_right);
1822 generator.emitMove(local, tempDst.get());
1823 generator.invalidateForInContextForLocal(local);
1824 if (generator.vm()->typeProfiler())
1825 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1826 return generator.moveToDestinationIfNeeded(dst, tempDst.get());
1827 }
1828 RegisterID* result = generator.emitNode(local, m_right);
1829 generator.invalidateForInContextForLocal(local);
1830 return generator.moveToDestinationIfNeeded(dst, result);
1831 }
1832
1833 if (generator.isStrictMode())
1834 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1835 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1836 if (dst == generator.ignoredResult())
1837 dst = 0;
1838 RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
1839 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1840 RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
1841 if (generator.vm()->typeProfiler()) {
1842 generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
1843 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1844 }
1845 return returnResult;
1846 }
1847
1848 // ------------------------------ AssignDotNode -----------------------------------
1849
1850 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1851 {
1852 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1853 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1854 RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
1855 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1856 RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
1857 generator.emitPutById(base.get(), m_ident, forwardResult);
1858 if (generator.vm()->typeProfiler()) {
1859 generator.emitProfileType(forwardResult, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1860 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1861 }
1862 return generator.moveToDestinationIfNeeded(dst, forwardResult);
1863 }
1864
1865 // ------------------------------ ReadModifyDotNode -----------------------------------
1866
1867 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1868 {
1869 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1870
1871 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1872 RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1873 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, static_cast<JSC::Operator>(m_operator), OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1874
1875 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1876 RegisterID* ret = generator.emitPutById(base.get(), m_ident, updatedValue);
1877 if (generator.vm()->typeProfiler()) {
1878 generator.emitProfileType(updatedValue, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1879 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1880 }
1881 return ret;
1882 }
1883
1884 // ------------------------------ AssignErrorNode -----------------------------------
1885
1886 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1887 {
1888 return emitThrowReferenceError(generator, ASCIILiteral("Left side of assignment is not a reference."));
1889 }
1890
1891 // ------------------------------ AssignBracketNode -----------------------------------
1892
1893 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1894 {
1895 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1896 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
1897 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1898 RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
1899
1900 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1901 RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
1902
1903 if (m_subscript->isString())
1904 generator.emitPutById(base.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
1905 else
1906 generator.emitPutByVal(base.get(), property.get(), forwardResult);
1907
1908 if (generator.vm()->typeProfiler()) {
1909 generator.emitProfileType(forwardResult, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1910 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1911 }
1912 return generator.moveToDestinationIfNeeded(dst, forwardResult);
1913 }
1914
1915 // ------------------------------ ReadModifyBracketNode -----------------------------------
1916
1917 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1918 {
1919 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1920 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
1921
1922 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1923 RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1924 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, static_cast<JSC::Operator>(m_operator), OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1925
1926 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1927 generator.emitPutByVal(base.get(), property.get(), updatedValue);
1928 if (generator.vm()->typeProfiler()) {
1929 generator.emitProfileType(updatedValue, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1930 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1931 }
1932
1933 return updatedValue;
1934 }
1935
1936 // ------------------------------ CommaNode ------------------------------------
1937
1938 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1939 {
1940 CommaNode* node = this;
1941 for (; node && node->next(); node = node->next())
1942 generator.emitNode(generator.ignoredResult(), node->m_expr);
1943 return generator.emitNode(dst, node->m_expr);
1944 }
1945
1946 // ------------------------------ ConstDeclNode ------------------------------------
1947
1948 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1949 {
1950 // FIXME: This code does not match the behavior of const in Firefox.
1951 Variable var = generator.variable(m_ident);
1952 if (RegisterID* local = var.local()) {
1953 if (!m_init)
1954 return local;
1955
1956 // FIXME: Maybe call emitExpressionInfo here.
1957 if (var.isSpecial() || generator.vm()->typeProfiler()) {
1958 RefPtr<RegisterID> tempDst = generator.newTemporary();
1959 generator.emitNode(tempDst.get(), m_init);
1960 return generator.emitMove(local, tempDst.get());
1961 }
1962
1963 return generator.emitNode(local, m_init);
1964 }
1965
1966 RefPtr<RegisterID> value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
1967
1968 if (generator.codeType() == GlobalCode)
1969 return generator.emitInitGlobalConst(m_ident, value.get());
1970
1971 if (generator.codeType() != EvalCode) {
1972 // Do a special kind of resolution. If anything fails, then don't perform the assignment. This is
1973 // pretty shady - particularly how negligent it is with inteleaving scopes - but it's the
1974 // behavior that JSC has had for a long time.
1975
1976 ASSERT(generator.codeType() == FunctionCode);
1977
1978 var = generator.variablePerSymbolTable(m_ident);
1979 if (!var.isResolved())
1980 return value.get();
1981
1982 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), var);
1983 return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
1984 }
1985
1986 // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope.
1987 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1988 return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
1989 }
1990
1991 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1992 {
1993 RegisterID* result = 0;
1994 for (ConstDeclNode* n = this; n; n = n->m_next)
1995 result = n->emitCodeSingle(generator);
1996
1997 return result;
1998 }
1999
2000 // ------------------------------ ConstStatementNode -----------------------------
2001
2002 void ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2003 {
2004 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2005 generator.emitNode(m_next);
2006 }
2007
2008 // ------------------------------ SourceElements -------------------------------
2009
2010
2011 inline StatementNode* SourceElements::lastStatement() const
2012 {
2013 return m_tail;
2014 }
2015
2016 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2017 {
2018 for (StatementNode* statement = m_head; statement; statement = statement->next())
2019 generator.emitNode(dst, statement);
2020 }
2021
2022 // ------------------------------ BlockNode ------------------------------------
2023
2024 inline StatementNode* BlockNode::lastStatement() const
2025 {
2026 return m_statements ? m_statements->lastStatement() : 0;
2027 }
2028
2029 StatementNode* BlockNode::singleStatement() const
2030 {
2031 return m_statements ? m_statements->singleStatement() : 0;
2032 }
2033
2034 void BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2035 {
2036 if (!m_statements)
2037 return;
2038 m_statements->emitBytecode(generator, dst);
2039 }
2040
2041 // ------------------------------ EmptyStatementNode ---------------------------
2042
2043 void EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2044 {
2045 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2046 }
2047
2048 // ------------------------------ DebuggerStatementNode ---------------------------
2049
2050 void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2051 {
2052 generator.emitDebugHook(DidReachBreakpoint, lastLine(), startOffset(), lineStartOffset());
2053 }
2054
2055 // ------------------------------ ExprStatementNode ----------------------------
2056
2057 void ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2058 {
2059 ASSERT(m_expr);
2060 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2061 generator.emitNode(dst, m_expr);
2062 }
2063
2064 // ------------------------------ VarStatementNode ----------------------------
2065
2066 void VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2067 {
2068 ASSERT(m_expr);
2069 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2070 generator.emitNode(m_expr);
2071 }
2072
2073 // ------------------------------ EmptyVarExpression ----------------------------
2074
2075 RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2076 {
2077 if (!generator.vm()->typeProfiler())
2078 return nullptr;
2079
2080 Variable var = generator.variable(m_ident);
2081 if (RegisterID* local = var.local())
2082 generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
2083 else {
2084 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2085 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
2086 generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
2087 }
2088
2089 generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2090
2091 // It's safe to return null here because this node will always be a child node of VarStatementNode which ignores our return value.
2092 return nullptr;
2093 }
2094
2095 // ------------------------------ IfElseNode ---------------------------------------
2096
2097 static inline StatementNode* singleStatement(StatementNode* statementNode)
2098 {
2099 if (statementNode->isBlock())
2100 return static_cast<BlockNode*>(statementNode)->singleStatement();
2101 return statementNode;
2102 }
2103
2104 bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock,
2105 Label*& trueTarget, FallThroughMode& fallThroughMode)
2106 {
2107 StatementNode* singleStatement = JSC::singleStatement(ifBlock);
2108 if (!singleStatement)
2109 return false;
2110
2111 if (singleStatement->isBreak()) {
2112 BreakNode* breakNode = static_cast<BreakNode*>(singleStatement);
2113 Label* target = breakNode->trivialTarget(generator);
2114 if (!target)
2115 return false;
2116 trueTarget = target;
2117 fallThroughMode = FallThroughMeansFalse;
2118 return true;
2119 }
2120
2121 if (singleStatement->isContinue()) {
2122 ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement);
2123 Label* target = continueNode->trivialTarget(generator);
2124 if (!target)
2125 return false;
2126 trueTarget = target;
2127 fallThroughMode = FallThroughMeansFalse;
2128 return true;
2129 }
2130
2131 return false;
2132 }
2133
2134 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2135 {
2136 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2137
2138 RefPtr<Label> beforeThen = generator.newLabel();
2139 RefPtr<Label> beforeElse = generator.newLabel();
2140 RefPtr<Label> afterElse = generator.newLabel();
2141
2142 Label* trueTarget = beforeThen.get();
2143 Label* falseTarget = beforeElse.get();
2144 FallThroughMode fallThroughMode = FallThroughMeansTrue;
2145 bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode);
2146
2147 generator.emitNodeInConditionContext(m_condition, trueTarget, falseTarget, fallThroughMode);
2148 generator.emitLabel(beforeThen.get());
2149 generator.emitProfileControlFlow(m_ifBlock->startOffset());
2150
2151 if (!didFoldIfBlock) {
2152 generator.emitNode(dst, m_ifBlock);
2153 if (m_elseBlock)
2154 generator.emitJump(afterElse.get());
2155 }
2156
2157 generator.emitLabel(beforeElse.get());
2158
2159 if (m_elseBlock) {
2160 generator.emitProfileControlFlow(m_ifBlock->endOffset() + (m_ifBlock->isBlock() ? 1 : 0));
2161 generator.emitNode(dst, m_elseBlock);
2162 }
2163
2164 generator.emitLabel(afterElse.get());
2165 StatementNode* endingBlock = m_elseBlock ? m_elseBlock : m_ifBlock;
2166 generator.emitProfileControlFlow(endingBlock->endOffset() + (endingBlock->isBlock() ? 1 : 0));
2167 }
2168
2169 // ------------------------------ DoWhileNode ----------------------------------
2170
2171 void DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2172 {
2173 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2174
2175 RefPtr<Label> topOfLoop = generator.newLabel();
2176 generator.emitLabel(topOfLoop.get());
2177 generator.emitLoopHint();
2178 generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2179
2180 generator.emitNode(dst, m_statement);
2181
2182 generator.emitLabel(scope->continueTarget());
2183 generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2184 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2185
2186 generator.emitLabel(scope->breakTarget());
2187 }
2188
2189 // ------------------------------ WhileNode ------------------------------------
2190
2191 void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2192 {
2193 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2194 RefPtr<Label> topOfLoop = generator.newLabel();
2195
2196 generator.emitDebugHook(WillExecuteStatement, m_expr->firstLine(), m_expr->startOffset(), m_expr->lineStartOffset());
2197 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2198
2199 generator.emitLabel(topOfLoop.get());
2200 generator.emitLoopHint();
2201
2202 generator.emitProfileControlFlow(m_statement->startOffset());
2203 generator.emitNode(dst, m_statement);
2204
2205 generator.emitLabel(scope->continueTarget());
2206 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2207
2208 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2209
2210 generator.emitLabel(scope->breakTarget());
2211
2212 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2213 }
2214
2215 // ------------------------------ ForNode --------------------------------------
2216
2217 void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2218 {
2219 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2220
2221 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2222
2223 if (m_expr1)
2224 generator.emitNode(generator.ignoredResult(), m_expr1);
2225
2226 RefPtr<Label> topOfLoop = generator.newLabel();
2227 if (m_expr2)
2228 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2229
2230 generator.emitLabel(topOfLoop.get());
2231 generator.emitLoopHint();
2232 generator.emitProfileControlFlow(m_statement->startOffset());
2233
2234 generator.emitNode(dst, m_statement);
2235
2236 generator.emitLabel(scope->continueTarget());
2237 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2238 if (m_expr3)
2239 generator.emitNode(generator.ignoredResult(), m_expr3);
2240
2241 if (m_expr2)
2242 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2243 else
2244 generator.emitJump(topOfLoop.get());
2245
2246 generator.emitLabel(scope->breakTarget());
2247 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2248 }
2249
2250 // ------------------------------ ForInNode ------------------------------------
2251
2252 RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator)
2253 {
2254 if (m_lexpr->isResolveNode()) {
2255 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2256 return generator.variable(ident).local();
2257 }
2258
2259 if (m_lexpr->isDestructuringNode()) {
2260 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2261 auto binding = assignNode->bindings();
2262 if (!binding->isBindingNode())
2263 return nullptr;
2264
2265 auto simpleBinding = static_cast<BindingNode*>(binding);
2266 const Identifier& ident = simpleBinding->boundProperty();
2267 Variable var = generator.variable(ident);
2268 if (var.isSpecial())
2269 return nullptr;
2270 return var.local();
2271 }
2272
2273 return nullptr;
2274 }
2275
2276 void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
2277 {
2278 if (m_lexpr->isResolveNode()) {
2279 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2280 Variable var = generator.variable(ident);
2281 if (RegisterID* local = var.local())
2282 generator.emitMove(local, propertyName);
2283 else {
2284 if (generator.isStrictMode())
2285 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2286 RegisterID* scope = generator.emitResolveScope(nullptr, var);
2287 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2288 generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
2289 if (generator.vm()->typeProfiler())
2290 generator.emitProfileType(propertyName, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
2291 }
2292 if (generator.vm()->typeProfiler())
2293 generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2294 return;
2295 }
2296 if (m_lexpr->isDotAccessorNode()) {
2297 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2298 const Identifier& ident = assignNode->identifier();
2299 RegisterID* base = generator.emitNode(assignNode->base());
2300 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2301 generator.emitPutById(base, ident, propertyName);
2302 if (generator.vm()->typeProfiler()) {
2303 generator.emitProfileType(propertyName, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
2304 generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
2305 }
2306 return;
2307 }
2308 if (m_lexpr->isBracketAccessorNode()) {
2309 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2310 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2311 RegisterID* subscript = generator.emitNode(assignNode->subscript());
2312 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2313 generator.emitPutByVal(base.get(), subscript, propertyName);
2314 if (generator.vm()->typeProfiler()) {
2315 generator.emitProfileType(propertyName, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
2316 generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
2317 }
2318 return;
2319 }
2320
2321 if (m_lexpr->isDestructuringNode()) {
2322 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2323 auto binding = assignNode->bindings();
2324 if (!binding->isBindingNode()) {
2325 assignNode->bindings()->bindValue(generator, propertyName);
2326 return;
2327 }
2328
2329 auto simpleBinding = static_cast<BindingNode*>(binding);
2330 const Identifier& ident = simpleBinding->boundProperty();
2331 Variable var = generator.variable(ident);
2332 if (!var.local() || var.isSpecial()) {
2333 assignNode->bindings()->bindValue(generator, propertyName);
2334 return;
2335 }
2336 generator.emitMove(var.local(), propertyName);
2337 if (generator.vm()->typeProfiler())
2338 generator.emitTypeProfilerExpressionInfo(simpleBinding->divotStart(), simpleBinding->divotEnd());
2339 return;
2340 }
2341
2342 RELEASE_ASSERT_NOT_REACHED();
2343 }
2344
2345 void ForInNode::emitMultiLoopBytecode(BytecodeGenerator& generator, RegisterID* dst)
2346 {
2347 if (!m_lexpr->isAssignmentLocation()) {
2348 emitThrowReferenceError(generator, ASCIILiteral("Left side of for-in statement is not a reference."));
2349 return;
2350 }
2351
2352 RefPtr<Label> end = generator.newLabel();
2353
2354 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2355
2356 RefPtr<RegisterID> base = generator.newTemporary();
2357 RefPtr<RegisterID> length;
2358 RefPtr<RegisterID> enumerator;
2359 generator.emitNode(base.get(), m_expr);
2360 RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
2361 RefPtr<RegisterID> enumeratorIndex;
2362
2363 int profilerStartOffset = m_statement->startOffset();
2364 int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
2365
2366 enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
2367
2368 // Indexed property loop.
2369 {
2370 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2371 RefPtr<Label> loopStart = generator.newLabel();
2372 RefPtr<Label> loopEnd = generator.newLabel();
2373
2374 length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
2375 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2376 RefPtr<RegisterID> propertyName = generator.newTemporary();
2377
2378 generator.emitLabel(loopStart.get());
2379 generator.emitLoopHint();
2380
2381 RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get());
2382 generator.emitJumpIfFalse(result.get(), loopEnd.get());
2383 generator.emitHasIndexedProperty(result.get(), base.get(), i.get());
2384 generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2385
2386 generator.emitToIndexString(propertyName.get(), i.get());
2387 this->emitLoopHeader(generator, propertyName.get());
2388
2389 generator.emitProfileControlFlow(profilerStartOffset);
2390
2391 generator.pushIndexedForInScope(local.get(), i.get());
2392 generator.emitNode(dst, m_statement);
2393 generator.popIndexedForInScope(local.get());
2394
2395 generator.emitProfileControlFlow(profilerEndOffset);
2396
2397 generator.emitLabel(scope->continueTarget());
2398 generator.emitInc(i.get());
2399 generator.emitJump(loopStart.get());
2400
2401 generator.emitLabel(scope->breakTarget());
2402 generator.emitJump(end.get());
2403 generator.emitLabel(loopEnd.get());
2404 }
2405
2406 // Structure property loop.
2407 {
2408 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2409 RefPtr<Label> loopStart = generator.newLabel();
2410 RefPtr<Label> loopEnd = generator.newLabel();
2411
2412 enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2413 RefPtr<RegisterID> propertyName = generator.newTemporary();
2414 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2415
2416 generator.emitLabel(loopStart.get());
2417 generator.emitLoopHint();
2418
2419 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2420 generator.emitJumpIfTrue(result.get(), loopEnd.get());
2421 generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
2422 generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2423
2424 this->emitLoopHeader(generator, propertyName.get());
2425
2426 generator.emitProfileControlFlow(profilerStartOffset);
2427
2428 generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
2429 generator.emitNode(dst, m_statement);
2430 generator.popStructureForInScope(local.get());
2431
2432 generator.emitProfileControlFlow(profilerEndOffset);
2433
2434 generator.emitLabel(scope->continueTarget());
2435 generator.emitInc(enumeratorIndex.get());
2436 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2437 generator.emitJump(loopStart.get());
2438
2439 generator.emitLabel(scope->breakTarget());
2440 generator.emitJump(end.get());
2441 generator.emitLabel(loopEnd.get());
2442 }
2443
2444 // Generic property loop.
2445 {
2446 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2447 RefPtr<Label> loopStart = generator.newLabel();
2448 RefPtr<Label> loopEnd = generator.newLabel();
2449
2450 RefPtr<RegisterID> propertyName = generator.newTemporary();
2451
2452 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2453
2454 generator.emitLabel(loopStart.get());
2455 generator.emitLoopHint();
2456
2457 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2458 generator.emitJumpIfTrue(result.get(), loopEnd.get());
2459
2460 generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
2461 generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2462
2463 this->emitLoopHeader(generator, propertyName.get());
2464
2465 generator.emitProfileControlFlow(profilerStartOffset);
2466
2467 generator.emitNode(dst, m_statement);
2468
2469 generator.emitLabel(scope->continueTarget());
2470 generator.emitInc(enumeratorIndex.get());
2471 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2472 generator.emitJump(loopStart.get());
2473
2474 generator.emitLabel(scope->breakTarget());
2475 generator.emitJump(end.get());
2476 generator.emitLabel(loopEnd.get());
2477 }
2478
2479 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2480 generator.emitLabel(end.get());
2481 generator.emitProfileControlFlow(profilerEndOffset);
2482 }
2483
2484 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2485 {
2486 this->emitMultiLoopBytecode(generator, dst);
2487 }
2488
2489 // ------------------------------ ForOfNode ------------------------------------
2490 void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2491 {
2492 if (!m_lexpr->isAssignmentLocation()) {
2493 emitThrowReferenceError(generator, ASCIILiteral("Left side of for-of statement is not a reference."));
2494 return;
2495 }
2496
2497 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2498 auto extractor = [this, dst](BytecodeGenerator& generator, RegisterID* value)
2499 {
2500 if (m_lexpr->isResolveNode()) {
2501 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2502 Variable var = generator.variable(ident);
2503 if (RegisterID* local = var.local())
2504 generator.emitMove(local, value);
2505 else {
2506 if (generator.isStrictMode())
2507 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2508 RegisterID* scope = generator.emitResolveScope(nullptr, var);
2509 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2510 generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
2511 if (generator.vm()->typeProfiler())
2512 generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
2513 }
2514 if (generator.vm()->typeProfiler())
2515 generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2516 } else if (m_lexpr->isDotAccessorNode()) {
2517 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2518 const Identifier& ident = assignNode->identifier();
2519 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2520
2521 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2522 generator.emitPutById(base.get(), ident, value);
2523 if (generator.vm()->typeProfiler()) {
2524 generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
2525 generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
2526 }
2527 } else if (m_lexpr->isBracketAccessorNode()) {
2528 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2529 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2530 RegisterID* subscript = generator.emitNode(assignNode->subscript());
2531
2532 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2533 generator.emitPutByVal(base.get(), subscript, value);
2534 if (generator.vm()->typeProfiler()) {
2535 generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
2536 generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
2537 }
2538 } else {
2539 ASSERT(m_lexpr->isDestructuringNode());
2540 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2541 assignNode->bindings()->bindValue(generator, value);
2542 }
2543 generator.emitProfileControlFlow(m_statement->startOffset());
2544 generator.emitNode(dst, m_statement);
2545 };
2546 generator.emitEnumeration(this, m_expr, extractor);
2547 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2548 }
2549
2550 // ------------------------------ ContinueNode ---------------------------------
2551
2552 Label* ContinueNode::trivialTarget(BytecodeGenerator& generator)
2553 {
2554 if (generator.shouldEmitDebugHooks())
2555 return 0;
2556
2557 LabelScopePtr scope = generator.continueTarget(m_ident);
2558 ASSERT(scope);
2559
2560 if (generator.scopeDepth() != scope->scopeDepth())
2561 return 0;
2562
2563 return scope->continueTarget();
2564 }
2565
2566 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2567 {
2568 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2569
2570 LabelScopePtr scope = generator.continueTarget(m_ident);
2571 ASSERT(scope);
2572
2573 generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2574 generator.emitJump(scope->continueTarget());
2575
2576 generator.emitProfileControlFlow(endOffset());
2577 }
2578
2579 // ------------------------------ BreakNode ------------------------------------
2580
2581 Label* BreakNode::trivialTarget(BytecodeGenerator& generator)
2582 {
2583 if (generator.shouldEmitDebugHooks())
2584 return 0;
2585
2586 LabelScopePtr scope = generator.breakTarget(m_ident);
2587 ASSERT(scope);
2588
2589 if (generator.scopeDepth() != scope->scopeDepth())
2590 return 0;
2591
2592 return scope->breakTarget();
2593 }
2594
2595 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2596 {
2597 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2598
2599 LabelScopePtr scope = generator.breakTarget(m_ident);
2600 ASSERT(scope);
2601
2602 generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2603 generator.emitJump(scope->breakTarget());
2604
2605 generator.emitProfileControlFlow(endOffset());
2606 }
2607
2608 // ------------------------------ ReturnNode -----------------------------------
2609
2610 void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2611 {
2612 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2613 ASSERT(generator.codeType() == FunctionCode);
2614
2615 if (dst == generator.ignoredResult())
2616 dst = 0;
2617
2618 RefPtr<RegisterID> returnRegister = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
2619 if (generator.vm()->typeProfiler()) {
2620 generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, nullptr);
2621 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
2622 }
2623 if (generator.scopeDepth()) {
2624 returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
2625 generator.emitPopScopes(generator.scopeRegister(), 0);
2626 }
2627
2628 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
2629 generator.emitReturn(returnRegister.get());
2630 generator.emitProfileControlFlow(endOffset());
2631 // Emitting an unreachable return here is needed in case this op_profile_control_flow is the
2632 // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode.
2633 if (generator.vm()->controlFlowProfiler())
2634 generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
2635 }
2636
2637 // ------------------------------ WithNode -------------------------------------
2638
2639 void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2640 {
2641 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2642
2643 RefPtr<RegisterID> scope = generator.emitNode(m_expr);
2644 generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
2645 generator.emitPushWithScope(generator.scopeRegister(), scope.get());
2646 generator.emitNode(dst, m_statement);
2647 generator.emitPopScope(generator.scopeRegister());
2648 }
2649
2650 // ------------------------------ CaseClauseNode --------------------------------
2651
2652 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2653 {
2654 generator.emitProfileControlFlow(m_startOffset);
2655 if (!m_statements)
2656 return;
2657 m_statements->emitBytecode(generator, dst);
2658 }
2659
2660 // ------------------------------ CaseBlockNode --------------------------------
2661
2662 enum SwitchKind {
2663 SwitchUnset = 0,
2664 SwitchNumber = 1,
2665 SwitchString = 2,
2666 SwitchNeither = 3
2667 };
2668
2669 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2670 {
2671 for (; list; list = list->getNext()) {
2672 ExpressionNode* clauseExpression = list->getClause()->expr();
2673 literalVector.append(clauseExpression);
2674 if (clauseExpression->isNumber()) {
2675 double value = static_cast<NumberNode*>(clauseExpression)->value();
2676 int32_t intVal = static_cast<int32_t>(value);
2677 if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
2678 typeForTable = SwitchNeither;
2679 break;
2680 }
2681 if (intVal < min_num)
2682 min_num = intVal;
2683 if (intVal > max_num)
2684 max_num = intVal;
2685 typeForTable = SwitchNumber;
2686 continue;
2687 }
2688 if (clauseExpression->isString()) {
2689 if (typeForTable & ~SwitchString) {
2690 typeForTable = SwitchNeither;
2691 break;
2692 }
2693 const String& value = static_cast<StringNode*>(clauseExpression)->value().string();
2694 if (singleCharacterSwitch &= value.length() == 1) {
2695 int32_t intVal = value[0];
2696 if (intVal < min_num)
2697 min_num = intVal;
2698 if (intVal > max_num)
2699 max_num = intVal;
2700 }
2701 typeForTable = SwitchString;
2702 continue;
2703 }
2704 typeForTable = SwitchNeither;
2705 break;
2706 }
2707 }
2708
2709 static inline size_t length(ClauseListNode* list1, ClauseListNode* list2)
2710 {
2711 size_t length = 0;
2712 for (ClauseListNode* node = list1; node; node = node->getNext())
2713 ++length;
2714 for (ClauseListNode* node = list2; node; node = node->getNext())
2715 ++length;
2716 return length;
2717 }
2718
2719 SwitchInfo::SwitchType CaseBlockNode::tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2720 {
2721 if (length(m_list1, m_list2) < s_tableSwitchMinimum)
2722 return SwitchInfo::SwitchNone;
2723
2724 SwitchKind typeForTable = SwitchUnset;
2725 bool singleCharacterSwitch = true;
2726
2727 processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2728 processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2729
2730 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2731 return SwitchInfo::SwitchNone;
2732
2733 if (typeForTable == SwitchNumber) {
2734 int32_t range = max_num - min_num;
2735 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2736 return SwitchInfo::SwitchImmediate;
2737 return SwitchInfo::SwitchNone;
2738 }
2739
2740 ASSERT(typeForTable == SwitchString);
2741
2742 if (singleCharacterSwitch) {
2743 int32_t range = max_num - min_num;
2744 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2745 return SwitchInfo::SwitchCharacter;
2746 }
2747
2748 return SwitchInfo::SwitchString;
2749 }
2750
2751 void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2752 {
2753 RefPtr<Label> defaultLabel;
2754 Vector<RefPtr<Label>, 8> labelVector;
2755 Vector<ExpressionNode*, 8> literalVector;
2756 int32_t min_num = std::numeric_limits<int32_t>::max();
2757 int32_t max_num = std::numeric_limits<int32_t>::min();
2758 SwitchInfo::SwitchType switchType = tryTableSwitch(literalVector, min_num, max_num);
2759
2760 if (switchType != SwitchInfo::SwitchNone) {
2761 // Prepare the various labels
2762 for (uint32_t i = 0; i < literalVector.size(); i++)
2763 labelVector.append(generator.newLabel());
2764 defaultLabel = generator.newLabel();
2765 generator.beginSwitch(switchExpression, switchType);
2766 } else {
2767 // Setup jumps
2768 for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
2769 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2770 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2771 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2772 labelVector.append(generator.newLabel());
2773 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2774 }
2775
2776 for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
2777 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2778 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2779 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2780 labelVector.append(generator.newLabel());
2781 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2782 }
2783 defaultLabel = generator.newLabel();
2784 generator.emitJump(defaultLabel.get());
2785 }
2786
2787 size_t i = 0;
2788 for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
2789 generator.emitLabel(labelVector[i++].get());
2790 list->getClause()->emitBytecode(generator, dst);
2791 }
2792
2793 if (m_defaultClause) {
2794 generator.emitLabel(defaultLabel.get());
2795 m_defaultClause->emitBytecode(generator, dst);
2796 }
2797
2798 for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
2799 generator.emitLabel(labelVector[i++].get());
2800 list->getClause()->emitBytecode(generator, dst);
2801 }
2802 if (!m_defaultClause)
2803 generator.emitLabel(defaultLabel.get());
2804
2805 ASSERT(i == labelVector.size());
2806 if (switchType != SwitchInfo::SwitchNone) {
2807 ASSERT(labelVector.size() == literalVector.size());
2808 generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2809 }
2810 }
2811
2812 // ------------------------------ SwitchNode -----------------------------------
2813
2814 void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2815 {
2816 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2817
2818 LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
2819
2820 RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
2821 m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2822
2823 generator.emitLabel(scope->breakTarget());
2824 generator.emitProfileControlFlow(endOffset());
2825 }
2826
2827 // ------------------------------ LabelNode ------------------------------------
2828
2829 void LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2830 {
2831 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2832
2833 ASSERT(!generator.breakTarget(m_name));
2834
2835 LabelScopePtr scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2836 generator.emitNode(dst, m_statement);
2837
2838 generator.emitLabel(scope->breakTarget());
2839 }
2840
2841 // ------------------------------ ThrowNode ------------------------------------
2842
2843 void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2844 {
2845 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2846
2847 if (dst == generator.ignoredResult())
2848 dst = 0;
2849 RefPtr<RegisterID> expr = generator.emitNode(m_expr);
2850 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2851 generator.emitThrow(expr.get());
2852
2853 generator.emitProfileControlFlow(endOffset());
2854 }
2855
2856 // ------------------------------ TryNode --------------------------------------
2857
2858 void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2859 {
2860 // NOTE: The catch and finally blocks must be labeled explicitly, so the
2861 // optimizer knows they may be jumped to from anywhere.
2862
2863 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2864
2865 ASSERT(m_catchBlock || m_finallyBlock);
2866
2867 RefPtr<Label> tryStartLabel = generator.newLabel();
2868 generator.emitLabel(tryStartLabel.get());
2869
2870 if (m_finallyBlock)
2871 generator.pushFinallyContext(m_finallyBlock);
2872 TryData* tryData = generator.pushTry(tryStartLabel.get());
2873
2874 generator.emitNode(dst, m_tryBlock);
2875
2876 if (m_catchBlock) {
2877 RefPtr<Label> catchEndLabel = generator.newLabel();
2878
2879 // Normal path: jump over the catch block.
2880 generator.emitJump(catchEndLabel.get());
2881
2882 // Uncaught exception path: the catch block.
2883 RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
2884 RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
2885 RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
2886 generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), here.get(), HandlerType::Catch);
2887
2888 if (m_finallyBlock) {
2889 // If the catch block throws an exception and we have a finally block, then the finally
2890 // block should "catch" that exception.
2891 tryData = generator.pushTry(here.get());
2892 }
2893
2894 generator.emitPushCatchScope(generator.scopeRegister(), m_thrownValueIdent, thrownValueRegister.get(), DontDelete);
2895 generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
2896 generator.emitNode(dst, m_catchBlock);
2897 generator.emitPopScope(generator.scopeRegister());
2898 generator.emitLabel(catchEndLabel.get());
2899 }
2900
2901 if (m_finallyBlock) {
2902 RefPtr<Label> preFinallyLabel = generator.emitLabel(generator.newLabel().get());
2903
2904 generator.popFinallyContext();
2905
2906 RefPtr<Label> finallyEndLabel = generator.newLabel();
2907
2908 int finallyStartOffset = m_catchBlock ? m_catchBlock->endOffset() + 1 : m_tryBlock->endOffset() + 1;
2909
2910 // Normal path: run the finally code, and jump to the end.
2911 generator.emitProfileControlFlow(finallyStartOffset);
2912 generator.emitNode(dst, m_finallyBlock);
2913 generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
2914 generator.emitJump(finallyEndLabel.get());
2915
2916 // Uncaught exception path: invoke the finally block, then re-throw the exception.
2917 RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
2918 RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
2919 generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), preFinallyLabel.get(), HandlerType::Finally);
2920 generator.emitProfileControlFlow(finallyStartOffset);
2921 generator.emitNode(dst, m_finallyBlock);
2922 generator.emitThrow(exceptionRegister.get());
2923
2924 generator.emitLabel(finallyEndLabel.get());
2925 generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
2926 } else
2927 generator.emitProfileControlFlow(m_catchBlock->endOffset() + 1);
2928
2929 }
2930
2931 // ------------------------------ ScopeNode -----------------------------
2932
2933 inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
2934 {
2935 if (!m_statements)
2936 return;
2937 m_statements->emitBytecode(generator, dst);
2938 }
2939
2940 // ------------------------------ ProgramNode -----------------------------
2941
2942 void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2943 {
2944 generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
2945
2946 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2947 generator.emitLoad(dstRegister.get(), jsUndefined());
2948 generator.emitProfileControlFlow(startStartOffset());
2949 emitStatementsBytecode(generator, dstRegister.get());
2950
2951 generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset());
2952 generator.emitEnd(dstRegister.get());
2953 }
2954
2955 // ------------------------------ EvalNode -----------------------------
2956
2957 void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2958 {
2959 generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
2960
2961 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2962 generator.emitLoad(dstRegister.get(), jsUndefined());
2963 emitStatementsBytecode(generator, dstRegister.get());
2964
2965 generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset());
2966 generator.emitEnd(dstRegister.get());
2967 }
2968
2969 // ------------------------------ FunctionBodyNode -----------------------------
2970
2971 void FunctionBodyNode::emitBytecode(BytecodeGenerator&, RegisterID*)
2972 {
2973 }
2974
2975 void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2976 {
2977 if (generator.vm()->typeProfiler()) {
2978 for (size_t i = 0; i < m_parameters->size(); i++) {
2979 // FIXME: Handle Destructuring assignments into arguments.
2980 if (!m_parameters->at(i)->isBindingNode())
2981 continue;
2982 BindingNode* parameter = static_cast<BindingNode*>(m_parameters->at(i));
2983 RegisterID reg(CallFrame::argumentOffset(i));
2984 generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, nullptr);
2985 generator.emitTypeProfilerExpressionInfo(parameter->divotStart(), parameter->divotEnd());
2986 }
2987 }
2988
2989 generator.emitProfileControlFlow(startStartOffset());
2990 generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset());
2991 emitStatementsBytecode(generator, generator.ignoredResult());
2992
2993 StatementNode* singleStatement = this->singleStatement();
2994 ReturnNode* returnNode = 0;
2995
2996 // Check for a return statement at the end of a function composed of a single block.
2997 if (singleStatement && singleStatement->isBlock()) {
2998 StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
2999 if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
3000 returnNode = static_cast<ReturnNode*>(lastStatementInBlock);
3001 }
3002
3003 // If there is no return we must automatically insert one.
3004 if (!returnNode) {
3005 RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
3006 if (generator.vm()->typeProfiler())
3007 generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement, nullptr); // Do not emit expression info for this profile because it's not in the user's source code.
3008 ASSERT(startOffset() >= lineStartOffset());
3009 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
3010 generator.emitReturn(r0);
3011 return;
3012 }
3013 }
3014
3015 // ------------------------------ FuncDeclNode ---------------------------------
3016
3017 void FuncDeclNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3018 {
3019 }
3020
3021 // ------------------------------ FuncExprNode ---------------------------------
3022
3023 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3024 {
3025 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
3026 }
3027
3028 #if ENABLE(ES6_CLASS_SYNTAX)
3029 // ------------------------------ ClassDeclNode ---------------------------------
3030
3031 void ClassDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3032 {
3033 generator.emitNode(dst, m_classDeclaration);
3034 }
3035
3036 // ------------------------------ ClassExprNode ---------------------------------
3037
3038 RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3039 {
3040 RefPtr<RegisterID> superclass;
3041 if (m_classHeritage) {
3042 superclass = generator.newTemporary();
3043 generator.emitNode(superclass.get(), m_classHeritage);
3044 }
3045
3046 RefPtr<RegisterID> constructor;
3047
3048 // FIXME: Make the prototype non-configurable & non-writable.
3049 if (m_constructorExpression)
3050 constructor = generator.emitNode(dst, m_constructorExpression);
3051 else {
3052 constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst),
3053 m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base, m_name);
3054 }
3055
3056 const auto& propertyNames = generator.propertyNames();
3057 RefPtr<RegisterID> prototype = generator.emitNewObject(generator.newTemporary());
3058
3059 if (superclass) {
3060 RefPtr<RegisterID> protoParent = generator.newTemporary();
3061 generator.emitLoad(protoParent.get(), jsNull());
3062
3063 RefPtr<RegisterID> tempRegister = generator.newTemporary();
3064
3065 // FIXME: Throw TypeError if it's a generator function.
3066 RefPtr<Label> superclassIsUndefinedLabel = generator.newLabel();
3067 generator.emitJumpIfTrue(generator.emitIsUndefined(tempRegister.get(), superclass.get()), superclassIsUndefinedLabel.get());
3068
3069 RefPtr<Label> superclassIsNullLabel = generator.newLabel();
3070 generator.emitJumpIfTrue(generator.emitUnaryOp(op_eq_null, tempRegister.get(), superclass.get()), superclassIsNullLabel.get());
3071
3072 RefPtr<Label> superclassIsObjectLabel = generator.newLabel();
3073 generator.emitJumpIfTrue(generator.emitIsObject(tempRegister.get(), superclass.get()), superclassIsObjectLabel.get());
3074 generator.emitLabel(superclassIsUndefinedLabel.get());
3075 generator.emitThrowTypeError(ASCIILiteral("The superclass is not an object."));
3076 generator.emitLabel(superclassIsObjectLabel.get());
3077 generator.emitGetById(protoParent.get(), superclass.get(), generator.propertyNames().prototype);
3078
3079 RefPtr<Label> protoParentIsObjectOrNullLabel = generator.newLabel();
3080 generator.emitJumpIfTrue(generator.emitUnaryOp(op_is_object_or_null, tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
3081 generator.emitThrowTypeError(ASCIILiteral("The superclass's prototype is not an object."));
3082 generator.emitLabel(protoParentIsObjectOrNullLabel.get());
3083
3084 generator.emitDirectPutById(constructor.get(), generator.propertyNames().underscoreProto, superclass.get(), PropertyNode::Unknown);
3085 generator.emitLabel(superclassIsNullLabel.get());
3086 generator.emitDirectPutById(prototype.get(), generator.propertyNames().underscoreProto, protoParent.get(), PropertyNode::Unknown);
3087
3088 emitPutHomeObject(generator, constructor.get(), prototype.get());
3089 }
3090
3091 RefPtr<RegisterID> constructorNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.constructor);
3092 generator.emitCallDefineProperty(prototype.get(), constructorNameRegister.get(), constructor.get(), nullptr, nullptr,
3093 BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
3094
3095 RefPtr<RegisterID> prototypeNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.prototype);
3096 generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0, m_position);
3097
3098 if (m_staticMethods)
3099 generator.emitNode(constructor.get(), m_staticMethods);
3100
3101 if (m_instanceMethods)
3102 generator.emitNode(prototype.get(), m_instanceMethods);
3103
3104 return generator.moveToDestinationIfNeeded(dst, constructor.get());
3105 }
3106 #endif
3107
3108 // ------------------------------ DestructuringAssignmentNode -----------------
3109 RegisterID* DestructuringAssignmentNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3110 {
3111 if (RegisterID* result = m_bindings->emitDirectBinding(generator, dst, m_initializer))
3112 return result;
3113 RefPtr<RegisterID> initializer = generator.tempDestination(dst);
3114 generator.emitNode(initializer.get(), m_initializer);
3115 m_bindings->bindValue(generator, initializer.get());
3116 return generator.moveToDestinationIfNeeded(dst, initializer.get());
3117 }
3118
3119 DestructuringPatternNode::~DestructuringPatternNode()
3120 {
3121 }
3122
3123 static void assignDefaultValueIfUndefined(BytecodeGenerator& generator, RegisterID* maybeUndefined, ExpressionNode* defaultValue)
3124 {
3125 ASSERT(defaultValue);
3126 RefPtr<Label> isNotUndefined = generator.newLabel();
3127 generator.emitJumpIfFalse(generator.emitIsUndefined(generator.newTemporary(), maybeUndefined), isNotUndefined.get());
3128 generator.emitNode(maybeUndefined, defaultValue);
3129 generator.emitLabel(isNotUndefined.get());
3130 }
3131
3132 void ArrayPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
3133 {
3134 RefPtr<RegisterID> iterator = generator.newTemporary();
3135 {
3136 generator.emitGetById(iterator.get(), rhs, generator.propertyNames().iteratorSymbol);
3137 CallArguments args(generator, nullptr);
3138 generator.emitMove(args.thisRegister(), rhs);
3139 generator.emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd());
3140 }
3141
3142 if (m_targetPatterns.isEmpty()) {
3143 generator.emitIteratorClose(iterator.get(), this);
3144 return;
3145 }
3146
3147 RefPtr<RegisterID> done;
3148 for (auto& target : m_targetPatterns) {
3149 switch (target.bindingType) {
3150 case BindingType::Elision:
3151 case BindingType::Element: {
3152 RefPtr<Label> iterationSkipped = generator.newLabel();
3153 if (!done)
3154 done = generator.newTemporary();
3155 else
3156 generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
3157
3158 RefPtr<RegisterID> value = generator.newTemporary();
3159 generator.emitIteratorNext(value.get(), iterator.get(), this);
3160 generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
3161 generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
3162 generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
3163
3164 {
3165 RefPtr<Label> valueIsSet = generator.newLabel();
3166 generator.emitJump(valueIsSet.get());
3167 generator.emitLabel(iterationSkipped.get());
3168 generator.emitLoad(value.get(), jsUndefined());
3169 generator.emitLabel(valueIsSet.get());
3170 }
3171
3172 if (target.bindingType == BindingType::Element) {
3173 if (target.defaultValue)
3174 assignDefaultValueIfUndefined(generator, value.get(), target.defaultValue);
3175 target.pattern->bindValue(generator, value.get());
3176 }
3177 break;
3178 }
3179
3180 case BindingType::RestElement: {
3181 RefPtr<RegisterID> array = generator.emitNewArray(generator.newTemporary(), 0, 0);
3182
3183 RefPtr<Label> iterationDone = generator.newLabel();
3184 if (!done)
3185 done = generator.newTemporary();
3186 else
3187 generator.emitJumpIfTrue(done.get(), iterationDone.get());
3188
3189 RefPtr<RegisterID> index = generator.newTemporary();
3190 generator.emitLoad(index.get(), jsNumber(0));
3191 RefPtr<Label> loopStart = generator.newLabel();
3192 generator.emitLabel(loopStart.get());
3193
3194 RefPtr<RegisterID> value = generator.newTemporary();
3195 generator.emitIteratorNext(value.get(), iterator.get(), this);
3196 generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
3197 generator.emitJumpIfTrue(done.get(), iterationDone.get());
3198 generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
3199
3200 generator.emitDirectPutByVal(array.get(), index.get(), value.get());
3201 generator.emitInc(index.get());
3202 generator.emitJump(loopStart.get());
3203
3204 generator.emitLabel(iterationDone.get());
3205 target.pattern->bindValue(generator, array.get());
3206 break;
3207 }
3208 }
3209 }
3210
3211 RefPtr<Label> iteratorClosed = generator.newLabel();
3212 generator.emitJumpIfTrue(done.get(), iteratorClosed.get());
3213 generator.emitIteratorClose(iterator.get(), this);
3214 generator.emitLabel(iteratorClosed.get());
3215 }
3216
3217 RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
3218 {
3219 if (!rhs->isSimpleArray())
3220 return 0;
3221
3222 RefPtr<RegisterID> resultRegister;
3223 if (dst && dst != generator.ignoredResult())
3224 resultRegister = generator.emitNewArray(generator.newTemporary(), 0, 0);
3225 ElementNode* elementNodes = static_cast<ArrayNode*>(rhs)->elements();
3226 Vector<ExpressionNode*> elements;
3227 for (; elementNodes; elementNodes = elementNodes->next())
3228 elements.append(elementNodes->value());
3229 if (m_targetPatterns.size() != elements.size())
3230 return 0;
3231 Vector<RefPtr<RegisterID>> registers;
3232 registers.reserveCapacity(m_targetPatterns.size());
3233 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3234 registers.uncheckedAppend(generator.newTemporary());
3235 generator.emitNode(registers.last().get(), elements[i]);
3236 if (m_targetPatterns[i].defaultValue)
3237 assignDefaultValueIfUndefined(generator, registers.last().get(), m_targetPatterns[i].defaultValue);
3238 if (resultRegister)
3239 generator.emitPutByIndex(resultRegister.get(), i, registers.last().get());
3240 }
3241
3242 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3243 if (m_targetPatterns[i].pattern)
3244 m_targetPatterns[i].pattern->bindValue(generator, registers[i].get());
3245 }
3246 if (resultRegister)
3247 return generator.moveToDestinationIfNeeded(dst, resultRegister.get());
3248 return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
3249 }
3250
3251 void ArrayPatternNode::toString(StringBuilder& builder) const
3252 {
3253 builder.append('[');
3254 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3255 const auto& target = m_targetPatterns[i];
3256
3257 switch (target.bindingType) {
3258 case BindingType::Elision:
3259 builder.append(',');
3260 break;
3261
3262 case BindingType::Element:
3263 target.pattern->toString(builder);
3264 if (i < m_targetPatterns.size() - 1)
3265 builder.append(',');
3266 break;
3267
3268 case BindingType::RestElement:
3269 builder.append("...");
3270 target.pattern->toString(builder);
3271 break;
3272 }
3273 }
3274 builder.append(']');
3275 }
3276
3277 void ArrayPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3278 {
3279 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3280 if (DestructuringPatternNode* node = m_targetPatterns[i].pattern.get())
3281 node->collectBoundIdentifiers(identifiers);
3282 }
3283 }
3284
3285 void ObjectPatternNode::toString(StringBuilder& builder) const
3286 {
3287 builder.append('{');
3288 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3289 if (m_targetPatterns[i].wasString)
3290 builder.appendQuotedJSONString(m_targetPatterns[i].propertyName.string());
3291 else
3292 builder.append(m_targetPatterns[i].propertyName.string());
3293 builder.append(':');
3294 m_targetPatterns[i].pattern->toString(builder);
3295 if (i < m_targetPatterns.size() - 1)
3296 builder.append(',');
3297 }
3298 builder.append('}');
3299 }
3300
3301 void ObjectPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
3302 {
3303 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3304 auto& target = m_targetPatterns[i];
3305 RefPtr<RegisterID> temp = generator.newTemporary();
3306 generator.emitGetById(temp.get(), rhs, target.propertyName);
3307 if (target.defaultValue)
3308 assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
3309 target.pattern->bindValue(generator, temp.get());
3310 }
3311 }
3312
3313 void ObjectPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3314 {
3315 for (size_t i = 0; i < m_targetPatterns.size(); i++)
3316 m_targetPatterns[i].pattern->collectBoundIdentifiers(identifiers);
3317 }
3318
3319 void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
3320 {
3321 Variable var = generator.variable(m_boundProperty);
3322 if (RegisterID* local = var.local()) {
3323 if (var.isReadOnly()) {
3324 generator.emitReadOnlyExceptionIfNeeded();
3325 return;
3326 }
3327 generator.emitMove(local, value);
3328 if (generator.vm()->typeProfiler())
3329 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
3330 return;
3331 }
3332 if (generator.isStrictMode())
3333 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3334 RegisterID* scope = generator.emitResolveScope(nullptr, var);
3335 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3336 generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
3337 if (generator.vm()->typeProfiler()) {
3338 generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
3339 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
3340 }
3341 return;
3342 }
3343
3344 void BindingNode::toString(StringBuilder& builder) const
3345 {
3346 builder.append(m_boundProperty.string());
3347 }
3348
3349 void BindingNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3350 {
3351 identifiers.append(m_boundProperty);
3352 }
3353
3354 RegisterID* SpreadExpressionNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3355 {
3356 RELEASE_ASSERT_NOT_REACHED();
3357 return 0;
3358 }
3359
3360 } // namespace JSC