2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003-2009, 2012-2013, 2015-2016 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"
36 #include "JSFunction.h"
37 #include "JSGeneratorFunction.h"
38 #include "JSGlobalObject.h"
39 #include "JSONObject.h"
40 #include "LabelScope.h"
42 #include "JSCInlines.h"
43 #include "JSTemplateRegistryKey.h"
45 #include "PropertyNameArray.h"
46 #include "RegExpCache.h"
47 #include "RegExpObject.h"
48 #include "StackAlignment.h"
49 #include "TemplateRegistryKey.h"
50 #include <wtf/Assertions.h>
51 #include <wtf/RefCountedLeakCounter.h>
52 #include <wtf/Threading.h>
59 Details of the emitBytecode function.
61 Return value: The register holding the production's value.
62 dst: An optional parameter specifying the most efficient destination at
63 which to store the production's value. The callee must honor dst.
65 The dst argument provides for a crude form of copy propagation. For example,
78 because the assignment node, "x =", passes r[x] as dst to the number node, "1".
81 void ExpressionNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
83 RegisterID* result = generator.emitNode(this);
84 if (fallThroughMode == FallThroughMeansTrue)
85 generator.emitJumpIfFalse(result, falseTarget);
87 generator.emitJumpIfTrue(result, trueTarget);
90 // ------------------------------ ThrowableExpressionData --------------------------------
92 RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message)
94 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
95 generator.emitThrowReferenceError(message);
96 return generator.newTemporary();
99 // ------------------------------ ConstantNode ----------------------------------
101 void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
103 TriState value = jsValue(generator).pureToBoolean();
104 if (value == MixedTriState)
105 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
106 else if (value == TrueTriState && fallThroughMode == FallThroughMeansFalse)
107 generator.emitJump(trueTarget);
108 else if (value == FalseTriState && fallThroughMode == FallThroughMeansTrue)
109 generator.emitJump(falseTarget);
111 // All other cases are unconditional fall-throughs, like "if (true)".
114 RegisterID* ConstantNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
116 if (dst == generator.ignoredResult())
118 return generator.emitLoad(dst, jsValue(generator));
121 JSValue StringNode::jsValue(BytecodeGenerator& generator) const
123 return generator.addStringConstant(m_value);
126 // ------------------------------ NumberNode ----------------------------------
128 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
130 if (dst == generator.ignoredResult())
132 return generator.emitLoad(dst, jsValue(generator), isIntegerNode() ? SourceCodeRepresentation::Integer : SourceCodeRepresentation::Double);
135 // ------------------------------ RegExpNode -----------------------------------
137 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
139 if (dst == generator.ignoredResult())
141 return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string())));
144 // ------------------------------ ThisNode -------------------------------------
146 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
148 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isSuperCallUsedInInnerArrowFunction())
149 generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
151 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived || generator.isDerivedConstructorContext())
152 generator.emitTDZCheck(generator.thisRegister());
154 if (dst == generator.ignoredResult())
157 RegisterID* result = generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
158 static const unsigned thisLength = 4;
159 generator.emitProfileType(generator.thisRegister(), position(), JSTextPosition(-1, position().offset + thisLength, -1));
163 // ------------------------------ SuperNode -------------------------------------
165 RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
167 if (dst == generator.ignoredResult())
170 if (generator.isDerivedConstructorContext())
171 return generator.emitGetById(generator.finalDestination(dst), generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(), generator.propertyNames().underscoreProto);
174 callee.setIndex(JSStack::Callee);
175 return generator.emitGetById(generator.finalDestination(dst), &callee, generator.propertyNames().underscoreProto);
178 static RegisterID* emitHomeObjectForCallee(BytecodeGenerator& generator)
180 if (generator.isDerivedClassContext() || generator.isDerivedConstructorContext()) {
181 RegisterID* derivedConstructor = generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
182 return generator.emitGetById(generator.newTemporary(), derivedConstructor, generator.propertyNames().homeObjectPrivateName);
186 callee.setIndex(JSStack::Callee);
187 return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
190 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator)
192 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
193 return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
196 // ------------------------------ NewTargetNode ----------------------------------
198 RegisterID* NewTargetNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
200 if (dst == generator.ignoredResult())
203 return generator.moveToDestinationIfNeeded(dst, generator.newTarget());
206 // ------------------------------ ResolveNode ----------------------------------
208 bool ResolveNode::isPure(BytecodeGenerator& generator) const
210 return generator.variable(m_ident).offset().isStack();
213 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
215 Variable var = generator.variable(m_ident);
216 if (RegisterID* local = var.local()) {
217 generator.emitTDZCheckIfNecessary(var, local, nullptr);
218 if (dst == generator.ignoredResult())
221 generator.emitProfileType(local, var, m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
222 return generator.moveToDestinationIfNeeded(dst, local);
225 JSTextPosition divot = m_start + m_ident.length();
226 generator.emitExpressionInfo(divot, m_start, divot);
227 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
228 RegisterID* finalDest = generator.finalDestination(dst);
229 RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
230 generator.emitTDZCheckIfNecessary(var, finalDest, nullptr);
231 generator.emitProfileType(finalDest, var, m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
235 // ------------------------------ TemplateStringNode -----------------------------------
237 RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
239 if (dst == generator.ignoredResult())
241 return generator.emitLoad(dst, JSValue(generator.addStringConstant(cooked())));
244 // ------------------------------ TemplateLiteralNode -----------------------------------
246 RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
248 if (!m_templateExpressions) {
249 TemplateStringNode* templateString = m_templateStrings->value();
250 ASSERT_WITH_MESSAGE(!m_templateStrings->next(), "Only one template element exists because there's no expression in a given template literal.");
251 return generator.emitNode(dst, templateString);
254 Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
256 TemplateStringListNode* templateString = m_templateStrings;
257 TemplateExpressionListNode* templateExpression = m_templateExpressions;
258 for (; templateExpression; templateExpression = templateExpression->next(), templateString = templateString->next()) {
259 // Evaluate TemplateString.
260 if (!templateString->value()->cooked().isEmpty()) {
261 temporaryRegisters.append(generator.newTemporary());
262 generator.emitNode(temporaryRegisters.last().get(), templateString->value());
265 // Evaluate Expression.
266 temporaryRegisters.append(generator.newTemporary());
267 generator.emitNode(temporaryRegisters.last().get(), templateExpression->value());
268 generator.emitToString(temporaryRegisters.last().get(), temporaryRegisters.last().get());
271 // Evaluate tail TemplateString.
272 if (!templateString->value()->cooked().isEmpty()) {
273 temporaryRegisters.append(generator.newTemporary());
274 generator.emitNode(temporaryRegisters.last().get(), templateString->value());
277 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
280 // ------------------------------ TaggedTemplateNode -----------------------------------
282 RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
284 ExpectedFunction expectedFunction = NoExpectedFunction;
285 RefPtr<RegisterID> tag = nullptr;
286 RefPtr<RegisterID> base = nullptr;
287 if (!m_tag->isLocation()) {
288 tag = generator.newTemporary();
289 tag = generator.emitNode(tag.get(), m_tag);
290 } else if (m_tag->isResolveNode()) {
291 ResolveNode* resolve = static_cast<ResolveNode*>(m_tag);
292 const Identifier& identifier = resolve->identifier();
293 expectedFunction = generator.expectedFunctionForIdentifier(identifier);
295 Variable var = generator.variable(identifier);
296 if (RegisterID* local = var.local())
297 tag = generator.emitMove(generator.newTemporary(), local);
299 tag = generator.newTemporary();
300 base = generator.newTemporary();
302 JSTextPosition newDivot = divotStart() + identifier.length();
303 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
304 generator.moveToDestinationIfNeeded(base.get(), generator.emitResolveScope(base.get(), var));
305 generator.emitGetFromScope(tag.get(), base.get(), var, ThrowIfNotFound);
307 } else if (m_tag->isBracketAccessorNode()) {
308 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(m_tag);
309 base = generator.newTemporary();
310 base = generator.emitNode(base.get(), bracket->base());
311 RefPtr<RegisterID> property = generator.emitNode(bracket->subscript());
312 tag = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
314 ASSERT(m_tag->isDotAccessorNode());
315 DotAccessorNode* dot = static_cast<DotAccessorNode*>(m_tag);
316 base = generator.newTemporary();
317 base = generator.emitNode(base.get(), dot->base());
318 tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
321 RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(generator.newTemporary(), this);
323 unsigned expressionsCount = 0;
324 for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
327 CallArguments callArguments(generator, nullptr, 1 + expressionsCount);
329 generator.emitMove(callArguments.thisRegister(), base.get());
331 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
333 unsigned argumentIndex = 0;
334 generator.emitMove(callArguments.argumentRegister(argumentIndex++), templateObject.get());
335 for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
336 generator.emitNode(callArguments.argumentRegister(argumentIndex++), templateExpression->value());
338 return generator.emitCall(generator.finalDestination(dst, tag.get()), tag.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
341 // ------------------------------ ArrayNode ------------------------------------
343 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
345 // FIXME: Should we put all of this code into emitNewArray?
348 ElementNode* firstPutElement;
349 for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
350 if (firstPutElement->elision() || firstPutElement->value()->isSpreadExpression())
355 if (!firstPutElement && !m_elision)
356 return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
358 RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
359 ElementNode* n = firstPutElement;
360 for (; n; n = n->next()) {
361 if (n->value()->isSpreadExpression())
363 RegisterID* value = generator.emitNode(n->value());
364 length += n->elision();
365 generator.emitPutByIndex(array.get(), length++, value);
369 RegisterID* value = generator.emitLoad(0, jsNumber(m_elision + length));
370 generator.emitPutById(array.get(), generator.propertyNames().length, value);
373 return generator.moveToDestinationIfNeeded(dst, array.get());
376 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(length));
377 auto spreader = [this, array, index](BytecodeGenerator& generator, RegisterID* value)
379 generator.emitDirectPutByVal(array.get(), index.get(), value);
380 generator.emitInc(index.get());
382 for (; n; n = n->next()) {
384 generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(n->elision())), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
385 if (n->value()->isSpreadExpression()) {
386 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(n->value());
387 generator.emitEnumeration(spread, spread->expression(), spreader);
389 generator.emitDirectPutByVal(array.get(), index.get(), generator.emitNode(n->value()));
390 generator.emitInc(index.get());
395 generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(m_elision)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
396 generator.emitPutById(array.get(), generator.propertyNames().length, index.get());
398 return generator.moveToDestinationIfNeeded(dst, array.get());
401 bool ArrayNode::isSimpleArray() const
403 if (m_elision || m_optional)
405 for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
412 ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNumber, int startPosition) const
414 ASSERT(!m_elision && !m_optional);
415 ElementNode* ptr = m_element;
418 JSTokenLocation location;
419 location.line = lineNumber;
420 location.startOffset = startPosition;
421 ArgumentListNode* head = new (parserArena) ArgumentListNode(location, ptr->value());
422 ArgumentListNode* tail = head;
424 for (; ptr; ptr = ptr->next()) {
425 ASSERT(!ptr->elision());
426 tail = new (parserArena) ArgumentListNode(location, tail, ptr->value());
431 // ------------------------------ ObjectLiteralNode ----------------------------
433 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
436 if (dst == generator.ignoredResult())
438 return generator.emitNewObject(generator.finalDestination(dst));
440 RefPtr<RegisterID> newObj = generator.emitNewObject(generator.tempDestination(dst));
441 generator.emitNode(newObj.get(), m_list);
442 return generator.moveToDestinationIfNeeded(dst, newObj.get());
445 // ------------------------------ PropertyListNode -----------------------------
447 static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject)
449 generator.emitPutById(function, generator.propertyNames().homeObjectPrivateName, homeObject);
452 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
454 // Fast case: this loop just handles regular value properties.
455 PropertyListNode* p = this;
456 for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next)
457 emitPutConstantProperty(generator, dst, *p->m_node);
459 // Were there any get/set properties?
461 // Build a list of getter/setter pairs to try to put them at the same time. If we encounter
462 // a computed property, just emit everything as that may override previous values.
463 bool hasComputedProperty = false;
465 typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
466 typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;
469 // Build a map, pairing get/set values together.
470 for (PropertyListNode* q = p; q; q = q->m_next) {
471 PropertyNode* node = q->m_node;
472 if (node->m_type & PropertyNode::Computed) {
473 hasComputedProperty = true;
476 if (node->m_type & PropertyNode::Constant)
479 // Duplicates are possible.
480 GetterSetterPair pair(node, static_cast<PropertyNode*>(nullptr));
481 GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair);
482 if (!result.isNewEntry) {
483 if (result.iterator->value.first->m_type == node->m_type)
484 result.iterator->value.first = node;
486 result.iterator->value.second = node;
490 // Iterate over the remaining properties in the list.
491 for (; p; p = p->m_next) {
492 PropertyNode* node = p->m_node;
494 // Handle regular values.
495 if (node->m_type & PropertyNode::Constant) {
496 emitPutConstantProperty(generator, dst, *node);
500 RefPtr<RegisterID> value = generator.emitNode(node->m_assign);
501 bool isClassProperty = node->needsSuperBinding();
503 emitPutHomeObject(generator, value.get(), dst);
504 unsigned attribute = isClassProperty ? (Accessor | DontEnum) : Accessor;
506 ASSERT(node->m_type & (PropertyNode::Getter | PropertyNode::Setter));
508 // This is a get/set property which may be overridden by a computed property later.
509 if (hasComputedProperty) {
510 // Computed accessors.
511 if (node->m_type & PropertyNode::Computed) {
512 RefPtr<RegisterID> propertyName = generator.emitNode(node->m_expression);
513 generator.emitSetFunctionNameIfNeeded(node->m_assign, value.get(), propertyName.get());
514 if (node->m_type & PropertyNode::Getter)
515 generator.emitPutGetterByVal(dst, propertyName.get(), attribute, value.get());
517 generator.emitPutSetterByVal(dst, propertyName.get(), attribute, value.get());
521 if (node->m_type & PropertyNode::Getter)
522 generator.emitPutGetterById(dst, *node->name(), attribute, value.get());
524 generator.emitPutSetterById(dst, *node->name(), attribute, value.get());
528 // This is a get/set property pair.
529 GetterSetterMap::iterator it = map.find(node->name()->impl());
530 ASSERT(it != map.end());
531 GetterSetterPair& pair = it->value;
533 // Was this already generated as a part of its partner?
534 if (pair.second == node)
537 // Generate the paired node now.
538 RefPtr<RegisterID> getterReg;
539 RefPtr<RegisterID> setterReg;
540 RegisterID* secondReg = nullptr;
542 if (node->m_type & PropertyNode::Getter) {
545 ASSERT(pair.second->m_type & PropertyNode::Setter);
546 setterReg = generator.emitNode(pair.second->m_assign);
547 secondReg = setterReg.get();
549 setterReg = generator.newTemporary();
550 generator.emitLoad(setterReg.get(), jsUndefined());
553 ASSERT(node->m_type & PropertyNode::Setter);
556 ASSERT(pair.second->m_type & PropertyNode::Getter);
557 getterReg = generator.emitNode(pair.second->m_assign);
558 secondReg = getterReg.get();
560 getterReg = generator.newTemporary();
561 generator.emitLoad(getterReg.get(), jsUndefined());
565 ASSERT(!pair.second || isClassProperty == pair.second->needsSuperBinding());
566 if (isClassProperty && pair.second)
567 emitPutHomeObject(generator, secondReg, dst);
569 generator.emitPutGetterSetter(dst, *node->name(), attribute, getterReg.get(), setterReg.get());
576 void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node)
578 RefPtr<RegisterID> value = generator.emitNode(node.m_assign);
579 if (node.needsSuperBinding()) {
580 emitPutHomeObject(generator, value.get(), newObj);
582 RefPtr<RegisterID> propertyNameRegister;
584 propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node.name());
586 propertyNameRegister = generator.emitNode(node.m_expression);
588 generator.emitCallDefineProperty(newObj, propertyNameRegister.get(),
589 value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
592 if (const auto* identifier = node.name()) {
593 Optional<uint32_t> optionalIndex = parseIndex(*identifier);
594 if (!optionalIndex) {
595 generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType());
599 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value()));
600 generator.emitDirectPutByVal(newObj, index.get(), value.get());
603 RefPtr<RegisterID> propertyName = generator.emitNode(node.m_expression);
604 generator.emitSetFunctionNameIfNeeded(node.m_assign, value.get(), propertyName.get());
605 generator.emitDirectPutByVal(newObj, propertyName.get(), value.get());
608 // ------------------------------ BracketAccessorNode --------------------------------
610 static bool isNonIndexStringElement(ExpressionNode& element)
612 return element.isString() && !parseIndex(static_cast<StringNode&>(element).value());
615 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
617 if (m_base->isSuperNode()) {
618 // FIXME: Should we generate the profiler info?
619 if (isNonIndexStringElement(*m_subscript)) {
620 const Identifier& id = static_cast<StringNode*>(m_subscript)->value();
621 return generator.emitGetById(generator.finalDestination(dst), emitSuperBaseForCallee(generator), id);
623 return generator.emitGetByVal(generator.finalDestination(dst), emitSuperBaseForCallee(generator), generator.emitNode(m_subscript));
627 RegisterID* finalDest = generator.finalDestination(dst);
629 if (isNonIndexStringElement(*m_subscript)) {
630 RefPtr<RegisterID> base = generator.emitNode(m_base);
631 ret = generator.emitGetById(finalDest, base.get(), static_cast<StringNode*>(m_subscript)->value());
633 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
634 RegisterID* property = generator.emitNode(m_subscript);
635 ret = generator.emitGetByVal(finalDest, base.get(), property);
638 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
640 generator.emitProfileType(finalDest, divotStart(), divotEnd());
644 // ------------------------------ DotAccessorNode --------------------------------
646 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
648 RefPtr<RegisterID> base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
649 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
650 RegisterID* finalDest = generator.finalDestination(dst);
651 RegisterID* ret = generator.emitGetById(finalDest, base.get(), m_ident);
652 generator.emitProfileType(finalDest, divotStart(), divotEnd());
656 // ------------------------------ ArgumentListNode -----------------------------
658 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
661 return generator.emitNode(dst, m_expr);
664 // ------------------------------ NewExprNode ----------------------------------
666 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
668 ExpectedFunction expectedFunction;
669 if (m_expr->isResolveNode())
670 expectedFunction = generator.expectedFunctionForIdentifier(static_cast<ResolveNode*>(m_expr)->identifier());
672 expectedFunction = NoExpectedFunction;
673 RefPtr<RegisterID> func = generator.emitNode(m_expr);
674 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
675 CallArguments callArguments(generator, m_args);
676 generator.emitMove(callArguments.thisRegister(), func.get());
677 return generator.emitConstruct(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
680 CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode, unsigned additionalArguments)
681 : m_argumentsNode(argumentsNode)
684 if (generator.shouldEmitProfileHooks())
685 m_profileHookRegister = generator.newTemporary();
687 size_t argumentCountIncludingThis = 1 + additionalArguments; // 'this' register.
689 for (ArgumentListNode* node = argumentsNode->m_listNode; node; node = node->m_next)
690 ++argumentCountIncludingThis;
693 m_argv.grow(argumentCountIncludingThis);
694 for (int i = argumentCountIncludingThis - 1; i >= 0; --i) {
695 m_argv[i] = generator.newTemporary();
696 ASSERT(static_cast<size_t>(i) == m_argv.size() - 1 || m_argv[i]->index() == m_argv[i + 1]->index() - 1);
699 // We need to ensure that the frame size is stack-aligned
700 while ((JSStack::CallFrameHeaderSize + m_argv.size()) % stackAlignmentRegisters()) {
701 m_argv.insert(0, generator.newTemporary());
705 while (stackOffset() % stackAlignmentRegisters()) {
706 m_argv.insert(0, generator.newTemporary());
711 // ------------------------------ EvalFunctionCallNode ----------------------------------
713 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
715 // We need try to load 'this' before call eval in constructor, because 'this' can created by 'super' in some of the arrow function
717 // constructor () { this.id = 'A'; }
720 // var B = class B extend A {
722 // var arrow = () => super();
724 // eval("this.id = 'B'");
727 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction())
728 generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
730 Variable var = generator.variable(generator.propertyNames().eval);
731 if (RegisterID* local = var.local()) {
732 RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
733 CallArguments callArguments(generator, m_args);
734 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
735 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
738 RefPtr<RegisterID> func = generator.newTemporary();
739 CallArguments callArguments(generator, m_args);
740 JSTextPosition newDivot = divotStart() + 4;
741 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
742 generator.moveToDestinationIfNeeded(
743 callArguments.thisRegister(),
744 generator.emitResolveScope(callArguments.thisRegister(), var));
745 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
746 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
749 // ------------------------------ FunctionCallValueNode ----------------------------------
751 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
753 RefPtr<RegisterID> func = generator.emitNode(m_expr);
754 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
755 CallArguments callArguments(generator, m_args);
756 if (m_expr->isSuperNode()) {
757 ASSERT(generator.isConstructor() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
758 ASSERT(generator.constructorKind() == ConstructorKind::Derived || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
759 generator.emitMove(callArguments.thisRegister(), generator.newTarget());
760 RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
761 generator.emitMove(generator.thisRegister(), ret);
763 bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Derived;
764 if (generator.isDerivedConstructorContext() || (isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext()))
765 generator.emitPutThisToArrowFunctionContextScope();
769 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
770 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
771 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
775 // ------------------------------ FunctionCallResolveNode ----------------------------------
777 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
779 ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
781 Variable var = generator.variable(m_ident);
782 if (RegisterID* local = var.local()) {
783 generator.emitTDZCheckIfNecessary(var, local, nullptr);
784 RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
785 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
786 CallArguments callArguments(generator, m_args);
787 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
788 // This passes NoExpectedFunction because we expect that if the function is in a
789 // local variable, then it's not one of our built-in constructors.
790 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
791 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
795 RefPtr<RegisterID> func = generator.newTemporary();
796 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
797 CallArguments callArguments(generator, m_args);
799 JSTextPosition newDivot = divotStart() + m_ident.length();
800 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
801 generator.moveToDestinationIfNeeded(
802 callArguments.thisRegister(),
803 generator.emitResolveScope(callArguments.thisRegister(), var));
804 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
805 generator.emitTDZCheckIfNecessary(var, func.get(), nullptr);
806 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
807 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
811 // ------------------------------ BytecodeIntrinsicNode ----------------------------------
813 RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
815 return (this->*m_emitter)(generator, dst);
818 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_assert(BytecodeGenerator& generator, RegisterID* dst)
821 ArgumentListNode* node = m_args->m_listNode;
822 RefPtr<RegisterID> condition = generator.emitNode(node);
823 generator.emitAssert(condition.get(), node->firstLine());
826 UNUSED_PARAM(generator);
831 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst)
833 ArgumentListNode* node = m_args->m_listNode;
834 RefPtr<RegisterID> base = generator.emitNode(node);
836 RefPtr<RegisterID> index = generator.emitNode(node);
838 RefPtr<RegisterID> value = generator.emitNode(node);
840 ASSERT(!node->m_next);
842 return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
845 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
847 ArgumentListNode* node = m_args->m_listNode;
848 RefPtr<RegisterID> src = generator.emitNode(node);
849 ASSERT(!node->m_next);
851 return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
854 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isObject(BytecodeGenerator& generator, RegisterID* dst)
856 ArgumentListNode* node = m_args->m_listNode;
857 RefPtr<RegisterID> src = generator.emitNode(node);
858 ASSERT(!node->m_next);
860 return generator.moveToDestinationIfNeeded(dst, generator.emitIsObject(generator.tempDestination(dst), src.get()));
864 #define JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS(name) \
865 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_##name(BytecodeGenerator& generator, RegisterID* dst) \
868 ASSERT(type() == Type::Constant); \
869 if (dst == generator.ignoredResult()) \
871 return generator.emitLoad(dst, generator.vm()->bytecodeIntrinsicRegistry().name##Value(generator)); \
873 JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS)
874 #undef JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS
876 // ------------------------------ FunctionCallBracketNode ----------------------------------
878 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
880 bool baseIsSuper = m_base->isSuperNode();
881 bool subscriptIsNonIndexString = isNonIndexStringElement(*m_subscript);
883 RefPtr<RegisterID> base;
885 base = emitSuperBaseForCallee(generator);
887 if (subscriptIsNonIndexString)
888 base = generator.emitNode(m_base);
890 base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
893 RefPtr<RegisterID> function;
894 if (subscriptIsNonIndexString) {
895 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
896 function = generator.emitGetById(generator.tempDestination(dst), base.get(), static_cast<StringNode*>(m_subscript)->value());
898 RefPtr<RegisterID> property = generator.emitNode(m_subscript);
899 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
900 function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
903 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
904 CallArguments callArguments(generator, m_args);
906 generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
908 generator.emitMove(callArguments.thisRegister(), base.get());
909 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
910 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
914 // ------------------------------ FunctionCallDotNode ----------------------------------
916 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
918 RefPtr<RegisterID> function = generator.tempDestination(dst);
919 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
920 CallArguments callArguments(generator, m_args);
921 bool baseIsSuper = m_base->isSuperNode();
923 generator.emitTDZCheck(generator.thisRegister());
924 generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
926 generator.emitNode(callArguments.thisRegister(), m_base);
927 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
928 generator.emitGetById(function.get(), baseIsSuper ? emitSuperBaseForCallee(generator) : callArguments.thisRegister(), m_ident);
929 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
930 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
934 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
936 RefPtr<Label> realCall = generator.newLabel();
937 RefPtr<Label> end = generator.newLabel();
938 RefPtr<RegisterID> base = generator.emitNode(m_base);
939 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
940 RefPtr<RegisterID> function;
941 bool emitCallCheck = !generator.isBuiltinFunction();
943 function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().callPublicName());
944 generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
946 RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
948 if (m_args->m_listNode && m_args->m_listNode->m_expr && m_args->m_listNode->m_expr->isSpreadExpression()) {
949 RefPtr<RegisterID> profileHookRegister;
950 if (generator.shouldEmitProfileHooks())
951 profileHookRegister = generator.newTemporary();
952 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
953 ExpressionNode* subject = spread->expression();
954 RefPtr<RegisterID> argumentsRegister;
955 argumentsRegister = generator.emitNode(subject);
956 generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
957 RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
958 generator.emitCallVarargsInTailPosition(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
959 } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
960 ArgumentListNode* oldList = m_args->m_listNode;
961 m_args->m_listNode = m_args->m_listNode->m_next;
963 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
964 CallArguments callArguments(generator, m_args);
965 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
966 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
967 m_args->m_listNode = oldList;
969 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
970 CallArguments callArguments(generator, m_args);
971 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
972 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
976 generator.emitJump(end.get());
977 generator.emitLabel(realCall.get());
979 CallArguments callArguments(generator, m_args);
980 generator.emitMove(callArguments.thisRegister(), base.get());
981 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
983 generator.emitLabel(end.get());
985 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
986 return returnValue.get();
989 static bool areTrivialApplyArguments(ArgumentsNode* args)
991 return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
992 || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
995 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
997 // A few simple cases can be trivially handled as ordinary function calls.
998 // function.apply(), function.apply(arg) -> identical to function.call
999 // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
1000 bool mayBeCall = areTrivialApplyArguments(m_args);
1002 RefPtr<Label> realCall = generator.newLabel();
1003 RefPtr<Label> end = generator.newLabel();
1004 RefPtr<RegisterID> base = generator.emitNode(m_base);
1005 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1006 RefPtr<RegisterID> function;
1007 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
1008 bool emitCallCheck = !generator.isBuiltinFunction();
1009 if (emitCallCheck) {
1010 function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().applyPublicName());
1011 generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
1014 if (m_args->m_listNode && m_args->m_listNode->m_expr) {
1015 ArgumentListNode* oldList = m_args->m_listNode;
1016 if (m_args->m_listNode->m_expr->isSpreadExpression()) {
1017 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
1018 RefPtr<RegisterID> profileHookRegister;
1019 if (generator.shouldEmitProfileHooks())
1020 profileHookRegister = generator.newTemporary();
1021 RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
1022 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(0));
1023 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1024 RefPtr<RegisterID> argumentsRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1026 auto extractor = [&thisRegister, &argumentsRegister, &index](BytecodeGenerator& generator, RegisterID* value)
1028 RefPtr<Label> haveThis = generator.newLabel();
1029 RefPtr<Label> end = generator.newLabel();
1030 RefPtr<RegisterID> compareResult = generator.newTemporary();
1031 RefPtr<RegisterID> indexZeroCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(0)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
1032 generator.emitJumpIfFalse(indexZeroCompareResult.get(), haveThis.get());
1033 generator.emitMove(thisRegister.get(), value);
1034 generator.emitLoad(index.get(), jsNumber(1));
1035 generator.emitJump(end.get());
1036 generator.emitLabel(haveThis.get());
1037 RefPtr<RegisterID> indexOneCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(1)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
1038 generator.emitJumpIfFalse(indexOneCompareResult.get(), end.get());
1039 generator.emitMove(argumentsRegister.get(), value);
1040 generator.emitLoad(index.get(), jsNumber(2));
1041 generator.emitLabel(end.get());
1043 generator.emitEnumeration(this, spread->expression(), extractor);
1044 generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
1045 } else if (m_args->m_listNode->m_next) {
1046 ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
1047 ASSERT(!m_args->m_listNode->m_next->m_next);
1048 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.parserArena(), 0, 0);
1049 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1050 CallArguments callArguments(generator, m_args);
1051 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1052 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1054 m_args->m_listNode = m_args->m_listNode->m_next;
1055 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1056 CallArguments callArguments(generator, m_args);
1057 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1058 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1060 m_args->m_listNode = oldList;
1062 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1063 CallArguments callArguments(generator, m_args);
1064 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
1065 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1068 ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
1069 RefPtr<RegisterID> profileHookRegister;
1070 if (generator.shouldEmitProfileHooks())
1071 profileHookRegister = generator.newTemporary();
1072 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1073 RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
1074 RefPtr<RegisterID> argsRegister;
1075 ArgumentListNode* args = m_args->m_listNode->m_next;
1076 argsRegister = generator.emitNode(args->m_expr);
1078 // Function.prototype.apply ignores extra arguments, but we still
1079 // need to evaluate them for side effects.
1080 while ((args = args->m_next))
1081 generator.emitNode(args->m_expr);
1083 generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
1085 if (emitCallCheck) {
1086 generator.emitJump(end.get());
1087 generator.emitLabel(realCall.get());
1088 CallArguments callArguments(generator, m_args);
1089 generator.emitMove(callArguments.thisRegister(), base.get());
1090 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1091 generator.emitLabel(end.get());
1093 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1094 return returnValue.get();
1097 // ------------------------------ PostfixNode ----------------------------------
1099 static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
1101 return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
1104 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
1107 return generator.emitToNumber(generator.finalDestination(dst), srcDst);
1108 RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
1109 emitIncOrDec(generator, srcDst, oper);
1110 return generator.moveToDestinationIfNeeded(dst, tmp.get());
1113 RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1115 if (dst == generator.ignoredResult())
1116 return PrefixNode::emitResolve(generator, dst);
1118 ASSERT(m_expr->isResolveNode());
1119 ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1120 const Identifier& ident = resolve->identifier();
1122 Variable var = generator.variable(ident);
1123 if (RegisterID* local = var.local()) {
1124 generator.emitTDZCheckIfNecessary(var, local, nullptr);
1125 RefPtr<RegisterID> localReg = local;
1126 if (var.isReadOnly()) {
1127 generator.emitReadOnlyExceptionIfNeeded(var);
1128 localReg = generator.emitMove(generator.tempDestination(dst), local);
1130 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
1131 generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1132 return oldValue.get();
1135 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1136 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1137 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1138 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1139 if (var.isReadOnly()) {
1140 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1144 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
1145 if (!var.isReadOnly()) {
1146 generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, NotInitialization);
1147 generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
1150 return oldValue.get();
1153 RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1155 if (dst == generator.ignoredResult())
1156 return PrefixNode::emitBracket(generator, dst);
1158 ASSERT(m_expr->isBracketAccessorNode());
1159 BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1160 ExpressionNode* baseNode = bracketAccessor->base();
1161 ExpressionNode* subscript = bracketAccessor->subscript();
1163 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1164 RefPtr<RegisterID> property = generator.emitNode(subscript);
1166 generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1167 RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1168 RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1169 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1170 generator.emitPutByVal(base.get(), property.get(), value.get());
1171 generator.emitProfileType(value.get(), divotStart(), divotEnd());
1172 return generator.moveToDestinationIfNeeded(dst, oldValue);
1175 RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1177 if (dst == generator.ignoredResult())
1178 return PrefixNode::emitDot(generator, dst);
1180 ASSERT(m_expr->isDotAccessorNode());
1181 DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1182 ExpressionNode* baseNode = dotAccessor->base();
1183 const Identifier& ident = dotAccessor->identifier();
1185 RefPtr<RegisterID> base = generator.emitNode(baseNode);
1187 generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1188 RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
1189 RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1190 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1191 generator.emitPutById(base.get(), ident, value.get());
1192 generator.emitProfileType(value.get(), divotStart(), divotEnd());
1193 return generator.moveToDestinationIfNeeded(dst, oldValue);
1196 RegisterID* PostfixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1198 if (m_expr->isResolveNode())
1199 return emitResolve(generator, dst);
1201 if (m_expr->isBracketAccessorNode())
1202 return emitBracket(generator, dst);
1204 if (m_expr->isDotAccessorNode())
1205 return emitDot(generator, dst);
1207 return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1208 ? ASCIILiteral("Postfix ++ operator applied to value that is not a reference.")
1209 : ASCIILiteral("Postfix -- operator applied to value that is not a reference."));
1212 // ------------------------------ DeleteResolveNode -----------------------------------
1214 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1216 Variable var = generator.variable(m_ident);
1218 generator.emitTDZCheckIfNecessary(var, var.local(), nullptr);
1219 return generator.emitLoad(generator.finalDestination(dst), false);
1222 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1223 RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
1224 generator.emitTDZCheckIfNecessary(var, nullptr, base.get());
1225 return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
1228 // ------------------------------ DeleteBracketNode -----------------------------------
1230 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1232 RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1233 RefPtr<RegisterID> r1 = generator.emitNode(m_subscript);
1235 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1236 if (m_base->isSuperNode())
1237 return emitThrowReferenceError(generator, "Cannot delete a super property");
1238 return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
1241 // ------------------------------ DeleteDotNode -----------------------------------
1243 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1245 RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1247 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1248 if (m_base->isSuperNode())
1249 return emitThrowReferenceError(generator, "Cannot delete a super property");
1250 return generator.emitDeleteById(generator.finalDestination(dst), r0.get(), m_ident);
1253 // ------------------------------ DeleteValueNode -----------------------------------
1255 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1257 generator.emitNode(generator.ignoredResult(), m_expr);
1259 // delete on a non-location expression ignores the value and returns true
1260 return generator.emitLoad(generator.finalDestination(dst), true);
1263 // ------------------------------ VoidNode -------------------------------------
1265 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1267 if (dst == generator.ignoredResult()) {
1268 generator.emitNode(generator.ignoredResult(), m_expr);
1271 RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1272 return generator.emitLoad(dst, jsUndefined());
1275 // ------------------------------ TypeOfResolveNode -----------------------------------
1277 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1279 Variable var = generator.variable(m_ident);
1280 if (RegisterID* local = var.local()) {
1281 generator.emitTDZCheckIfNecessary(var, local, nullptr);
1282 if (dst == generator.ignoredResult())
1284 return generator.emitTypeOf(generator.finalDestination(dst), local);
1287 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1288 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
1289 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1290 if (dst == generator.ignoredResult())
1292 return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
1295 // ------------------------------ TypeOfValueNode -----------------------------------
1297 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1299 if (dst == generator.ignoredResult()) {
1300 generator.emitNode(generator.ignoredResult(), m_expr);
1303 RefPtr<RegisterID> src = generator.emitNode(m_expr);
1304 return generator.emitTypeOf(generator.finalDestination(dst), src.get());
1307 // ------------------------------ PrefixNode ----------------------------------
1309 RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1311 ASSERT(m_expr->isResolveNode());
1312 ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1313 const Identifier& ident = resolve->identifier();
1315 Variable var = generator.variable(ident);
1316 if (RegisterID* local = var.local()) {
1317 generator.emitTDZCheckIfNecessary(var, local, nullptr);
1318 RefPtr<RegisterID> localReg = local;
1319 if (var.isReadOnly()) {
1320 generator.emitReadOnlyExceptionIfNeeded(var);
1321 localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
1322 } else if (generator.vm()->typeProfiler()) {
1323 RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1324 generator.emitMove(tempDst.get(), localReg.get());
1325 emitIncOrDec(generator, tempDst.get(), m_operator);
1326 generator.emitMove(localReg.get(), tempDst.get());
1327 generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1328 return generator.moveToDestinationIfNeeded(dst, tempDst.get());
1330 emitIncOrDec(generator, localReg.get(), m_operator);
1331 return generator.moveToDestinationIfNeeded(dst, localReg.get());
1334 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1335 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1336 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1337 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1338 if (var.isReadOnly()) {
1339 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1344 emitIncOrDec(generator, value.get(), m_operator);
1345 if (!var.isReadOnly()) {
1346 generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, NotInitialization);
1347 generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
1349 return generator.moveToDestinationIfNeeded(dst, value.get());
1352 RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1354 ASSERT(m_expr->isBracketAccessorNode());
1355 BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1356 ExpressionNode* baseNode = bracketAccessor->base();
1357 ExpressionNode* subscript = bracketAccessor->subscript();
1359 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1360 RefPtr<RegisterID> property = generator.emitNode(subscript);
1361 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1363 generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1364 RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1365 emitIncOrDec(generator, value, m_operator);
1366 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1367 generator.emitPutByVal(base.get(), property.get(), value);
1368 generator.emitProfileType(value, divotStart(), divotEnd());
1369 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1372 RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1374 ASSERT(m_expr->isDotAccessorNode());
1375 DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1376 ExpressionNode* baseNode = dotAccessor->base();
1377 const Identifier& ident = dotAccessor->identifier();
1379 RefPtr<RegisterID> base = generator.emitNode(baseNode);
1380 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1382 generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1383 RegisterID* value = generator.emitGetById(propDst.get(), base.get(), ident);
1384 emitIncOrDec(generator, value, m_operator);
1385 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1386 generator.emitPutById(base.get(), ident, value);
1387 generator.emitProfileType(value, divotStart(), divotEnd());
1388 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1391 RegisterID* PrefixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1393 if (m_expr->isResolveNode())
1394 return emitResolve(generator, dst);
1396 if (m_expr->isBracketAccessorNode())
1397 return emitBracket(generator, dst);
1399 if (m_expr->isDotAccessorNode())
1400 return emitDot(generator, dst);
1402 return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1403 ? ASCIILiteral("Prefix ++ operator applied to value that is not a reference.")
1404 : ASCIILiteral("Prefix -- operator applied to value that is not a reference."));
1407 // ------------------------------ Unary Operation Nodes -----------------------------------
1409 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1411 RefPtr<RegisterID> src = generator.emitNode(m_expr);
1412 generator.emitExpressionInfo(position(), position(), position());
1413 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get());
1416 // ------------------------------ BitwiseNotNode -----------------------------------
1418 RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1420 RefPtr<RegisterID> src2 = generator.emitLoad(generator.newTemporary(), jsNumber(-1));
1421 RefPtr<RegisterID> src1 = generator.emitNode(m_expr);
1422 return generator.emitBinaryOp(op_bitxor, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr->resultDescriptor(), ResultType::numberTypeIsInt32()));
1425 // ------------------------------ LogicalNotNode -----------------------------------
1427 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1429 // reverse the true and false targets
1430 generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode));
1434 // ------------------------------ Binary Operation Nodes -----------------------------------
1436 // BinaryOpNode::emitStrcat:
1438 // This node generates an op_strcat operation. This opcode can handle concatenation of three or
1439 // more values, where we can determine a set of separate op_add operations would be operating on
1442 // This function expects to be operating on a graph of AST nodes looking something like this:
1452 // The assignment operation is optional, if it exists the register holding the value on the
1453 // lefthand side of the assignment should be passing as the optional 'lhs' argument.
1455 // The method should be called on the node at the root of the tree of regular binary add
1456 // operations (marked in the diagram with a double set of parentheses). This node must
1457 // be performing a string concatenation (determined by statically detecting that at least
1458 // one child must be a string).
1460 // Since the minimum number of values being concatenated together is expected to be 3, if
1461 // a lhs to a concatenating assignment is not provided then the root add should have at
1462 // least one left child that is also an add that can be determined to be operating on strings.
1464 RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
1467 ASSERT(resultDescriptor().definitelyIsString());
1469 // Create a list of expressions for all the adds in the tree of nodes we can convert into
1470 // a string concatenation. The rightmost node (c) is added first. The rightmost node is
1471 // added first, and the leftmost child is never added, so the vector produced for the
1472 // example above will be [ c, b ].
1473 Vector<ExpressionNode*, 16> reverseExpressionList;
1474 reverseExpressionList.append(m_expr2);
1476 // Examine the left child of the add. So long as this is a string add, add its right-child
1477 // to the list, and keep processing along the left fork.
1478 ExpressionNode* leftMostAddChild = m_expr1;
1479 while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
1480 reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
1481 leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
1484 Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
1486 // If there is an assignment, allocate a temporary to hold the lhs after conversion.
1487 // We could possibly avoid this (the lhs is converted last anyway, we could let the
1488 // op_strcat node handle its conversion if required).
1490 temporaryRegisters.append(generator.newTemporary());
1492 // Emit code for the leftmost node ((a) in the example).
1493 temporaryRegisters.append(generator.newTemporary());
1494 RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
1495 generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
1497 // Note on ordering of conversions:
1499 // We maintain the same ordering of conversions as we would see if the concatenations
1500 // was performed as a sequence of adds (otherwise this optimization could change
1501 // behaviour should an object have been provided a valueOf or toString method).
1503 // Considering the above example, the sequnce of execution is:
1504 // * evaluate operand (a)
1505 // * evaluate operand (b)
1506 // * convert (a) to primitive <- (this would be triggered by the first add)
1507 // * convert (b) to primitive <- (ditto)
1508 // * evaluate operand (c)
1509 // * convert (c) to primitive <- (this would be triggered by the second add)
1510 // And optionally, if there is an assignment:
1511 // * convert (d) to primitive <- (this would be triggered by the assigning addition)
1513 // As such we do not plant an op to convert the leftmost child now. Instead, use
1514 // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
1515 // once the second node has been generated. However, if the leftmost child is an
1516 // immediate we can trivially determine that no conversion will be required.
1517 // If this is the case
1518 if (leftMostAddChild->isString())
1519 leftMostAddChildTempRegister = 0;
1521 while (reverseExpressionList.size()) {
1522 ExpressionNode* node = reverseExpressionList.last();
1523 reverseExpressionList.removeLast();
1525 // Emit the code for the current node.
1526 temporaryRegisters.append(generator.newTemporary());
1527 generator.emitNode(temporaryRegisters.last().get(), node);
1529 // On the first iteration of this loop, when we first reach this point we have just
1530 // generated the second node, which means it is time to convert the leftmost operand.
1531 if (leftMostAddChildTempRegister) {
1532 generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
1533 leftMostAddChildTempRegister = 0; // Only do this once.
1535 // Plant a conversion for this node, if necessary.
1536 if (!node->isString())
1537 generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
1539 ASSERT(temporaryRegisters.size() >= 3);
1541 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1542 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1543 if (emitExpressionInfoForMe)
1544 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1545 // If there is an assignment convert the lhs now. This will also copy lhs to
1546 // the temporary register we allocated for it.
1548 generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
1550 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
1553 void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1555 TriState branchCondition;
1556 ExpressionNode* branchExpression;
1557 tryFoldToBranch(generator, branchCondition, branchExpression);
1559 if (branchCondition == MixedTriState)
1560 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
1561 else if (branchCondition == TrueTriState)
1562 generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode);
1564 generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode));
1567 static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant)
1569 ResultType expressionType = branchExpression->resultDescriptor();
1571 if (expressionType.definitelyIsBoolean() && constant.isBoolean())
1573 else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1))
1574 return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch.
1575 else if (expressionType.isInt32() && constant.isInt32() && constant.asInt32() == 0)
1581 void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression)
1583 branchCondition = MixedTriState;
1584 branchExpression = 0;
1586 ConstantNode* constant = 0;
1587 if (m_expr1->isConstant()) {
1588 constant = static_cast<ConstantNode*>(m_expr1);
1589 branchExpression = m_expr2;
1590 } else if (m_expr2->isConstant()) {
1591 constant = static_cast<ConstantNode*>(m_expr2);
1592 branchExpression = m_expr1;
1597 ASSERT(branchExpression);
1599 OpcodeID opcodeID = this->opcodeID();
1600 JSValue value = constant->jsValue(generator);
1601 bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
1602 if (!canFoldToBranch)
1605 if (opcodeID == op_eq || opcodeID == op_stricteq)
1606 branchCondition = triState(value.pureToBoolean());
1607 else if (opcodeID == op_neq || opcodeID == op_nstricteq)
1608 branchCondition = triState(!value.pureToBoolean());
1611 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1613 OpcodeID opcodeID = this->opcodeID();
1615 if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString()) {
1616 generator.emitExpressionInfo(position(), position(), position());
1617 return emitStrcat(generator, dst);
1620 if (opcodeID == op_neq) {
1621 if (m_expr1->isNull() || m_expr2->isNull()) {
1622 RefPtr<RegisterID> src = generator.tempDestination(dst);
1623 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1624 return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
1628 ExpressionNode* left = m_expr1;
1629 ExpressionNode* right = m_expr2;
1630 if (opcodeID == op_neq || opcodeID == op_nstricteq) {
1631 if (left->isString())
1632 std::swap(left, right);
1635 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
1636 bool wasTypeof = generator.lastOpcodeID() == op_typeof;
1637 RefPtr<RegisterID> src2 = generator.emitNode(right);
1638 generator.emitExpressionInfo(position(), position(), position());
1639 if (wasTypeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
1640 RefPtr<RegisterID> tmp = generator.tempDestination(dst);
1641 if (opcodeID == op_neq)
1642 generator.emitEqualityOp(op_eq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
1643 else if (opcodeID == op_nstricteq)
1644 generator.emitEqualityOp(op_stricteq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
1646 RELEASE_ASSERT_NOT_REACHED();
1647 return generator.emitUnaryOp(op_not, generator.finalDestination(dst, tmp.get()), tmp.get());
1649 RegisterID* result = generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
1650 if (opcodeID == op_urshift && dst != generator.ignoredResult())
1651 return generator.emitUnaryOp(op_unsigned, result, result);
1655 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1657 if (m_expr1->isNull() || m_expr2->isNull()) {
1658 RefPtr<RegisterID> src = generator.tempDestination(dst);
1659 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1660 return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
1663 ExpressionNode* left = m_expr1;
1664 ExpressionNode* right = m_expr2;
1665 if (left->isString())
1666 std::swap(left, right);
1668 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
1669 RefPtr<RegisterID> src2 = generator.emitNode(right);
1670 return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
1673 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1675 ExpressionNode* left = m_expr1;
1676 ExpressionNode* right = m_expr2;
1677 if (left->isString())
1678 std::swap(left, right);
1680 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
1681 RefPtr<RegisterID> src2 = generator.emitNode(right);
1682 return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
1685 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1687 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
1688 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
1689 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1690 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1693 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1695 RefPtr<RegisterID> hasInstanceValue = generator.newTemporary();
1696 RefPtr<RegisterID> isObject = generator.newTemporary();
1697 RefPtr<RegisterID> isCustom = generator.newTemporary();
1698 RefPtr<RegisterID> prototype = generator.newTemporary();
1699 RefPtr<RegisterID> value = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
1700 RefPtr<RegisterID> constructor = generator.emitNode(m_expr2);
1701 RefPtr<RegisterID> dstReg = generator.finalDestination(dst, value.get());
1702 RefPtr<Label> custom = generator.newLabel();
1703 RefPtr<Label> done = generator.newLabel();
1704 RefPtr<Label> typeError = generator.newLabel();
1706 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1707 generator.emitIsObject(isObject.get(), constructor.get());
1708 generator.emitJumpIfFalse(isObject.get(), typeError.get());
1710 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1711 generator.emitGetById(hasInstanceValue.get(), constructor.get(), generator.vm()->propertyNames->hasInstanceSymbol);
1713 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1714 generator.emitOverridesHasInstance(isCustom.get(), constructor.get(), hasInstanceValue.get());
1716 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1717 generator.emitJumpIfTrue(isCustom.get(), custom.get());
1719 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1720 generator.emitGetById(prototype.get(), constructor.get(), generator.vm()->propertyNames->prototype);
1722 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1723 generator.emitInstanceOf(dstReg.get(), value.get(), prototype.get());
1725 generator.emitJump(done.get());
1727 generator.emitLabel(typeError.get());
1728 generator.emitThrowTypeError("Right hand side of instanceof is not an object");
1730 generator.emitLabel(custom.get());
1732 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1733 generator.emitInstanceOfCustom(dstReg.get(), value.get(), constructor.get(), hasInstanceValue.get());
1735 generator.emitLabel(done.get());
1737 return dstReg.get();
1740 // ------------------------------ LogicalOpNode ----------------------------
1742 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1744 RefPtr<RegisterID> temp = generator.tempDestination(dst);
1745 RefPtr<Label> target = generator.newLabel();
1747 generator.emitNode(temp.get(), m_expr1);
1748 if (m_operator == OpLogicalAnd)
1749 generator.emitJumpIfFalse(temp.get(), target.get());
1751 generator.emitJumpIfTrue(temp.get(), target.get());
1752 generator.emitNodeInTailPosition(temp.get(), m_expr2);
1753 generator.emitLabel(target.get());
1755 return generator.moveToDestinationIfNeeded(dst, temp.get());
1758 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1760 RefPtr<Label> afterExpr1 = generator.newLabel();
1761 if (m_operator == OpLogicalAnd)
1762 generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, FallThroughMeansTrue);
1764 generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), FallThroughMeansFalse);
1765 generator.emitLabel(afterExpr1.get());
1767 generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMode);
1770 // ------------------------------ ConditionalNode ------------------------------
1772 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1774 RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1775 RefPtr<Label> beforeElse = generator.newLabel();
1776 RefPtr<Label> afterElse = generator.newLabel();
1778 RefPtr<Label> beforeThen = generator.newLabel();
1779 generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
1780 generator.emitLabel(beforeThen.get());
1782 generator.emitProfileControlFlow(m_expr1->startOffset());
1783 generator.emitNodeInTailPosition(newDst.get(), m_expr1);
1784 generator.emitJump(afterElse.get());
1786 generator.emitLabel(beforeElse.get());
1787 generator.emitProfileControlFlow(m_expr1->endOffset() + 1);
1788 generator.emitNodeInTailPosition(newDst.get(), m_expr2);
1790 generator.emitLabel(afterElse.get());
1792 generator.emitProfileControlFlow(m_expr2->endOffset() + 1);
1794 return newDst.get();
1797 // ------------------------------ ReadModifyResolveNode -----------------------------------
1799 // FIXME: should this be moved to be a method on BytecodeGenerator?
1800 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
1811 if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
1812 return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
1819 opcodeID = op_lshift;
1822 opcodeID = op_rshift;
1825 opcodeID = op_urshift;
1828 opcodeID = op_bitand;
1831 opcodeID = op_bitxor;
1834 opcodeID = op_bitor;
1840 RELEASE_ASSERT_NOT_REACHED();
1844 RegisterID* src2 = generator.emitNode(m_right);
1846 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1847 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1848 if (emitExpressionInfoForMe)
1849 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1850 RegisterID* result = generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1851 if (oper == OpURShift)
1852 return generator.emitUnaryOp(op_unsigned, result, result);
1856 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1858 JSTextPosition newDivot = divotStart() + m_ident.length();
1859 Variable var = generator.variable(m_ident);
1860 if (RegisterID* local = var.local()) {
1861 generator.emitTDZCheckIfNecessary(var, local, nullptr);
1862 if (var.isReadOnly()) {
1863 generator.emitReadOnlyExceptionIfNeeded(var);
1864 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1865 generator.emitProfileType(result, divotStart(), divotEnd());
1869 if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1870 RefPtr<RegisterID> result = generator.newTemporary();
1871 generator.emitMove(result.get(), local);
1872 emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1873 generator.emitMove(local, result.get());
1874 generator.invalidateForInContextForLocal(local);
1875 generator.emitProfileType(local, divotStart(), divotEnd());
1876 return generator.moveToDestinationIfNeeded(dst, result.get());
1879 RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1880 generator.invalidateForInContextForLocal(local);
1881 generator.emitProfileType(result, divotStart(), divotEnd());
1882 return generator.moveToDestinationIfNeeded(dst, result);
1885 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
1886 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1887 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1888 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1889 if (var.isReadOnly()) {
1890 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1894 RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
1895 RegisterID* returnResult = result.get();
1896 if (!var.isReadOnly()) {
1897 returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, NotInitialization);
1898 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
1900 return returnResult;
1903 // ------------------------------ AssignResolveNode -----------------------------------
1905 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1907 Variable var = generator.variable(m_ident);
1908 bool isReadOnly = var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement;
1909 if (RegisterID* local = var.local()) {
1910 RegisterID* result = nullptr;
1911 if (m_assignmentContext == AssignmentContext::AssignmentExpression)
1912 generator.emitTDZCheckIfNecessary(var, local, nullptr);
1915 result = generator.emitNode(dst, m_right); // Execute side effects first.
1916 generator.emitReadOnlyExceptionIfNeeded(var);
1917 generator.emitProfileType(result, var, divotStart(), divotEnd());
1918 } else if (var.isSpecial()) {
1919 RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1920 generator.emitNode(tempDst.get(), m_right);
1921 generator.emitMove(local, tempDst.get());
1922 generator.emitProfileType(local, var, divotStart(), divotEnd());
1923 generator.invalidateForInContextForLocal(local);
1924 result = generator.moveToDestinationIfNeeded(dst, tempDst.get());
1926 RegisterID* right = generator.emitNode(local, m_right);
1927 generator.emitProfileType(right, var, divotStart(), divotEnd());
1928 generator.invalidateForInContextForLocal(local);
1929 result = generator.moveToDestinationIfNeeded(dst, right);
1932 if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
1933 generator.liftTDZCheckIfPossible(var);
1937 if (generator.isStrictMode())
1938 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1939 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1940 if (m_assignmentContext == AssignmentContext::AssignmentExpression)
1941 generator.emitTDZCheckIfNecessary(var, nullptr, scope.get());
1942 if (dst == generator.ignoredResult())
1944 RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
1946 RegisterID* result = generator.emitNode(dst, m_right); // Execute side effects first.
1947 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1951 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1952 RegisterID* returnResult = result.get();
1954 returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound,
1955 m_assignmentContext == AssignmentContext::ConstDeclarationStatement || m_assignmentContext == AssignmentContext::DeclarationStatement ? Initialization : NotInitialization);
1956 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
1959 if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
1960 generator.liftTDZCheckIfPossible(var);
1961 return returnResult;
1964 // ------------------------------ AssignDotNode -----------------------------------
1966 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1968 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1969 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1970 RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
1971 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1972 RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
1973 generator.emitPutById(base.get(), m_ident, forwardResult);
1974 generator.emitProfileType(forwardResult, divotStart(), divotEnd());
1975 return generator.moveToDestinationIfNeeded(dst, forwardResult);
1978 // ------------------------------ ReadModifyDotNode -----------------------------------
1980 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1982 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1984 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1985 RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1986 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()));
1988 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1989 RegisterID* ret = generator.emitPutById(base.get(), m_ident, updatedValue);
1990 generator.emitProfileType(updatedValue, divotStart(), divotEnd());
1994 // ------------------------------ AssignErrorNode -----------------------------------
1996 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1998 return emitThrowReferenceError(generator, ASCIILiteral("Left side of assignment is not a reference."));
2001 // ------------------------------ AssignBracketNode -----------------------------------
2003 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2005 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
2006 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
2007 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
2008 RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
2010 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2011 RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
2013 if (isNonIndexStringElement(*m_subscript))
2014 generator.emitPutById(base.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
2016 generator.emitPutByVal(base.get(), property.get(), forwardResult);
2018 generator.emitProfileType(forwardResult, divotStart(), divotEnd());
2019 return generator.moveToDestinationIfNeeded(dst, forwardResult);
2022 // ------------------------------ ReadModifyBracketNode -----------------------------------
2024 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2026 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
2027 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
2029 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
2030 RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
2031 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()));
2033 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2034 generator.emitPutByVal(base.get(), property.get(), updatedValue);
2035 generator.emitProfileType(updatedValue, divotStart(), divotEnd());
2037 return updatedValue;
2040 // ------------------------------ CommaNode ------------------------------------
2042 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2044 CommaNode* node = this;
2045 for (; node && node->next(); node = node->next())
2046 generator.emitNode(generator.ignoredResult(), node->m_expr);
2047 return generator.emitNodeInTailPosition(dst, node->m_expr);
2050 // ------------------------------ SourceElements -------------------------------
2053 inline StatementNode* SourceElements::lastStatement() const
2058 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2060 for (StatementNode* statement = m_head; statement; statement = statement->next())
2061 generator.emitNodeInTailPosition(dst, statement);
2064 // ------------------------------ BlockNode ------------------------------------
2066 inline StatementNode* BlockNode::lastStatement() const
2068 return m_statements ? m_statements->lastStatement() : 0;
2071 StatementNode* BlockNode::singleStatement() const
2073 return m_statements ? m_statements->singleStatement() : 0;
2076 void BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2080 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
2081 m_statements->emitBytecode(generator, dst);
2082 generator.popLexicalScope(this);
2085 // ------------------------------ EmptyStatementNode ---------------------------
2087 void EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2089 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2092 // ------------------------------ DebuggerStatementNode ---------------------------
2094 void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2096 generator.emitDebugHook(DidReachBreakpoint, lastLine(), startOffset(), lineStartOffset());
2099 // ------------------------------ ExprStatementNode ----------------------------
2101 void ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2104 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2105 generator.emitNode(dst, m_expr);
2108 // ------------------------------ DeclarationStatement ----------------------------
2110 void DeclarationStatement::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2113 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2114 generator.emitNode(m_expr);
2117 // ------------------------------ EmptyVarExpression ----------------------------
2119 RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2121 // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
2122 if (!generator.vm()->typeProfiler())
2125 Variable var = generator.variable(m_ident);
2126 if (RegisterID* local = var.local())
2127 generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2129 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2130 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
2131 generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2137 // ------------------------------ EmptyLetExpression ----------------------------
2139 RegisterID* EmptyLetExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2141 // Lexical declarations like 'let' must move undefined into their variables so we don't
2142 // get TDZ errors for situations like this: `let x; x;`
2143 Variable var = generator.variable(m_ident);
2144 if (RegisterID* local = var.local()) {
2145 generator.emitLoad(local, jsUndefined());
2146 generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2148 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2149 RefPtr<RegisterID> value = generator.emitLoad(nullptr, jsUndefined());
2150 generator.emitPutToScope(scope.get(), var, value.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, Initialization);
2151 generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2154 generator.liftTDZCheckIfPossible(var);
2156 // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
2160 // ------------------------------ IfElseNode ---------------------------------------
2162 static inline StatementNode* singleStatement(StatementNode* statementNode)
2164 if (statementNode->isBlock())
2165 return static_cast<BlockNode*>(statementNode)->singleStatement();
2166 return statementNode;
2169 bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock,
2170 Label*& trueTarget, FallThroughMode& fallThroughMode)
2172 StatementNode* singleStatement = JSC::singleStatement(ifBlock);
2173 if (!singleStatement)
2176 if (singleStatement->isBreak()) {
2177 BreakNode* breakNode = static_cast<BreakNode*>(singleStatement);
2178 Label* target = breakNode->trivialTarget(generator);
2181 trueTarget = target;
2182 fallThroughMode = FallThroughMeansFalse;
2186 if (singleStatement->isContinue()) {
2187 ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement);
2188 Label* target = continueNode->trivialTarget(generator);
2191 trueTarget = target;
2192 fallThroughMode = FallThroughMeansFalse;
2199 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2201 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2203 RefPtr<Label> beforeThen = generator.newLabel();
2204 RefPtr<Label> beforeElse = generator.newLabel();
2205 RefPtr<Label> afterElse = generator.newLabel();
2207 Label* trueTarget = beforeThen.get();
2208 Label* falseTarget = beforeElse.get();
2209 FallThroughMode fallThroughMode = FallThroughMeansTrue;
2210 bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode);
2212 generator.emitNodeInConditionContext(m_condition, trueTarget, falseTarget, fallThroughMode);
2213 generator.emitLabel(beforeThen.get());
2214 generator.emitProfileControlFlow(m_ifBlock->startOffset());
2216 if (!didFoldIfBlock) {
2217 generator.emitNodeInTailPosition(dst, m_ifBlock);
2219 generator.emitJump(afterElse.get());
2222 generator.emitLabel(beforeElse.get());
2225 generator.emitProfileControlFlow(m_ifBlock->endOffset() + (m_ifBlock->isBlock() ? 1 : 0));
2226 generator.emitNodeInTailPosition(dst, m_elseBlock);
2229 generator.emitLabel(afterElse.get());
2230 StatementNode* endingBlock = m_elseBlock ? m_elseBlock : m_ifBlock;
2231 generator.emitProfileControlFlow(endingBlock->endOffset() + (endingBlock->isBlock() ? 1 : 0));
2234 // ------------------------------ DoWhileNode ----------------------------------
2236 void DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2238 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2240 RefPtr<Label> topOfLoop = generator.newLabel();
2241 generator.emitLabel(topOfLoop.get());
2242 generator.emitLoopHint();
2243 generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2245 generator.emitNodeInTailPosition(dst, m_statement);
2247 generator.emitLabel(scope->continueTarget());
2248 generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2249 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2251 generator.emitLabel(scope->breakTarget());
2254 // ------------------------------ WhileNode ------------------------------------
2256 void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2258 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2259 RefPtr<Label> topOfLoop = generator.newLabel();
2261 generator.emitDebugHook(WillExecuteStatement, m_expr->firstLine(), m_expr->startOffset(), m_expr->lineStartOffset());
2262 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2264 generator.emitLabel(topOfLoop.get());
2265 generator.emitLoopHint();
2267 generator.emitProfileControlFlow(m_statement->startOffset());
2268 generator.emitNodeInTailPosition(dst, m_statement);
2270 generator.emitLabel(scope->continueTarget());
2271 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2273 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2275 generator.emitLabel(scope->breakTarget());
2277 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2280 // ------------------------------ ForNode --------------------------------------
2282 void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2284 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2286 RegisterID* forLoopSymbolTable = nullptr;
2287 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2289 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2292 generator.emitNode(generator.ignoredResult(), m_expr1);
2294 RefPtr<Label> topOfLoop = generator.newLabel();
2296 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2298 generator.emitLabel(topOfLoop.get());
2299 generator.emitLoopHint();
2300 generator.emitProfileControlFlow(m_statement->startOffset());
2302 generator.emitNodeInTailPosition(dst, m_statement);
2304 generator.emitLabel(scope->continueTarget());
2305 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2306 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2308 generator.emitNode(generator.ignoredResult(), m_expr3);
2311 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2313 generator.emitJump(topOfLoop.get());
2315 generator.emitLabel(scope->breakTarget());
2316 generator.popLexicalScope(this);
2317 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2320 // ------------------------------ ForInNode ------------------------------------
2322 RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator)
2324 if (m_lexpr->isResolveNode()) {
2325 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2326 return generator.variable(ident).local();
2329 if (m_lexpr->isDestructuringNode()) {
2330 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2331 auto binding = assignNode->bindings();
2332 if (!binding->isBindingNode())
2335 auto simpleBinding = static_cast<BindingNode*>(binding);
2336 const Identifier& ident = simpleBinding->boundProperty();
2337 Variable var = generator.variable(ident);
2338 if (var.isSpecial())
2346 void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
2348 if (m_lexpr->isResolveNode()) {
2349 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2350 Variable var = generator.variable(ident);
2351 if (RegisterID* local = var.local())
2352 generator.emitMove(local, propertyName);
2354 if (generator.isStrictMode())
2355 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2356 RegisterID* scope = generator.emitResolveScope(nullptr, var);
2357 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2358 generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, NotInitialization);
2360 generator.emitProfileType(propertyName, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2363 if (m_lexpr->isDotAccessorNode()) {
2364 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2365 const Identifier& ident = assignNode->identifier();
2366 RegisterID* base = generator.emitNode(assignNode->base());
2367 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2368 generator.emitPutById(base, ident, propertyName);
2369 generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
2372 if (m_lexpr->isBracketAccessorNode()) {
2373 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2374 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2375 RegisterID* subscript = generator.emitNode(assignNode->subscript());
2376 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2377 generator.emitPutByVal(base.get(), subscript, propertyName);
2378 generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
2382 if (m_lexpr->isDestructuringNode()) {
2383 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2384 auto binding = assignNode->bindings();
2385 if (!binding->isBindingNode()) {
2386 assignNode->bindings()->bindValue(generator, propertyName);
2390 auto simpleBinding = static_cast<BindingNode*>(binding);
2391 const Identifier& ident = simpleBinding->boundProperty();
2392 Variable var = generator.variable(ident);
2393 if (!var.local() || var.isSpecial()) {
2394 assignNode->bindings()->bindValue(generator, propertyName);
2397 generator.emitMove(var.local(), propertyName);
2398 generator.emitProfileType(propertyName, var, simpleBinding->divotStart(), simpleBinding->divotEnd());
2402 RELEASE_ASSERT_NOT_REACHED();
2405 void ForInNode::emitMultiLoopBytecode(BytecodeGenerator& generator, RegisterID* dst)
2407 if (!m_lexpr->isAssignmentLocation()) {
2408 emitThrowReferenceError(generator, ASCIILiteral("Left side of for-in statement is not a reference."));
2412 RefPtr<Label> end = generator.newLabel();
2414 RegisterID* forLoopSymbolTable = nullptr;
2415 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2417 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2419 RefPtr<RegisterID> base = generator.newTemporary();
2420 RefPtr<RegisterID> length;
2421 RefPtr<RegisterID> enumerator;
2422 generator.emitNode(base.get(), m_expr);
2423 RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
2424 RefPtr<RegisterID> enumeratorIndex;
2426 int profilerStartOffset = m_statement->startOffset();
2427 int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
2429 enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
2431 // Indexed property loop.
2433 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2434 RefPtr<Label> loopStart = generator.newLabel();
2435 RefPtr<Label> loopEnd = generator.newLabel();
2437 length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
2438 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2439 RefPtr<RegisterID> propertyName = generator.newTemporary();
2441 generator.emitLabel(loopStart.get());
2442 generator.emitLoopHint();
2444 RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get());
2445 generator.emitJumpIfFalse(result.get(), loopEnd.get());
2446 generator.emitHasIndexedProperty(result.get(), base.get(), i.get());
2447 generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2449 generator.emitToIndexString(propertyName.get(), i.get());
2450 this->emitLoopHeader(generator, propertyName.get());
2452 generator.emitProfileControlFlow(profilerStartOffset);
2454 generator.pushIndexedForInScope(local.get(), i.get());
2455 generator.emitNode(dst, m_statement);
2456 generator.popIndexedForInScope(local.get());
2458 generator.emitProfileControlFlow(profilerEndOffset);
2460 generator.emitLabel(scope->continueTarget());
2461 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2462 generator.emitInc(i.get());
2463 generator.emitJump(loopStart.get());
2465 generator.emitLabel(scope->breakTarget());
2466 generator.emitJump(end.get());
2467 generator.emitLabel(loopEnd.get());
2470 // Structure property loop.
2472 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2473 RefPtr<Label> loopStart = generator.newLabel();
2474 RefPtr<Label> loopEnd = generator.newLabel();
2476 enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2477 RefPtr<RegisterID> propertyName = generator.newTemporary();
2478 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2480 generator.emitLabel(loopStart.get());
2481 generator.emitLoopHint();
2483 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2484 generator.emitJumpIfTrue(result.get(), loopEnd.get());
2485 generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
2486 generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2488 this->emitLoopHeader(generator, propertyName.get());
2490 generator.emitProfileControlFlow(profilerStartOffset);
2492 generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
2493 generator.emitNode(dst, m_statement);
2494 generator.popStructureForInScope(local.get());
2496 generator.emitProfileControlFlow(profilerEndOffset);
2498 generator.emitLabel(scope->continueTarget());
2499 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2500 generator.emitInc(enumeratorIndex.get());
2501 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2502 generator.emitJump(loopStart.get());
2504 generator.emitLabel(scope->breakTarget());
2505 generator.emitJump(end.get());
2506 generator.emitLabel(loopEnd.get());
2509 // Generic property loop.
2511 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2512 RefPtr<Label> loopStart = generator.newLabel();
2513 RefPtr<Label> loopEnd = generator.newLabel();
2515 RefPtr<RegisterID> propertyName = generator.newTemporary();
2517 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2519 generator.emitLabel(loopStart.get());
2520 generator.emitLoopHint();
2522 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2523 generator.emitJumpIfTrue(result.get(), loopEnd.get());
2525 generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
2526 generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2528 this->emitLoopHeader(generator, propertyName.get());
2530 generator.emitProfileControlFlow(profilerStartOffset);
2532 generator.emitNode(dst, m_statement);
2534 generator.emitLabel(scope->continueTarget());
2535 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2536 generator.emitInc(enumeratorIndex.get());
2537 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2538 generator.emitJump(loopStart.get());
2540 generator.emitLabel(scope->breakTarget());
2541 generator.emitJump(end.get());
2542 generator.emitLabel(loopEnd.get());
2545 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2546 generator.emitLabel(end.get());
2547 generator.popLexicalScope(this);
2548 generator.emitProfileControlFlow(profilerEndOffset);
2551 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2553 this->emitMultiLoopBytecode(generator, dst);
2556 // ------------------------------ ForOfNode ------------------------------------
2557 void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2559 if (!m_lexpr->isAssignmentLocation()) {
2560 emitThrowReferenceError(generator, ASCIILiteral("Left side of for-of statement is not a reference."));
2564 RegisterID* forLoopSymbolTable = nullptr;
2565 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2566 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2567 auto extractor = [this, dst](BytecodeGenerator& generator, RegisterID* value)
2569 if (m_lexpr->isResolveNode()) {
2570 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2571 Variable var = generator.variable(ident);
2572 if (RegisterID* local = var.local())
2573 generator.emitMove(local, value);
2575 if (generator.isStrictMode())
2576 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2577 RegisterID* scope = generator.emitResolveScope(nullptr, var);
2578 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2579 generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, NotInitialization);
2581 generator.emitProfileType(value, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2582 } else if (m_lexpr->isDotAccessorNode()) {
2583 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2584 const Identifier& ident = assignNode->identifier();
2585 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2587 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2588 generator.emitPutById(base.get(), ident, value);
2589 generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
2590 } else if (m_lexpr->isBracketAccessorNode()) {
2591 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2592 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2593 RegisterID* subscript = generator.emitNode(assignNode->subscript());
2595 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2596 generator.emitPutByVal(base.get(), subscript, value);
2597 generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
2599 ASSERT(m_lexpr->isDestructuringNode());
2600 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2601 assignNode->bindings()->bindValue(generator, value);
2603 generator.emitProfileControlFlow(m_statement->startOffset());
2604 generator.emitNode(dst, m_statement);
2606 generator.emitEnumeration(this, m_expr, extractor, this, forLoopSymbolTable);
2607 generator.popLexicalScope(this);
2608 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2611 // ------------------------------ ContinueNode ---------------------------------
2613 Label* ContinueNode::trivialTarget(BytecodeGenerator& generator)
2615 if (generator.shouldEmitDebugHooks())
2618 LabelScopePtr scope = generator.continueTarget(m_ident);
2621 if (generator.labelScopeDepth() != scope->scopeDepth())
2624 return scope->continueTarget();
2627 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2629 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2631 LabelScopePtr scope = generator.continueTarget(m_ident);
2634 generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2635 generator.emitJump(scope->continueTarget());
2637 generator.emitProfileControlFlow(endOffset());
2640 // ------------------------------ BreakNode ------------------------------------
2642 Label* BreakNode::trivialTarget(BytecodeGenerator& generator)
2644 if (generator.shouldEmitDebugHooks())
2647 LabelScopePtr scope = generator.breakTarget(m_ident);
2650 if (generator.labelScopeDepth() != scope->scopeDepth())
2653 return scope->breakTarget();
2656 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2658 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2660 LabelScopePtr scope = generator.breakTarget(m_ident);
2663 generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2664 generator.emitJump(scope->breakTarget());
2666 generator.emitProfileControlFlow(endOffset());
2669 // ------------------------------ ReturnNode -----------------------------------
2671 void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2673 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2674 ASSERT(generator.codeType() == FunctionCode);
2676 if (dst == generator.ignoredResult())
2679 RefPtr<RegisterID> returnRegister = m_value ? generator.emitNodeInTailPosition(dst, m_value) : generator.emitLoad(dst, jsUndefined());
2681 generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, divotStart(), divotEnd());
2682 if (generator.isInFinallyBlock()) {
2683 returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
2684 generator.emitPopScopes(generator.scopeRegister(), 0);
2687 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
2688 generator.emitReturn(returnRegister.get());
2689 generator.emitProfileControlFlow(endOffset());
2690 // Emitting an unreachable return here is needed in case this op_profile_control_flow is the
2691 // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode.
2692 if (generator.vm()->controlFlowProfiler())
2693 generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
2696 // ------------------------------ WithNode -------------------------------------
2698 void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2700 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2702 RefPtr<RegisterID> scope = generator.emitNode(m_expr);
2703 generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
2704 generator.emitPushWithScope(scope.get());
2705 generator.emitNodeInTailPosition(dst, m_statement);
2706 generator.emitPopWithScope();
2709 // ------------------------------ CaseClauseNode --------------------------------
2711 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2713 generator.emitProfileControlFlow(m_startOffset);
2716 m_statements->emitBytecode(generator, dst);
2719 // ------------------------------ CaseBlockNode --------------------------------
2728 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2730 for (; list; list = list->getNext()) {
2731 ExpressionNode* clauseExpression = list->getClause()->expr();
2732 literalVector.append(clauseExpression);
2733 if (clauseExpression->isNumber()) {
2734 double value = static_cast<NumberNode*>(clauseExpression)->value();
2735 int32_t intVal = static_cast<int32_t>(value);
2736 if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
2737 typeForTable = SwitchNeither;
2740 if (intVal < min_num)
2742 if (intVal > max_num)
2744 typeForTable = SwitchNumber;
2747 if (clauseExpression->isString()) {
2748 if (typeForTable & ~SwitchString) {
2749 typeForTable = SwitchNeither;
2752 const String& value = static_cast<StringNode*>(clauseExpression)->value().string();
2753 if (singleCharacterSwitch &= value.length() == 1) {
2754 int32_t intVal = value[0];
2755 if (intVal < min_num)
2757 if (intVal > max_num)
2760 typeForTable = SwitchString;
2763 typeForTable = SwitchNeither;
2768 static inline size_t length(ClauseListNode* list1, ClauseListNode* list2)
2771 for (ClauseListNode* node = list1; node; node = node->getNext())
2773 for (ClauseListNode* node = list2; node; node = node->getNext())
2778 SwitchInfo::SwitchType CaseBlockNode::tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2780 if (length(m_list1, m_list2) < s_tableSwitchMinimum)
2781 return SwitchInfo::SwitchNone;
2783 SwitchKind typeForTable = SwitchUnset;
2784 bool singleCharacterSwitch = true;
2786 processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2787 processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2789 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2790 return SwitchInfo::SwitchNone;
2792 if (typeForTable == SwitchNumber) {
2793 int32_t range = max_num - min_num;
2794 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2795 return SwitchInfo::SwitchImmediate;
2796 return SwitchInfo::SwitchNone;
2799 ASSERT(typeForTable == SwitchString);
2801 if (singleCharacterSwitch) {
2802 int32_t range = max_num - min_num;
2803 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2804 return SwitchInfo::SwitchCharacter;
2807 return SwitchInfo::SwitchString;
2810 void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2812 RefPtr<Label> defaultLabel;
2813 Vector<RefPtr<Label>, 8> labelVector;
2814 Vector<ExpressionNode*, 8> literalVector;
2815 int32_t min_num = std::numeric_limits<int32_t>::max();
2816 int32_t max_num = std::numeric_limits<int32_t>::min();
2817 SwitchInfo::SwitchType switchType = tryTableSwitch(literalVector, min_num, max_num);
2819 if (switchType != SwitchInfo::SwitchNone) {
2820 // Prepare the various labels
2821 for (uint32_t i = 0; i < literalVector.size(); i++)
2822 labelVector.append(generator.newLabel());
2823 defaultLabel = generator.newLabel();
2824 generator.beginSwitch(switchExpression, switchType);
2827 for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
2828 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2829 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2830 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2831 labelVector.append(generator.newLabel());
2832 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2835 for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
2836 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2837 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2838 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2839 labelVector.append(generator.newLabel());
2840 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2842 defaultLabel = generator.newLabel();
2843 generator.emitJump(defaultLabel.get());
2847 for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
2848 generator.emitLabel(labelVector[i++].get());
2849 list->getClause()->emitBytecode(generator, dst);
2852 if (m_defaultClause) {
2853 generator.emitLabel(defaultLabel.get());
2854 m_defaultClause->emitBytecode(generator, dst);
2857 for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
2858 generator.emitLabel(labelVector[i++].get());
2859 list->getClause()->emitBytecode(generator, dst);
2861 if (!m_defaultClause)
2862 generator.emitLabel(defaultLabel.get());
2864 ASSERT(i == labelVector.size());
2865 if (switchType != SwitchInfo::SwitchNone) {
2866 ASSERT(labelVector.size() == literalVector.size());
2867 generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2871 // ------------------------------ SwitchNode -----------------------------------
2873 void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2875 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2877 LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
2879 RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
2881 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::DoNotOptimize, BytecodeGenerator::NestedScopeType::IsNested);
2882 m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2883 generator.popLexicalScope(this);
2885 generator.emitLabel(scope->breakTarget());
2886 generator.emitProfileControlFlow(endOffset());
2889 // ------------------------------ LabelNode ------------------------------------
2891 void LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2893 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2895 ASSERT(!generator.breakTarget(m_name));
2897 LabelScopePtr scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2898 generator.emitNodeInTailPosition(dst, m_statement);
2900 generator.emitLabel(scope->breakTarget());
2903 // ------------------------------ ThrowNode ------------------------------------
2905 void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2907 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2909 if (dst == generator.ignoredResult())
2911 RefPtr<RegisterID> expr = generator.emitNode(m_expr);
2912 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2913 generator.emitThrow(expr.get());
2915 generator.emitProfileControlFlow(endOffset());
2918 // ------------------------------ TryNode --------------------------------------
2920 void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2922 // NOTE: The catch and finally blocks must be labeled explicitly, so the
2923 // optimizer knows they may be jumped to from anywhere.
2925 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2927 ASSERT(m_catchBlock || m_finallyBlock);
2929 RefPtr<Label> tryStartLabel = generator.newLabel();
2930 generator.emitLabel(tryStartLabel.get());
2933 generator.pushFinallyContext(m_finallyBlock);
2934 TryData* tryData = generator.pushTry(tryStartLabel.get());
2936 generator.emitNode(dst, m_tryBlock);
2939 RefPtr<Label> catchEndLabel = generator.newLabel();
2941 // Normal path: jump over the catch block.
2942 generator.emitJump(catchEndLabel.get());
2944 // Uncaught exception path: the catch block.
2945 RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
2946 RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
2947 RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
2948 generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), here.get(), HandlerType::Catch);
2950 if (m_finallyBlock) {
2951 // If the catch block throws an exception and we have a finally block, then the finally
2952 // block should "catch" that exception.
2953 tryData = generator.pushTry(here.get());
2956 generator.emitPushCatchScope(m_lexicalVariables);
2957 m_catchPattern->bindValue(generator, thrownValueRegister.get());
2958 generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
2960 generator.emitNode(dst, m_catchBlock);
2962 generator.emitNodeInTailPosition(dst, m_catchBlock);
2963 generator.emitPopCatchScope(m_lexicalVariables);
2964 generator.emitLabel(catchEndLabel.get());
2967 if (m_finallyBlock) {
2968 RefPtr<Label> preFinallyLabel = generator.emitLabel(generator.newLabel().get());
2970 generator.popFinallyContext();
2972 RefPtr<Label> finallyEndLabel = generator.newLabel();
2974 int finallyStartOffset = m_catchBlock ? m_catchBlock->endOffset() + 1 : m_tryBlock->endOffset() + 1;
2976 // Normal path: run the finally code, and jump to the end.
2977 generator.emitProfileControlFlow(finallyStartOffset);
2978 generator.emitNodeInTailPosition(dst, m_finallyBlock);
2979 generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
2980 generator.emitJump(finallyEndLabel.get());
2982 // Uncaught exception path: invoke the finally block, then re-throw the exception.
2983 RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
2984 RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
2985 generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), preFinallyLabel.get(), HandlerType::Finally);
2986 generator.emitProfileControlFlow(finallyStartOffset);
2987 generator.emitNodeInTailPosition(dst, m_finallyBlock);
2988 generator.emitThrow(exceptionRegister.get());
2990 generator.emitLabel(finallyEndLabel.get());
2991 generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
2993 generator.emitProfileControlFlow(m_catchBlock->endOffset() + 1);
2997 // ------------------------------ ScopeNode -----------------------------
2999 inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
3003 m_statements->emitBytecode(generator, dst);
3006 static void emitProgramNodeBytecode(BytecodeGenerator& generator, ScopeNode& scopeNode)
3008 generator.emitDebugHook(WillExecuteProgram, scopeNode.startLine(), scopeNode.startStartOffset(), scopeNode.startLineStartOffset());
3010 RefPtr<RegisterID> dstRegister = generator.newTemporary();
3011 generator.emitLoad(dstRegister.get(), jsUndefined());
3012 generator.emitProfileControlFlow(scopeNode.startStartOffset());
3013 scopeNode.emitStatementsBytecode(generator, dstRegister.get());
3015 generator.emitDebugHook(DidExecuteProgram, scopeNode.lastLine(), scopeNode.startOffset(), scopeNode.lineStartOffset());
3016 generator.emitEnd(dstRegister.get());
3019 // ------------------------------ ProgramNode -----------------------------
3021 void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3023 emitProgramNodeBytecode(generator, *this);
3026 // ------------------------------ ModuleProgramNode --------------------
3028 void ModuleProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3030 emitProgramNodeBytecode(generator, *this);
3033 // ------------------------------ EvalNode -----------------------------
3035 void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3037 generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
3039 RefPtr<RegisterID> dstRegister = generator.newTemporary();
3040 generator.emitLoad(dstRegister.get(), jsUndefined());
3041 emitStatementsBytecode(generator, dstRegister.get());
3043 generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset());
3044 generator.emitEnd(dstRegister.get());
3047 // ------------------------------ FunctionNode -----------------------------
3049 void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3051 if (generator.vm()->typeProfiler()) {
3052 for (size_t i = 0; i < m_parameters->size(); i++) {
3053 // Destructuring parameters are handled in destructuring nodes.
3054 if (!m_parameters->at(i).first->isBindingNode())
3056 BindingNode* parameter = static_cast<BindingNode*>(m_parameters->at(i).first);
3057 RegisterID reg(CallFrame::argumentOffset(i));
3058 generator.emitProfileType(®, ProfileTypeBytecodeFunctionArgument, parameter->divotStart(), parameter->divotEnd());
3062 generator.emitProfileControlFlow(startStartOffset());
3063 generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset());
3065 switch (generator.parseMode()) {
3066 case SourceParseMode::GeneratorWrapperFunctionMode: {
3067 StatementNode* singleStatement = this->singleStatement();
3068 ASSERT(singleStatement->isExprStatement());
3069 ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement);
3070 ExpressionNode* expr = exprStatement->expr();
3071 ASSERT(expr->isFuncExprNode());
3072 FuncExprNode* funcExpr = static_cast<FuncExprNode*>(expr);
3074 RefPtr<RegisterID> next = generator.newTemporary();
3075 generator.emitNode(next.get(), funcExpr);
3077 if (generator.superBinding() == SuperBinding::Needed) {
3078 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
3079 emitPutHomeObject(generator, next.get(), homeObject.get());
3082 // FIXME: Currently, we just create an object and store generator related fields as its properties for ease.
3083 // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties.
3084 // https://bugs.webkit.org/show_bug.cgi?id=151545
3086 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorNextPrivateName, next.get(), PropertyNode::KnownDirect);
3088 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorThisPrivateName, generator.thisRegister(), PropertyNode::KnownDirect);
3090 RegisterID* initialState = generator.emitLoad(nullptr, jsNumber(0));
3091 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorStatePrivateName, initialState, PropertyNode::KnownDirect);
3093 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorFramePrivateName, generator.emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
3095 ASSERT(startOffset() >= lineStartOffset());
3096 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
3097 generator.emitReturn(generator.generatorRegister());
3101 case SourceParseMode::GeneratorBodyMode: {
3102 RefPtr<Label> generatorBodyLabel = generator.newLabel();
3104 RefPtr<RegisterID> condition = generator.newTemporary();
3105 generator.emitEqualityOp(op_stricteq, condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode))));
3106 generator.emitJumpIfTrue(condition.get(), generatorBodyLabel.get());
3108 RefPtr<Label> throwLabel = generator.newLabel();
3109 generator.emitEqualityOp(op_stricteq, condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ThrowMode))));
3110 generator.emitJumpIfTrue(condition.get(), throwLabel.get());
3112 generator.emitReturn(generator.generatorValueRegister());
3114 generator.emitLabel(throwLabel.get());
3115 generator.emitThrow(generator.generatorValueRegister());
3118 generator.emitLabel(generatorBodyLabel.get());
3120 emitStatementsBytecode(generator, generator.ignoredResult());
3122 RefPtr<Label> done = generator.newLabel();
3123 generator.emitLabel(done.get());
3124 generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
3125 generator.endGenerator(done.get());
3130 emitStatementsBytecode(generator, generator.ignoredResult());
3132 StatementNode* singleStatement = this->singleStatement();
3133 ReturnNode* returnNode = 0;
3135 // Check for a return statement at the end of a function composed of a single block.
3136 if (singleStatement && singleStatement->isBlock()) {
3137 StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
3138 if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
3139 returnNode = static_cast<ReturnNode*>(lastStatementInBlock);
3142 // If there is no return we must automatically insert one.
3144 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isSuperCallUsedInInnerArrowFunction())
3145 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); // Arrow function can invoke 'super' in constructor and before leave constructor we need load 'this' from lexical arrow function environment
3147 RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
3148 generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code.
3149 ASSERT(startOffset() >= lineStartOffset());
3150 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
3151 generator.emitReturn(r0);
3159 // ------------------------------ FuncDeclNode ---------------------------------
3161 void FuncDeclNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3165 // ------------------------------ FuncExprNode ---------------------------------
3167 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3169 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
3172 // ------------------------------ ArrowFuncExprNode ---------------------------------
3174 RegisterID* ArrowFuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3176 return generator.emitNewArrowFunctionExpression(generator.finalDestination(dst), this);
3179 // ------------------------------ MethodDefinitionNode ---------------------------------
3181 RegisterID* MethodDefinitionNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3183 return generator.emitNewMethodDefinition(generator.finalDestination(dst), this);
3186 // ------------------------------ YieldExprNode --------------------------------
3188 RegisterID* YieldExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3191 RefPtr<RegisterID> arg = nullptr;
3193 arg = generator.newTemporary();
3194 generator.emitNode(arg.get(), argument());
3196 arg = generator.emitLoad(nullptr, jsUndefined());
3197 RefPtr<RegisterID> value = generator.emitYield(arg.get());
3198 if (dst == generator.ignoredResult())
3200 return generator.emitMove(generator.finalDestination(dst), value.get());
3202 RefPtr<RegisterID> arg = generator.newTemporary();
3203 generator.emitNode(arg.get(), argument());
3204 RefPtr<RegisterID> value = generator.emitDelegateYield(arg.get(), this);
3205 if (dst == generator.ignoredResult())
3207 return generator.emitMove(generator.finalDestination(dst), value.get());
3210 // ------------------------------ ClassDeclNode ---------------------------------
3212 void ClassDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3214 generator.emitNode(dst, m_classDeclaration);
3217 // ------------------------------ ClassExprNode ---------------------------------
3219 RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3221 if (!m_name.isNull())
3222 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
3224 RefPtr<RegisterID> superclass;
3225 if (m_classHeritage) {
3226 superclass = generator.newTemporary();
3227 generator.emitNode(superclass.get(), m_classHeritage);
3230 RefPtr<RegisterID> constructor;
3232 // FIXME: Make the prototype non-configurable & non-writable.
3233 if (m_constructorExpression) {
3234 ASSERT(m_constructorExpression->isFuncExprNode());
3235 FunctionMetadataNode* metadata = static_cast<FuncExprNode*>(m_constructorExpression)->metadata();
3236 metadata->setEcmaName(ecmaName());
3237 metadata->setClassSource(m_classSource);
3238 constructor = generator.emitNode(dst, m_constructorExpression);
3240 constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst),
3241 m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base,
3242 m_name, ecmaName(), m_classSource);
3245 const auto& propertyNames = generator.propertyNames();
3246 RefPtr<RegisterID> prototype = generator.emitNewObject(generator.newTemporary());
3249 RefPtr<RegisterID> protoParent = generator.newTemporary();
3250 generator.emitLoad(protoParent.get(), jsNull());
3252 RefPtr<RegisterID> tempRegister = generator.newTemporary();
3254 // FIXME: Throw TypeError if it's a generator function.
3255 RefPtr<Label> superclassIsUndefinedLabel = generator.newLabel();
3256 generator.emitJumpIfTrue(generator.emitIsUndefined(tempRegister.get(), superclass.get()), superclassIsUndefinedLabel.get());
3258 RefPtr<Label> superclassIsNullLabel = generator.newLabel();
3259 generator.emitJumpIfTrue(generator.emitUnaryOp(op_eq_null, tempRegister.get(), superclass.get()), superclassIsNullLabel.get());
3261 RefPtr<Label> superclassIsObjectLabel = generator.newLabel();
3262 generator.emitJumpIfTrue(generator.emitIsObject(tempRegister.get(), superclass.get()), superclassIsObjectLabel.get());
3263 generator.emitLabel(superclassIsUndefinedLabel.get());
3264 generator.emitThrowTypeError(ASCIILiteral("The superclass is not an object."));
3265 generator.emitLabel(superclassIsObjectLabel.get());
3266 generator.emitGetById(protoParent.get(), superclass.get(), generator.propertyNames().prototype);
3268 RefPtr<Label> protoParentIsObjectOrNullLabel = generator.newLabel();
3269 generator.emitJumpIfTrue(generator.emitUnaryOp(op_is_object_or_null, tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
3270 generator.emitJumpIfTrue(generator.emitUnaryOp(op_is_function, tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
3271 generator.emitThrowTypeError(ASCIILiteral("The value of the superclass's prototype property is not an object."));
3272 generator.emitLabel(protoParentIsObjectOrNullLabel.get());
3274 generator.emitDirectPutById(constructor.get(), generator.propertyNames().underscoreProto, superclass.get(), PropertyNode::Unknown);
3275 generator.emitLabel(superclassIsNullLabel.get());
3276 generator.emitDirectPutById(prototype.get(), generator.propertyNames().underscoreProto, protoParent.get(), PropertyNode::Unknown);
3278 emitPutHomeObject(generator, constructor.get(), prototype.get());
3281 RefPtr<RegisterID> constructorNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.constructor);
3282 generator.emitCallDefineProperty(prototype.get(), constructorNameRegister.get(), constructor.get(), nullptr, nullptr,
3283 BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
3285 RefPtr<RegisterID> prototypeNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.prototype);
3286 generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0, m_position);
3288 if (m_staticMethods)
3289 generator.emitNode(constructor.get(), m_staticMethods);
3291 if (m_instanceMethods)
3292 generator.emitNode(prototype.get(), m_instanceMethods);
3294 if (!m_name.isNull()) {
3295 Variable classNameVar = generator.variable(m_name);
3296 RELEASE_ASSERT(classNameVar.isResolved());
3297 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, classNameVar);
3298 generator.emitPutToScope(scope.get(), classNameVar, constructor.get(), ThrowIfNotFound, Initialization);
3299 generator.popLexicalScope(this);
3302 return generator.moveToDestinationIfNeeded(dst, constructor.get());
3305 // ------------------------------ ImportDeclarationNode -----------------------
3307 void ImportDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3309 // Do nothing at runtime.
3312 // ------------------------------ ExportAllDeclarationNode --------------------
3314 void ExportAllDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3316 // Do nothing at runtime.
3319 // ------------------------------ ExportDefaultDeclarationNode ----------------
3321 void ExportDefaultDeclarationNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3323 ASSERT(m_declaration);
3324 generator.emitNode(dst, m_declaration);
3327 // ------------------------------ ExportLocalDeclarationNode ------------------
3329 void ExportLocalDeclarationNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3331 ASSERT(m_declaration);
3332 generator.emitNode(dst, m_declaration);
3335 // ------------------------------ ExportNamedDeclarationNode ------------------
3337 void ExportNamedDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3339 // Do nothing at runtime.
3342 // ------------------------------ DestructuringAssignmentNode -----------------
3343 RegisterID* DestructuringAssignmentNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3345 if (RegisterID* result = m_bindings->emitDirectBinding(generator, dst, m_initializer))
3347 RefPtr<RegisterID> initializer = generator.tempDestination(dst);
3348 generator.emitNode(initializer.get(), m_initializer);
3349 m_bindings->bindValue(generator, initializer.get());
3350 return generator.moveToDestinationIfNeeded(dst, initializer.get());
3353 static void assignDefaultValueIfUndefined(BytecodeGenerator& generator, RegisterID* maybeUndefined, ExpressionNode* defaultValue)
3355 ASSERT(defaultValue);
3356 RefPtr<Label> isNotUndefined = generator.newLabel();
3357 generator.emitJumpIfFalse(generator.emitIsUndefined(generator.newTemporary(), maybeUndefined), isNotUndefined.get());
3358 generator.emitNode(maybeUndefined, defaultValue);
3359 generator.emitLabel(isNotUndefined.get());
3362 void ArrayPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
3364 RefPtr<RegisterID> iterator = generator.newTemporary();
3366 generator.emitGetById(iterator.get(), rhs, generator.propertyNames().iteratorSymbol);
3367 CallArguments args(generator, nullptr);
3368 generator.emitMove(args.thisRegister(), rhs);
3369 generator.emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd());
3372 if (m_targetPatterns.isEmpty()) {
3373 generator.emitIteratorClose(iterator.get(), this);
3377 RefPtr<RegisterID> done;
3378 for (auto& target : m_targetPatterns) {
3379 switch (target.bindingType) {
3380 case BindingType::Elision:
3381 case BindingType::Element: {
3382 RefPtr<Label> iterationSkipped = generator.newLabel();
3384 done = generator.newTemporary();
3386 generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
3388 RefPtr<RegisterID> value = generator.newTemporary();
3389 generator.emitIteratorNext(value.get(), iterator.get(), this);
3390 generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
3391 generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
3392 generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
3395 RefPtr<Label> valueIsSet = generator.newLabel();
3396 generator.emitJump(valueIsSet.get());
3397 generator.emitLabel(iterationSkipped.get());
3398 generator.emitLoad(value.get(), jsUndefined());
3399 generator.emitLabel(valueIsSet.get());
3402 if (target.bindingType == BindingType::Element) {
3403 if (target.defaultValue)
3404 assignDefaultValueIfUndefined(generator, value.get(), target.defaultValue);
3405 target.pattern->bindValue(generator, value.get());
3410 case BindingType::RestElement: {
3411 RefPtr<RegisterID> array = generator.emitNewArray(generator.newTemporary(), 0, 0);
3413 RefPtr<Label> iterationDone = generator.newLabel();
3415 done = generator.newTemporary();
3417 generator.emitJumpIfTrue(done.get(), iterationDone.get());
3419 RefPtr<RegisterID> index = generator.newTemporary();
3420 generator.emitLoad(index.get(), jsNumber(0));
3421 RefPtr<Label> loopStart = generator.newLabel();
3422 generator.emitLabel(loopStart.get());
3424 RefPtr<RegisterID> value = generator.newTemporary();
3425 generator.emitIteratorNext(value.get(), iterator.get(), this);
3426 generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
3427 generator.emitJumpIfTrue(done.get(), iterationDone.get());
3428 generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
3430 generator.emitDirectPutByVal(array.get(), index.get(), value.get());
3431 generator.emitInc(index.get());
3432 generator.emitJump(loopStart.get());
3434 generator.emitLabel(iterationDone.get());
3435 target.pattern->bindValue(generator, array.get());
3441 RefPtr<Label> iteratorClosed = generator.newLabel();
3442 generator.emitJumpIfTrue(done.get(), iteratorClosed.get());
3443 generator.emitIteratorClose(iterator.get(), this);
3444 generator.emitLabel(iteratorClosed.get());
3447 RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
3449 if (!rhs->isSimpleArray())
3452 ElementNode* elementNodes = static_cast<ArrayNode*>(rhs)->elements();
3453 Vector<ExpressionNode*> elements;
3454 for (; elementNodes; elementNodes = elementNodes->next()) {
3455 ExpressionNode* value = elementNodes->value();
3456 if (value->isSpreadExpression())
3458 elements.append(value);
3461 RefPtr<RegisterID> resultRegister;
3462 if (dst && dst != generator.ignoredResult())
3463 resultRegister = generator.emitNewArray(generator.newTemporary(), 0, 0);
3464 if (m_targetPatterns.size() != elements.size())
3466 Vector<RefPtr<RegisterID>> registers;
3467 registers.reserveCapacity(m_targetPatterns.size());
3468 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3469 registers.uncheckedAppend(generator.newTemporary());
3470 generator.emitNode(registers.last().get(), elements[i]);
3471 if (m_targetPatterns[i].defaultValue)
3472 assignDefaultValueIfUndefined(generator, registers.last().get(), m_targetPatterns[i].defaultValue);
3474 generator.emitPutByIndex(resultRegister.get(), i, registers.last().get());
3477 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3478 if (m_targetPatterns[i].pattern)
3479 m_targetPatterns[i].pattern->bindValue(generator, registers[i].get());
3482 return generator.moveToDestinationIfNeeded(dst, resultRegister.get());
3483 return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
3486 void ArrayPatternNode::toString(StringBuilder& builder) const
3488 builder.append('[');
3489 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3490 const auto& target = m_targetPatterns[i];
3492 switch (target.bindingType) {
3493 case BindingType::Elision:
3494 builder.append(',');
3497 case BindingType::Element:
3498 target.pattern->toString(builder);
3499 if (i < m_targetPatterns.size() - 1)
3500 builder.append(',');
3503 case BindingType::RestElement:
3504 builder.append("...");
3505 target.pattern->toString(builder);
3509 builder.append(']');
3512 void ArrayPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3514 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3515 if (DestructuringPatternNode* node = m_targetPatterns[i].pattern)
3516 node->collectBoundIdentifiers(identifiers);
3520 void ObjectPatternNode::toString(StringBuilder& builder) const
3522 builder.append('{');
3523 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3524 if (m_targetPatterns[i].wasString)
3525 builder.appendQuotedJSONString(m_targetPatterns[i].propertyName.string());
3527 builder.append(m_targetPatterns[i].propertyName.string());
3528 builder.append(':');
3529 m_targetPatterns[i].pattern->toString(builder);
3530 if (i < m_targetPatterns.size() - 1)
3531 builder.append(',');
3533 builder.append('}');
3536 void ObjectPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
3538 generator.emitRequireObjectCoercible(rhs, ASCIILiteral("Right side of assignment cannot be destructured"));
3539 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3540 auto& target = m_targetPatterns[i];
3541 RefPtr<RegisterID> temp = generator.newTemporary();
3542 if (!target.propertyExpression) {
3543 // Should not emit get_by_id for indexed ones.
3544 Optional<uint32_t> optionalIndex = parseIndex(target.propertyName);
3546 generator.emitGetById(temp.get(), rhs, target.propertyName);
3548 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value()));
3549 generator.emitGetByVal(temp.get(), rhs, index.get());
3552 RefPtr<RegisterID> propertyName = generator.emitNode(target.propertyExpression);
3553 generator.emitGetByVal(temp.get(), rhs, propertyName.get());
3556 if (target.defaultValue)
3557 assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
3558 target.pattern->bindValue(generator, temp.get());
3562 void ObjectPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3564 for (size_t i = 0; i < m_targetPatterns.size(); i++)
3565 m_targetPatterns[i].pattern->collectBoundIdentifiers(identifiers);
3568 void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
3570 Variable var = generator.variable(m_boundProperty);
3571 bool isReadOnly = var.isReadOnly() && m_bindingContext != AssignmentContext::ConstDeclarationStatement;
3572 if (RegisterID* local = var.local()) {
3573 if (m_bindingContext == AssignmentContext::AssignmentExpression)
3574 generator.emitTDZCheckIfNecessary(var, local, nullptr);
3576 generator.emitReadOnlyExceptionIfNeeded(var);
3579 generator.emitMove(local, value);
3580 generator.emitProfileType(local, var, divotStart(), divotEnd());
3581 if (m_bindingContext == AssignmentContext::DeclarationStatement || m_bindingContext == AssignmentContext::ConstDeclarationStatement)
3582 generator.liftTDZCheckIfPossible(var);
3585 if (generator.isStrictMode())
3586 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3587 RegisterID* scope = generator.emitResolveScope(nullptr, var);
3588 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3589 if (m_bindingContext == AssignmentContext::AssignmentExpression)
3590 generator.emitTDZCheckIfNecessary(var, nullptr, scope);
3592 generator.emitReadOnlyExceptionIfNeeded(var);
3595 generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound,
3596 m_bindingContext == AssignmentContext::ConstDeclarationStatement || m_bindingContext == AssignmentContext::DeclarationStatement ? Initialization : NotInitialization);
3597 generator.emitProfileType(value, var, divotStart(), divotEnd());
3598 if (m_bindingContext == AssignmentContext::DeclarationStatement || m_bindingContext == AssignmentContext::ConstDeclarationStatement)
3599 generator.liftTDZCheckIfPossible(var);
3603 void BindingNode::toString(StringBuilder& builder) const
3605 builder.append(m_boundProperty.string());
3608 void BindingNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3610 identifiers.append(m_boundProperty);
3613 void AssignmentElementNode::collectBoundIdentifiers(Vector<Identifier>&) const
3617 void AssignmentElementNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
3619 if (m_assignmentTarget->isResolveNode()) {
3620 ResolveNode* lhs = static_cast<ResolveNode*>(m_assignmentTarget);
3621 Variable var = generator.variable(lhs->identifier());
3622 bool isReadOnly = var.isReadOnly();
3623 if (RegisterID* local = var.local()) {
3624 generator.emitTDZCheckIfNecessary(var, local, nullptr);
3627 generator.emitReadOnlyExceptionIfNeeded(var);
3629 generator.invalidateForInContextForLocal(local);
3630 generator.moveToDestinationIfNeeded(local, value);
3631 generator.emitProfileType(local, divotStart(), divotEnd());
3635 if (generator.isStrictMode())
3636 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3637 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
3638 generator.emitTDZCheckIfNecessary(var, nullptr, scope.get());
3640 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
3644 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3646 generator.emitPutToScope(scope.get(), var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, NotInitialization);
3647 generator.emitProfileType(value, var, divotStart(), divotEnd());
3649 } else if (m_assignmentTarget->isDotAccessorNode()) {
3650 DotAccessorNode* lhs = static_cast<DotAccessorNode*>(m_assignmentTarget);
3651 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(lhs->base(), true, false);
3652 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3653 generator.emitPutById(base.get(), lhs->identifier(), value);
3654 generator.emitProfileType(value, divotStart(), divotEnd());
3655 } else if (m_assignmentTarget->isBracketAccessorNode()) {
3656 BracketAccessorNode* lhs = static_cast<BracketAccessorNode*>(m_assignmentTarget);
3657 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(lhs->base(), true, false);
3658 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(lhs->subscript(), true, false);
3659 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3660 generator.emitPutByVal(base.get(), property.get(), value);
3661 generator.emitProfileType(value, divotStart(), divotEnd());
3665 void AssignmentElementNode::toString(StringBuilder& builder) const
3667 if (m_assignmentTarget->isResolveNode())
3668 builder.append(static_cast<ResolveNode*>(m_assignmentTarget)->identifier().string());
3671 void RestParameterNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3673 identifiers.append(m_name);
3675 void RestParameterNode::toString(StringBuilder& builder) const
3677 builder.append(m_name.string());
3679 void RestParameterNode::bindValue(BytecodeGenerator&, RegisterID*) const
3681 RELEASE_ASSERT_NOT_REACHED();
3683 void RestParameterNode::emit(BytecodeGenerator& generator)
3685 Variable var = generator.variable(m_name);
3686 if (RegisterID* local = var.local()) {
3687 generator.emitRestParameter(local, m_numParametersToSkip);
3688 generator.emitProfileType(local, var, m_divotStart, m_divotEnd);
3692 RefPtr<RegisterID> restParameterArray = generator.newTemporary();
3693 generator.emitRestParameter(restParameterArray.get(), m_numParametersToSkip);
3694 generator.emitProfileType(restParameterArray.get(), var, m_divotStart, m_divotEnd);
3695 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
3696 generator.emitExpressionInfo(m_divotEnd, m_divotStart, m_divotEnd);
3697 generator.emitPutToScope(scope.get(), var, restParameterArray.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, Initialization);
3701 RegisterID* SpreadExpressionNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3703 RELEASE_ASSERT_NOT_REACHED();