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