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