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