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