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.
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.
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.
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.
29 #include "NodeConstructors.h"
31 #include "BuiltinNames.h"
32 #include "BytecodeGenerator.h"
33 #include "CallFrame.h"
35 #include "JSCInlines.h"
36 #include "JSFunction.h"
37 #include "JSGeneratorFunction.h"
38 #include "JSGlobalObject.h"
39 #include "LabelScope.h"
42 #include "StackAlignment.h"
43 #include <wtf/Assertions.h>
44 #include <wtf/Threading.h>
45 #include <wtf/text/StringBuilder.h>
52 Details of the emitBytecode function.
54 Return value: The register holding the production's value.
55 dst: An optional parameter specifying the most efficient destination at
56 which to store the production's value. The callee must honor dst.
58 The dst argument provides for a crude form of copy propagation. For example,
71 because the assignment node, "x =", passes r[x] as dst to the number node, "1".
74 void ExpressionNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
76 RegisterID* result = generator.emitNode(this);
77 if (fallThroughMode == FallThroughMeansTrue)
78 generator.emitJumpIfFalse(result, falseTarget);
80 generator.emitJumpIfTrue(result, trueTarget);
83 // ------------------------------ ThrowableExpressionData --------------------------------
85 RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message)
87 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
88 generator.emitThrowReferenceError(message);
89 return generator.newTemporary();
92 // ------------------------------ ConstantNode ----------------------------------
94 void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
96 TriState value = jsValue(generator).pureToBoolean();
98 if (UNLIKELY(needsDebugHook())) {
99 if (value != MixedTriState)
100 generator.emitDebugHook(this);
103 if (value == MixedTriState)
104 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
105 else if (value == TrueTriState && fallThroughMode == FallThroughMeansFalse)
106 generator.emitJump(trueTarget);
107 else if (value == FalseTriState && fallThroughMode == FallThroughMeansTrue)
108 generator.emitJump(falseTarget);
110 // All other cases are unconditional fall-throughs, like "if (true)".
113 RegisterID* ConstantNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
115 if (dst == generator.ignoredResult())
117 return generator.emitLoad(dst, jsValue(generator));
120 JSValue StringNode::jsValue(BytecodeGenerator& generator) const
122 return generator.addStringConstant(m_value);
125 // ------------------------------ NumberNode ----------------------------------
127 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
129 if (dst == generator.ignoredResult())
131 return generator.emitLoad(dst, jsValue(generator), isIntegerNode() ? SourceCodeRepresentation::Integer : SourceCodeRepresentation::Double);
134 // ------------------------------ RegExpNode -----------------------------------
136 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
138 if (dst == generator.ignoredResult())
140 return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string())));
143 // ------------------------------ ThisNode -------------------------------------
145 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
147 generator.ensureThis();
148 if (dst == generator.ignoredResult())
151 RegisterID* result = generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
152 static const unsigned thisLength = 4;
153 generator.emitProfileType(generator.thisRegister(), position(), JSTextPosition(-1, position().offset + thisLength, -1));
157 // ------------------------------ SuperNode -------------------------------------
159 static RegisterID* emitHomeObjectForCallee(BytecodeGenerator& generator)
161 if (generator.isDerivedClassContext() || generator.isDerivedConstructorContext()) {
162 RegisterID* derivedConstructor = generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
163 return generator.emitGetById(generator.newTemporary(), derivedConstructor, generator.propertyNames().builtinNames().homeObjectPrivateName());
167 callee.setIndex(CallFrameSlot::callee);
168 return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().builtinNames().homeObjectPrivateName());
171 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator)
173 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
174 return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
177 static RegisterID* emitGetSuperFunctionForConstruct(BytecodeGenerator& generator)
179 if (generator.isDerivedConstructorContext())
180 return generator.emitGetById(generator.newTemporary(), generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(), generator.propertyNames().underscoreProto);
183 callee.setIndex(CallFrameSlot::callee);
184 return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().underscoreProto);
187 RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
189 RegisterID* result = emitSuperBaseForCallee(generator);
190 return generator.moveToDestinationIfNeeded(generator.finalDestination(dst), result);
193 // ------------------------------ ImportNode -------------------------------------
195 RegisterID* ImportNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
197 RefPtr<RegisterID> importModule = generator.emitGetGlobalPrivate(generator.newTemporary(), generator.propertyNames().builtinNames().importModulePrivateName());
198 CallArguments arguments(generator, nullptr, 1);
199 generator.emitLoad(arguments.thisRegister(), jsUndefined());
200 generator.emitNode(arguments.argumentRegister(0), m_expr);
201 return generator.emitCall(generator.finalDestination(dst, importModule.get()), importModule.get(), NoExpectedFunction, arguments, divot(), divotStart(), divotEnd(), DebuggableCall::No);
204 // ------------------------------ NewTargetNode ----------------------------------
206 RegisterID* NewTargetNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
208 if (dst == generator.ignoredResult())
211 return generator.moveToDestinationIfNeeded(dst, generator.newTarget());
214 // ------------------------------ ResolveNode ----------------------------------
216 bool ResolveNode::isPure(BytecodeGenerator& generator) const
218 return generator.variable(m_ident).offset().isStack();
221 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
223 Variable var = generator.variable(m_ident);
224 if (RegisterID* local = var.local()) {
225 generator.emitTDZCheckIfNecessary(var, local, nullptr);
226 if (dst == generator.ignoredResult())
229 generator.emitProfileType(local, var, m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
230 return generator.moveToDestinationIfNeeded(dst, local);
233 JSTextPosition divot = m_start + m_ident.length();
234 generator.emitExpressionInfo(divot, m_start, divot);
235 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
236 RegisterID* finalDest = generator.finalDestination(dst);
237 RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
238 generator.emitTDZCheckIfNecessary(var, finalDest, nullptr);
239 generator.emitProfileType(finalDest, var, m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
243 // ------------------------------ TemplateStringNode -----------------------------------
245 RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
247 if (dst == generator.ignoredResult())
250 return generator.emitLoad(dst, JSValue(generator.addStringConstant(*cooked())));
253 // ------------------------------ TemplateLiteralNode -----------------------------------
255 RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
257 if (!m_templateExpressions) {
258 TemplateStringNode* templateString = m_templateStrings->value();
259 ASSERT_WITH_MESSAGE(!m_templateStrings->next(), "Only one template element exists because there's no expression in a given template literal.");
260 return generator.emitNode(dst, templateString);
263 Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
265 TemplateStringListNode* templateString = m_templateStrings;
266 TemplateExpressionListNode* templateExpression = m_templateExpressions;
267 for (; templateExpression; templateExpression = templateExpression->next(), templateString = templateString->next()) {
268 // Evaluate TemplateString.
269 ASSERT(templateString->value()->cooked());
270 if (!templateString->value()->cooked()->isEmpty()) {
271 temporaryRegisters.append(generator.newTemporary());
272 generator.emitNode(temporaryRegisters.last().get(), templateString->value());
275 // Evaluate Expression.
276 temporaryRegisters.append(generator.newTemporary());
277 generator.emitNode(temporaryRegisters.last().get(), templateExpression->value());
278 generator.emitToString(temporaryRegisters.last().get(), temporaryRegisters.last().get());
281 // Evaluate tail TemplateString.
282 ASSERT(templateString->value()->cooked());
283 if (!templateString->value()->cooked()->isEmpty()) {
284 temporaryRegisters.append(generator.newTemporary());
285 generator.emitNode(temporaryRegisters.last().get(), templateString->value());
288 if (temporaryRegisters.size() == 1)
289 return generator.emitToString(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get());
291 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
294 // ------------------------------ TaggedTemplateNode -----------------------------------
296 RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
298 ExpectedFunction expectedFunction = NoExpectedFunction;
299 RefPtr<RegisterID> tag = nullptr;
300 RefPtr<RegisterID> base = nullptr;
301 if (!m_tag->isLocation()) {
302 tag = generator.newTemporary();
303 tag = generator.emitNode(tag.get(), m_tag);
304 } else if (m_tag->isResolveNode()) {
305 ResolveNode* resolve = static_cast<ResolveNode*>(m_tag);
306 const Identifier& identifier = resolve->identifier();
307 expectedFunction = generator.expectedFunctionForIdentifier(identifier);
309 Variable var = generator.variable(identifier);
310 if (RegisterID* local = var.local()) {
311 generator.emitTDZCheckIfNecessary(var, local, nullptr);
312 tag = generator.emitMove(generator.newTemporary(), local);
314 tag = generator.newTemporary();
315 base = generator.newTemporary();
317 JSTextPosition newDivot = divotStart() + identifier.length();
318 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
319 generator.moveToDestinationIfNeeded(base.get(), generator.emitResolveScope(base.get(), var));
320 generator.emitGetFromScope(tag.get(), base.get(), var, ThrowIfNotFound);
321 generator.emitTDZCheckIfNecessary(var, tag.get(), nullptr);
323 } else if (m_tag->isBracketAccessorNode()) {
324 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(m_tag);
325 base = generator.newTemporary();
326 base = generator.emitNode(base.get(), bracket->base());
327 RefPtr<RegisterID> property = generator.emitNodeForProperty(bracket->subscript());
328 if (bracket->base()->isSuperNode()) {
329 RefPtr<RegisterID> thisValue = generator.ensureThis();
330 tag = generator.emitGetByVal(generator.newTemporary(), base.get(), thisValue.get(), property.get());
332 tag = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
334 ASSERT(m_tag->isDotAccessorNode());
335 DotAccessorNode* dot = static_cast<DotAccessorNode*>(m_tag);
336 base = generator.newTemporary();
337 base = generator.emitNode(base.get(), dot->base());
338 if (dot->base()->isSuperNode()) {
339 RefPtr<RegisterID> thisValue = generator.ensureThis();
340 tag = generator.emitGetById(generator.newTemporary(), base.get(), thisValue.get(), dot->identifier());
342 tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
345 RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(nullptr, this);
347 unsigned expressionsCount = 0;
348 for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
351 CallArguments callArguments(generator, nullptr, 1 + expressionsCount);
353 generator.emitMove(callArguments.thisRegister(), base.get());
355 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
357 unsigned argumentIndex = 0;
358 generator.emitMove(callArguments.argumentRegister(argumentIndex++), templateObject.get());
359 for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
360 generator.emitNode(callArguments.argumentRegister(argumentIndex++), templateExpression->value());
362 return generator.emitCallInTailPosition(generator.finalDestination(dst, tag.get()), tag.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
365 // ------------------------------ ArrayNode ------------------------------------
367 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
369 // FIXME: Should we put all of this code into emitNewArray?
372 ElementNode* firstPutElement;
373 for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
374 if (firstPutElement->elision() || firstPutElement->value()->isSpreadExpression())
379 if (!firstPutElement && !m_elision)
380 return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
382 if (firstPutElement && firstPutElement->value()->isSpreadExpression()) {
383 bool hasElision = false;
384 for (ElementNode* node = m_element; node; node = node->next()) {
385 if (!!node->elision()) {
394 return generator.emitNewArrayWithSpread(generator.finalDestination(dst), m_element);
397 RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
398 ElementNode* n = firstPutElement;
399 for (; n; n = n->next()) {
400 if (n->value()->isSpreadExpression())
402 RegisterID* value = generator.emitNode(n->value());
403 length += n->elision();
404 generator.emitPutByIndex(array.get(), length++, value);
408 RegisterID* value = generator.emitLoad(0, jsNumber(m_elision + length));
409 generator.emitPutById(array.get(), generator.propertyNames().length, value);
412 return generator.moveToDestinationIfNeeded(dst, array.get());
415 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(length));
416 auto spreader = [array, index](BytecodeGenerator& generator, RegisterID* value)
418 generator.emitDirectPutByVal(array.get(), index.get(), value);
419 generator.emitInc(index.get());
421 for (; n; n = n->next()) {
423 generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(n->elision())), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
424 if (n->value()->isSpreadExpression()) {
425 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(n->value());
426 generator.emitEnumeration(spread, spread->expression(), spreader);
428 generator.emitDirectPutByVal(array.get(), index.get(), generator.emitNode(n->value()));
429 generator.emitInc(index.get());
434 generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(m_elision)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
435 generator.emitPutById(array.get(), generator.propertyNames().length, index.get());
437 return generator.moveToDestinationIfNeeded(dst, array.get());
440 bool ArrayNode::isSimpleArray() const
442 if (m_elision || m_optional)
444 for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
447 if (ptr->value()->isSpreadExpression())
453 ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNumber, int startPosition) const
455 ASSERT(!m_elision && !m_optional);
456 ElementNode* ptr = m_element;
459 JSTokenLocation location;
460 location.line = lineNumber;
461 location.startOffset = startPosition;
462 ArgumentListNode* head = new (parserArena) ArgumentListNode(location, ptr->value());
463 ArgumentListNode* tail = head;
465 for (; ptr; ptr = ptr->next()) {
466 ASSERT(!ptr->elision());
467 tail = new (parserArena) ArgumentListNode(location, tail, ptr->value());
472 // ------------------------------ ObjectLiteralNode ----------------------------
474 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
477 if (dst == generator.ignoredResult())
479 return generator.emitNewObject(generator.finalDestination(dst));
481 RefPtr<RegisterID> newObj = generator.emitNewObject(generator.tempDestination(dst));
482 generator.emitNode(newObj.get(), m_list);
483 return generator.moveToDestinationIfNeeded(dst, newObj.get());
486 // ------------------------------ PropertyListNode -----------------------------
488 static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject)
490 generator.emitPutById(function, generator.propertyNames().builtinNames().homeObjectPrivateName(), homeObject);
493 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
495 // Fast case: this loop just handles regular value properties.
496 PropertyListNode* p = this;
497 for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next)
498 emitPutConstantProperty(generator, dst, *p->m_node);
500 // Were there any get/set properties?
502 // Build a list of getter/setter pairs to try to put them at the same time. If we encounter
503 // a computed property or a spread, just emit everything as that may override previous values.
504 bool canOverrideProperties = false;
506 typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
507 typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;
510 // Build a map, pairing get/set values together.
511 for (PropertyListNode* q = p; q; q = q->m_next) {
512 PropertyNode* node = q->m_node;
513 if (node->m_type & PropertyNode::Computed || node->m_type & PropertyNode::Spread) {
514 canOverrideProperties = true;
518 if (node->m_type & PropertyNode::Constant)
521 // Duplicates are possible.
522 GetterSetterPair pair(node, static_cast<PropertyNode*>(nullptr));
523 GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair);
524 if (!result.isNewEntry) {
525 if (result.iterator->value.first->m_type == node->m_type)
526 result.iterator->value.first = node;
528 result.iterator->value.second = node;
532 // Iterate over the remaining properties in the list.
533 for (; p; p = p->m_next) {
534 PropertyNode* node = p->m_node;
536 // Handle regular values.
537 if (node->m_type & PropertyNode::Constant) {
538 emitPutConstantProperty(generator, dst, *node);
540 } else if (node->m_type & PropertyNode::Spread) {
541 generator.emitNode(dst, node->m_assign);
545 RefPtr<RegisterID> value = generator.emitNode(node->m_assign);
546 bool needsSuperBinding = node->needsSuperBinding();
547 if (needsSuperBinding)
548 emitPutHomeObject(generator, value.get(), dst);
550 unsigned attributes = node->isClassProperty() ? (Accessor | DontEnum) : Accessor;
552 ASSERT(node->m_type & (PropertyNode::Getter | PropertyNode::Setter));
554 // This is a get/set property which may be overridden by a computed property or spread later.
555 if (canOverrideProperties) {
556 // Computed accessors.
557 if (node->m_type & PropertyNode::Computed) {
558 RefPtr<RegisterID> propertyName = generator.emitNode(node->m_expression);
559 generator.emitSetFunctionNameIfNeeded(node->m_assign, value.get(), propertyName.get());
560 if (node->m_type & PropertyNode::Getter)
561 generator.emitPutGetterByVal(dst, propertyName.get(), attributes, value.get());
563 generator.emitPutSetterByVal(dst, propertyName.get(), attributes, value.get());
567 if (node->m_type & PropertyNode::Getter)
568 generator.emitPutGetterById(dst, *node->name(), attributes, value.get());
570 generator.emitPutSetterById(dst, *node->name(), attributes, value.get());
574 // This is a get/set property pair.
575 GetterSetterMap::iterator it = map.find(node->name()->impl());
576 ASSERT(it != map.end());
577 GetterSetterPair& pair = it->value;
579 // Was this already generated as a part of its partner?
580 if (pair.second == node)
583 // Generate the paired node now.
584 RefPtr<RegisterID> getterReg;
585 RefPtr<RegisterID> setterReg;
586 RegisterID* secondReg = nullptr;
588 if (node->m_type & PropertyNode::Getter) {
591 ASSERT(pair.second->m_type & PropertyNode::Setter);
592 setterReg = generator.emitNode(pair.second->m_assign);
593 secondReg = setterReg.get();
595 setterReg = generator.newTemporary();
596 generator.emitLoad(setterReg.get(), jsUndefined());
599 ASSERT(node->m_type & PropertyNode::Setter);
602 ASSERT(pair.second->m_type & PropertyNode::Getter);
603 getterReg = generator.emitNode(pair.second->m_assign);
604 secondReg = getterReg.get();
606 getterReg = generator.newTemporary();
607 generator.emitLoad(getterReg.get(), jsUndefined());
611 ASSERT(!pair.second || needsSuperBinding == pair.second->needsSuperBinding());
612 if (needsSuperBinding && pair.second)
613 emitPutHomeObject(generator, secondReg, dst);
615 generator.emitPutGetterSetter(dst, *node->name(), attributes, getterReg.get(), setterReg.get());
622 void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node)
624 RefPtr<RegisterID> value = generator.emitNode(node.m_assign);
625 if (node.needsSuperBinding())
626 emitPutHomeObject(generator, value.get(), newObj);
628 if (node.isClassProperty()) {
629 ASSERT(node.needsSuperBinding());
630 RefPtr<RegisterID> propertyNameRegister;
632 propertyNameRegister = generator.emitLoad(nullptr, *node.name());
634 propertyNameRegister = generator.emitNode(node.m_expression);
636 generator.emitSetFunctionNameIfNeeded(node.m_assign, value.get(), propertyNameRegister.get());
637 generator.emitCallDefineProperty(newObj, propertyNameRegister.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
640 if (const auto* identifier = node.name()) {
641 std::optional<uint32_t> optionalIndex = parseIndex(*identifier);
642 if (!optionalIndex) {
643 generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType());
647 RefPtr<RegisterID> index = generator.emitLoad(nullptr, jsNumber(optionalIndex.value()));
648 generator.emitDirectPutByVal(newObj, index.get(), value.get());
651 RefPtr<RegisterID> propertyName = generator.emitNode(node.m_expression);
652 generator.emitSetFunctionNameIfNeeded(node.m_assign, value.get(), propertyName.get());
653 generator.emitDirectPutByVal(newObj, propertyName.get(), value.get());
656 // ------------------------------ BracketAccessorNode --------------------------------
658 static bool isNonIndexStringElement(ExpressionNode& element)
660 return element.isString() && !parseIndex(static_cast<StringNode&>(element).value());
663 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
665 if (m_base->isSuperNode()) {
666 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
667 RefPtr<RegisterID> thisValue = generator.ensureThis();
668 RefPtr<RegisterID> superBase = emitSuperBaseForCallee(generator);
670 if (isNonIndexStringElement(*m_subscript)) {
671 const Identifier& id = static_cast<StringNode*>(m_subscript)->value();
672 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
673 generator.emitGetById(finalDest.get(), superBase.get(), thisValue.get(), id);
675 RefPtr<RegisterID> subscript = generator.emitNodeForProperty(m_subscript);
676 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
677 generator.emitGetByVal(finalDest.get(), superBase.get(), thisValue.get(), subscript.get());
680 generator.emitProfileType(finalDest.get(), divotStart(), divotEnd());
681 return finalDest.get();
685 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
687 if (isNonIndexStringElement(*m_subscript)) {
688 RefPtr<RegisterID> base = generator.emitNode(m_base);
689 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
690 ret = generator.emitGetById(finalDest.get(), base.get(), static_cast<StringNode*>(m_subscript)->value());
692 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
693 RegisterID* property = generator.emitNodeForProperty(m_subscript);
694 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
695 ret = generator.emitGetByVal(finalDest.get(), base.get(), property);
698 generator.emitProfileType(finalDest.get(), divotStart(), divotEnd());
702 // ------------------------------ DotAccessorNode --------------------------------
704 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
706 bool baseIsSuper = m_base->isSuperNode();
707 RefPtr<RegisterID> base = baseIsSuper ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
708 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
709 RegisterID* finalDest = generator.finalDestination(dst);
712 RefPtr<RegisterID> thisValue = generator.ensureThis();
713 ret = generator.emitGetById(finalDest, base.get(), thisValue.get(), m_ident);
715 ret = generator.emitGetById(finalDest, base.get(), m_ident);
716 generator.emitProfileType(finalDest, divotStart(), divotEnd());
720 // ------------------------------ ArgumentListNode -----------------------------
722 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
725 return generator.emitNode(dst, m_expr);
728 // ------------------------------ NewExprNode ----------------------------------
730 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
732 ExpectedFunction expectedFunction;
733 if (m_expr->isResolveNode())
734 expectedFunction = generator.expectedFunctionForIdentifier(static_cast<ResolveNode*>(m_expr)->identifier());
736 expectedFunction = NoExpectedFunction;
737 RefPtr<RegisterID> func = generator.emitNode(m_expr);
738 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
739 CallArguments callArguments(generator, m_args);
740 return generator.emitConstruct(returnValue.get(), func.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
743 CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode, unsigned additionalArguments)
744 : m_argumentsNode(argumentsNode)
747 size_t argumentCountIncludingThis = 1 + additionalArguments; // 'this' register.
749 for (ArgumentListNode* node = argumentsNode->m_listNode; node; node = node->m_next)
750 ++argumentCountIncludingThis;
753 m_argv.grow(argumentCountIncludingThis);
754 for (int i = argumentCountIncludingThis - 1; i >= 0; --i) {
755 m_argv[i] = generator.newTemporary();
756 ASSERT(static_cast<size_t>(i) == m_argv.size() - 1 || m_argv[i]->index() == m_argv[i + 1]->index() - 1);
759 // We need to ensure that the frame size is stack-aligned
760 while ((CallFrame::headerSizeInRegisters + m_argv.size()) % stackAlignmentRegisters()) {
761 m_argv.insert(0, generator.newTemporary());
765 while (stackOffset() % stackAlignmentRegisters()) {
766 m_argv.insert(0, generator.newTemporary());
771 // ------------------------------ EvalFunctionCallNode ----------------------------------
773 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
775 // We need try to load 'this' before call eval in constructor, because 'this' can created by 'super' in some of the arrow function
777 // constructor () { this.id = 'A'; }
780 // var B = class B extend A {
782 // var arrow = () => super();
784 // eval("this.id = 'B'");
787 if (generator.constructorKind() == ConstructorKind::Extends && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction())
788 generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
790 Variable var = generator.variable(generator.propertyNames().eval);
791 if (RegisterID* local = var.local()) {
792 generator.emitTDZCheckIfNecessary(var, local, nullptr);
793 RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
794 CallArguments callArguments(generator, m_args);
795 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
796 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::No);
799 RefPtr<RegisterID> func = generator.newTemporary();
800 CallArguments callArguments(generator, m_args);
801 JSTextPosition newDivot = divotStart() + 4;
802 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
803 generator.moveToDestinationIfNeeded(
804 callArguments.thisRegister(),
805 generator.emitResolveScope(callArguments.thisRegister(), var));
806 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
807 generator.emitTDZCheckIfNecessary(var, func.get(), nullptr);
808 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::No);
811 // ------------------------------ FunctionCallValueNode ----------------------------------
813 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
815 if (m_expr->isSuperNode()) {
816 RefPtr<RegisterID> func = emitGetSuperFunctionForConstruct(generator);
817 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
818 CallArguments callArguments(generator, m_args);
820 ASSERT(generator.isConstructor() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
821 ASSERT(generator.constructorKind() == ConstructorKind::Extends || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
822 RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), generator.newTarget(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
824 bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Extends;
825 bool doWeUseArrowFunctionInConstructor = isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext();
827 if (generator.isDerivedConstructorContext() || (doWeUseArrowFunctionInConstructor && generator.isSuperCallUsedInInnerArrowFunction()))
828 generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
830 Ref<Label> thisIsEmptyLabel = generator.newLabel();
831 generator.emitJumpIfTrue(generator.emitIsEmpty(generator.newTemporary(), generator.thisRegister()), thisIsEmptyLabel.get());
832 generator.emitThrowReferenceError(ASCIILiteral("'super()' can't be called more than once in a constructor."));
833 generator.emitLabel(thisIsEmptyLabel.get());
835 generator.emitMove(generator.thisRegister(), ret);
837 if (generator.isDerivedConstructorContext() || doWeUseArrowFunctionInConstructor)
838 generator.emitPutThisToArrowFunctionContextScope();
842 RefPtr<RegisterID> func = generator.emitNode(m_expr);
843 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
844 CallArguments callArguments(generator, m_args);
845 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
846 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
847 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
851 // ------------------------------ FunctionCallResolveNode ----------------------------------
853 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
855 ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
857 Variable var = generator.variable(m_ident);
858 if (RegisterID* local = var.local()) {
859 generator.emitTDZCheckIfNecessary(var, local, nullptr);
860 RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
861 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
862 CallArguments callArguments(generator, m_args);
863 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
864 // This passes NoExpectedFunction because we expect that if the function is in a
865 // local variable, then it's not one of our built-in constructors.
866 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
867 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
871 RefPtr<RegisterID> func = generator.newTemporary();
872 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
873 CallArguments callArguments(generator, m_args);
875 JSTextPosition newDivot = divotStart() + m_ident.length();
876 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
877 generator.moveToDestinationIfNeeded(
878 callArguments.thisRegister(),
879 generator.emitResolveScope(callArguments.thisRegister(), var));
880 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
881 generator.emitTDZCheckIfNecessary(var, func.get(), nullptr);
882 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
883 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
887 // ------------------------------ BytecodeIntrinsicNode ----------------------------------
889 RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
891 return (this->*m_emitter)(generator, dst);
894 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argument(BytecodeGenerator& generator, RegisterID* dst)
896 ArgumentListNode* node = m_args->m_listNode;
897 ASSERT(node->m_expr->isNumber());
898 double value = static_cast<NumberNode*>(node->m_expr)->value();
899 int32_t index = static_cast<int32_t>(value);
900 ASSERT(value == index);
902 ASSERT(!node->m_next);
904 // The body functions of generator and async have different mechanism for arguments.
905 ASSERT(generator.parseMode() != SourceParseMode::GeneratorBodyMode);
906 ASSERT(!isAsyncFunctionBodyParseMode(generator.parseMode()));
908 return generator.emitGetArgument(generator.finalDestination(dst), index);
911 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argumentCount(BytecodeGenerator& generator, RegisterID* dst)
913 ASSERT(!m_args->m_listNode);
915 return generator.emitUnaryNoDstOp(op_argument_count, generator.finalDestination(dst));
918 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_assert(BytecodeGenerator& generator, RegisterID* dst)
921 ArgumentListNode* node = m_args->m_listNode;
922 RefPtr<RegisterID> condition = generator.emitNode(node);
923 generator.emitAssert(condition.get(), node->firstLine());
926 UNUSED_PARAM(generator);
931 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst)
933 ArgumentListNode* node = m_args->m_listNode;
934 RefPtr<RegisterID> base = generator.emitNode(node);
936 RefPtr<RegisterID> index = generator.emitNodeForProperty(node);
938 RefPtr<RegisterID> value = generator.emitNode(node);
940 ASSERT(!node->m_next);
942 return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
945 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tailCallForwardArguments(BytecodeGenerator& generator, RegisterID* dst)
947 ArgumentListNode* node = m_args->m_listNode;
948 RefPtr<RegisterID> function = generator.emitNode(node);
950 RefPtr<RegisterID> thisRegister = generator.emitNode(node);
951 ASSERT(!node->m_next);
953 RefPtr<RegisterID> finalDst = generator.finalDestination(dst);
954 return generator.emitCallForwardArgumentsInTailPosition(finalDst.get(), function.get(), thisRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd(), DebuggableCall::No);
957 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwTypeError(BytecodeGenerator& generator, RegisterID* dst)
959 ArgumentListNode* node = m_args->m_listNode;
960 ASSERT(!node->m_next);
961 if (node->m_expr->isString()) {
962 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
963 generator.emitThrowTypeError(ident);
965 RefPtr<RegisterID> message = generator.emitNode(node);
966 generator.emitThrowStaticError(ErrorType::TypeError, message.get());
971 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwRangeError(BytecodeGenerator& generator, RegisterID* dst)
973 ArgumentListNode* node = m_args->m_listNode;
974 ASSERT(!node->m_next);
975 if (node->m_expr->isString()) {
976 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
977 generator.emitThrowRangeError(ident);
979 RefPtr<RegisterID> message = generator.emitNode(node);
980 generator.emitThrowStaticError(ErrorType::RangeError, message.get());
986 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwOutOfMemoryError(BytecodeGenerator& generator, RegisterID* dst)
988 ASSERT(!m_args->m_listNode);
990 generator.emitThrowOutOfMemoryError();
994 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tryGetById(BytecodeGenerator& generator, RegisterID* dst)
996 ArgumentListNode* node = m_args->m_listNode;
997 RefPtr<RegisterID> base = generator.emitNode(node);
1000 // Since this is a builtin we expect the creator to use a string literal as the second argument.
1001 ASSERT(node->m_expr->isString());
1002 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
1003 ASSERT(!node->m_next);
1005 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
1006 return generator.emitTryGetById(finalDest.get(), base.get(), ident);
1009 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toNumber(BytecodeGenerator& generator, RegisterID* dst)
1011 ArgumentListNode* node = m_args->m_listNode;
1012 RefPtr<RegisterID> src = generator.emitNode(node);
1013 ASSERT(!node->m_next);
1015 return generator.moveToDestinationIfNeeded(dst, generator.emitToNumber(generator.tempDestination(dst), src.get()));
1018 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
1020 ArgumentListNode* node = m_args->m_listNode;
1021 RefPtr<RegisterID> src = generator.emitNode(node);
1022 ASSERT(!node->m_next);
1024 return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
1027 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_idWithProfile(BytecodeGenerator& generator, RegisterID* dst)
1029 ArgumentListNode* node = m_args->m_listNode;
1030 RefPtr<RegisterID> idValue = generator.newTemporary();
1031 generator.emitNode(idValue.get(), node);
1032 SpeculatedType speculation = SpecNone;
1033 while (node->m_next) {
1034 node = node->m_next;
1035 ASSERT(node->m_expr->isString());
1036 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
1037 speculation |= speculationFromString(ident.utf8().data());
1040 return generator.moveToDestinationIfNeeded(dst, generator.emitIdWithProfile(idValue.get(), speculation));
1043 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isJSArray(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1045 ArgumentListNode* node = m_args->m_listNode;
1046 RefPtr<RegisterID> src = generator.emitNode(node);
1047 ASSERT(!node->m_next);
1049 return generator.moveToDestinationIfNeeded(dst, generator.emitIsJSArray(generator.tempDestination(dst), src.get()));
1052 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isProxyObject(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1054 ArgumentListNode* node = m_args->m_listNode;
1055 RefPtr<RegisterID> src = generator.emitNode(node);
1056 ASSERT(!node->m_next);
1058 return generator.moveToDestinationIfNeeded(dst, generator.emitIsProxyObject(generator.tempDestination(dst), src.get()));
1061 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isRegExpObject(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1063 ArgumentListNode* node = m_args->m_listNode;
1064 RefPtr<RegisterID> src = generator.emitNode(node);
1065 ASSERT(!node->m_next);
1067 return generator.moveToDestinationIfNeeded(dst, generator.emitIsRegExpObject(generator.tempDestination(dst), src.get()));
1070 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isObject(BytecodeGenerator& generator, RegisterID* dst)
1072 ArgumentListNode* node = m_args->m_listNode;
1073 RefPtr<RegisterID> src = generator.emitNode(node);
1074 ASSERT(!node->m_next);
1076 return generator.moveToDestinationIfNeeded(dst, generator.emitIsObject(generator.tempDestination(dst), src.get()));
1079 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isDerivedArray(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1081 ArgumentListNode* node = m_args->m_listNode;
1082 RefPtr<RegisterID> src = generator.emitNode(node);
1083 ASSERT(!node->m_next);
1085 return generator.moveToDestinationIfNeeded(dst, generator.emitIsDerivedArray(generator.tempDestination(dst), src.get()));
1088 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isMap(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1090 ArgumentListNode* node = m_args->m_listNode;
1091 RefPtr<RegisterID> src = generator.emitNode(node);
1092 ASSERT(!node->m_next);
1094 return generator.moveToDestinationIfNeeded(dst, generator.emitIsMap(generator.tempDestination(dst), src.get()));
1097 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isSet(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1099 ArgumentListNode* node = m_args->m_listNode;
1100 RefPtr<RegisterID> src = generator.emitNode(node);
1101 ASSERT(!node->m_next);
1103 return generator.moveToDestinationIfNeeded(dst, generator.emitIsSet(generator.tempDestination(dst), src.get()));
1106 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_newArrayWithSize(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1108 ArgumentListNode* node = m_args->m_listNode;
1109 RefPtr<RegisterID> size = generator.emitNode(node);
1110 ASSERT(!node->m_next);
1112 RefPtr<RegisterID> finalDestination = generator.finalDestination(dst);
1113 generator.emitNewArrayWithSize(finalDestination.get(), size.get());
1114 return finalDestination.get();
1117 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_defineEnumerableWritableConfigurableDataProperty(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1119 ArgumentListNode* node = m_args->m_listNode;
1120 RefPtr<RegisterID> newObj = generator.emitNode(node);
1121 node = node->m_next;
1122 RefPtr<RegisterID> propertyNameRegister = generator.emitNode(node);
1123 node = node->m_next;
1124 RefPtr<RegisterID> value = generator.emitNode(node);
1125 ASSERT(!node->m_next);
1127 generator.emitCallDefineProperty(newObj.get(), propertyNameRegister.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable | BytecodeGenerator::PropertyEnumerable, m_position);
1131 #define JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS(name) \
1132 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_##name(BytecodeGenerator& generator, RegisterID* dst) \
1135 ASSERT(type() == Type::Constant); \
1136 if (dst == generator.ignoredResult()) \
1138 return generator.emitLoad(dst, generator.vm()->bytecodeIntrinsicRegistry().name##Value(generator)); \
1140 JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS)
1141 #undef JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS
1143 // ------------------------------ FunctionCallBracketNode ----------------------------------
1145 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1147 bool baseIsSuper = m_base->isSuperNode();
1148 bool subscriptIsNonIndexString = isNonIndexStringElement(*m_subscript);
1150 RefPtr<RegisterID> base;
1152 base = emitSuperBaseForCallee(generator);
1154 if (subscriptIsNonIndexString)
1155 base = generator.emitNode(m_base);
1157 base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
1160 RefPtr<RegisterID> function;
1161 RefPtr<RegisterID> thisRegister;
1163 // 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.
1164 thisRegister = generator.ensureThis();
1166 if (subscriptIsNonIndexString) {
1167 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1169 function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisRegister.get(), static_cast<StringNode*>(m_subscript)->value());
1171 function = generator.emitGetById(generator.tempDestination(dst), base.get(), static_cast<StringNode*>(m_subscript)->value());
1173 RefPtr<RegisterID> property = generator.emitNodeForProperty(m_subscript);
1174 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1176 function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisRegister.get(), property.get());
1178 function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1181 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
1182 CallArguments callArguments(generator, m_args);
1184 generator.emitTDZCheck(generator.thisRegister());
1185 generator.emitMove(callArguments.thisRegister(), thisRegister.get());
1187 generator.emitMove(callArguments.thisRegister(), base.get());
1188 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1189 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1193 // ------------------------------ FunctionCallDotNode ----------------------------------
1195 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1197 RefPtr<RegisterID> function = generator.tempDestination(dst);
1198 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
1199 CallArguments callArguments(generator, m_args);
1200 bool baseIsSuper = m_base->isSuperNode();
1202 generator.emitMove(callArguments.thisRegister(), generator.ensureThis());
1204 generator.emitNode(callArguments.thisRegister(), m_base);
1205 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1207 RefPtr<RegisterID> superBase = emitSuperBaseForCallee(generator);
1208 generator.emitGetById(function.get(), superBase.get(), callArguments.thisRegister(), m_ident);
1210 generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
1211 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1212 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1216 static constexpr size_t maxDistanceToInnermostCallOrApply = 2;
1218 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1220 RefPtr<RegisterID> base = generator.emitNode(m_base);
1221 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1222 RefPtr<RegisterID> function;
1223 RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
1225 auto makeFunction = [&] {
1226 if (m_base->isSuperNode()) {
1227 RefPtr<RegisterID> thisValue = generator.ensureThis();
1228 function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), generator.propertyNames().builtinNames().callPublicName());
1230 function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().callPublicName());
1233 bool emitCallCheck = !generator.isBuiltinFunction();
1234 if (m_distanceToInnermostCallOrApply > maxDistanceToInnermostCallOrApply && emitCallCheck) {
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 generator.moveToDestinationIfNeeded(dst, returnValue.get());
1240 return returnValue.get();
1243 Ref<Label> realCall = generator.newLabel();
1244 Ref<Label> end = generator.newLabel();
1246 if (emitCallCheck) {
1248 generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
1251 if (m_args->m_listNode && m_args->m_listNode->m_expr && m_args->m_listNode->m_expr->isSpreadExpression()) {
1252 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
1253 ExpressionNode* subject = spread->expression();
1254 RefPtr<RegisterID> argumentsRegister;
1255 argumentsRegister = generator.emitNode(subject);
1256 generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
1257 RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
1258 generator.emitCallVarargsInTailPosition(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1259 } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
1260 ArgumentListNode* oldList = m_args->m_listNode;
1261 m_args->m_listNode = m_args->m_listNode->m_next;
1263 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1264 CallArguments callArguments(generator, m_args);
1265 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1266 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1267 m_args->m_listNode = oldList;
1269 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1270 CallArguments callArguments(generator, m_args);
1271 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
1272 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1275 if (emitCallCheck) {
1276 generator.emitJump(end.get());
1277 generator.emitLabel(realCall.get());
1279 CallArguments callArguments(generator, m_args);
1280 generator.emitMove(callArguments.thisRegister(), base.get());
1281 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1283 generator.emitLabel(end.get());
1285 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1286 return returnValue.get();
1289 static bool areTrivialApplyArguments(ArgumentsNode* args)
1291 return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
1292 || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
1295 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1297 // A few simple cases can be trivially handled as ordinary function calls.
1298 // function.apply(), function.apply(arg) -> identical to function.call
1299 // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
1300 bool mayBeCall = areTrivialApplyArguments(m_args);
1302 RefPtr<RegisterID> function;
1303 RefPtr<RegisterID> base = generator.emitNode(m_base);
1304 RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
1305 auto makeFunction = [&] {
1306 if (m_base->isSuperNode()) {
1307 RefPtr<RegisterID> thisValue = generator.ensureThis();
1308 function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), generator.propertyNames().builtinNames().applyPublicName());
1310 function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().applyPublicName());
1313 bool emitCallCheck = !generator.isBuiltinFunction();
1314 if (m_distanceToInnermostCallOrApply > maxDistanceToInnermostCallOrApply && emitCallCheck) {
1316 CallArguments callArguments(generator, m_args);
1317 generator.emitMove(callArguments.thisRegister(), base.get());
1318 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1319 generator.moveToDestinationIfNeeded(dst, returnValue.get());
1320 return returnValue.get();
1323 Ref<Label> realCall = generator.newLabel();
1324 Ref<Label> end = generator.newLabel();
1325 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1326 if (emitCallCheck) {
1328 generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
1331 if (m_args->m_listNode && m_args->m_listNode->m_expr) {
1332 ArgumentListNode* oldList = m_args->m_listNode;
1333 if (m_args->m_listNode->m_expr->isSpreadExpression()) {
1334 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
1335 RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
1336 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(0));
1337 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1338 RefPtr<RegisterID> argumentsRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1340 auto extractor = [&thisRegister, &argumentsRegister, &index](BytecodeGenerator& generator, RegisterID* value)
1342 Ref<Label> haveThis = generator.newLabel();
1343 Ref<Label> end = generator.newLabel();
1344 RefPtr<RegisterID> compareResult = generator.newTemporary();
1345 RefPtr<RegisterID> indexZeroCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(0)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
1346 generator.emitJumpIfFalse(indexZeroCompareResult.get(), haveThis.get());
1347 generator.emitMove(thisRegister.get(), value);
1348 generator.emitLoad(index.get(), jsNumber(1));
1349 generator.emitJump(end.get());
1350 generator.emitLabel(haveThis.get());
1351 RefPtr<RegisterID> indexOneCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(1)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
1352 generator.emitJumpIfFalse(indexOneCompareResult.get(), end.get());
1353 generator.emitMove(argumentsRegister.get(), value);
1354 generator.emitLoad(index.get(), jsNumber(2));
1355 generator.emitLabel(end.get());
1357 generator.emitEnumeration(this, spread->expression(), extractor);
1358 generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1359 } else if (m_args->m_listNode->m_next) {
1360 ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
1361 ASSERT(!m_args->m_listNode->m_next->m_next);
1362 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.parserArena(), 0, 0);
1363 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1364 CallArguments callArguments(generator, m_args);
1365 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1366 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1368 m_args->m_listNode = m_args->m_listNode->m_next;
1369 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1370 CallArguments callArguments(generator, m_args);
1371 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1372 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1374 m_args->m_listNode = oldList;
1376 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1377 CallArguments callArguments(generator, m_args);
1378 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
1379 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1382 ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
1383 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1384 RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
1385 RefPtr<RegisterID> argsRegister;
1386 ArgumentListNode* args = m_args->m_listNode->m_next;
1387 argsRegister = generator.emitNode(args->m_expr);
1389 // Function.prototype.apply ignores extra arguments, but we still
1390 // need to evaluate them for side effects.
1391 while ((args = args->m_next))
1392 generator.emitNode(args->m_expr);
1394 generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1396 if (emitCallCheck) {
1397 generator.emitJump(end.get());
1398 generator.emitLabel(realCall.get());
1399 CallArguments callArguments(generator, m_args);
1400 generator.emitMove(callArguments.thisRegister(), base.get());
1401 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
1402 generator.emitLabel(end.get());
1404 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1405 return returnValue.get();
1408 // ------------------------------ PostfixNode ----------------------------------
1410 static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
1412 return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
1415 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
1418 return generator.emitToNumber(generator.finalDestination(dst), srcDst);
1419 RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
1420 emitIncOrDec(generator, srcDst, oper);
1421 return generator.moveToDestinationIfNeeded(dst, tmp.get());
1424 RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1426 if (dst == generator.ignoredResult())
1427 return PrefixNode::emitResolve(generator, dst);
1429 ASSERT(m_expr->isResolveNode());
1430 ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1431 const Identifier& ident = resolve->identifier();
1433 Variable var = generator.variable(ident);
1434 if (RegisterID* local = var.local()) {
1435 generator.emitTDZCheckIfNecessary(var, local, nullptr);
1436 RefPtr<RegisterID> localReg = local;
1437 if (var.isReadOnly()) {
1438 generator.emitReadOnlyExceptionIfNeeded(var);
1439 localReg = generator.emitMove(generator.tempDestination(dst), local);
1441 generator.invalidateForInContextForLocal(local);
1442 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
1443 generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1444 return oldValue.get();
1447 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1448 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1449 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1450 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1451 if (var.isReadOnly()) {
1452 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1456 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
1457 if (!var.isReadOnly()) {
1458 generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
1459 generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
1462 return oldValue.get();
1465 RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1467 if (dst == generator.ignoredResult())
1468 return PrefixNode::emitBracket(generator, dst);
1470 ASSERT(m_expr->isBracketAccessorNode());
1471 BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1472 ExpressionNode* baseNode = bracketAccessor->base();
1473 ExpressionNode* subscript = bracketAccessor->subscript();
1475 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1476 RefPtr<RegisterID> property = generator.emitNodeForProperty(subscript);
1478 generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1479 RefPtr<RegisterID> value;
1480 RefPtr<RegisterID> thisValue;
1481 if (baseNode->isSuperNode()) {
1482 thisValue = generator.ensureThis();
1483 value = generator.emitGetByVal(generator.newTemporary(), base.get(), thisValue.get(), property.get());
1485 value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1486 RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1487 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1488 if (baseNode->isSuperNode())
1489 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value.get());
1491 generator.emitPutByVal(base.get(), property.get(), value.get());
1492 generator.emitProfileType(value.get(), divotStart(), divotEnd());
1493 return generator.moveToDestinationIfNeeded(dst, oldValue);
1496 RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1498 if (dst == generator.ignoredResult())
1499 return PrefixNode::emitDot(generator, dst);
1501 ASSERT(m_expr->isDotAccessorNode());
1502 DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1503 ExpressionNode* baseNode = dotAccessor->base();
1504 bool baseIsSuper = baseNode->isSuperNode();
1505 const Identifier& ident = dotAccessor->identifier();
1507 RefPtr<RegisterID> base = generator.emitNode(baseNode);
1509 generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1510 RefPtr<RegisterID> value;
1511 RefPtr<RegisterID> thisValue;
1513 thisValue = generator.ensureThis();
1514 value = generator.emitGetById(generator.newTemporary(), base.get(), thisValue.get(), ident);
1516 value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
1517 RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1518 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1520 generator.emitPutById(base.get(), thisValue.get(), ident, value.get());
1522 generator.emitPutById(base.get(), ident, value.get());
1523 generator.emitProfileType(value.get(), divotStart(), divotEnd());
1524 return generator.moveToDestinationIfNeeded(dst, oldValue);
1527 RegisterID* PostfixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1529 if (m_expr->isResolveNode())
1530 return emitResolve(generator, dst);
1532 if (m_expr->isBracketAccessorNode())
1533 return emitBracket(generator, dst);
1535 if (m_expr->isDotAccessorNode())
1536 return emitDot(generator, dst);
1538 return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1539 ? ASCIILiteral("Postfix ++ operator applied to value that is not a reference.")
1540 : ASCIILiteral("Postfix -- operator applied to value that is not a reference."));
1543 // ------------------------------ DeleteResolveNode -----------------------------------
1545 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1547 Variable var = generator.variable(m_ident);
1549 generator.emitTDZCheckIfNecessary(var, var.local(), nullptr);
1550 return generator.emitLoad(generator.finalDestination(dst), false);
1553 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1554 RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
1555 generator.emitTDZCheckIfNecessary(var, nullptr, base.get());
1556 return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
1559 // ------------------------------ DeleteBracketNode -----------------------------------
1561 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1563 RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1564 RefPtr<RegisterID> r1 = generator.emitNode(m_subscript);
1566 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1567 if (m_base->isSuperNode())
1568 return emitThrowReferenceError(generator, "Cannot delete a super property");
1569 return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
1572 // ------------------------------ DeleteDotNode -----------------------------------
1574 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1576 RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1578 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1579 if (m_base->isSuperNode())
1580 return emitThrowReferenceError(generator, "Cannot delete a super property");
1581 return generator.emitDeleteById(generator.finalDestination(dst), r0.get(), m_ident);
1584 // ------------------------------ DeleteValueNode -----------------------------------
1586 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1588 generator.emitNode(generator.ignoredResult(), m_expr);
1590 // delete on a non-location expression ignores the value and returns true
1591 return generator.emitLoad(generator.finalDestination(dst), true);
1594 // ------------------------------ VoidNode -------------------------------------
1596 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1598 if (dst == generator.ignoredResult()) {
1599 generator.emitNode(generator.ignoredResult(), m_expr);
1602 RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1603 return generator.emitLoad(dst, jsUndefined());
1606 // ------------------------------ TypeOfResolveNode -----------------------------------
1608 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1610 Variable var = generator.variable(m_ident);
1611 if (RegisterID* local = var.local()) {
1612 generator.emitTDZCheckIfNecessary(var, local, nullptr);
1613 if (dst == generator.ignoredResult())
1615 return generator.emitTypeOf(generator.finalDestination(dst), local);
1618 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1619 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
1620 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1621 if (dst == generator.ignoredResult())
1623 return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
1626 // ------------------------------ TypeOfValueNode -----------------------------------
1628 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1630 if (dst == generator.ignoredResult()) {
1631 generator.emitNode(generator.ignoredResult(), m_expr);
1634 RefPtr<RegisterID> src = generator.emitNode(m_expr);
1635 return generator.emitTypeOf(generator.finalDestination(dst), src.get());
1638 // ------------------------------ PrefixNode ----------------------------------
1640 RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1642 ASSERT(m_expr->isResolveNode());
1643 ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1644 const Identifier& ident = resolve->identifier();
1646 Variable var = generator.variable(ident);
1647 if (RegisterID* local = var.local()) {
1648 generator.emitTDZCheckIfNecessary(var, local, nullptr);
1649 RefPtr<RegisterID> localReg = local;
1650 if (var.isReadOnly()) {
1651 generator.emitReadOnlyExceptionIfNeeded(var);
1652 localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
1653 } else if (generator.vm()->typeProfiler()) {
1654 generator.invalidateForInContextForLocal(local);
1655 RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1656 generator.emitMove(tempDst.get(), localReg.get());
1657 emitIncOrDec(generator, tempDst.get(), m_operator);
1658 generator.emitMove(localReg.get(), tempDst.get());
1659 generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1660 return generator.moveToDestinationIfNeeded(dst, tempDst.get());
1662 generator.invalidateForInContextForLocal(local);
1663 emitIncOrDec(generator, localReg.get(), m_operator);
1664 return generator.moveToDestinationIfNeeded(dst, localReg.get());
1667 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1668 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1669 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1670 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1671 if (var.isReadOnly()) {
1672 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1677 emitIncOrDec(generator, value.get(), m_operator);
1678 if (!var.isReadOnly()) {
1679 generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
1680 generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
1682 return generator.moveToDestinationIfNeeded(dst, value.get());
1685 RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1687 ASSERT(m_expr->isBracketAccessorNode());
1688 BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1689 ExpressionNode* baseNode = bracketAccessor->base();
1690 ExpressionNode* subscript = bracketAccessor->subscript();
1692 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1693 RefPtr<RegisterID> property = generator.emitNodeForProperty(subscript);
1694 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1696 generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1698 RefPtr<RegisterID> thisValue;
1699 if (baseNode->isSuperNode()) {
1700 thisValue = generator.ensureThis();
1701 value = generator.emitGetByVal(propDst.get(), base.get(), thisValue.get(), property.get());
1703 value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1704 emitIncOrDec(generator, value, m_operator);
1705 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1706 if (baseNode->isSuperNode())
1707 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value);
1709 generator.emitPutByVal(base.get(), property.get(), value);
1710 generator.emitProfileType(value, divotStart(), divotEnd());
1711 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1714 RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1716 ASSERT(m_expr->isDotAccessorNode());
1717 DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1718 ExpressionNode* baseNode = dotAccessor->base();
1719 const Identifier& ident = dotAccessor->identifier();
1721 RefPtr<RegisterID> base = generator.emitNode(baseNode);
1722 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1724 generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1726 RefPtr<RegisterID> thisValue;
1727 if (baseNode->isSuperNode()) {
1728 thisValue = generator.ensureThis();
1729 value = generator.emitGetById(propDst.get(), base.get(), thisValue.get(), ident);
1731 value = generator.emitGetById(propDst.get(), base.get(), ident);
1732 emitIncOrDec(generator, value, m_operator);
1733 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1734 if (baseNode->isSuperNode())
1735 generator.emitPutById(base.get(), thisValue.get(), ident, value);
1737 generator.emitPutById(base.get(), ident, value);
1738 generator.emitProfileType(value, divotStart(), divotEnd());
1739 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1742 RegisterID* PrefixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1744 if (m_expr->isResolveNode())
1745 return emitResolve(generator, dst);
1747 if (m_expr->isBracketAccessorNode())
1748 return emitBracket(generator, dst);
1750 if (m_expr->isDotAccessorNode())
1751 return emitDot(generator, dst);
1753 return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1754 ? ASCIILiteral("Prefix ++ operator applied to value that is not a reference.")
1755 : ASCIILiteral("Prefix -- operator applied to value that is not a reference."));
1758 // ------------------------------ Unary Operation Nodes -----------------------------------
1760 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1762 RefPtr<RegisterID> src = generator.emitNode(m_expr);
1763 generator.emitExpressionInfo(position(), position(), position());
1764 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), OperandTypes(m_expr->resultDescriptor()));
1767 // ------------------------------ UnaryPlusNode -----------------------------------
1769 RegisterID* UnaryPlusNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1771 ASSERT(opcodeID() == op_to_number);
1772 RefPtr<RegisterID> src = generator.emitNode(expr());
1773 generator.emitExpressionInfo(position(), position(), position());
1774 return generator.emitToNumber(generator.finalDestination(dst), src.get());
1777 // ------------------------------ BitwiseNotNode -----------------------------------
1779 RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1781 RefPtr<RegisterID> src2 = generator.emitLoad(nullptr, jsNumber(-1));
1782 RefPtr<RegisterID> src1 = generator.emitNode(m_expr);
1783 return generator.emitBinaryOp(op_bitxor, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr->resultDescriptor(), ResultType::numberTypeIsInt32()));
1786 // ------------------------------ LogicalNotNode -----------------------------------
1788 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
1790 if (UNLIKELY(needsDebugHook()))
1791 generator.emitDebugHook(this);
1793 // Reverse the true and false targets.
1794 generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode));
1798 // ------------------------------ Binary Operation Nodes -----------------------------------
1800 // BinaryOpNode::emitStrcat:
1802 // This node generates an op_strcat operation. This opcode can handle concatenation of three or
1803 // more values, where we can determine a set of separate op_add operations would be operating on
1806 // This function expects to be operating on a graph of AST nodes looking something like this:
1816 // The assignment operation is optional, if it exists the register holding the value on the
1817 // lefthand side of the assignment should be passing as the optional 'lhs' argument.
1819 // The method should be called on the node at the root of the tree of regular binary add
1820 // operations (marked in the diagram with a double set of parentheses). This node must
1821 // be performing a string concatenation (determined by statically detecting that at least
1822 // one child must be a string).
1824 // Since the minimum number of values being concatenated together is expected to be 3, if
1825 // a lhs to a concatenating assignment is not provided then the root add should have at
1826 // least one left child that is also an add that can be determined to be operating on strings.
1828 RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
1831 ASSERT(resultDescriptor().definitelyIsString());
1833 // Create a list of expressions for all the adds in the tree of nodes we can convert into
1834 // a string concatenation. The rightmost node (c) is added first. The rightmost node is
1835 // added first, and the leftmost child is never added, so the vector produced for the
1836 // example above will be [ c, b ].
1837 Vector<ExpressionNode*, 16> reverseExpressionList;
1838 reverseExpressionList.append(m_expr2);
1840 // Examine the left child of the add. So long as this is a string add, add its right-child
1841 // to the list, and keep processing along the left fork.
1842 ExpressionNode* leftMostAddChild = m_expr1;
1843 while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
1844 reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
1845 leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
1848 Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
1850 // If there is an assignment, allocate a temporary to hold the lhs after conversion.
1851 // We could possibly avoid this (the lhs is converted last anyway, we could let the
1852 // op_strcat node handle its conversion if required).
1854 temporaryRegisters.append(generator.newTemporary());
1856 // Emit code for the leftmost node ((a) in the example).
1857 temporaryRegisters.append(generator.newTemporary());
1858 RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
1859 generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
1861 // Note on ordering of conversions:
1863 // We maintain the same ordering of conversions as we would see if the concatenations
1864 // was performed as a sequence of adds (otherwise this optimization could change
1865 // behaviour should an object have been provided a valueOf or toString method).
1867 // Considering the above example, the sequnce of execution is:
1868 // * evaluate operand (a)
1869 // * evaluate operand (b)
1870 // * convert (a) to primitive <- (this would be triggered by the first add)
1871 // * convert (b) to primitive <- (ditto)
1872 // * evaluate operand (c)
1873 // * convert (c) to primitive <- (this would be triggered by the second add)
1874 // And optionally, if there is an assignment:
1875 // * convert (d) to primitive <- (this would be triggered by the assigning addition)
1877 // As such we do not plant an op to convert the leftmost child now. Instead, use
1878 // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
1879 // once the second node has been generated. However, if the leftmost child is an
1880 // immediate we can trivially determine that no conversion will be required.
1881 // If this is the case
1882 if (leftMostAddChild->isString())
1883 leftMostAddChildTempRegister = 0;
1885 while (reverseExpressionList.size()) {
1886 ExpressionNode* node = reverseExpressionList.last();
1887 reverseExpressionList.removeLast();
1889 // Emit the code for the current node.
1890 temporaryRegisters.append(generator.newTemporary());
1891 generator.emitNode(temporaryRegisters.last().get(), node);
1893 // On the first iteration of this loop, when we first reach this point we have just
1894 // generated the second node, which means it is time to convert the leftmost operand.
1895 if (leftMostAddChildTempRegister) {
1896 generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
1897 leftMostAddChildTempRegister = 0; // Only do this once.
1899 // Plant a conversion for this node, if necessary.
1900 if (!node->isString())
1901 generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
1903 ASSERT(temporaryRegisters.size() >= 3);
1905 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1906 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1907 if (emitExpressionInfoForMe)
1908 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1909 // If there is an assignment convert the lhs now. This will also copy lhs to
1910 // the temporary register we allocated for it.
1912 generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
1914 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
1917 void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
1919 TriState branchCondition;
1920 ExpressionNode* branchExpression;
1921 tryFoldToBranch(generator, branchCondition, branchExpression);
1923 if (UNLIKELY(needsDebugHook())) {
1924 if (branchCondition != MixedTriState)
1925 generator.emitDebugHook(this);
1928 if (branchCondition == MixedTriState)
1929 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
1930 else if (branchCondition == TrueTriState)
1931 generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode);
1933 generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode));
1936 static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant)
1938 ResultType expressionType = branchExpression->resultDescriptor();
1940 if (expressionType.definitelyIsBoolean() && constant.isBoolean())
1942 else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1))
1943 return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch.
1944 else if (expressionType.isInt32() && constant.isInt32() && constant.asInt32() == 0)
1950 void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression)
1952 branchCondition = MixedTriState;
1953 branchExpression = 0;
1955 ConstantNode* constant = 0;
1956 if (m_expr1->isConstant()) {
1957 constant = static_cast<ConstantNode*>(m_expr1);
1958 branchExpression = m_expr2;
1959 } else if (m_expr2->isConstant()) {
1960 constant = static_cast<ConstantNode*>(m_expr2);
1961 branchExpression = m_expr1;
1966 ASSERT(branchExpression);
1968 OpcodeID opcodeID = this->opcodeID();
1969 JSValue value = constant->jsValue(generator);
1970 bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
1971 if (!canFoldToBranch)
1974 if (opcodeID == op_eq || opcodeID == op_stricteq)
1975 branchCondition = triState(value.pureToBoolean());
1976 else if (opcodeID == op_neq || opcodeID == op_nstricteq)
1977 branchCondition = triState(!value.pureToBoolean());
1980 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1982 OpcodeID opcodeID = this->opcodeID();
1984 if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString()) {
1985 generator.emitExpressionInfo(position(), position(), position());
1986 return emitStrcat(generator, dst);
1989 if (opcodeID == op_neq) {
1990 if (m_expr1->isNull() || m_expr2->isNull()) {
1991 RefPtr<RegisterID> src = generator.tempDestination(dst);
1992 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1993 return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
1997 ExpressionNode* left = m_expr1;
1998 ExpressionNode* right = m_expr2;
1999 if (opcodeID == op_neq || opcodeID == op_nstricteq) {
2000 if (left->isString())
2001 std::swap(left, right);
2004 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
2005 bool wasTypeof = generator.lastOpcodeID() == op_typeof;
2006 RefPtr<RegisterID> src2 = generator.emitNode(right);
2007 generator.emitExpressionInfo(position(), position(), position());
2008 if (wasTypeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
2009 RefPtr<RegisterID> tmp = generator.tempDestination(dst);
2010 if (opcodeID == op_neq)
2011 generator.emitEqualityOp(op_eq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
2012 else if (opcodeID == op_nstricteq)
2013 generator.emitEqualityOp(op_stricteq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
2015 RELEASE_ASSERT_NOT_REACHED();
2016 return generator.emitUnaryOp(op_not, generator.finalDestination(dst, tmp.get()), tmp.get());
2018 RegisterID* result = generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
2019 if (opcodeID == op_urshift && dst != generator.ignoredResult())
2020 return generator.emitUnaryOp(op_unsigned, result, result);
2024 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2026 if (m_expr1->isNull() || m_expr2->isNull()) {
2027 RefPtr<RegisterID> src = generator.tempDestination(dst);
2028 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
2029 return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
2032 ExpressionNode* left = m_expr1;
2033 ExpressionNode* right = m_expr2;
2034 if (left->isString())
2035 std::swap(left, right);
2037 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
2038 RefPtr<RegisterID> src2 = generator.emitNode(right);
2039 return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
2042 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2044 ExpressionNode* left = m_expr1;
2045 ExpressionNode* right = m_expr2;
2046 if (left->isString())
2047 std::swap(left, right);
2049 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
2050 RefPtr<RegisterID> src2 = generator.emitNode(right);
2051 return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
2054 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2056 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
2057 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
2058 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2059 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
2062 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2064 RefPtr<RegisterID> hasInstanceValue = generator.newTemporary();
2065 RefPtr<RegisterID> isObject = generator.newTemporary();
2066 RefPtr<RegisterID> isCustom = generator.newTemporary();
2067 RefPtr<RegisterID> prototype = generator.newTemporary();
2068 RefPtr<RegisterID> value = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
2069 RefPtr<RegisterID> constructor = generator.emitNode(m_expr2);
2070 RefPtr<RegisterID> dstReg = generator.finalDestination(dst, value.get());
2071 Ref<Label> custom = generator.newLabel();
2072 Ref<Label> done = generator.newLabel();
2073 Ref<Label> typeError = generator.newLabel();
2075 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2076 generator.emitIsObject(isObject.get(), constructor.get());
2077 generator.emitJumpIfFalse(isObject.get(), typeError.get());
2079 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2080 generator.emitGetById(hasInstanceValue.get(), constructor.get(), generator.vm()->propertyNames->hasInstanceSymbol);
2082 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2083 generator.emitOverridesHasInstance(isCustom.get(), constructor.get(), hasInstanceValue.get());
2085 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2086 generator.emitJumpIfTrue(isCustom.get(), custom.get());
2088 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2089 generator.emitGetById(prototype.get(), constructor.get(), generator.vm()->propertyNames->prototype);
2091 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2092 generator.emitInstanceOf(dstReg.get(), value.get(), prototype.get());
2094 generator.emitJump(done.get());
2096 generator.emitLabel(typeError.get());
2097 generator.emitThrowTypeError("Right hand side of instanceof is not an object");
2099 generator.emitLabel(custom.get());
2101 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2102 generator.emitInstanceOfCustom(dstReg.get(), value.get(), constructor.get(), hasInstanceValue.get());
2104 generator.emitLabel(done.get());
2106 return dstReg.get();
2109 // ------------------------------ InNode ----------------------------
2111 RegisterID* InNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2113 RefPtr<RegisterID> key = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
2114 RefPtr<RegisterID> base = generator.emitNode(m_expr2);
2115 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2116 return generator.emitIn(generator.finalDestination(dst, key.get()), key.get(), base.get());
2120 // ------------------------------ LogicalOpNode ----------------------------
2122 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2124 RefPtr<RegisterID> temp = generator.tempDestination(dst);
2125 Ref<Label> target = generator.newLabel();
2127 generator.emitNode(temp.get(), m_expr1);
2128 if (m_operator == OpLogicalAnd)
2129 generator.emitJumpIfFalse(temp.get(), target.get());
2131 generator.emitJumpIfTrue(temp.get(), target.get());
2132 generator.emitNodeInTailPosition(temp.get(), m_expr2);
2133 generator.emitLabel(target.get());
2135 return generator.moveToDestinationIfNeeded(dst, temp.get());
2138 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
2140 if (UNLIKELY(needsDebugHook()))
2141 generator.emitDebugHook(this);
2143 Ref<Label> afterExpr1 = generator.newLabel();
2144 if (m_operator == OpLogicalAnd)
2145 generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, FallThroughMeansTrue);
2147 generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), FallThroughMeansFalse);
2148 generator.emitLabel(afterExpr1.get());
2150 generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMode);
2153 // ------------------------------ ConditionalNode ------------------------------
2155 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2157 RefPtr<RegisterID> newDst = generator.finalDestination(dst);
2158 Ref<Label> beforeElse = generator.newLabel();
2159 Ref<Label> afterElse = generator.newLabel();
2161 Ref<Label> beforeThen = generator.newLabel();
2162 generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
2163 generator.emitLabel(beforeThen.get());
2165 generator.emitProfileControlFlow(m_expr1->startOffset());
2166 generator.emitNodeInTailPosition(newDst.get(), m_expr1);
2167 generator.emitJump(afterElse.get());
2169 generator.emitLabel(beforeElse.get());
2170 generator.emitProfileControlFlow(m_expr1->endOffset() + 1);
2171 generator.emitNodeInTailPosition(newDst.get(), m_expr2);
2173 generator.emitLabel(afterElse.get());
2175 generator.emitProfileControlFlow(m_expr2->endOffset() + 1);
2177 return newDst.get();
2180 // ------------------------------ ReadModifyResolveNode -----------------------------------
2182 // FIXME: should this be moved to be a method on BytecodeGenerator?
2183 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
2194 if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
2195 return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
2202 opcodeID = op_lshift;
2205 opcodeID = op_rshift;
2208 opcodeID = op_urshift;
2211 opcodeID = op_bitand;
2214 opcodeID = op_bitxor;
2217 opcodeID = op_bitor;
2226 RELEASE_ASSERT_NOT_REACHED();
2230 RegisterID* src2 = generator.emitNode(m_right);
2232 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
2233 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
2234 if (emitExpressionInfoForMe)
2235 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
2236 RegisterID* result = generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
2237 if (oper == OpURShift)
2238 return generator.emitUnaryOp(op_unsigned, result, result);
2242 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2244 JSTextPosition newDivot = divotStart() + m_ident.length();
2245 Variable var = generator.variable(m_ident);
2246 if (RegisterID* local = var.local()) {
2247 generator.emitTDZCheckIfNecessary(var, local, nullptr);
2248 if (var.isReadOnly()) {
2249 generator.emitReadOnlyExceptionIfNeeded(var);
2250 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2251 generator.emitProfileType(result, divotStart(), divotEnd());
2255 if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
2256 RefPtr<RegisterID> result = generator.newTemporary();
2257 generator.emitMove(result.get(), local);
2258 emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2259 generator.emitMove(local, result.get());
2260 generator.invalidateForInContextForLocal(local);
2261 generator.emitProfileType(local, divotStart(), divotEnd());
2262 return generator.moveToDestinationIfNeeded(dst, result.get());
2265 RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2266 generator.invalidateForInContextForLocal(local);
2267 generator.emitProfileType(result, divotStart(), divotEnd());
2268 return generator.moveToDestinationIfNeeded(dst, result);
2271 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
2272 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2273 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
2274 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
2275 if (var.isReadOnly()) {
2276 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2280 RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
2281 RegisterID* returnResult = result.get();
2282 if (!var.isReadOnly()) {
2283 returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
2284 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
2286 return returnResult;
2289 static InitializationMode initializationModeForAssignmentContext(AssignmentContext assignmentContext)
2291 switch (assignmentContext) {
2292 case AssignmentContext::DeclarationStatement:
2293 return InitializationMode::Initialization;
2294 case AssignmentContext::ConstDeclarationStatement:
2295 return InitializationMode::ConstInitialization;
2296 case AssignmentContext::AssignmentExpression:
2297 return InitializationMode::NotInitialization;
2300 ASSERT_NOT_REACHED();
2301 return InitializationMode::NotInitialization;
2304 // ------------------------------ AssignResolveNode -----------------------------------
2306 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2308 Variable var = generator.variable(m_ident);
2309 bool isReadOnly = var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement;
2310 if (RegisterID* local = var.local()) {
2311 RegisterID* result = nullptr;
2312 if (m_assignmentContext == AssignmentContext::AssignmentExpression)
2313 generator.emitTDZCheckIfNecessary(var, local, nullptr);
2316 result = generator.emitNode(dst, m_right); // Execute side effects first.
2317 generator.emitReadOnlyExceptionIfNeeded(var);
2318 generator.emitProfileType(result, var, divotStart(), divotEnd());
2319 } else if (var.isSpecial()) {
2320 RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
2321 generator.emitNode(tempDst.get(), m_right);
2322 generator.emitMove(local, tempDst.get());
2323 generator.emitProfileType(local, var, divotStart(), divotEnd());
2324 generator.invalidateForInContextForLocal(local);
2325 result = generator.moveToDestinationIfNeeded(dst, tempDst.get());
2327 RegisterID* right = generator.emitNode(local, m_right);
2328 generator.emitProfileType(right, var, divotStart(), divotEnd());
2329 generator.invalidateForInContextForLocal(local);
2330 result = generator.moveToDestinationIfNeeded(dst, right);
2333 if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
2334 generator.liftTDZCheckIfPossible(var);
2338 if (generator.isStrictMode())
2339 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2340 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2341 if (m_assignmentContext == AssignmentContext::AssignmentExpression)
2342 generator.emitTDZCheckIfNecessary(var, nullptr, scope.get());
2343 if (dst == generator.ignoredResult())
2345 RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
2347 RegisterID* result = generator.emitNode(dst, m_right); // Execute side effects first.
2348 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2352 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2353 RegisterID* returnResult = result.get();
2355 returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, initializationModeForAssignmentContext(m_assignmentContext));
2356 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
2359 if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
2360 generator.liftTDZCheckIfPossible(var);
2361 return returnResult;
2364 // ------------------------------ AssignDotNode -----------------------------------
2366 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2368 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
2369 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
2370 RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
2371 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2372 RefPtr<RegisterID> forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
2373 if (m_base->isSuperNode()) {
2374 RefPtr<RegisterID> thisValue = generator.ensureThis();
2375 generator.emitPutById(base.get(), thisValue.get(), m_ident, forwardResult.get());
2377 generator.emitPutById(base.get(), m_ident, forwardResult.get());
2378 generator.emitProfileType(forwardResult.get(), divotStart(), divotEnd());
2379 return generator.moveToDestinationIfNeeded(dst, forwardResult.get());
2382 // ------------------------------ ReadModifyDotNode -----------------------------------
2384 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2386 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
2388 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
2389 RefPtr<RegisterID> value;
2390 RefPtr<RegisterID> thisValue;
2391 if (m_base->isSuperNode()) {
2392 thisValue = generator.ensureThis();
2393 value = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), m_ident);
2395 value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
2396 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()));
2398 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2400 if (m_base->isSuperNode())
2401 ret = generator.emitPutById(base.get(), thisValue.get(), m_ident, updatedValue);
2403 ret = generator.emitPutById(base.get(), m_ident, updatedValue);
2404 generator.emitProfileType(updatedValue, divotStart(), divotEnd());
2408 // ------------------------------ AssignErrorNode -----------------------------------
2410 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2412 return emitThrowReferenceError(generator, ASCIILiteral("Left side of assignment is not a reference."));
2415 // ------------------------------ AssignBracketNode -----------------------------------
2417 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2419 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
2420 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSideForProperty(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
2421 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
2422 RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
2424 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2425 RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
2427 if (isNonIndexStringElement(*m_subscript)) {
2428 if (m_base->isSuperNode()) {
2429 RefPtr<RegisterID> thisValue = generator.ensureThis();
2430 generator.emitPutById(base.get(), thisValue.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
2432 generator.emitPutById(base.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
2434 if (m_base->isSuperNode()) {
2435 RefPtr<RegisterID> thisValue = generator.ensureThis();
2436 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), forwardResult);
2438 generator.emitPutByVal(base.get(), property.get(), forwardResult);
2441 generator.emitProfileType(forwardResult, divotStart(), divotEnd());
2442 return generator.moveToDestinationIfNeeded(dst, forwardResult);
2445 // ------------------------------ ReadModifyBracketNode -----------------------------------
2447 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2449 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
2450 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSideForProperty(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
2452 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
2453 RefPtr<RegisterID> value;
2454 RefPtr<RegisterID> thisValue;
2455 if (m_base->isSuperNode()) {
2456 thisValue = generator.ensureThis();
2457 value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisValue.get(), property.get());
2459 value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
2460 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()));
2462 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2463 if (m_base->isSuperNode())
2464 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), updatedValue);
2466 generator.emitPutByVal(base.get(), property.get(), updatedValue);
2467 generator.emitProfileType(updatedValue, divotStart(), divotEnd());
2469 return updatedValue;
2472 // ------------------------------ CommaNode ------------------------------------
2474 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2476 CommaNode* node = this;
2477 for (; node && node->next(); node = node->next())
2478 generator.emitNode(generator.ignoredResult(), node->m_expr);
2479 return generator.emitNodeInTailPosition(dst, node->m_expr);
2482 // ------------------------------ SourceElements -------------------------------
2484 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2486 StatementNode* lastStatementWithCompletionValue = nullptr;
2487 if (generator.shouldBeConcernedWithCompletionValue()) {
2488 for (StatementNode* statement = m_head; statement; statement = statement->next()) {
2489 if (statement->hasCompletionValue())
2490 lastStatementWithCompletionValue = statement;
2494 for (StatementNode* statement = m_head; statement; statement = statement->next()) {
2495 if (statement == lastStatementWithCompletionValue)
2496 generator.emitLoad(dst, jsUndefined());
2497 generator.emitNodeInTailPosition(dst, statement);
2501 // ------------------------------ BlockNode ------------------------------------
2503 void BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2507 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
2508 m_statements->emitBytecode(generator, dst);
2509 generator.popLexicalScope(this);
2512 // ------------------------------ EmptyStatementNode ---------------------------
2514 void EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID*)
2516 RELEASE_ASSERT(needsDebugHook());
2519 // ------------------------------ DebuggerStatementNode ---------------------------
2521 void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2523 generator.emitDebugHook(DidReachBreakpoint, position());
2526 // ------------------------------ ExprStatementNode ----------------------------
2528 void ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2531 generator.emitNode(dst, m_expr);
2534 // ------------------------------ DeclarationStatement ----------------------------
2536 void DeclarationStatement::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2539 generator.emitNode(m_expr);
2542 // ------------------------------ EmptyVarExpression ----------------------------
2544 RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2546 // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
2547 if (!generator.vm()->typeProfiler())
2550 Variable var = generator.variable(m_ident);
2551 if (RegisterID* local = var.local())
2552 generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2554 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2555 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
2556 generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2562 // ------------------------------ EmptyLetExpression ----------------------------
2564 RegisterID* EmptyLetExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2566 // Lexical declarations like 'let' must move undefined into their variables so we don't
2567 // get TDZ errors for situations like this: `let x; x;`
2568 Variable var = generator.variable(m_ident);
2569 if (RegisterID* local = var.local()) {
2570 generator.emitLoad(local, jsUndefined());
2571 generator.invalidateForInContextForLocal(local);
2572 generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2574 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2575 RefPtr<RegisterID> value = generator.emitLoad(nullptr, jsUndefined());
2576 generator.emitPutToScope(scope.get(), var, value.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::Initialization);
2577 generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2580 generator.liftTDZCheckIfPossible(var);
2582 // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
2586 // ------------------------------ IfElseNode ---------------------------------------
2588 static inline StatementNode* singleStatement(StatementNode* statementNode)
2590 if (statementNode->isBlock())
2591 return static_cast<BlockNode*>(statementNode)->singleStatement();
2592 return statementNode;
2595 bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock,
2596 Label*& trueTarget, FallThroughMode& fallThroughMode)
2598 StatementNode* singleStatement = JSC::singleStatement(ifBlock);
2599 if (!singleStatement)
2602 if (singleStatement->isBreak()) {
2603 BreakNode* breakNode = static_cast<BreakNode*>(singleStatement);
2604 Label* target = breakNode->trivialTarget(generator);
2607 trueTarget = target;
2608 fallThroughMode = FallThroughMeansFalse;
2612 if (singleStatement->isContinue()) {
2613 ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement);
2614 Label* target = continueNode->trivialTarget(generator);
2617 trueTarget = target;
2618 fallThroughMode = FallThroughMeansFalse;
2625 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2627 if (generator.shouldBeConcernedWithCompletionValue()) {
2628 if (m_ifBlock->hasEarlyBreakOrContinue() || (m_elseBlock && m_elseBlock->hasEarlyBreakOrContinue()))
2629 generator.emitLoad(dst, jsUndefined());
2632 Ref<Label> beforeThen = generator.newLabel();
2633 Ref<Label> beforeElse = generator.newLabel();
2634 Ref<Label> afterElse = generator.newLabel();
2636 Label* trueTarget = beforeThen.ptr();
2637 Label& falseTarget = beforeElse.get();
2638 FallThroughMode fallThroughMode = FallThroughMeansTrue;
2639 bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode);
2641 generator.emitNodeInConditionContext(m_condition, *trueTarget, falseTarget, fallThroughMode);
2642 generator.emitLabel(beforeThen.get());
2643 generator.emitProfileControlFlow(m_ifBlock->startOffset());
2645 if (!didFoldIfBlock) {
2646 generator.emitNodeInTailPosition(dst, m_ifBlock);
2648 generator.emitJump(afterElse.get());
2651 generator.emitLabel(beforeElse.get());
2654 generator.emitProfileControlFlow(m_ifBlock->endOffset() + (m_ifBlock->isBlock() ? 1 : 0));
2655 generator.emitNodeInTailPosition(dst, m_elseBlock);
2658 generator.emitLabel(afterElse.get());
2659 StatementNode* endingBlock = m_elseBlock ? m_elseBlock : m_ifBlock;
2660 generator.emitProfileControlFlow(endingBlock->endOffset() + (endingBlock->isBlock() ? 1 : 0));
2663 // ------------------------------ DoWhileNode ----------------------------------
2665 void DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2667 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
2668 generator.emitLoad(dst, jsUndefined());
2670 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
2672 Ref<Label> topOfLoop = generator.newLabel();
2673 generator.emitLabel(topOfLoop.get());
2674 generator.emitLoopHint();
2676 generator.emitNodeInTailPosition(dst, m_statement);
2678 generator.emitLabel(*scope->continueTarget());
2679 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2681 generator.emitLabel(scope->breakTarget());
2684 // ------------------------------ WhileNode ------------------------------------
2686 void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2688 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
2689 generator.emitLoad(dst, jsUndefined());
2691 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
2692 Ref<Label> topOfLoop = generator.newLabel();
2694 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2696 generator.emitLabel(topOfLoop.get());
2697 generator.emitLoopHint();
2699 generator.emitProfileControlFlow(m_statement->startOffset());
2700 generator.emitNodeInTailPosition(dst, m_statement);
2702 generator.emitLabel(*scope->continueTarget());
2704 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2706 generator.emitLabel(scope->breakTarget());
2708 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2711 // ------------------------------ ForNode --------------------------------------
2713 void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2715 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
2716 generator.emitLoad(dst, jsUndefined());
2718 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
2720 RegisterID* forLoopSymbolTable = nullptr;
2721 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2724 generator.emitNode(generator.ignoredResult(), m_expr1);
2726 Ref<Label> topOfLoop = generator.newLabel();
2728 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2730 generator.emitLabel(topOfLoop.get());
2731 generator.emitLoopHint();
2732 generator.emitProfileControlFlow(m_statement->startOffset());
2734 generator.emitNodeInTailPosition(dst, m_statement);
2736 generator.emitLabel(*scope->continueTarget());
2737 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2739 generator.emitNode(generator.ignoredResult(), m_expr3);
2742 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2744 generator.emitJump(topOfLoop.get());
2746 generator.emitLabel(scope->breakTarget());
2747 generator.popLexicalScope(this);
2748 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2751 // ------------------------------ ForInNode ------------------------------------
2753 RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator)
2755 if (m_lexpr->isResolveNode()) {
2756 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2757 return generator.variable(ident).local();
2760 if (m_lexpr->isDestructuringNode()) {
2761 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2762 auto binding = assignNode->bindings();
2763 if (!binding->isBindingNode())
2766 auto simpleBinding = static_cast<BindingNode*>(binding);
2767 const Identifier& ident = simpleBinding->boundProperty();
2768 Variable var = generator.variable(ident);
2769 if (var.isSpecial())
2777 void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
2779 auto lambdaEmitResolveVariable = [&] (const Identifier& ident) {
2780 Variable var = generator.variable(ident);
2781 if (RegisterID* local = var.local()) {
2782 if (var.isReadOnly())
2783 generator.emitReadOnlyExceptionIfNeeded(var);
2784 generator.emitMove(local, propertyName);
2785 generator.invalidateForInContextForLocal(local);
2787 if (generator.isStrictMode())
2788 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2789 if (var.isReadOnly())
2790 generator.emitReadOnlyExceptionIfNeeded(var);
2791 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2792 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2793 generator.emitPutToScope(scope.get(), var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2795 generator.emitProfileType(propertyName, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2798 if (m_lexpr->isResolveNode()) {
2799 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2800 lambdaEmitResolveVariable(ident);
2804 if (m_lexpr->isAssignResolveNode()) {
2805 const Identifier& ident = static_cast<AssignResolveNode*>(m_lexpr)->identifier();
2806 lambdaEmitResolveVariable(ident);
2810 if (m_lexpr->isDotAccessorNode()) {
2811 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2812 const Identifier& ident = assignNode->identifier();
2813 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2814 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2815 if (assignNode->base()->isSuperNode()) {
2816 RefPtr<RegisterID> thisValue = generator.ensureThis();
2817 generator.emitPutById(base.get(), thisValue.get(), ident, propertyName);
2819 generator.emitPutById(base.get(), ident, propertyName);
2820 generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
2823 if (m_lexpr->isBracketAccessorNode()) {
2824 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2825 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2826 RefPtr<RegisterID> subscript = generator.emitNodeForProperty(assignNode->subscript());
2827 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2828 if (assignNode->base()->isSuperNode()) {
2829 RefPtr<RegisterID> thisValue = generator.ensureThis();
2830 generator.emitPutByVal(base.get(), thisValue.get(), subscript.get(), propertyName);
2832 generator.emitPutByVal(base.get(), subscript.get(), propertyName);
2833 generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
2837 if (m_lexpr->isDestructuringNode()) {
2838 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2839 auto binding = assignNode->bindings();
2840 if (!binding->isBindingNode()) {
2841 assignNode->bindings()->bindValue(generator, propertyName);
2845 auto simpleBinding = static_cast<BindingNode*>(binding);
2846 const Identifier& ident = simpleBinding->boundProperty();
2847 Variable var = generator.variable(ident);
2848 if (!var.local() || var.isSpecial()) {
2849 assignNode->bindings()->bindValue(generator, propertyName);
2852 generator.emitMove(var.local(), propertyName);
2853 generator.invalidateForInContextForLocal(var.local());
2854 generator.emitProfileType(propertyName, var, simpleBinding->divotStart(), simpleBinding->divotEnd());
2858 RELEASE_ASSERT_NOT_REACHED();
2861 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2863 if (!m_lexpr->isAssignResolveNode() && !m_lexpr->isAssignmentLocation()) {
2864 emitThrowReferenceError(generator, ASCIILiteral("Left side of for-in statement is not a reference."));
2868 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
2869 generator.emitLoad(dst, jsUndefined());
2871 Ref<Label> end = generator.newLabel();
2873 RegisterID* forLoopSymbolTable = nullptr;
2874 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2876 if (m_lexpr->isAssignResolveNode())
2877 generator.emitNode(generator.ignoredResult(), m_lexpr);
2879 RefPtr<RegisterID> base = generator.newTemporary();
2880 RefPtr<RegisterID> length;
2881 RefPtr<RegisterID> enumerator;
2883 generator.emitNode(base.get(), m_expr);
2884 RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
2885 RefPtr<RegisterID> enumeratorIndex;
2887 // Pause at the assignment expression for each for..in iteration.
2888 generator.emitDebugHook(m_lexpr);
2890 int profilerStartOffset = m_statement->startOffset();
2891 int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
2893 enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
2895 // Indexed property loop.
2897 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
2898 Ref<Label> loopStart = generator.newLabel();
2899 Ref<Label> loopEnd = generator.newLabel();
2901 length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
2902 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2903 RefPtr<RegisterID> propertyName = generator.newTemporary();
2905 generator.emitLabel(loopStart.get());
2906 generator.emitLoopHint();
2908 RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get());
2909 generator.emitJumpIfFalse(result.get(), loopEnd.get());
2910 generator.emitHasIndexedProperty(result.get(), base.get(), i.get());
2911 generator.emitJumpIfFalse(result.get(), *scope->continueTarget());
2913 generator.emitToIndexString(propertyName.get(), i.get());
2914 this->emitLoopHeader(generator, propertyName.get());
2916 generator.emitProfileControlFlow(profilerStartOffset);
2918 generator.pushIndexedForInScope(local.get(), i.get());
2919 generator.emitNode(dst, m_statement);
2920 generator.popIndexedForInScope(local.get());
2922 generator.emitProfileControlFlow(profilerEndOffset);
2924 generator.emitLabel(*scope->continueTarget());
2925 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2926 generator.emitInc(i.get());
2927 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration.
2928 generator.emitJump(loopStart.get());
2930 generator.emitLabel(scope->breakTarget());
2931 generator.emitJump(end.get());
2932 generator.emitLabel(loopEnd.get());
2935 // Structure property loop.
2937 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
2938 Ref<Label> loopStart = generator.newLabel();
2939 Ref<Label> loopEnd = generator.newLabel();
2941 enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2942 RefPtr<RegisterID> propertyName = generator.newTemporary();
2943 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2945 generator.emitLabel(loopStart.get());
2946 generator.emitLoopHint();
2948 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2949 generator.emitJumpIfTrue(result.get(), loopEnd.get());
2950 generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
2951 generator.emitJumpIfFalse(result.get(), *scope->continueTarget());
2953 this->emitLoopHeader(generator, propertyName.get());
2955 generator.emitProfileControlFlow(profilerStartOffset);
2957 generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
2958 generator.emitNode(dst, m_statement);
2959 generator.popStructureForInScope(local.get());
2961 generator.emitProfileControlFlow(profilerEndOffset);
2963 generator.emitLabel(*scope->continueTarget());
2964 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2965 generator.emitInc(enumeratorIndex.get());
2966 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2967 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration.
2968 generator.emitJump(loopStart.get());
2970 generator.emitLabel(scope->breakTarget());
2971 generator.emitJump(end.get());
2972 generator.emitLabel(loopEnd.get());
2975 // Generic property loop.
2977 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
2978 Ref<Label> loopStart = generator.newLabel();
2979 Ref<Label> loopEnd = generator.newLabel();
2981 RefPtr<RegisterID> propertyName = generator.newTemporary();
2983 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2985 generator.emitLabel(loopStart.get());
2986 generator.emitLoopHint();
2988 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2989 generator.emitJumpIfTrue(result.get(), loopEnd.get());
2991 generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
2992 generator.emitJumpIfFalse(result.get(), *scope->continueTarget());
2994 this->emitLoopHeader(generator, propertyName.get());
2996 generator.emitProfileControlFlow(profilerStartOffset);
2998 generator.emitNode(dst, m_statement);
3000 generator.emitLabel(*scope->continueTarget());
3001 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
3002 generator.emitInc(enumeratorIndex.get());
3003 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
3004 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration.
3005 generator.emitJump(loopStart.get());
3007 generator.emitLabel(scope->breakTarget());
3008 generator.emitJump(end.get());
3009 generator.emitLabel(loopEnd.get());
3012 generator.emitLabel(end.get());
3013 generator.popLexicalScope(this);
3014 generator.emitProfileControlFlow(profilerEndOffset);
3017 // ------------------------------ ForOfNode ------------------------------------
3018 void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3020 if (!m_lexpr->isAssignmentLocation()) {
3021 emitThrowReferenceError(generator, ASCIILiteral("Left side of for-of statement is not a reference."));
3025 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
3026 generator.emitLoad(dst, jsUndefined());
3028 RegisterID* forLoopSymbolTable = nullptr;
3029 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
3030 auto extractor = [this, dst](BytecodeGenerator& generator, RegisterID* value)
3032 if (m_lexpr->isResolveNode()) {
3033 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
3034 Variable var = generator.variable(ident);
3035 if (RegisterID* local = var.local()) {
3036 if (var.isReadOnly())
3037 generator.emitReadOnlyExceptionIfNeeded(var);
3038 generator.emitMove(local, value);
3039 generator.invalidateForInContextForLocal(local);
3041 if (generator.isStrictMode())
3042 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
3043 if (var.isReadOnly())
3044 generator.emitReadOnlyExceptionIfNeeded(var);
3045 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
3046 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
3047 generator.emitPutToScope(scope.get(), var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
3049 generator.emitProfileType(value, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
3050 } else if (m_lexpr->isDotAccessorNode()) {
3051 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
3052 const Identifier& ident = assignNode->identifier();
3053 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
3055 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
3056 if (assignNode->base()->isSuperNode()) {
3057 RefPtr<RegisterID> thisValue = generator.ensureThis();
3058 generator.emitPutById(base.get(), thisValue.get(), ident, value);
3060 generator.emitPutById(base.get(), ident, value);
3061 generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
3062 } else if (m_lexpr->isBracketAccessorNode()) {
3063 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
3064 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
3065 RegisterID* subscript = generator.emitNodeForProperty(assignNode->subscript());
3067 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
3068 if (assignNode->base()->isSuperNode()) {
3069 RefPtr<RegisterID> thisValue = generator.ensureThis();
3070 generator.emitPutByVal(base.get(), thisValue.get(), subscript, value);
3072 generator.emitPutByVal(base.get(), subscript, value);
3073 generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
3075 ASSERT(m_lexpr->isDestructuringNode());
3076 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
3077 assignNode->bindings()->bindValue(generator, value);
3079 generator.emitProfileControlFlow(m_statement->startOffset());
3080 generator.emitNode(dst, m_statement);
3082 generator.emitEnumeration(this, m_expr, extractor, this, forLoopSymbolTable);
3083 generator.popLexicalScope(this);
3084 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
3087 // ------------------------------ ContinueNode ---------------------------------
3089 Label* ContinueNode::trivialTarget(BytecodeGenerator& generator)
3091 if (generator.shouldEmitDebugHooks())
3094 LabelScope* scope = generator.continueTarget(m_ident);
3097 if (generator.labelScopeDepth() != scope->scopeDepth())
3100 return scope->continueTarget();
3103 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3105 LabelScope* scope = generator.continueTarget(m_ident);
3108 bool hasFinally = generator.emitJumpViaFinallyIfNeeded(scope->scopeDepth(), *scope->continueTarget());
3110 int lexicalScopeIndex = generator.labelScopeDepthToLexicalScopeIndex(scope->scopeDepth());
3111 generator.restoreScopeRegister(lexicalScopeIndex);
3112 generator.emitJump(*scope->continueTarget());
3115 generator.emitProfileControlFlow(endOffset());
3118 // ------------------------------ BreakNode ------------------------------------
3120 Label* BreakNode::trivialTarget(BytecodeGenerator& generator)
3122 if (generator.shouldEmitDebugHooks())
3125 LabelScope* scope = generator.breakTarget(m_ident);
3128 if (generator.labelScopeDepth() != scope->scopeDepth())
3131 return &scope->breakTarget();
3134 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3136 LabelScope* scope = generator.breakTarget(m_ident);
3139 bool hasFinally = generator.emitJumpViaFinallyIfNeeded(scope->scopeDepth(), scope->breakTarget());
3141 int lexicalScopeIndex = generator.labelScopeDepthToLexicalScopeIndex(scope->scopeDepth());
3142 generator.restoreScopeRegister(lexicalScopeIndex);
3143 generator.emitJump(scope->breakTarget());
3146 generator.emitProfileControlFlow(endOffset());
3149 // ------------------------------ ReturnNode -----------------------------------
3151 void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3153 ASSERT(generator.codeType() == FunctionCode);
3155 if (dst == generator.ignoredResult())
3158 RefPtr<RegisterID> returnRegister = m_value ? generator.emitNodeInTailPosition(dst, m_value) : generator.emitLoad(dst, jsUndefined());
3160 generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, divotStart(), divotEnd());
3162 bool hasFinally = generator.emitReturnViaFinallyIfNeeded(returnRegister.get());
3164 if (generator.parseMode() == SourceParseMode::AsyncGeneratorBodyMode) {
3165 returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
3166 generator.emitAwait(returnRegister.get());
3169 generator.emitWillLeaveCallFrameDebugHook();
3170 generator.emitReturn(returnRegister.get());
3173 generator.emitProfileControlFlow(endOffset());
3174 // Emitting an unreachable return here is needed in case this op_profile_control_flow is the
3175 // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode.
3176 if (generator.vm()->controlFlowProfiler())
3177 generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
3180 // ------------------------------ WithNode -------------------------------------
3182 void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3184 RefPtr<RegisterID> scope = generator.emitNode(m_expr);
3185 generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
3186 generator.emitPushWithScope(scope.get());
3187 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
3188 generator.emitLoad(dst, jsUndefined());
3189 generator.emitNodeInTailPosition(dst, m_statement);
3190 generator.emitPopWithScope();
3193 // ------------------------------ CaseClauseNode --------------------------------
3195 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3197 generator.emitProfileControlFlow(m_startOffset);
3200 m_statements->emitBytecode(generator, dst);
3203 // ------------------------------ CaseBlockNode --------------------------------
3212 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
3214 for (; list; list = list->getNext()) {
3215 ExpressionNode* clauseExpression = list->getClause()->expr();
3216 literalVector.append(clauseExpression);
3217 if (clauseExpression->isNumber()) {
3218 double value = static_cast<NumberNode*>(clauseExpression)->value();
3219 int32_t intVal = static_cast<