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