blob: 45cfae907ee6d3c6b7dbec4e19756f61180cae7f [file] [log] [blame]
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001/*
2* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3* Copyright (C) 2001 Peter Kelly (pmk@post.com)
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004* Copyright (C) 2003-2019 Apple Inc. All rights reserved.
mjs@apple.comaed3cef2009-12-09 01:29:52 +00005* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6* Copyright (C) 2007 Maks Orlovich
7* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
commit-queue@webkit.org2fea7402012-02-01 19:37:00 +00008 * Copyright (C) 2012 Igalia, S.L.
mjs@apple.comaed3cef2009-12-09 01:29:52 +00009*
10* This library is free software; you can redistribute it and/or
11* modify it under the terms of the GNU Library General Public
12* License as published by the Free Software Foundation; either
13* version 2 of the License, or (at your option) any later version.
14*
15* This library is distributed in the hope that it will be useful,
16* but WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18* Library General Public License for more details.
19*
20* You should have received a copy of the GNU Library General Public License
21* along with this library; see the file COPYING.LIB. If not, write to
22* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23* Boston, MA 02110-1301, USA.
24*
25*/
26
27#include "config.h"
28#include "Nodes.h"
oliver@apple.comd04e0a02014-02-01 01:37:59 +000029#include "NodeConstructors.h"
mjs@apple.comaed3cef2009-12-09 01:29:52 +000030
oliver@apple.comc422ba02014-02-27 23:25:29 +000031#include "BuiltinNames.h"
mjs@apple.comaed3cef2009-12-09 01:29:52 +000032#include "BytecodeGenerator.h"
aperez@igalia.comf4d8dc32019-12-15 18:20:02 +000033#include "BytecodeGeneratorBaseInlines.h"
mjs@apple.comaed3cef2009-12-09 01:29:52 +000034#include "CallFrame.h"
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +000035#include "JSArrayIterator.h"
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +000036#include "JSAsyncGenerator.h"
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +000037#include "JSGenerator.h"
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +000038#include "JSImmutableButterfly.h"
ysuzuki@apple.come8a2d402020-04-16 13:07:48 +000039#include "JSMapIterator.h"
40#include "JSSetIterator.h"
ysuzuki@apple.comf0017752020-01-13 03:12:13 +000041#include "JSStringIterator.h"
mjs@apple.comaed3cef2009-12-09 01:29:52 +000042#include "LabelScope.h"
ross.kirsling@sony.com0ebe33c2020-05-15 19:39:36 +000043#include "LinkTimeConstant.h"
44#include "ModuleScopeData.h"
fpizlo@apple.come94ae4a2013-11-22 20:18:18 +000045#include "StackAlignment.h"
ross.kirsling@sony.com3d654ba2019-03-11 06:20:53 +000046#include "YarrFlags.h"
mjs@apple.comaed3cef2009-12-09 01:29:52 +000047#include <wtf/Assertions.h>
joepeck@webkit.org7e07f392016-09-22 18:59:47 +000048#include <wtf/text/StringBuilder.h>
mjs@apple.comaed3cef2009-12-09 01:29:52 +000049
mjs@apple.comaed3cef2009-12-09 01:29:52 +000050namespace JSC {
51
52/*
53 Details of the emitBytecode function.
54
55 Return value: The register holding the production's value.
56 dst: An optional parameter specifying the most efficient destination at
57 which to store the production's value. The callee must honor dst.
58
59 The dst argument provides for a crude form of copy propagation. For example,
60
61 x = 1
62
63 becomes
64
65 load r[x], 1
66
67 instead of
68
69 load r0, 1
70 mov r[x], r0
71
72 because the assignment node, "x =", passes r[x] as dst to the number node, "1".
73*/
74
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +000075void ExpressionNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +000076{
77 RegisterID* result = generator.emitNode(this);
78 if (fallThroughMode == FallThroughMeansTrue)
79 generator.emitJumpIfFalse(result, falseTarget);
80 else
81 generator.emitJumpIfTrue(result, trueTarget);
82}
83
mjs@apple.comaed3cef2009-12-09 01:29:52 +000084// ------------------------------ ThrowableExpressionData --------------------------------
85
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +000086RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message)
mjs@apple.comaed3cef2009-12-09 01:29:52 +000087{
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +000088 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
barraclough@apple.com4920ae92010-11-12 03:06:07 +000089 generator.emitThrowReferenceError(message);
90 return generator.newTemporary();
mjs@apple.comaed3cef2009-12-09 01:29:52 +000091}
92
ggaren@apple.com81c68cc2013-04-27 06:43:33 +000093// ------------------------------ ConstantNode ----------------------------------
mjs@apple.comaed3cef2009-12-09 01:29:52 +000094
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +000095void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
mjs@apple.comaed3cef2009-12-09 01:29:52 +000096{
ggaren@apple.com81c68cc2013-04-27 06:43:33 +000097 TriState value = jsValue(generator).pureToBoolean();
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +000098
99 if (UNLIKELY(needsDebugHook())) {
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +0000100 if (value != TriState::Indeterminate)
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +0000101 generator.emitDebugHook(this);
102 }
103
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +0000104 if (value == TriState::Indeterminate)
ggaren@apple.com81c68cc2013-04-27 06:43:33 +0000105 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +0000106 else if (value == TriState::True && fallThroughMode == FallThroughMeansFalse)
ggaren@apple.com81c68cc2013-04-27 06:43:33 +0000107 generator.emitJump(trueTarget);
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +0000108 else if (value == TriState::False && fallThroughMode == FallThroughMeansTrue)
ggaren@apple.com81c68cc2013-04-27 06:43:33 +0000109 generator.emitJump(falseTarget);
110
111 // All other cases are unconditional fall-throughs, like "if (true)".
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000112}
113
ggaren@apple.com81c68cc2013-04-27 06:43:33 +0000114RegisterID* ConstantNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000115{
fpizlo@apple.com335ba392013-04-26 00:40:27 +0000116 if (dst == generator.ignoredResult())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +0000117 return nullptr;
rmorisset@apple.com23fa4432020-01-17 07:16:34 +0000118 JSValue constant = jsValue(generator);
119 if (UNLIKELY(!constant)) {
120 // This can happen if we try to parse a string or BigInt so enormous that we OOM.
121 return generator.emitThrowExpressionTooDeepException();
122 }
123 return generator.emitLoad(dst, constant);
fpizlo@apple.com335ba392013-04-26 00:40:27 +0000124}
125
ggaren@apple.com81c68cc2013-04-27 06:43:33 +0000126JSValue StringNode::jsValue(BytecodeGenerator& generator) const
fpizlo@apple.com335ba392013-04-26 00:40:27 +0000127{
ggaren@apple.com81c68cc2013-04-27 06:43:33 +0000128 return generator.addStringConstant(m_value);
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000129}
130
ticaiolima@gmail.comb9da09d2017-12-12 21:01:57 +0000131JSValue BigIntNode::jsValue(BytecodeGenerator& generator) const
132{
ticaiolima@gmail.com9b7918e2018-05-28 03:19:37 +0000133 return generator.addBigIntConstant(m_value, m_radix, m_sign);
ticaiolima@gmail.comb9da09d2017-12-12 21:01:57 +0000134}
135
benjamin@webkit.org54d94f52015-02-28 03:21:37 +0000136// ------------------------------ NumberNode ----------------------------------
137
138RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
139{
140 if (dst == generator.ignoredResult())
141 return nullptr;
142 return generator.emitLoad(dst, jsValue(generator), isIntegerNode() ? SourceCodeRepresentation::Integer : SourceCodeRepresentation::Double);
143}
144
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000145// ------------------------------ RegExpNode -----------------------------------
146
147RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
148{
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000149 if (dst == generator.ignoredResult())
utatane.tea@gmail.com0f74fb902017-12-21 01:58:28 +0000150 return nullptr;
ross.kirsling@sony.com3d654ba2019-03-11 06:20:53 +0000151
152 auto flags = Yarr::parseFlags(m_flags.string());
153 ASSERT(flags.hasValue());
mark.lam@apple.com5ba07792019-08-27 22:14:52 +0000154 RegExp* regExp = RegExp::create(generator.vm(), m_pattern.string(), flags.value());
utatane.tea@gmail.com0f74fb902017-12-21 01:58:28 +0000155 if (regExp->isValid())
156 return generator.emitNewRegExp(generator.finalDestination(dst), regExp);
ross.kirsling@sony.com3d654ba2019-03-11 06:20:53 +0000157
utatane.tea@gmail.com0f74fb902017-12-21 01:58:28 +0000158 const char* messageCharacters = regExp->errorMessage();
159 const Identifier& message = generator.parserArena().identifierArena().makeIdentifier(generator.vm(), bitwise_cast<const LChar*>(messageCharacters), strlen(messageCharacters));
160 generator.emitThrowStaticError(ErrorType::SyntaxError, message);
161 return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000162}
163
164// ------------------------------ ThisNode -------------------------------------
165
166RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
167{
sbarati@apple.com23315d62016-05-09 20:17:23 +0000168 generator.ensureThis();
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000169 if (dst == generator.ignoredResult())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +0000170 return nullptr;
commit-queue@webkit.orgeafc9b32014-08-14 23:59:44 +0000171
keith_miller@apple.com35210892018-06-01 18:11:36 +0000172 RegisterID* result = generator.move(dst, generator.thisRegister());
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +0000173 static const unsigned thisLength = strlen("this");
174 generator.emitProfileType(generator.thisRegister(), position(), position() + thisLength);
commit-queue@webkit.orgeafc9b32014-08-14 23:59:44 +0000175 return result;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000176}
177
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000178// ------------------------------ SuperNode -------------------------------------
179
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +0000180static RegisterID* emitHomeObjectForCallee(BytecodeGenerator& generator)
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000181{
caitp@igalia.comce715b22020-01-16 00:09:50 +0000182 if ((generator.isDerivedClassContext() || generator.isDerivedConstructorContext()) && generator.parseMode() != SourceParseMode::InstanceFieldInitializerMode) {
commit-queue@webkit.orgefc86f52015-12-30 21:08:16 +0000183 RegisterID* derivedConstructor = generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
keith_miller@apple.com1ec869c2016-06-21 17:54:33 +0000184 return generator.emitGetById(generator.newTemporary(), derivedConstructor, generator.propertyNames().builtinNames().homeObjectPrivateName());
commit-queue@webkit.orgefc86f52015-12-30 21:08:16 +0000185 }
186
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000187 RegisterID callee;
mark.lam@apple.com2bd89342016-07-08 22:58:15 +0000188 callee.setIndex(CallFrameSlot::callee);
keith_miller@apple.com1ec869c2016-06-21 17:54:33 +0000189 return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().builtinNames().homeObjectPrivateName());
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +0000190}
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000191
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +0000192static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator)
193{
194 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000195 return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
196}
197
sbarati@apple.com23315d62016-05-09 20:17:23 +0000198static RegisterID* emitGetSuperFunctionForConstruct(BytecodeGenerator& generator)
199{
200 if (generator.isDerivedConstructorContext())
201 return generator.emitGetById(generator.newTemporary(), generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(), generator.propertyNames().underscoreProto);
202
203 RegisterID callee;
mark.lam@apple.com2bd89342016-07-08 22:58:15 +0000204 callee.setIndex(CallFrameSlot::callee);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000205 return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().underscoreProto);
206}
207
208RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
209{
210 RegisterID* result = emitSuperBaseForCallee(generator);
keith_miller@apple.com35210892018-06-01 18:11:36 +0000211 return generator.move(generator.finalDestination(dst), result);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000212}
213
utatane.tea@gmail.com5e639122017-01-09 22:02:47 +0000214// ------------------------------ ImportNode -------------------------------------
215
216RegisterID* ImportNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
217{
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +0000218 RefPtr<RegisterID> importModule = generator.moveLinkTimeConstant(nullptr, LinkTimeConstant::importModule);
utatane.tea@gmail.com5e639122017-01-09 22:02:47 +0000219 CallArguments arguments(generator, nullptr, 1);
220 generator.emitLoad(arguments.thisRegister(), jsUndefined());
221 generator.emitNode(arguments.argumentRegister(0), m_expr);
222 return generator.emitCall(generator.finalDestination(dst, importModule.get()), importModule.get(), NoExpectedFunction, arguments, divot(), divotStart(), divotEnd(), DebuggableCall::No);
223}
224
commit-queue@webkit.org17f99e42015-07-21 18:18:42 +0000225// ------------------------------ NewTargetNode ----------------------------------
226
227RegisterID* NewTargetNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
228{
229 if (dst == generator.ignoredResult())
230 return nullptr;
231
keith_miller@apple.com35210892018-06-01 18:11:36 +0000232 return generator.move(dst, generator.newTarget());
commit-queue@webkit.org17f99e42015-07-21 18:18:42 +0000233}
234
utatane.tea@gmail.com614f7692017-10-12 06:45:23 +0000235// ------------------------------ ImportMetaNode ---------------------------------
236
237RegisterID* ImportMetaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
238{
239 return generator.emitNode(dst, m_expr);
240}
241
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000242// ------------------------------ ResolveNode ----------------------------------
243
244bool ResolveNode::isPure(BytecodeGenerator& generator) const
245{
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000246 return generator.variable(m_ident).offset().isStack();
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000247}
248
249RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
250{
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000251 Variable var = generator.variable(m_ident);
252 if (RegisterID* local = var.local()) {
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000253 generator.emitTDZCheckIfNecessary(var, local, nullptr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000254 if (dst == generator.ignoredResult())
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000255 return nullptr;
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +0000256
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +0000257 generator.emitProfileType(local, var, m_position, m_position + m_ident.length());
keith_miller@apple.com35210892018-06-01 18:11:36 +0000258 return generator.move(dst, local);
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000259 }
260
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +0000261 JSTextPosition divot = m_start + m_ident.length();
262 generator.emitExpressionInfo(divot, m_start, divot);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000263 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
commit-queue@webkit.orgeafc9b32014-08-14 23:59:44 +0000264 RegisterID* finalDest = generator.finalDestination(dst);
fpizlo@apple.comfefbece2018-03-30 20:31:00 +0000265 RefPtr<RegisterID> uncheckedResult = generator.newTemporary();
266 generator.emitGetFromScope(uncheckedResult.get(), scope.get(), var, ThrowIfNotFound);
267 generator.emitTDZCheckIfNecessary(var, uncheckedResult.get(), nullptr);
keith_miller@apple.com35210892018-06-01 18:11:36 +0000268 generator.move(finalDest, uncheckedResult.get());
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +0000269 generator.emitProfileType(finalDest, var, m_position, m_position + m_ident.length());
fpizlo@apple.comfefbece2018-03-30 20:31:00 +0000270 return finalDest;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000271}
272
utatane.tea@gmail.com4014aea2015-04-27 00:27:28 +0000273// ------------------------------ TemplateStringNode -----------------------------------
274
275RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
276{
277 if (dst == generator.ignoredResult())
278 return nullptr;
utatane.tea@gmail.coma10944d2017-01-28 03:09:12 +0000279 ASSERT(cooked());
280 return generator.emitLoad(dst, JSValue(generator.addStringConstant(*cooked())));
utatane.tea@gmail.com4014aea2015-04-27 00:27:28 +0000281}
282
283// ------------------------------ TemplateLiteralNode -----------------------------------
284
285RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
286{
287 if (!m_templateExpressions) {
288 TemplateStringNode* templateString = m_templateStrings->value();
289 ASSERT_WITH_MESSAGE(!m_templateStrings->next(), "Only one template element exists because there's no expression in a given template literal.");
290 return generator.emitNode(dst, templateString);
291 }
292
293 Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
294
295 TemplateStringListNode* templateString = m_templateStrings;
296 TemplateExpressionListNode* templateExpression = m_templateExpressions;
297 for (; templateExpression; templateExpression = templateExpression->next(), templateString = templateString->next()) {
298 // Evaluate TemplateString.
utatane.tea@gmail.coma10944d2017-01-28 03:09:12 +0000299 ASSERT(templateString->value()->cooked());
300 if (!templateString->value()->cooked()->isEmpty()) {
utatane.tea@gmail.com4014aea2015-04-27 00:27:28 +0000301 temporaryRegisters.append(generator.newTemporary());
302 generator.emitNode(temporaryRegisters.last().get(), templateString->value());
303 }
304
305 // Evaluate Expression.
306 temporaryRegisters.append(generator.newTemporary());
307 generator.emitNode(temporaryRegisters.last().get(), templateExpression->value());
308 generator.emitToString(temporaryRegisters.last().get(), temporaryRegisters.last().get());
309 }
310
311 // Evaluate tail TemplateString.
utatane.tea@gmail.coma10944d2017-01-28 03:09:12 +0000312 ASSERT(templateString->value()->cooked());
313 if (!templateString->value()->cooked()->isEmpty()) {
utatane.tea@gmail.com4014aea2015-04-27 00:27:28 +0000314 temporaryRegisters.append(generator.newTemporary());
315 generator.emitNode(temporaryRegisters.last().get(), templateString->value());
316 }
317
oliver@apple.com1aec7c72016-06-13 23:17:00 +0000318 if (temporaryRegisters.size() == 1)
319 return generator.emitToString(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get());
320
utatane.tea@gmail.com4014aea2015-04-27 00:27:28 +0000321 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
322}
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000323
324// ------------------------------ TaggedTemplateNode -----------------------------------
325
326RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
327{
328 ExpectedFunction expectedFunction = NoExpectedFunction;
329 RefPtr<RegisterID> tag = nullptr;
330 RefPtr<RegisterID> base = nullptr;
331 if (!m_tag->isLocation()) {
utatane.tea@gmail.coma26653e2015-05-14 19:58:00 +0000332 tag = generator.newTemporary();
333 tag = generator.emitNode(tag.get(), m_tag);
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000334 } else if (m_tag->isResolveNode()) {
335 ResolveNode* resolve = static_cast<ResolveNode*>(m_tag);
336 const Identifier& identifier = resolve->identifier();
337 expectedFunction = generator.expectedFunctionForIdentifier(identifier);
338
339 Variable var = generator.variable(identifier);
sbarati@apple.com7040cea2016-05-23 20:27:28 +0000340 if (RegisterID* local = var.local()) {
341 generator.emitTDZCheckIfNecessary(var, local, nullptr);
keith_miller@apple.com35210892018-06-01 18:11:36 +0000342 tag = generator.move(generator.newTemporary(), local);
sbarati@apple.com7040cea2016-05-23 20:27:28 +0000343 } else {
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000344 tag = generator.newTemporary();
345 base = generator.newTemporary();
346
347 JSTextPosition newDivot = divotStart() + identifier.length();
348 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
keith_miller@apple.com35210892018-06-01 18:11:36 +0000349 generator.move(base.get(), generator.emitResolveScope(base.get(), var));
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000350 generator.emitGetFromScope(tag.get(), base.get(), var, ThrowIfNotFound);
sbarati@apple.com7040cea2016-05-23 20:27:28 +0000351 generator.emitTDZCheckIfNecessary(var, tag.get(), nullptr);
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000352 }
353 } else if (m_tag->isBracketAccessorNode()) {
354 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(m_tag);
utatane.tea@gmail.coma26653e2015-05-14 19:58:00 +0000355 base = generator.newTemporary();
356 base = generator.emitNode(base.get(), bracket->base());
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +0000357 RefPtr<RegisterID> property = generator.emitNodeForProperty(bracket->subscript());
sbarati@apple.com23315d62016-05-09 20:17:23 +0000358 if (bracket->base()->isSuperNode()) {
359 RefPtr<RegisterID> thisValue = generator.ensureThis();
360 tag = generator.emitGetByVal(generator.newTemporary(), base.get(), thisValue.get(), property.get());
361 } else
362 tag = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000363 } else {
364 ASSERT(m_tag->isDotAccessorNode());
365 DotAccessorNode* dot = static_cast<DotAccessorNode*>(m_tag);
utatane.tea@gmail.coma26653e2015-05-14 19:58:00 +0000366 base = generator.newTemporary();
367 base = generator.emitNode(base.get(), dot->base());
sbarati@apple.com23315d62016-05-09 20:17:23 +0000368 if (dot->base()->isSuperNode()) {
369 RefPtr<RegisterID> thisValue = generator.ensureThis();
370 tag = generator.emitGetById(generator.newTemporary(), base.get(), thisValue.get(), dot->identifier());
371 } else
372 tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000373 }
374
utatane.tea@gmail.com6cd55812017-04-05 07:09:41 +0000375 RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(nullptr, this);
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000376
377 unsigned expressionsCount = 0;
378 for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
379 ++expressionsCount;
380
381 CallArguments callArguments(generator, nullptr, 1 + expressionsCount);
382 if (base)
keith_miller@apple.com35210892018-06-01 18:11:36 +0000383 generator.move(callArguments.thisRegister(), base.get());
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000384 else
385 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
386
387 unsigned argumentIndex = 0;
keith_miller@apple.com35210892018-06-01 18:11:36 +0000388 generator.move(callArguments.argumentRegister(argumentIndex++), templateObject.get());
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000389 for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
390 generator.emitNode(callArguments.argumentRegister(argumentIndex++), templateExpression->value());
391
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +0000392 return generator.emitCallInTailPosition(generator.finalDestination(dst, tag.get()), tag.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
utatane.tea@gmail.comd68d2482015-05-14 16:07:54 +0000393}
utatane.tea@gmail.com4014aea2015-04-27 00:27:28 +0000394
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000395// ------------------------------ ArrayNode ------------------------------------
396
397RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
398{
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000399 bool hadVariableExpression = false;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000400 unsigned length = 0;
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +0000401
402 IndexingType recommendedIndexingType = ArrayWithUndecided;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000403 ElementNode* firstPutElement;
404 for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
oliver@apple.com72f8a822013-10-17 01:02:34 +0000405 if (firstPutElement->elision() || firstPutElement->value()->isSpreadExpression())
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000406 break;
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000407 if (!firstPutElement->value()->isConstant())
408 hadVariableExpression = true;
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +0000409 else
410 recommendedIndexingType = leastUpperBoundOfIndexingTypeAndValue(recommendedIndexingType, static_cast<ConstantNode*>(firstPutElement->value())->jsValue(generator));
411
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000412 ++length;
413 }
414
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +0000415 auto newArray = [&] (RegisterID* dst, ElementNode* elements, unsigned length, bool hadVariableExpression) {
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000416 if (length && !hadVariableExpression) {
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +0000417 recommendedIndexingType |= CopyOnWrite;
mark.lam@apple.com5ba07792019-08-27 22:14:52 +0000418 ASSERT(generator.vm().heap.isDeferred()); // We run bytecode generator under a DeferGC. If we stopped doing that, we'd need to put a DeferGC here as we filled in these slots.
419 auto* array = JSImmutableButterfly::create(generator.vm(), recommendedIndexingType, length);
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000420 unsigned index = 0;
421 for (ElementNode* element = elements; index < length; element = element->next()) {
422 ASSERT(element->value()->isConstant());
mark.lam@apple.com5ba07792019-08-27 22:14:52 +0000423 array->setIndex(generator.vm(), index++, static_cast<ConstantNode*>(element->value())->jsValue(generator));
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000424 }
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +0000425 return generator.emitNewArrayBuffer(dst, array, recommendedIndexingType);
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000426 }
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +0000427 return generator.emitNewArray(dst, elements, length, recommendedIndexingType);
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000428 };
429
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000430 if (!firstPutElement && !m_elision)
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000431 return newArray(generator.finalDestination(dst), m_element, length, hadVariableExpression);
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000432
sbarati@apple.com99ed4792016-11-12 02:58:11 +0000433 if (firstPutElement && firstPutElement->value()->isSpreadExpression()) {
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000434 bool hasElision = m_elision;
435 if (!hasElision) {
436 for (ElementNode* node = firstPutElement; node; node = node->next()) {
437 if (node->elision()) {
438 hasElision = true;
439 break;
440 }
sbarati@apple.com99ed4792016-11-12 02:58:11 +0000441 }
442 }
sbarati@apple.com99ed4792016-11-12 02:58:11 +0000443
444 if (!hasElision)
445 return generator.emitNewArrayWithSpread(generator.finalDestination(dst), m_element);
446 }
447
utatane.tea@gmail.come1b432c2018-03-27 08:49:41 +0000448 RefPtr<RegisterID> array = newArray(generator.tempDestination(dst), m_element, length, hadVariableExpression);
oliver@apple.com72f8a822013-10-17 01:02:34 +0000449 ElementNode* n = firstPutElement;
450 for (; n; n = n->next()) {
451 if (n->value()->isSpreadExpression())
452 goto handleSpread;
utatane.tea@gmail.com1edb3192018-03-22 15:40:57 +0000453 RefPtr<RegisterID> value = generator.emitNode(n->value());
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000454 length += n->elision();
utatane.tea@gmail.com1edb3192018-03-22 15:40:57 +0000455
456 RefPtr<RegisterID> index = generator.emitLoad(nullptr, jsNumber(length++));
457 generator.emitDirectPutByVal(array.get(), index.get(), value.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000458 }
459
460 if (m_elision) {
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +0000461 RegisterID* value = generator.emitLoad(nullptr, jsNumber(m_elision + length));
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000462 generator.emitPutById(array.get(), generator.propertyNames().length, value);
463 }
464
keith_miller@apple.com35210892018-06-01 18:11:36 +0000465 return generator.move(dst, array.get());
oliver@apple.com72f8a822013-10-17 01:02:34 +0000466
467handleSpread:
468 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(length));
utatane.tea@gmail.comb67c9082018-07-21 13:10:43 +0000469 auto spreader = scopedLambda<void(BytecodeGenerator&, RegisterID*)>([array, index](BytecodeGenerator& generator, RegisterID* value)
oliver@apple.com72f8a822013-10-17 01:02:34 +0000470 {
oliver@apple.come050d642013-10-19 00:09:28 +0000471 generator.emitDirectPutByVal(array.get(), index.get(), value);
oliver@apple.com72f8a822013-10-17 01:02:34 +0000472 generator.emitInc(index.get());
utatane.tea@gmail.comb67c9082018-07-21 13:10:43 +0000473 });
oliver@apple.com72f8a822013-10-17 01:02:34 +0000474 for (; n; n = n->next()) {
475 if (n->elision())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +0000476 generator.emitBinaryOp<OpAdd>(index.get(), index.get(), generator.emitLoad(nullptr, jsNumber(n->elision())), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
oliver@apple.com72f8a822013-10-17 01:02:34 +0000477 if (n->value()->isSpreadExpression()) {
478 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(n->value());
479 generator.emitEnumeration(spread, spread->expression(), spreader);
480 } else {
oliver@apple.come050d642013-10-19 00:09:28 +0000481 generator.emitDirectPutByVal(array.get(), index.get(), generator.emitNode(n->value()));
oliver@apple.com72f8a822013-10-17 01:02:34 +0000482 generator.emitInc(index.get());
483 }
484 }
485
486 if (m_elision) {
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +0000487 generator.emitBinaryOp<OpAdd>(index.get(), index.get(), generator.emitLoad(nullptr, jsNumber(m_elision)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
oliver@apple.com72f8a822013-10-17 01:02:34 +0000488 generator.emitPutById(array.get(), generator.propertyNames().length, index.get());
489 }
keith_miller@apple.com35210892018-06-01 18:11:36 +0000490 return generator.move(dst, array.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000491}
492
493bool ArrayNode::isSimpleArray() const
494{
495 if (m_elision || m_optional)
496 return false;
497 for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
498 if (ptr->elision())
499 return false;
commit-queue@webkit.org1a78b432016-09-15 01:14:45 +0000500 if (ptr->value()->isSpreadExpression())
501 return false;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000502 }
503 return true;
504}
505
ggaren@apple.comc0ccae02014-12-03 23:23:56 +0000506ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNumber, int startPosition) const
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000507{
508 ASSERT(!m_elision && !m_optional);
509 ElementNode* ptr = m_element;
510 if (!ptr)
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +0000511 return nullptr;
mark.lam@apple.com0d5fdb92013-07-24 00:41:46 +0000512 JSTokenLocation location;
commit-queue@webkit.org1b331cb2012-08-06 03:16:46 +0000513 location.line = lineNumber;
mark.lam@apple.com5b45f902013-07-09 16:15:12 +0000514 location.startOffset = startPosition;
ggaren@apple.comc0ccae02014-12-03 23:23:56 +0000515 ArgumentListNode* head = new (parserArena) ArgumentListNode(location, ptr->value());
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000516 ArgumentListNode* tail = head;
517 ptr = ptr->next();
518 for (; ptr; ptr = ptr->next()) {
519 ASSERT(!ptr->elision());
ggaren@apple.comc0ccae02014-12-03 23:23:56 +0000520 tail = new (parserArena) ArgumentListNode(location, tail, ptr->value());
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000521 }
522 return head;
523}
524
525// ------------------------------ ObjectLiteralNode ----------------------------
526
527RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
528{
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +0000529 if (!m_list) {
530 if (dst == generator.ignoredResult())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +0000531 return nullptr;
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +0000532 return generator.emitNewObject(generator.finalDestination(dst));
533 }
534 RefPtr<RegisterID> newObj = generator.emitNewObject(generator.tempDestination(dst));
535 generator.emitNode(newObj.get(), m_list);
keith_miller@apple.com35210892018-06-01 18:11:36 +0000536 return generator.move(dst, newObj.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000537}
538
539// ------------------------------ PropertyListNode -----------------------------
540
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000541static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject)
542{
keith_miller@apple.com1ec869c2016-06-21 17:54:33 +0000543 generator.emitPutById(function, generator.propertyNames().builtinNames().homeObjectPrivateName(), homeObject);
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000544}
545
caitp@igalia.comce715b22020-01-16 00:09:50 +0000546RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dstOrConstructor, RegisterID* prototype, Vector<JSTextPosition>* instanceFieldLocations)
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000547{
barraclough@apple.com09a55682012-01-30 18:28:39 +0000548 // Fast case: this loop just handles regular value properties.
549 PropertyListNode* p = this;
caitp@igalia.com276f8de2018-03-14 20:00:21 +0000550 RegisterID* dst = nullptr;
551 for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next) {
552 dst = p->m_node->isInstanceClassProperty() ? prototype : dstOrConstructor;
caitp@igalia.comce715b22020-01-16 00:09:50 +0000553
554 if (p->isComputedClassField())
555 emitSaveComputedFieldName(generator, *p->m_node);
556
557 if (p->isInstanceClassField()) {
558 ASSERT(instanceFieldLocations);
559 instanceFieldLocations->append(p->position());
560 continue;
561 }
562
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +0000563 emitPutConstantProperty(generator, dst, *p->m_node);
caitp@igalia.com276f8de2018-03-14 20:00:21 +0000564 }
barraclough@apple.com09a55682012-01-30 18:28:39 +0000565
566 // Were there any get/set properties?
567 if (p) {
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000568 // Build a list of getter/setter pairs to try to put them at the same time. If we encounter
ticaiolima@gmail.comf62044c2017-07-13 07:11:45 +0000569 // a computed property or a spread, just emit everything as that may override previous values.
570 bool canOverrideProperties = false;
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000571
barraclough@apple.com09a55682012-01-30 18:28:39 +0000572 typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
utatane.tea@gmail.com8268d392015-05-23 18:41:53 +0000573 typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;
caitp@igalia.com276f8de2018-03-14 20:00:21 +0000574 GetterSetterMap instanceMap;
575 GetterSetterMap staticMap;
barraclough@apple.com09a55682012-01-30 18:28:39 +0000576
577 // Build a map, pairing get/set values together.
578 for (PropertyListNode* q = p; q; q = q->m_next) {
579 PropertyNode* node = q->m_node;
ticaiolima@gmail.comf62044c2017-07-13 07:11:45 +0000580 if (node->m_type & PropertyNode::Computed || node->m_type & PropertyNode::Spread) {
581 canOverrideProperties = true;
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000582 break;
583 }
ticaiolima@gmail.comf62044c2017-07-13 07:11:45 +0000584
mark.lam@apple.comcf0bf6c2017-05-16 00:21:59 +0000585 if (node->m_type & PropertyNode::Constant)
barraclough@apple.com09a55682012-01-30 18:28:39 +0000586 continue;
587
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000588 // Duplicates are possible.
589 GetterSetterPair pair(node, static_cast<PropertyNode*>(nullptr));
caitp@igalia.com276f8de2018-03-14 20:00:21 +0000590 GetterSetterMap& map = node->isStaticClassProperty() ? staticMap : instanceMap;
oliver@apple.com72d38322013-10-21 19:23:24 +0000591 GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair);
mark.lam@apple.com301cd912018-01-09 18:49:25 +0000592 auto& resultPair = result.iterator->value;
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000593 if (!result.isNewEntry) {
mark.lam@apple.com301cd912018-01-09 18:49:25 +0000594 if (resultPair.first->m_type == node->m_type) {
595 resultPair.first->setIsOverriddenByDuplicate();
596 resultPair.first = node;
597 } else {
598 if (resultPair.second)
599 resultPair.second->setIsOverriddenByDuplicate();
600 resultPair.second = node;
601 }
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000602 }
barraclough@apple.com09a55682012-01-30 18:28:39 +0000603 }
604
605 // Iterate over the remaining properties in the list.
606 for (; p; p = p->m_next) {
607 PropertyNode* node = p->m_node;
caitp@igalia.com276f8de2018-03-14 20:00:21 +0000608 dst = node->isInstanceClassProperty() ? prototype : dstOrConstructor;
barraclough@apple.com09a55682012-01-30 18:28:39 +0000609
caitp@igalia.comce715b22020-01-16 00:09:50 +0000610 if (p->isComputedClassField())
611 emitSaveComputedFieldName(generator, *p->m_node);
612
613 if (p->isInstanceClassField()) {
614 ASSERT(instanceFieldLocations);
615 ASSERT(node->m_type & PropertyNode::Constant);
616 instanceFieldLocations->append(p->position());
617 continue;
618 }
619
barraclough@apple.com09a55682012-01-30 18:28:39 +0000620 // Handle regular values.
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000621 if (node->m_type & PropertyNode::Constant) {
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +0000622 emitPutConstantProperty(generator, dst, *node);
barraclough@apple.com09a55682012-01-30 18:28:39 +0000623 continue;
ticaiolima@gmail.comf62044c2017-07-13 07:11:45 +0000624 } else if (node->m_type & PropertyNode::Spread) {
625 generator.emitNode(dst, node->m_assign);
626 continue;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000627 }
rniwa@webkit.org95698ee2015-01-22 18:07:16 +0000628
utatane.tea@gmail.comf0153d02015-09-08 19:43:58 +0000629 RefPtr<RegisterID> value = generator.emitNode(node->m_assign);
ggaren@apple.comcadd8c52016-04-22 23:04:55 +0000630 bool needsSuperBinding = node->needsSuperBinding();
631 if (needsSuperBinding)
utatane.tea@gmail.comf0153d02015-09-08 19:43:58 +0000632 emitPutHomeObject(generator, value.get(), dst);
ggaren@apple.comcadd8c52016-04-22 23:04:55 +0000633
achristensen@apple.com5c6da6e2017-09-25 22:37:03 +0000634 unsigned attributes = node->isClassProperty() ? (PropertyAttribute::Accessor | PropertyAttribute::DontEnum) : static_cast<unsigned>(PropertyAttribute::Accessor);
barraclough@apple.com09a55682012-01-30 18:28:39 +0000635
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000636 ASSERT(node->m_type & (PropertyNode::Getter | PropertyNode::Setter));
637
ticaiolima@gmail.comf62044c2017-07-13 07:11:45 +0000638 // This is a get/set property which may be overridden by a computed property or spread later.
639 if (canOverrideProperties) {
utatane.tea@gmail.comf0153d02015-09-08 19:43:58 +0000640 // Computed accessors.
641 if (node->m_type & PropertyNode::Computed) {
642 RefPtr<RegisterID> propertyName = generator.emitNode(node->m_expression);
ross.kirsling@sony.com45f6de02020-02-18 20:01:20 +0000643 if (generator.shouldSetFunctionName(node->m_assign)) {
644 propertyName = generator.emitToPropertyKey(generator.newTemporary(), propertyName.get());
645 generator.emitSetFunctionName(value.get(), propertyName.get());
646 }
utatane.tea@gmail.comf0153d02015-09-08 19:43:58 +0000647 if (node->m_type & PropertyNode::Getter)
ggaren@apple.comcadd8c52016-04-22 23:04:55 +0000648 generator.emitPutGetterByVal(dst, propertyName.get(), attributes, value.get());
utatane.tea@gmail.comf0153d02015-09-08 19:43:58 +0000649 else
ggaren@apple.comcadd8c52016-04-22 23:04:55 +0000650 generator.emitPutSetterByVal(dst, propertyName.get(), attributes, value.get());
utatane.tea@gmail.comf0153d02015-09-08 19:43:58 +0000651 continue;
652 }
653
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000654 if (node->m_type & PropertyNode::Getter)
ggaren@apple.comcadd8c52016-04-22 23:04:55 +0000655 generator.emitPutGetterById(dst, *node->name(), attributes, value.get());
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000656 else
ggaren@apple.comcadd8c52016-04-22 23:04:55 +0000657 generator.emitPutSetterById(dst, *node->name(), attributes, value.get());
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000658 continue;
659 }
660
661 // This is a get/set property pair.
caitp@igalia.com276f8de2018-03-14 20:00:21 +0000662 GetterSetterMap& map = node->isStaticClassProperty() ? staticMap : instanceMap;
oliver@apple.com72d38322013-10-21 19:23:24 +0000663 GetterSetterMap::iterator it = map.find(node->name()->impl());
barraclough@apple.com09a55682012-01-30 18:28:39 +0000664 ASSERT(it != map.end());
benjamin@webkit.orgee554052012-10-07 23:12:07 +0000665 GetterSetterPair& pair = it->value;
barraclough@apple.com09a55682012-01-30 18:28:39 +0000666
667 // Was this already generated as a part of its partner?
mark.lam@apple.com301cd912018-01-09 18:49:25 +0000668 if (pair.second == node || node->isOverriddenByDuplicate())
barraclough@apple.com09a55682012-01-30 18:28:39 +0000669 continue;
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000670
barraclough@apple.com09a55682012-01-30 18:28:39 +0000671 // Generate the paired node now.
672 RefPtr<RegisterID> getterReg;
673 RefPtr<RegisterID> setterReg;
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000674 RegisterID* secondReg = nullptr;
barraclough@apple.com09a55682012-01-30 18:28:39 +0000675
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000676 if (node->m_type & PropertyNode::Getter) {
barraclough@apple.com09a55682012-01-30 18:28:39 +0000677 getterReg = value;
678 if (pair.second) {
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000679 ASSERT(pair.second->m_type & PropertyNode::Setter);
barraclough@apple.com09a55682012-01-30 18:28:39 +0000680 setterReg = generator.emitNode(pair.second->m_assign);
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000681 secondReg = setterReg.get();
barraclough@apple.com09a55682012-01-30 18:28:39 +0000682 } else {
683 setterReg = generator.newTemporary();
684 generator.emitLoad(setterReg.get(), jsUndefined());
685 }
686 } else {
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000687 ASSERT(node->m_type & PropertyNode::Setter);
barraclough@apple.com09a55682012-01-30 18:28:39 +0000688 setterReg = value;
689 if (pair.second) {
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000690 ASSERT(pair.second->m_type & PropertyNode::Getter);
barraclough@apple.com09a55682012-01-30 18:28:39 +0000691 getterReg = generator.emitNode(pair.second->m_assign);
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000692 secondReg = getterReg.get();
barraclough@apple.com09a55682012-01-30 18:28:39 +0000693 } else {
694 getterReg = generator.newTemporary();
695 generator.emitLoad(getterReg.get(), jsUndefined());
696 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000697 }
barraclough@apple.com09a55682012-01-30 18:28:39 +0000698
ggaren@apple.comcadd8c52016-04-22 23:04:55 +0000699 ASSERT(!pair.second || needsSuperBinding == pair.second->needsSuperBinding());
700 if (needsSuperBinding && pair.second)
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000701 emitPutHomeObject(generator, secondReg, dst);
702
ggaren@apple.comcadd8c52016-04-22 23:04:55 +0000703 generator.emitPutGetterSetter(dst, *node->name(), attributes, getterReg.get(), setterReg.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000704 }
705 }
barraclough@apple.com09a55682012-01-30 18:28:39 +0000706
caitp@igalia.com276f8de2018-03-14 20:00:21 +0000707 return dstOrConstructor;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000708}
709
rniwa@webkit.org95698ee2015-01-22 18:07:16 +0000710void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node)
711{
ross.kirsling@sony.comdf44fe12020-02-20 03:01:03 +0000712 bool shouldSetFunctionName = generator.shouldSetFunctionName(node.m_assign);
713
714 RefPtr<RegisterID> propertyName;
715 if (!node.name()) {
716 propertyName = generator.newTemporary();
717 if (shouldSetFunctionName)
718 generator.emitToPropertyKey(propertyName.get(), generator.emitNode(node.m_expression));
719 else
720 generator.emitNode(propertyName.get(), node.m_expression);
721 }
722
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000723 RefPtr<RegisterID> value = generator.emitNode(node.m_assign);
utatane.tea@gmail.com9b114152016-09-18 17:40:11 +0000724 if (node.needsSuperBinding())
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000725 emitPutHomeObject(generator, value.get(), newObj);
rniwa@webkit.org49d0cc12015-04-25 22:03:30 +0000726
utatane.tea@gmail.com9b114152016-09-18 17:40:11 +0000727 if (node.isClassProperty()) {
728 ASSERT(node.needsSuperBinding());
rniwa@webkit.org49d0cc12015-04-25 22:03:30 +0000729 if (node.name())
ross.kirsling@sony.comdf44fe12020-02-20 03:01:03 +0000730 propertyName = generator.emitLoad(nullptr, *node.name());
rniwa@webkit.org49d0cc12015-04-25 22:03:30 +0000731
ross.kirsling@sony.comdf44fe12020-02-20 03:01:03 +0000732 if (shouldSetFunctionName)
733 generator.emitSetFunctionName(value.get(), propertyName.get());
734 generator.emitCallDefineProperty(newObj, propertyName.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
rniwa@webkit.org49d0cc12015-04-25 22:03:30 +0000735 return;
736 }
ross.kirsling@sony.comdf44fe12020-02-20 03:01:03 +0000737
utatane.tea@gmail.comac224502015-05-26 17:26:40 +0000738 if (const auto* identifier = node.name()) {
ross.kirsling@sony.comdf44fe12020-02-20 03:01:03 +0000739 ASSERT(!propertyName);
cdumez@apple.com8b7a0222018-12-20 04:41:11 +0000740 Optional<uint32_t> optionalIndex = parseIndex(*identifier);
utatane.tea@gmail.comac224502015-05-26 17:26:40 +0000741 if (!optionalIndex) {
742 generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType());
743 return;
744 }
745
ross.kirsling@sony.comdf44fe12020-02-20 03:01:03 +0000746 propertyName = generator.emitLoad(nullptr, jsNumber(optionalIndex.value()));
747 generator.emitDirectPutByVal(newObj, propertyName.get(), value.get());
rniwa@webkit.org95698ee2015-01-22 18:07:16 +0000748 return;
749 }
ross.kirsling@sony.comdf44fe12020-02-20 03:01:03 +0000750
751 if (shouldSetFunctionName)
ross.kirsling@sony.com45f6de02020-02-18 20:01:20 +0000752 generator.emitSetFunctionName(value.get(), propertyName.get());
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000753 generator.emitDirectPutByVal(newObj, propertyName.get(), value.get());
rniwa@webkit.org95698ee2015-01-22 18:07:16 +0000754}
755
caitp@igalia.comce715b22020-01-16 00:09:50 +0000756void PropertyListNode::emitSaveComputedFieldName(BytecodeGenerator& generator, PropertyNode& node)
757{
758 ASSERT(node.isComputedClassField());
759 RefPtr<RegisterID> propertyExpr;
760
761 // The 'name' refers to a synthetic numeric variable name in the private name scope, where the property key is saved for later use.
762 const Identifier& description = *node.name();
763 Variable var = generator.variable(description);
764 ASSERT(!var.local());
765
766 propertyExpr = generator.emitNode(node.m_expression);
767 RegisterID* propertyName = generator.emitToPropertyKey(generator.newTemporary(), propertyExpr.get());
768
769 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
770 generator.emitPutToScope(scope.get(), var, propertyName, ThrowIfNotFound, InitializationMode::ConstInitialization);
771}
772
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000773// ------------------------------ BracketAccessorNode --------------------------------
774
utatane.tea@gmail.com109ad312015-12-14 02:52:51 +0000775static bool isNonIndexStringElement(ExpressionNode& element)
776{
777 return element.isString() && !parseIndex(static_cast<StringNode&>(element).value());
778}
779
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000780RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
781{
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000782 if (m_base->isSuperNode()) {
sbarati@apple.com23315d62016-05-09 20:17:23 +0000783 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
784 RefPtr<RegisterID> thisValue = generator.ensureThis();
785 RefPtr<RegisterID> superBase = emitSuperBaseForCallee(generator);
commit-queue@webkit.org31924df2016-10-14 06:31:40 +0000786
utatane.tea@gmail.com109ad312015-12-14 02:52:51 +0000787 if (isNonIndexStringElement(*m_subscript)) {
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000788 const Identifier& id = static_cast<StringNode*>(m_subscript)->value();
commit-queue@webkit.org31924df2016-10-14 06:31:40 +0000789 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +0000790 generator.emitGetById(finalDest.get(), superBase.get(), thisValue.get(), id);
791 } else {
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +0000792 RefPtr<RegisterID> subscript = generator.emitNodeForProperty(m_subscript);
commit-queue@webkit.org31924df2016-10-14 06:31:40 +0000793 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +0000794 generator.emitGetByVal(finalDest.get(), superBase.get(), thisValue.get(), subscript.get());
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000795 }
sbarati@apple.com23315d62016-05-09 20:17:23 +0000796
sbarati@apple.com23315d62016-05-09 20:17:23 +0000797 generator.emitProfileType(finalDest.get(), divotStart(), divotEnd());
798 return finalDest.get();
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000799 }
800
akling@apple.comcbb8cfc2014-11-12 21:13:13 +0000801 RegisterID* ret;
sbarati@apple.com23315d62016-05-09 20:17:23 +0000802 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
akling@apple.comcbb8cfc2014-11-12 21:13:13 +0000803
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000804 bool subscriptIsNonIndexString = isNonIndexStringElement(*m_subscript);
805 RefPtr<RegisterID> base = subscriptIsNonIndexString
806 ? generator.emitNode(m_base)
807 : generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
808
809 if (m_base->isOptionalChainBase())
810 generator.emitOptionalCheck(base.get());
811
812 if (subscriptIsNonIndexString) {
commit-queue@webkit.org31924df2016-10-14 06:31:40 +0000813 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +0000814 ret = generator.emitGetById(finalDest.get(), base.get(), static_cast<StringNode*>(m_subscript)->value());
akling@apple.comcbb8cfc2014-11-12 21:13:13 +0000815 } else {
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +0000816 RegisterID* property = generator.emitNodeForProperty(m_subscript);
commit-queue@webkit.org31924df2016-10-14 06:31:40 +0000817 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +0000818 ret = generator.emitGetByVal(finalDest.get(), base.get(), property);
akling@apple.comcbb8cfc2014-11-12 21:13:13 +0000819 }
820
sbarati@apple.com23315d62016-05-09 20:17:23 +0000821 generator.emitProfileType(finalDest.get(), divotStart(), divotEnd());
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +0000822 return ret;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000823}
824
825// ------------------------------ DotAccessorNode --------------------------------
826
827RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
828{
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000829 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000830 bool baseIsSuper = m_base->isSuperNode();
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000831
832 RefPtr<RegisterID> base;
833 if (baseIsSuper)
834 base = emitSuperBaseForCallee(generator);
835 else {
836 base = generator.emitNode(m_base);
837 if (m_base->isOptionalChainBase())
838 generator.emitOptionalCheck(base.get());
839 }
840
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +0000841 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +0000842 RegisterID* ret;
843 if (baseIsSuper) {
844 RefPtr<RegisterID> thisValue = generator.ensureThis();
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000845 ret = generator.emitGetById(finalDest.get(), base.get(), thisValue.get(), m_ident);
sbarati@apple.com23315d62016-05-09 20:17:23 +0000846 } else
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000847 ret = generator.emitGetById(finalDest.get(), base.get(), m_ident);
848 generator.emitProfileType(finalDest.get(), divotStart(), divotEnd());
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +0000849 return ret;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000850}
851
852// ------------------------------ ArgumentListNode -----------------------------
853
854RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
855{
856 ASSERT(m_expr);
857 return generator.emitNode(dst, m_expr);
858}
859
860// ------------------------------ NewExprNode ----------------------------------
861
862RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
863{
fpizlo@apple.com4500e352012-10-17 21:39:11 +0000864 ExpectedFunction expectedFunction;
865 if (m_expr->isResolveNode())
866 expectedFunction = generator.expectedFunctionForIdentifier(static_cast<ResolveNode*>(m_expr)->identifier());
867 else
868 expectedFunction = NoExpectedFunction;
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000869 RefPtr<RegisterID> func = generator.emitNode(m_expr);
oliver@apple.comcf0e6c42013-07-25 04:01:45 +0000870 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
barraclough@apple.com9835d1d2010-06-01 23:13:23 +0000871 CallArguments callArguments(generator, m_args);
fpizlo@apple.com42125692017-05-18 19:55:01 +0000872 return generator.emitConstruct(returnValue.get(), func.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
barraclough@apple.com9835d1d2010-06-01 23:13:23 +0000873}
874
oliver@apple.com72f8a822013-10-17 01:02:34 +0000875CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode, unsigned additionalArguments)
barraclough@apple.com9835d1d2010-06-01 23:13:23 +0000876 : m_argumentsNode(argumentsNode)
fpizlo@apple.come94ae4a2013-11-22 20:18:18 +0000877 , m_padding(0)
barraclough@apple.com9835d1d2010-06-01 23:13:23 +0000878{
oliver@apple.com20a9bf02013-10-04 20:35:24 +0000879 size_t argumentCountIncludingThis = 1 + additionalArguments; // 'this' register.
ggaren@apple.com0af14682011-12-12 00:35:51 +0000880 if (argumentsNode) {
881 for (ArgumentListNode* node = argumentsNode->m_listNode; node; node = node->m_next)
882 ++argumentCountIncludingThis;
883 }
884
885 m_argv.grow(argumentCountIncludingThis);
886 for (int i = argumentCountIncludingThis - 1; i >= 0; --i) {
887 m_argv[i] = generator.newTemporary();
msaboff@apple.comb70e41b2013-09-13 18:03:55 +0000888 ASSERT(static_cast<size_t>(i) == m_argv.size() - 1 || m_argv[i]->index() == m_argv[i + 1]->index() - 1);
ggaren@apple.com0af14682011-12-12 00:35:51 +0000889 }
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000890
891 // We need to ensure that the frame size is stack-aligned
mark.lam@apple.com2bd89342016-07-08 22:58:15 +0000892 while ((CallFrame::headerSizeInRegisters + m_argv.size()) % stackAlignmentRegisters()) {
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000893 m_argv.insert(0, generator.newTemporary());
894 m_padding++;
895 }
fpizlo@apple.come94ae4a2013-11-22 20:18:18 +0000896
897 while (stackOffset() % stackAlignmentRegisters()) {
898 m_argv.insert(0, generator.newTemporary());
899 m_padding++;
900 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000901}
902
903// ------------------------------ EvalFunctionCallNode ----------------------------------
904
905RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
906{
commit-queue@webkit.orgb2610c02015-12-08 20:24:04 +0000907 // We need try to load 'this' before call eval in constructor, because 'this' can created by 'super' in some of the arrow function
908 // var A = class A {
909 // constructor () { this.id = 'A'; }
910 // }
911 //
912 // var B = class B extend A {
913 // constructor () {
914 // var arrow = () => super();
915 // arrow();
916 // eval("this.id = 'B'");
917 // }
918 // }
sbarati@apple.com8a1620b62016-08-03 01:28:16 +0000919 if (generator.constructorKind() == ConstructorKind::Extends && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction())
commit-queue@webkit.orgb2610c02015-12-08 20:24:04 +0000920 generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
921
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000922 Variable var = generator.variable(generator.propertyNames().eval);
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000923 RefPtr<RegisterID> local = var.local();
924 RefPtr<RegisterID> func;
925 if (local) {
926 generator.emitTDZCheckIfNecessary(var, local.get(), nullptr);
927 func = generator.move(generator.tempDestination(dst), local.get());
928 } else
929 func = generator.newTemporary();
930 CallArguments callArguments(generator, m_args);
931
932 if (local)
oliver@apple.com58c86752013-07-25 04:02:40 +0000933 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000934 else {
935 JSTextPosition newDivot = divotStart() + 4;
936 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
937 generator.move(
938 callArguments.thisRegister(),
939 generator.emitResolveScope(callArguments.thisRegister(), var));
940 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
941 generator.emitTDZCheckIfNecessary(var, func.get(), nullptr);
oliver@apple.com58c86752013-07-25 04:02:40 +0000942 }
943
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000944 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
945 if (isOptionalChainBase())
946 generator.emitOptionalCheck(func.get());
947
948 return generator.emitCallEval(returnValue.get(), func.get(), callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::No);
mjs@apple.comaed3cef2009-12-09 01:29:52 +0000949}
950
951// ------------------------------ FunctionCallValueNode ----------------------------------
952
953RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
954{
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000955 if (m_expr->isSuperNode()) {
sbarati@apple.com23315d62016-05-09 20:17:23 +0000956 RefPtr<RegisterID> func = emitGetSuperFunctionForConstruct(generator);
957 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
958 CallArguments callArguments(generator, m_args);
959
commit-queue@webkit.orgefc86f52015-12-30 21:08:16 +0000960 ASSERT(generator.isConstructor() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
sbarati@apple.com8a1620b62016-08-03 01:28:16 +0000961 ASSERT(generator.constructorKind() == ConstructorKind::Extends || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
fpizlo@apple.com42125692017-05-18 19:55:01 +0000962 RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), generator.newTarget(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
gskachkov@gmail.com086f8f62016-04-26 18:40:41 +0000963
sbarati@apple.com8a1620b62016-08-03 01:28:16 +0000964 bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Extends;
gskachkov@gmail.com086f8f62016-04-26 18:40:41 +0000965 bool doWeUseArrowFunctionInConstructor = isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext();
966
967 if (generator.isDerivedConstructorContext() || (doWeUseArrowFunctionInConstructor && generator.isSuperCallUsedInInnerArrowFunction()))
968 generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
969
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +0000970 Ref<Label> thisIsEmptyLabel = generator.newLabel();
gskachkov@gmail.com086f8f62016-04-26 18:40:41 +0000971 generator.emitJumpIfTrue(generator.emitIsEmpty(generator.newTemporary(), generator.thisRegister()), thisIsEmptyLabel.get());
utatane.tea@gmail.com84077632018-06-23 08:39:34 +0000972 generator.emitThrowReferenceError("'super()' can't be called more than once in a constructor."_s);
gskachkov@gmail.com086f8f62016-04-26 18:40:41 +0000973 generator.emitLabel(thisIsEmptyLabel.get());
974
keith_miller@apple.com35210892018-06-01 18:11:36 +0000975 generator.move(generator.thisRegister(), ret);
commit-queue@webkit.orgb2610c02015-12-08 20:24:04 +0000976
gskachkov@gmail.com086f8f62016-04-26 18:40:41 +0000977 if (generator.isDerivedConstructorContext() || doWeUseArrowFunctionInConstructor)
commit-queue@webkit.orgb2610c02015-12-08 20:24:04 +0000978 generator.emitPutThisToArrowFunctionContextScope();
caitp@igalia.comce715b22020-01-16 00:09:50 +0000979
980 // Initialize instance fields after super-call.
ysuzuki@apple.comeb5b9bf2020-03-07 16:09:58 +0000981 if (Options::usePublicClassFields() && generator.needsClassFieldInitializer() == NeedsClassFieldInitializer::Yes) {
caitp@igalia.comce715b22020-01-16 00:09:50 +0000982 ASSERT(generator.isConstructor() || generator.isDerivedConstructorContext());
983 func = generator.emitLoadDerivedConstructor();
984 generator.emitInstanceFieldInitializationIfNeeded(generator.thisRegister(), func.get(), divot(), divotStart(), divotEnd());
985 }
986
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +0000987 return ret;
988 }
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000989
sbarati@apple.com23315d62016-05-09 20:17:23 +0000990 RefPtr<RegisterID> func = generator.emitNode(m_expr);
991 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +0000992 if (isOptionalChainBase())
993 generator.emitOptionalCheck(func.get());
994
sbarati@apple.com23315d62016-05-09 20:17:23 +0000995 CallArguments callArguments(generator, m_args);
oliver@apple.com64126552010-10-18 18:32:39 +0000996 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +0000997 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +0000998 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +0000999 return ret;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001000}
1001
1002// ------------------------------ FunctionCallResolveNode ----------------------------------
1003
1004RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1005{
mark.lam@apple.com65724362020-01-06 22:24:50 +00001006 if (!ASSERT_ENABLED) {
1007 if (UNLIKELY(m_ident == generator.vm().propertyNames->builtinNames().assertPrivateName()))
keith_miller@apple.com35210892018-06-01 18:11:36 +00001008 return generator.move(dst, generator.emitLoad(nullptr, jsUndefined()));
sbarati@apple.come23fa112017-12-29 07:52:24 +00001009 }
1010
fpizlo@apple.com4500e352012-10-17 21:39:11 +00001011 ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
commit-queue@webkit.org2fea7402012-02-01 19:37:00 +00001012
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001013 Variable var = generator.variable(m_ident);
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001014 RefPtr<RegisterID> local = var.local();
1015 RefPtr<RegisterID> func;
1016 if (local) {
1017 generator.emitTDZCheckIfNecessary(var, local.get(), nullptr);
1018 func = generator.move(generator.tempDestination(dst), local.get());
1019 } else
1020 func = generator.newTemporary();
1021 CallArguments callArguments(generator, m_args);
1022
1023 if (local) {
oliver@apple.com64126552010-10-18 18:32:39 +00001024 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
fpizlo@apple.com4500e352012-10-17 21:39:11 +00001025 // This passes NoExpectedFunction because we expect that if the function is in a
1026 // local variable, then it's not one of our built-in constructors.
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001027 expectedFunction = NoExpectedFunction;
1028 } else {
1029 JSTextPosition newDivot = divotStart() + m_ident.length();
1030 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
1031 generator.move(
1032 callArguments.thisRegister(),
1033 generator.emitResolveScope(callArguments.thisRegister(), var));
1034 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
1035 generator.emitTDZCheckIfNecessary(var, func.get(), nullptr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001036 }
1037
oliver@apple.comcf0e6c42013-07-25 04:01:45 +00001038 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001039 if (isOptionalChainBase())
1040 generator.emitOptionalCheck(func.get());
commit-queue@webkit.org2fea7402012-02-01 19:37:00 +00001041
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001042 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00001043 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001044 return ret;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001045}
1046
utatane.tea@gmail.comdefc1662015-04-20 01:45:50 +00001047// ------------------------------ BytecodeIntrinsicNode ----------------------------------
1048
1049RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1050{
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001051 if (m_entry.type() == BytecodeIntrinsicRegistry::Type::Emitter)
1052 return (this->*m_entry.emitter())(generator, dst);
1053 if (dst == generator.ignoredResult())
1054 return nullptr;
1055 return generator.moveLinkTimeConstant(dst, m_entry.linkTimeConstant());
utatane.tea@gmail.comdefc1662015-04-20 01:45:50 +00001056}
1057
utatane.tea@gmail.com0e0c28a2018-04-08 16:21:38 +00001058RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getByIdDirect(BytecodeGenerator& generator, RegisterID* dst)
1059{
1060 ArgumentListNode* node = m_args->m_listNode;
1061 RefPtr<RegisterID> base = generator.emitNode(node);
1062 node = node->m_next;
1063 ASSERT(node->m_expr->isString());
1064 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
1065 ASSERT(!node->m_next);
1066 return generator.emitDirectGetById(generator.finalDestination(dst), base.get(), ident);
1067}
1068
1069RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getByIdDirectPrivate(BytecodeGenerator& generator, RegisterID* dst)
1070{
1071 ArgumentListNode* node = m_args->m_listNode;
1072 RefPtr<RegisterID> base = generator.emitNode(node);
1073 node = node->m_next;
1074 ASSERT(node->m_expr->isString());
ysuzuki@apple.com55953af462020-02-29 08:04:13 +00001075 SymbolImpl* symbol = generator.vm().propertyNames->builtinNames().lookUpPrivateName(static_cast<StringNode*>(node->m_expr)->value());
ysuzuki@apple.com5f133792019-02-06 22:58:00 +00001076 ASSERT(symbol);
utatane.tea@gmail.com0e0c28a2018-04-08 16:21:38 +00001077 ASSERT(!node->m_next);
ysuzuki@apple.com5f133792019-02-06 22:58:00 +00001078 return generator.emitDirectGetById(generator.finalDestination(dst), base.get(), generator.parserArena().identifierArena().makeIdentifier(generator.vm(), symbol));
utatane.tea@gmail.com0e0c28a2018-04-08 16:21:38 +00001079}
1080
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00001081static JSPromise::Field promiseInternalFieldIndex(BytecodeIntrinsicNode* node)
1082{
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001083 ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
1084 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_promiseFieldFlags)
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00001085 return JSPromise::Field::Flags;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001086 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_promiseFieldReactionsOrResult)
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00001087 return JSPromise::Field::ReactionsOrResult;
1088 RELEASE_ASSERT_NOT_REACHED();
1089 return JSPromise::Field::Flags;
1090}
1091
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001092static JSGenerator::Field generatorInternalFieldIndex(BytecodeIntrinsicNode* node)
1093{
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001094 ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
1095 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldState)
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001096 return JSGenerator::Field::State;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001097 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldNext)
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001098 return JSGenerator::Field::Next;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001099 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldThis)
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001100 return JSGenerator::Field::This;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001101 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldFrame)
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001102 return JSGenerator::Field::Frame;
1103 RELEASE_ASSERT_NOT_REACHED();
1104 return JSGenerator::Field::State;
1105}
1106
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001107static JSAsyncGenerator::Field asyncGeneratorInternalFieldIndex(BytecodeIntrinsicNode* node)
1108{
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001109 ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
1110 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldState)
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001111 return JSAsyncGenerator::Field::State;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001112 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldNext)
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001113 return JSAsyncGenerator::Field::Next;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001114 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldThis)
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001115 return JSAsyncGenerator::Field::This;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001116 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldFrame)
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001117 return JSAsyncGenerator::Field::Frame;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001118 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_asyncGeneratorFieldSuspendReason)
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001119 return JSAsyncGenerator::Field::SuspendReason;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001120 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_asyncGeneratorFieldQueueFirst)
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001121 return JSAsyncGenerator::Field::QueueFirst;
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00001122 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_asyncGeneratorFieldQueueLast)
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001123 return JSAsyncGenerator::Field::QueueLast;
1124 RELEASE_ASSERT_NOT_REACHED();
1125 return JSAsyncGenerator::Field::State;
1126}
1127
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001128static JSArrayIterator::Field arrayIteratorInternalFieldIndex(BytecodeIntrinsicNode* node)
1129{
1130 ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
1131 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_arrayIteratorFieldIndex)
1132 return JSArrayIterator::Field::Index;
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001133 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_arrayIteratorFieldIteratedObject)
1134 return JSArrayIterator::Field::IteratedObject;
1135 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_arrayIteratorFieldKind)
1136 return JSArrayIterator::Field::Kind;
1137 RELEASE_ASSERT_NOT_REACHED();
1138 return JSArrayIterator::Field::Index;
1139}
1140
ysuzuki@apple.comf0017752020-01-13 03:12:13 +00001141static JSStringIterator::Field stringIteratorInternalFieldIndex(BytecodeIntrinsicNode* node)
1142{
1143 ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
1144 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_stringIteratorFieldIndex)
1145 return JSStringIterator::Field::Index;
1146 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_stringIteratorFieldIteratedString)
1147 return JSStringIterator::Field::IteratedString;
1148 RELEASE_ASSERT_NOT_REACHED();
1149 return JSStringIterator::Field::Index;
1150}
1151
ysuzuki@apple.come8a2d402020-04-16 13:07:48 +00001152static JSMapIterator::Field mapIteratorInternalFieldIndex(BytecodeIntrinsicNode* node)
1153{
1154 ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
1155 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_mapIteratorFieldMapBucket)
1156 return JSMapIterator::Field::MapBucket;
1157 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_mapIteratorFieldKind)
1158 return JSMapIterator::Field::Kind;
1159 RELEASE_ASSERT_NOT_REACHED();
1160 return JSMapIterator::Field::MapBucket;
1161}
1162
1163static JSSetIterator::Field setIteratorInternalFieldIndex(BytecodeIntrinsicNode* node)
1164{
1165 ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
1166 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_setIteratorFieldSetBucket)
1167 return JSSetIterator::Field::SetBucket;
1168 if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_setIteratorFieldKind)
1169 return JSSetIterator::Field::Kind;
1170 RELEASE_ASSERT_NOT_REACHED();
1171 return JSSetIterator::Field::SetBucket;
1172}
1173
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00001174RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getPromiseInternalField(BytecodeGenerator& generator, RegisterID* dst)
1175{
1176 ArgumentListNode* node = m_args->m_listNode;
1177 RefPtr<RegisterID> base = generator.emitNode(node);
1178 node = node->m_next;
1179 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1180 unsigned index = static_cast<unsigned>(promiseInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1181 ASSERT(index < JSPromise::numberOfInternalFields);
1182 ASSERT(!node->m_next);
1183
ysuzuki@apple.com38026c62019-09-05 21:48:43 +00001184 return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00001185}
1186
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001187RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getGeneratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1188{
1189 ArgumentListNode* node = m_args->m_listNode;
1190 RefPtr<RegisterID> base = generator.emitNode(node);
1191 node = node->m_next;
1192 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1193 unsigned index = static_cast<unsigned>(generatorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1194 ASSERT(index < JSGenerator::numberOfInternalFields);
1195 ASSERT(!node->m_next);
1196
1197 return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
1198}
1199
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001200RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getAsyncGeneratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1201{
1202 ArgumentListNode* node = m_args->m_listNode;
1203 RefPtr<RegisterID> base = generator.emitNode(node);
1204 node = node->m_next;
1205 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1206 unsigned index = static_cast<unsigned>(asyncGeneratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1207 ASSERT(index < JSAsyncGenerator::numberOfInternalFields);
1208 ASSERT(!node->m_next);
1209
1210 return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
1211}
1212
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001213RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getArrayIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1214{
1215 ArgumentListNode* node = m_args->m_listNode;
1216 RefPtr<RegisterID> base = generator.emitNode(node);
1217 node = node->m_next;
1218 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1219 unsigned index = static_cast<unsigned>(arrayIteratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1220 ASSERT(index < JSArrayIterator::numberOfInternalFields);
1221 ASSERT(!node->m_next);
1222
1223 return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
1224}
1225
ysuzuki@apple.comf0017752020-01-13 03:12:13 +00001226RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getStringIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1227{
1228 ArgumentListNode* node = m_args->m_listNode;
1229 RefPtr<RegisterID> base = generator.emitNode(node);
1230 node = node->m_next;
1231 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1232 unsigned index = static_cast<unsigned>(stringIteratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1233 ASSERT(index < JSStringIterator::numberOfInternalFields);
1234 ASSERT(!node->m_next);
1235
1236 return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
1237}
1238
ysuzuki@apple.come8a2d402020-04-16 13:07:48 +00001239RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getMapIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1240{
1241 ArgumentListNode* node = m_args->m_listNode;
1242 RefPtr<RegisterID> base = generator.emitNode(node);
1243 node = node->m_next;
1244 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1245 unsigned index = static_cast<unsigned>(mapIteratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1246 ASSERT(index < JSMapIterator::numberOfInternalFields);
1247 ASSERT(!node->m_next);
1248
1249 return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
1250}
1251
1252RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getSetIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1253{
1254 ArgumentListNode* node = m_args->m_listNode;
1255 RefPtr<RegisterID> base = generator.emitNode(node);
1256 node = node->m_next;
1257 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1258 unsigned index = static_cast<unsigned>(setIteratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1259 ASSERT(index < JSSetIterator::numberOfInternalFields);
1260 ASSERT(!node->m_next);
1261
1262 return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
1263}
1264
utatane.tea@gmail.combebf7852016-11-10 06:34:05 +00001265RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argument(BytecodeGenerator& generator, RegisterID* dst)
1266{
1267 ArgumentListNode* node = m_args->m_listNode;
1268 ASSERT(node->m_expr->isNumber());
1269 double value = static_cast<NumberNode*>(node->m_expr)->value();
1270 int32_t index = static_cast<int32_t>(value);
1271 ASSERT(value == index);
1272 ASSERT(index >= 0);
1273 ASSERT(!node->m_next);
1274
1275 // The body functions of generator and async have different mechanism for arguments.
1276 ASSERT(generator.parseMode() != SourceParseMode::GeneratorBodyMode);
1277 ASSERT(!isAsyncFunctionBodyParseMode(generator.parseMode()));
1278
1279 return generator.emitGetArgument(generator.finalDestination(dst), index);
1280}
1281
keith_miller@apple.com85aeabb2016-06-03 23:06:39 +00001282RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argumentCount(BytecodeGenerator& generator, RegisterID* dst)
1283{
1284 ASSERT(!m_args->m_listNode);
1285
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00001286 return generator.emitArgumentCount(generator.finalDestination(dst));
keith_miller@apple.com85aeabb2016-06-03 23:06:39 +00001287}
1288
utatane.tea@gmail.comadc32b12018-04-10 01:05:40 +00001289RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByIdDirect(BytecodeGenerator& generator, RegisterID* dst)
1290{
1291 ArgumentListNode* node = m_args->m_listNode;
1292 RefPtr<RegisterID> base = generator.emitNode(node);
1293 node = node->m_next;
1294 ASSERT(node->m_expr->isString());
1295 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
1296 node = node->m_next;
1297 RefPtr<RegisterID> value = generator.emitNode(node);
1298
1299 ASSERT(!node->m_next);
1300
keith_miller@apple.com35210892018-06-01 18:11:36 +00001301 return generator.move(dst, generator.emitDirectPutById(base.get(), ident, value.get(), PropertyNode::KnownDirect));
utatane.tea@gmail.comadc32b12018-04-10 01:05:40 +00001302}
1303
1304RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByIdDirectPrivate(BytecodeGenerator& generator, RegisterID* dst)
1305{
1306 ArgumentListNode* node = m_args->m_listNode;
1307 RefPtr<RegisterID> base = generator.emitNode(node);
1308 node = node->m_next;
1309 ASSERT(node->m_expr->isString());
ysuzuki@apple.com55953af462020-02-29 08:04:13 +00001310 SymbolImpl* symbol = generator.vm().propertyNames->builtinNames().lookUpPrivateName(static_cast<StringNode*>(node->m_expr)->value());
ysuzuki@apple.com5f133792019-02-06 22:58:00 +00001311 ASSERT(symbol);
utatane.tea@gmail.comadc32b12018-04-10 01:05:40 +00001312 node = node->m_next;
1313 RefPtr<RegisterID> value = generator.emitNode(node);
1314
1315 ASSERT(!node->m_next);
1316
ysuzuki@apple.com5f133792019-02-06 22:58:00 +00001317 return generator.move(dst, generator.emitDirectPutById(base.get(), generator.parserArena().identifierArena().makeIdentifier(generator.vm(), symbol), value.get(), PropertyNode::KnownDirect));
utatane.tea@gmail.comadc32b12018-04-10 01:05:40 +00001318}
1319
utatane.tea@gmail.comdefc1662015-04-20 01:45:50 +00001320RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst)
1321{
1322 ArgumentListNode* node = m_args->m_listNode;
1323 RefPtr<RegisterID> base = generator.emitNode(node);
1324 node = node->m_next;
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00001325 RefPtr<RegisterID> index = generator.emitNodeForProperty(node);
utatane.tea@gmail.comdefc1662015-04-20 01:45:50 +00001326 node = node->m_next;
1327 RefPtr<RegisterID> value = generator.emitNode(node);
1328
1329 ASSERT(!node->m_next);
1330
keith_miller@apple.com35210892018-06-01 18:11:36 +00001331 return generator.move(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
utatane.tea@gmail.comdefc1662015-04-20 01:45:50 +00001332}
1333
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00001334RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putPromiseInternalField(BytecodeGenerator& generator, RegisterID* dst)
1335{
1336 ArgumentListNode* node = m_args->m_listNode;
1337 RefPtr<RegisterID> base = generator.emitNode(node);
1338 node = node->m_next;
1339 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1340 unsigned index = static_cast<unsigned>(promiseInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1341 ASSERT(index < JSPromise::numberOfInternalFields);
1342 node = node->m_next;
1343 RefPtr<RegisterID> value = generator.emitNode(node);
1344
1345 ASSERT(!node->m_next);
1346
ysuzuki@apple.com38026c62019-09-05 21:48:43 +00001347 return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00001348}
1349
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001350RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putGeneratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1351{
1352 ArgumentListNode* node = m_args->m_listNode;
1353 RefPtr<RegisterID> base = generator.emitNode(node);
1354 node = node->m_next;
1355 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1356 unsigned index = static_cast<unsigned>(generatorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1357 ASSERT(index < JSGenerator::numberOfInternalFields);
1358 node = node->m_next;
1359 RefPtr<RegisterID> value = generator.emitNode(node);
1360
1361 ASSERT(!node->m_next);
1362
1363 return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
1364}
1365
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001366RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putAsyncGeneratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1367{
1368 ArgumentListNode* node = m_args->m_listNode;
1369 RefPtr<RegisterID> base = generator.emitNode(node);
1370 node = node->m_next;
1371 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1372 unsigned index = static_cast<unsigned>(asyncGeneratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1373 ASSERT(index < JSAsyncGenerator::numberOfInternalFields);
1374 node = node->m_next;
1375 RefPtr<RegisterID> value = generator.emitNode(node);
1376
1377 ASSERT(!node->m_next);
1378
1379 return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
1380}
1381
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001382RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putArrayIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1383{
1384 ArgumentListNode* node = m_args->m_listNode;
1385 RefPtr<RegisterID> base = generator.emitNode(node);
1386 node = node->m_next;
1387 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1388 unsigned index = static_cast<unsigned>(arrayIteratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1389 ASSERT(index < JSArrayIterator::numberOfInternalFields);
1390 node = node->m_next;
1391 RefPtr<RegisterID> value = generator.emitNode(node);
1392
1393 ASSERT(!node->m_next);
1394
1395 return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
1396}
1397
ysuzuki@apple.comf0017752020-01-13 03:12:13 +00001398RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putStringIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1399{
1400 ArgumentListNode* node = m_args->m_listNode;
1401 RefPtr<RegisterID> base = generator.emitNode(node);
1402 node = node->m_next;
1403 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1404 unsigned index = static_cast<unsigned>(stringIteratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1405 ASSERT(index < JSStringIterator::numberOfInternalFields);
1406 node = node->m_next;
1407 RefPtr<RegisterID> value = generator.emitNode(node);
1408
1409 ASSERT(!node->m_next);
1410
1411 return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
1412}
1413
ysuzuki@apple.come8a2d402020-04-16 13:07:48 +00001414RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putMapIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1415{
1416 ArgumentListNode* node = m_args->m_listNode;
1417 RefPtr<RegisterID> base = generator.emitNode(node);
1418 node = node->m_next;
1419 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1420 unsigned index = static_cast<unsigned>(mapIteratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1421 ASSERT(index < JSMapIterator::numberOfInternalFields);
1422 node = node->m_next;
1423 RefPtr<RegisterID> value = generator.emitNode(node);
1424
1425 ASSERT(!node->m_next);
1426
1427 return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
1428}
1429
1430RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putSetIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
1431{
1432 ArgumentListNode* node = m_args->m_listNode;
1433 RefPtr<RegisterID> base = generator.emitNode(node);
1434 node = node->m_next;
1435 RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
1436 unsigned index = static_cast<unsigned>(setIteratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
1437 ASSERT(index < JSSetIterator::numberOfInternalFields);
1438 node = node->m_next;
1439 RefPtr<RegisterID> value = generator.emitNode(node);
1440
1441 ASSERT(!node->m_next);
1442
1443 return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
1444}
1445
keith_miller@apple.come497e202016-06-13 21:05:36 +00001446RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tailCallForwardArguments(BytecodeGenerator& generator, RegisterID* dst)
1447{
1448 ArgumentListNode* node = m_args->m_listNode;
1449 RefPtr<RegisterID> function = generator.emitNode(node);
1450 node = node->m_next;
1451 RefPtr<RegisterID> thisRegister = generator.emitNode(node);
1452 ASSERT(!node->m_next);
1453
1454 RefPtr<RegisterID> finalDst = generator.finalDestination(dst);
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001455 return generator.emitCallForwardArgumentsInTailPosition(finalDst.get(), function.get(), thisRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd(), DebuggableCall::No);
keith_miller@apple.come497e202016-06-13 21:05:36 +00001456}
1457
utatane.tea@gmail.com0eb0f832016-10-06 07:44:23 +00001458RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwTypeError(BytecodeGenerator& generator, RegisterID* dst)
1459{
1460 ArgumentListNode* node = m_args->m_listNode;
utatane.tea@gmail.com0eb0f832016-10-06 07:44:23 +00001461 ASSERT(!node->m_next);
utatane.tea@gmail.comb756d92b2016-10-06 17:59:33 +00001462 if (node->m_expr->isString()) {
1463 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
1464 generator.emitThrowTypeError(ident);
1465 } else {
1466 RefPtr<RegisterID> message = generator.emitNode(node);
1467 generator.emitThrowStaticError(ErrorType::TypeError, message.get());
1468 }
utatane.tea@gmail.com0eb0f832016-10-06 07:44:23 +00001469 return dst;
1470}
1471
1472RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwRangeError(BytecodeGenerator& generator, RegisterID* dst)
1473{
1474 ArgumentListNode* node = m_args->m_listNode;
utatane.tea@gmail.com0eb0f832016-10-06 07:44:23 +00001475 ASSERT(!node->m_next);
utatane.tea@gmail.comb756d92b2016-10-06 17:59:33 +00001476 if (node->m_expr->isString()) {
1477 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
1478 generator.emitThrowRangeError(ident);
1479 } else {
1480 RefPtr<RegisterID> message = generator.emitNode(node);
1481 generator.emitThrowStaticError(ErrorType::RangeError, message.get());
1482 }
utatane.tea@gmail.com0eb0f832016-10-06 07:44:23 +00001483
utatane.tea@gmail.com0eb0f832016-10-06 07:44:23 +00001484 return dst;
1485}
1486
1487RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwOutOfMemoryError(BytecodeGenerator& generator, RegisterID* dst)
1488{
1489 ASSERT(!m_args->m_listNode);
1490
1491 generator.emitThrowOutOfMemoryError();
1492 return dst;
1493}
1494
keith_miller@apple.com8844d302016-04-07 19:38:00 +00001495RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tryGetById(BytecodeGenerator& generator, RegisterID* dst)
1496{
1497 ArgumentListNode* node = m_args->m_listNode;
1498 RefPtr<RegisterID> base = generator.emitNode(node);
1499 node = node->m_next;
1500
ross.kirsling@sony.com4b953952020-03-25 02:07:38 +00001501 ASSERT(node->m_expr->isString());
1502 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
keith_miller@apple.com8844d302016-04-07 19:38:00 +00001503 ASSERT(!node->m_next);
1504
keith_miller@apple.come497e202016-06-13 21:05:36 +00001505 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
1506 return generator.emitTryGetById(finalDest.get(), base.get(), ident);
keith_miller@apple.com8844d302016-04-07 19:38:00 +00001507}
1508
ross.kirsling@sony.com4b953952020-03-25 02:07:38 +00001509RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tryGetByIdWithWellKnownSymbol(BytecodeGenerator& generator, RegisterID* dst)
1510{
1511 ArgumentListNode* node = m_args->m_listNode;
1512 RefPtr<RegisterID> base = generator.emitNode(node);
1513 node = node->m_next;
1514
1515 ASSERT(node->m_expr->isString());
1516 SymbolImpl* symbol = generator.vm().propertyNames->builtinNames().lookUpWellKnownSymbol(static_cast<StringNode*>(node->m_expr)->value());
1517 RELEASE_ASSERT(symbol);
1518 ASSERT(!node->m_next);
1519
1520 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
1521 return generator.emitTryGetById(finalDest.get(), base.get(), generator.parserArena().identifierArena().makeIdentifier(generator.vm(), symbol));
1522}
1523
utatane.tea@gmail.comdb32c542016-06-30 15:26:47 +00001524RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toNumber(BytecodeGenerator& generator, RegisterID* dst)
1525{
1526 ArgumentListNode* node = m_args->m_listNode;
1527 RefPtr<RegisterID> src = generator.emitNode(node);
1528 ASSERT(!node->m_next);
1529
keith_miller@apple.com35210892018-06-01 18:11:36 +00001530 return generator.move(dst, generator.emitToNumber(generator.tempDestination(dst), src.get()));
utatane.tea@gmail.comdb32c542016-06-30 15:26:47 +00001531}
1532
utatane.tea@gmail.com965344f2015-05-13 16:48:33 +00001533RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
1534{
1535 ArgumentListNode* node = m_args->m_listNode;
1536 RefPtr<RegisterID> src = generator.emitNode(node);
1537 ASSERT(!node->m_next);
1538
keith_miller@apple.com35210892018-06-01 18:11:36 +00001539 return generator.move(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
utatane.tea@gmail.com965344f2015-05-13 16:48:33 +00001540}
keith_miller@apple.com591a67d2017-08-15 04:18:56 +00001541
utatane.tea@gmail.com076aa232017-11-01 17:32:08 +00001542RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toObject(BytecodeGenerator& generator, RegisterID* dst)
1543{
1544 ArgumentListNode* node = m_args->m_listNode;
1545 RefPtr<RegisterID> src = generator.emitNode(node);
1546 node = node->m_next;
1547
1548 RefPtr<RegisterID> temp = generator.tempDestination(dst);
1549 if (node) {
1550 ASSERT(node->m_expr->isString());
1551 const Identifier& message = static_cast<StringNode*>(node->m_expr)->value();
1552 ASSERT(!node->m_next);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001553 return generator.move(dst, generator.emitToObject(temp.get(), src.get(), message));
utatane.tea@gmail.com076aa232017-11-01 17:32:08 +00001554 }
mark.lam@apple.com5ba07792019-08-27 22:14:52 +00001555 return generator.move(dst, generator.emitToObject(temp.get(), src.get(), generator.vm().propertyNames->emptyIdentifier));
utatane.tea@gmail.com076aa232017-11-01 17:32:08 +00001556}
1557
keith_miller@apple.com591a67d2017-08-15 04:18:56 +00001558RegisterID* BytecodeIntrinsicNode::emit_intrinsic_idWithProfile(BytecodeGenerator& generator, RegisterID* dst)
1559{
keith_miller@apple.com591a67d2017-08-15 04:18:56 +00001560 ArgumentListNode* node = m_args->m_listNode;
sbarati@apple.com756d3072017-09-15 23:27:56 +00001561 RefPtr<RegisterID> idValue = generator.newTemporary();
1562 generator.emitNode(idValue.get(), node);
keith_miller@apple.com591a67d2017-08-15 04:18:56 +00001563 SpeculatedType speculation = SpecNone;
1564 while (node->m_next) {
1565 node = node->m_next;
1566 ASSERT(node->m_expr->isString());
1567 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
1568 speculation |= speculationFromString(ident.utf8().data());
1569 }
1570
keith_miller@apple.com35210892018-06-01 18:11:36 +00001571 return generator.move(dst, generator.emitIdWithProfile(idValue.get(), speculation));
keith_miller@apple.com591a67d2017-08-15 04:18:56 +00001572}
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001573
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001574#define CREATE_INTRINSIC_FOR_BRAND_CHECK(lowerName, upperName) \
1575 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_##lowerName(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst) \
1576 { \
1577 ArgumentListNode* node = m_args->m_listNode; \
1578 RefPtr<RegisterID> src = generator.emitNode(node); \
1579 ASSERT(!node->m_next); \
1580 return generator.move(dst, generator.emit##upperName(generator.tempDestination(dst), src.get())); \
1581 }
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00001582
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001583CREATE_INTRINSIC_FOR_BRAND_CHECK(isObject, IsObject)
shvaikalesh@gmail.com087fc322020-05-13 06:41:34 +00001584CREATE_INTRINSIC_FOR_BRAND_CHECK(isConstructor, IsConstructor)
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001585CREATE_INTRINSIC_FOR_BRAND_CHECK(isJSArray, IsJSArray)
1586CREATE_INTRINSIC_FOR_BRAND_CHECK(isProxyObject, IsProxyObject)
1587CREATE_INTRINSIC_FOR_BRAND_CHECK(isDerivedArray, IsDerivedArray)
1588CREATE_INTRINSIC_FOR_BRAND_CHECK(isGenerator, IsGenerator)
1589CREATE_INTRINSIC_FOR_BRAND_CHECK(isAsyncGenerator, IsAsyncGenerator)
1590CREATE_INTRINSIC_FOR_BRAND_CHECK(isPromise, IsPromise)
1591CREATE_INTRINSIC_FOR_BRAND_CHECK(isRegExpObject, IsRegExpObject)
1592CREATE_INTRINSIC_FOR_BRAND_CHECK(isMap, IsMap)
1593CREATE_INTRINSIC_FOR_BRAND_CHECK(isSet, IsSet)
ysuzuki@apple.comf0017752020-01-13 03:12:13 +00001594CREATE_INTRINSIC_FOR_BRAND_CHECK(isStringIterator, IsStringIterator)
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001595CREATE_INTRINSIC_FOR_BRAND_CHECK(isArrayIterator, IsArrayIterator)
ysuzuki@apple.come8a2d402020-04-16 13:07:48 +00001596CREATE_INTRINSIC_FOR_BRAND_CHECK(isMapIterator, IsMapIterator)
1597CREATE_INTRINSIC_FOR_BRAND_CHECK(isSetIterator, IsSetIterator)
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001598CREATE_INTRINSIC_FOR_BRAND_CHECK(isUndefinedOrNull, IsUndefinedOrNull)
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00001599
keith_miller@apple.com0ac4b9d2020-01-09 06:07:29 +00001600#undef CREATE_INTRINSIC_FOR_BRAND_CHECK
yusukesuzuki@slowstart.orgc52e54d2019-01-09 02:56:15 +00001601
sbarati@apple.com3cc67a72016-08-18 17:17:41 +00001602RegisterID* BytecodeIntrinsicNode::emit_intrinsic_newArrayWithSize(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1603{
1604 ArgumentListNode* node = m_args->m_listNode;
1605 RefPtr<RegisterID> size = generator.emitNode(node);
1606 ASSERT(!node->m_next);
1607
1608 RefPtr<RegisterID> finalDestination = generator.finalDestination(dst);
1609 generator.emitNewArrayWithSize(finalDestination.get(), size.get());
1610 return finalDestination.get();
1611}
1612
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00001613RegisterID* BytecodeIntrinsicNode::emit_intrinsic_createPromise(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1614{
1615 ArgumentListNode* node = m_args->m_listNode;
1616 RefPtr<RegisterID> newTarget = generator.emitNode(node);
1617 node = node->m_next;
1618 bool isInternalPromise = static_cast<BooleanNode*>(node->m_expr)->value();
1619 ASSERT(!node->m_next);
1620
1621 return generator.emitCreatePromise(generator.finalDestination(dst), newTarget.get(), isInternalPromise);
1622}
1623
1624RegisterID* BytecodeIntrinsicNode::emit_intrinsic_newPromise(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1625{
1626 ASSERT(!m_args->m_listNode);
1627 RefPtr<RegisterID> finalDestination = generator.finalDestination(dst);
1628 bool isInternalPromise = false;
1629 generator.emitNewPromise(finalDestination.get(), isInternalPromise);
1630 return finalDestination.get();
1631}
1632
ysuzuki@apple.com88da11f2019-12-22 03:12:00 +00001633RegisterID* BytecodeIntrinsicNode::emit_intrinsic_createArgumentsButterfly(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1634{
1635 ASSERT(!m_args->m_listNode);
1636 return generator.emitCreateArgumentsButterfly(generator.finalDestination(dst));
1637}
1638
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00001639RegisterID* BytecodeIntrinsicNode::emit_intrinsic_defineEnumerableWritableConfigurableDataProperty(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
1640{
1641 ArgumentListNode* node = m_args->m_listNode;
1642 RefPtr<RegisterID> newObj = generator.emitNode(node);
1643 node = node->m_next;
1644 RefPtr<RegisterID> propertyNameRegister = generator.emitNode(node);
1645 node = node->m_next;
1646 RefPtr<RegisterID> value = generator.emitNode(node);
1647 ASSERT(!node->m_next);
1648
1649 generator.emitCallDefineProperty(newObj.get(), propertyNameRegister.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable | BytecodeGenerator::PropertyEnumerable, m_position);
1650 return dst;
1651}
utatane.tea@gmail.combf8978b2016-02-02 19:33:05 +00001652
1653#define JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS(name) \
1654 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_##name(BytecodeGenerator& generator, RegisterID* dst) \
1655 { \
1656 ASSERT(!m_args); \
1657 ASSERT(type() == Type::Constant); \
1658 if (dst == generator.ignoredResult()) \
1659 return nullptr; \
mark.lam@apple.com5ba07792019-08-27 22:14:52 +00001660 return generator.emitLoad(dst, generator.vm().bytecodeIntrinsicRegistry().name##Value(generator)); \
utatane.tea@gmail.combf8978b2016-02-02 19:33:05 +00001661 }
1662 JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS)
1663#undef JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS
1664
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001665// ------------------------------ FunctionCallBracketNode ----------------------------------
1666
1667RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1668{
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001669 RefPtr<RegisterID> function = generator.tempDestination(dst);
1670 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00001671 bool baseIsSuper = m_base->isSuperNode();
utatane.tea@gmail.com109ad312015-12-14 02:52:51 +00001672 bool subscriptIsNonIndexString = isNonIndexStringElement(*m_subscript);
utatane.tea@gmail.comc85b06f2015-05-07 22:35:56 +00001673
1674 RefPtr<RegisterID> base;
1675 if (baseIsSuper)
1676 base = emitSuperBaseForCallee(generator);
1677 else {
utatane.tea@gmail.com109ad312015-12-14 02:52:51 +00001678 if (subscriptIsNonIndexString)
utatane.tea@gmail.comc85b06f2015-05-07 22:35:56 +00001679 base = generator.emitNode(m_base);
1680 else
1681 base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001682
1683 if (m_base->isOptionalChainBase())
1684 generator.emitOptionalCheck(base.get());
utatane.tea@gmail.comc85b06f2015-05-07 22:35:56 +00001685 }
1686
sbarati@apple.com23315d62016-05-09 20:17:23 +00001687 RefPtr<RegisterID> thisRegister;
1688 if (baseIsSuper) {
1689 // Note that we only need to do this once because we either have a non-TDZ this or we throw. Once we have a non-TDZ this, we can't change its value back to TDZ.
1690 thisRegister = generator.ensureThis();
1691 }
utatane.tea@gmail.com109ad312015-12-14 02:52:51 +00001692 if (subscriptIsNonIndexString) {
utatane.tea@gmail.comc85b06f2015-05-07 22:35:56 +00001693 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00001694 if (baseIsSuper)
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001695 generator.emitGetById(function.get(), base.get(), thisRegister.get(), static_cast<StringNode*>(m_subscript)->value());
sbarati@apple.com23315d62016-05-09 20:17:23 +00001696 else
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001697 generator.emitGetById(function.get(), base.get(), static_cast<StringNode*>(m_subscript)->value());
utatane.tea@gmail.comc85b06f2015-05-07 22:35:56 +00001698 } else {
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00001699 RefPtr<RegisterID> property = generator.emitNodeForProperty(m_subscript);
utatane.tea@gmail.comc85b06f2015-05-07 22:35:56 +00001700 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00001701 if (baseIsSuper)
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001702 generator.emitGetByVal(function.get(), base.get(), thisRegister.get(), property.get());
sbarati@apple.com23315d62016-05-09 20:17:23 +00001703 else
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001704 generator.emitGetByVal(function.get(), base.get(), property.get());
utatane.tea@gmail.comc85b06f2015-05-07 22:35:56 +00001705 }
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001706 if (isOptionalChainBase())
1707 generator.emitOptionalCheck(function.get());
utatane.tea@gmail.comc85b06f2015-05-07 22:35:56 +00001708
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001709 CallArguments callArguments(generator, m_args);
gskachkov@gmail.comc307ee42016-04-28 15:12:10 +00001710 if (baseIsSuper) {
1711 generator.emitTDZCheck(generator.thisRegister());
keith_miller@apple.com35210892018-06-01 18:11:36 +00001712 generator.move(callArguments.thisRegister(), thisRegister.get());
gskachkov@gmail.comc307ee42016-04-28 15:12:10 +00001713 } else
keith_miller@apple.com35210892018-06-01 18:11:36 +00001714 generator.move(callArguments.thisRegister(), base.get());
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001715 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00001716 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001717 return ret;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001718}
1719
1720// ------------------------------ FunctionCallDotNode ----------------------------------
1721
1722RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1723{
1724 RefPtr<RegisterID> function = generator.tempDestination(dst);
oliver@apple.comcf0e6c42013-07-25 04:01:45 +00001725 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001726 CallArguments callArguments(generator, m_args);
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00001727 bool baseIsSuper = m_base->isSuperNode();
sbarati@apple.com23315d62016-05-09 20:17:23 +00001728 if (baseIsSuper)
keith_miller@apple.com35210892018-06-01 18:11:36 +00001729 generator.move(callArguments.thisRegister(), generator.ensureThis());
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001730 else {
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00001731 generator.emitNode(callArguments.thisRegister(), m_base);
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001732 if (m_base->isOptionalChainBase())
1733 generator.emitOptionalCheck(callArguments.thisRegister());
1734 }
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00001735 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00001736 if (baseIsSuper) {
1737 RefPtr<RegisterID> superBase = emitSuperBaseForCallee(generator);
1738 generator.emitGetById(function.get(), superBase.get(), callArguments.thisRegister(), m_ident);
1739 } else
1740 generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001741
1742 if (isOptionalChainBase())
1743 generator.emitOptionalCheck(function.get());
1744
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001745 RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00001746 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001747 return ret;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001748}
1749
sbarati@apple.com4ddd2ec2017-05-04 12:20:59 +00001750static constexpr size_t maxDistanceToInnermostCallOrApply = 2;
sbarati@apple.com07f9fa92017-04-18 19:02:01 +00001751
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001752RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1753{
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001754 RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001755 RefPtr<RegisterID> base = generator.emitNode(m_base);
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001756
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001757 if (m_base->isOptionalChainBase())
1758 generator.emitOptionalCheck(base.get());
1759
1760 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1761
1762 RefPtr<RegisterID> function;
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001763 auto makeFunction = [&] {
sbarati@apple.com23315d62016-05-09 20:17:23 +00001764 if (m_base->isSuperNode()) {
1765 RefPtr<RegisterID> thisValue = generator.ensureThis();
1766 function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), generator.propertyNames().builtinNames().callPublicName());
1767 } else
1768 function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().callPublicName());
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001769
1770 if (isOptionalChainBase())
1771 generator.emitOptionalCheck(function.get());
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001772 };
1773
1774 bool emitCallCheck = !generator.isBuiltinFunction();
sbarati@apple.com07f9fa92017-04-18 19:02:01 +00001775 if (m_distanceToInnermostCallOrApply > maxDistanceToInnermostCallOrApply && emitCallCheck) {
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001776 makeFunction();
1777 CallArguments callArguments(generator, m_args);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001778 generator.move(callArguments.thisRegister(), base.get());
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001779 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001780 generator.move(dst, returnValue.get());
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001781 return returnValue.get();
1782 }
1783
1784 Ref<Label> realCall = generator.newLabel();
1785 Ref<Label> end = generator.newLabel();
1786
1787 if (emitCallCheck) {
1788 makeFunction();
oliver@apple.comba848d12014-02-12 17:14:23 +00001789 generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
oliver@apple.com2f5c83b2014-02-25 06:59:38 +00001790 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001791 {
oliver@apple.com2f5c83b2014-02-25 06:59:38 +00001792 if (m_args->m_listNode && m_args->m_listNode->m_expr && m_args->m_listNode->m_expr->isSpreadExpression()) {
oliver@apple.com2f5c83b2014-02-25 06:59:38 +00001793 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
1794 ExpressionNode* subject = spread->expression();
oliver@apple.com2f5c83b2014-02-25 06:59:38 +00001795 RefPtr<RegisterID> argumentsRegister;
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001796 argumentsRegister = generator.emitNode(subject);
1797 generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00001798 RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(nullptr, jsNumber(0)));
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001799 generator.emitCallVarargsInTailPosition(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
oliver@apple.com2f5c83b2014-02-25 06:59:38 +00001800 } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001801 ArgumentListNode* oldList = m_args->m_listNode;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001802 m_args->m_listNode = m_args->m_listNode->m_next;
oliver@apple.comd04e0a02014-02-01 01:37:59 +00001803
keith_miller@apple.com35210892018-06-01 18:11:36 +00001804 RefPtr<RegisterID> realFunction = generator.move(generator.tempDestination(dst), base.get());
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001805 CallArguments callArguments(generator, m_args);
1806 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001807 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001808 m_args->m_listNode = oldList;
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001809 } else {
keith_miller@apple.com35210892018-06-01 18:11:36 +00001810 RefPtr<RegisterID> realFunction = generator.move(generator.tempDestination(dst), base.get());
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001811 CallArguments callArguments(generator, m_args);
oliver@apple.com64126552010-10-18 18:32:39 +00001812 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001813 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001814 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001815 }
oliver@apple.comba848d12014-02-12 17:14:23 +00001816 if (emitCallCheck) {
1817 generator.emitJump(end.get());
1818 generator.emitLabel(realCall.get());
1819 {
1820 CallArguments callArguments(generator, m_args);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001821 generator.move(callArguments.thisRegister(), base.get());
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001822 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
oliver@apple.comba848d12014-02-12 17:14:23 +00001823 }
1824 generator.emitLabel(end.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001825 }
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00001826 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
oliver@apple.comcf0e6c42013-07-25 04:01:45 +00001827 return returnValue.get();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001828}
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001829
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001830static bool areTrivialApplyArguments(ArgumentsNode* args)
1831{
1832 return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
1833 || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
1834}
1835
1836RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1837{
1838 // A few simple cases can be trivially handled as ordinary function calls.
1839 // function.apply(), function.apply(arg) -> identical to function.call
1840 // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
1841 bool mayBeCall = areTrivialApplyArguments(m_args);
1842
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001843 RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001844 RefPtr<RegisterID> base = generator.emitNode(m_base);
1845
1846 if (m_base->isOptionalChainBase())
1847 generator.emitOptionalCheck(base.get());
1848
1849 RefPtr<RegisterID> function;
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001850 auto makeFunction = [&] {
sbarati@apple.com23315d62016-05-09 20:17:23 +00001851 if (m_base->isSuperNode()) {
1852 RefPtr<RegisterID> thisValue = generator.ensureThis();
1853 function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), generator.propertyNames().builtinNames().applyPublicName());
1854 } else
1855 function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().applyPublicName());
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00001856
1857 if (isOptionalChainBase())
1858 generator.emitOptionalCheck(function.get());
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001859 };
1860
1861 bool emitCallCheck = !generator.isBuiltinFunction();
sbarati@apple.com07f9fa92017-04-18 19:02:01 +00001862 if (m_distanceToInnermostCallOrApply > maxDistanceToInnermostCallOrApply && emitCallCheck) {
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001863 makeFunction();
1864 CallArguments callArguments(generator, m_args);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001865 generator.move(callArguments.thisRegister(), base.get());
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001866 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001867 generator.move(dst, returnValue.get());
sbarati@apple.com3e433d82017-04-18 06:43:54 +00001868 return returnValue.get();
1869 }
1870
1871 Ref<Label> realCall = generator.newLabel();
1872 Ref<Label> end = generator.newLabel();
1873 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1874 if (emitCallCheck) {
1875 makeFunction();
mark.lam@apple.com95eb1cb2018-10-17 23:56:56 +00001876 ASSERT(!m_base->isResolveNode() || static_cast<ResolveNode*>(m_base)->identifier() != "Reflect");
oliver@apple.comba848d12014-02-12 17:14:23 +00001877 generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
1878 }
1879 if (mayBeCall) {
1880 if (m_args->m_listNode && m_args->m_listNode->m_expr) {
1881 ArgumentListNode* oldList = m_args->m_listNode;
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001882 if (m_args->m_listNode->m_expr->isSpreadExpression()) {
1883 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001884 RefPtr<RegisterID> realFunction = generator.move(generator.newTemporary(), base.get());
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001885 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(0));
1886 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1887 RefPtr<RegisterID> argumentsRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1888
utatane.tea@gmail.comb67c9082018-07-21 13:10:43 +00001889 auto extractor = scopedLambda<void(BytecodeGenerator&, RegisterID*)>([&thisRegister, &argumentsRegister, &index](BytecodeGenerator& generator, RegisterID* value)
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001890 {
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00001891 Ref<Label> haveThis = generator.newLabel();
1892 Ref<Label> end = generator.newLabel();
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001893 RefPtr<RegisterID> compareResult = generator.newTemporary();
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00001894 RefPtr<RegisterID> indexZeroCompareResult = generator.emitBinaryOp<OpEq>(compareResult.get(), index.get(), generator.emitLoad(nullptr, jsNumber(0)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001895 generator.emitJumpIfFalse(indexZeroCompareResult.get(), haveThis.get());
keith_miller@apple.com35210892018-06-01 18:11:36 +00001896 generator.move(thisRegister.get(), value);
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001897 generator.emitLoad(index.get(), jsNumber(1));
1898 generator.emitJump(end.get());
1899 generator.emitLabel(haveThis.get());
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00001900 RefPtr<RegisterID> indexOneCompareResult = generator.emitBinaryOp<OpEq>(compareResult.get(), index.get(), generator.emitLoad(nullptr, jsNumber(1)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001901 generator.emitJumpIfFalse(indexOneCompareResult.get(), end.get());
keith_miller@apple.com35210892018-06-01 18:11:36 +00001902 generator.move(argumentsRegister.get(), value);
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001903 generator.emitLoad(index.get(), jsNumber(2));
1904 generator.emitLabel(end.get());
utatane.tea@gmail.comb67c9082018-07-21 13:10:43 +00001905 });
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001906 generator.emitEnumeration(this, spread->expression(), extractor);
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001907 generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
oliver@apple.com0989d9b2014-02-26 20:40:46 +00001908 } else if (m_args->m_listNode->m_next) {
oliver@apple.comba848d12014-02-12 17:14:23 +00001909 ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
1910 ASSERT(!m_args->m_listNode->m_next->m_next);
ggaren@apple.comc0ccae02014-12-03 23:23:56 +00001911 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.parserArena(), 0, 0);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001912 RefPtr<RegisterID> realFunction = generator.move(generator.tempDestination(dst), base.get());
oliver@apple.comfca9a922014-01-31 21:34:38 +00001913 CallArguments callArguments(generator, m_args);
oliver@apple.comba848d12014-02-12 17:14:23 +00001914 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001915 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
oliver@apple.comba848d12014-02-12 17:14:23 +00001916 } else {
1917 m_args->m_listNode = m_args->m_listNode->m_next;
keith_miller@apple.com35210892018-06-01 18:11:36 +00001918 RefPtr<RegisterID> realFunction = generator.move(generator.tempDestination(dst), base.get());
oliver@apple.comba848d12014-02-12 17:14:23 +00001919 CallArguments callArguments(generator, m_args);
1920 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001921 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001922 }
oliver@apple.comba848d12014-02-12 17:14:23 +00001923 m_args->m_listNode = oldList;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001924 } else {
keith_miller@apple.com35210892018-06-01 18:11:36 +00001925 RefPtr<RegisterID> realFunction = generator.move(generator.tempDestination(dst), base.get());
oliver@apple.comba848d12014-02-12 17:14:23 +00001926 CallArguments callArguments(generator, m_args);
1927 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001928 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001929 }
oliver@apple.comba848d12014-02-12 17:14:23 +00001930 } else {
1931 ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001932 RefPtr<RegisterID> realFunction = generator.move(generator.tempDestination(dst), base.get());
oliver@apple.comba848d12014-02-12 17:14:23 +00001933 RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
1934 RefPtr<RegisterID> argsRegister;
1935 ArgumentListNode* args = m_args->m_listNode->m_next;
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001936 argsRegister = generator.emitNode(args->m_expr);
oliver@apple.comba848d12014-02-12 17:14:23 +00001937
1938 // Function.prototype.apply ignores extra arguments, but we still
1939 // need to evaluate them for side effects.
1940 while ((args = args->m_next))
1941 generator.emitNode(args->m_expr);
1942
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001943 generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
oliver@apple.comd04e0a02014-02-01 01:37:59 +00001944 }
oliver@apple.comba848d12014-02-12 17:14:23 +00001945 if (emitCallCheck) {
1946 generator.emitJump(end.get());
1947 generator.emitLabel(realCall.get());
barraclough@apple.com9835d1d2010-06-01 23:13:23 +00001948 CallArguments callArguments(generator, m_args);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001949 generator.move(callArguments.thisRegister(), base.get());
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00001950 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes);
oliver@apple.comba848d12014-02-12 17:14:23 +00001951 generator.emitLabel(end.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001952 }
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00001953 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
oliver@apple.comcf0e6c42013-07-25 04:01:45 +00001954 return returnValue.get();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001955}
1956
barraclough@apple.comff7867a2012-09-05 23:00:29 +00001957// ------------------------------ PostfixNode ----------------------------------
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001958
ggaren@apple.comf3036112013-04-27 23:14:04 +00001959static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001960{
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00001961 return (oper == Operator::PlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001962}
1963
1964static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
1965{
ggaren@apple.comf3036112013-04-27 23:14:04 +00001966 if (dst == srcDst)
rmorisset@apple.comec9d9322019-11-20 03:41:57 +00001967 return generator.emitToNumeric(generator.finalDestination(dst), srcDst);
1968 RefPtr<RegisterID> tmp = generator.emitToNumeric(generator.newTemporary(), srcDst);
rmorisset@apple.com96f91982019-10-21 19:06:48 +00001969 RefPtr<RegisterID> result = generator.tempDestination(srcDst);
1970 generator.move(result.get(), tmp.get());
1971 emitIncOrDec(generator, result.get(), oper);
1972 generator.move(srcDst, result.get());
keith_miller@apple.com35210892018-06-01 18:11:36 +00001973 return generator.move(dst, tmp.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001974}
1975
barraclough@apple.comff7867a2012-09-05 23:00:29 +00001976RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001977{
ggaren@apple.com20c0b6c2013-04-04 18:31:37 +00001978 if (dst == generator.ignoredResult())
1979 return PrefixNode::emitResolve(generator, dst);
1980
barraclough@apple.comff7867a2012-09-05 23:00:29 +00001981 ASSERT(m_expr->isResolveNode());
1982 ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1983 const Identifier& ident = resolve->identifier();
1984
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001985 Variable var = generator.variable(ident);
1986 if (RegisterID* local = var.local()) {
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00001987 generator.emitTDZCheckIfNecessary(var, local, nullptr);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001988 RefPtr<RegisterID> localReg = local;
1989 if (var.isReadOnly()) {
saambarati1@gmail.come4556722015-07-19 16:57:44 +00001990 generator.emitReadOnlyExceptionIfNeeded(var);
keith_miller@apple.com35210892018-06-01 18:11:36 +00001991 localReg = generator.move(generator.tempDestination(dst), local);
fpizlo@apple.com0309686b2013-12-02 19:49:43 +00001992 }
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00001993 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
1994 generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1995 return oldValue.get();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00001996 }
oliver@apple.com75f804e2013-03-07 00:25:20 +00001997
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00001998 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001999 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2000 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002001 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
saambarati1@gmail.come4556722015-07-19 16:57:44 +00002002 if (var.isReadOnly()) {
2003 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2004 if (threwException)
2005 return value.get();
2006 }
ggaren@apple.com20c0b6c2013-04-04 18:31:37 +00002007 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00002008 if (!var.isReadOnly()) {
sbarati@apple.come67fd782016-04-19 01:38:30 +00002009 generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00002010 generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
2011 }
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00002012
ggaren@apple.com20c0b6c2013-04-04 18:31:37 +00002013 return oldValue.get();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002014}
2015
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002016RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002017{
ggaren@apple.com20c0b6c2013-04-04 18:31:37 +00002018 if (dst == generator.ignoredResult())
2019 return PrefixNode::emitBracket(generator, dst);
2020
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002021 ASSERT(m_expr->isBracketAccessorNode());
2022 BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
2023 ExpressionNode* baseNode = bracketAccessor->base();
2024 ExpressionNode* subscript = bracketAccessor->subscript();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002025
barraclough@apple.come3aa3f52012-09-06 00:55:46 +00002026 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00002027 RefPtr<RegisterID> property = generator.emitNodeForProperty(subscript);
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002028
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002029 generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00002030 RefPtr<RegisterID> value;
2031 RefPtr<RegisterID> thisValue;
2032 if (baseNode->isSuperNode()) {
2033 thisValue = generator.ensureThis();
2034 value = generator.emitGetByVal(generator.newTemporary(), base.get(), thisValue.get(), property.get());
2035 } else
2036 value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
barraclough@apple.com9b6b67b2012-09-06 02:02:54 +00002037 RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002038 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00002039 if (baseNode->isSuperNode())
2040 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value.get());
2041 else
2042 generator.emitPutByVal(base.get(), property.get(), value.get());
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002043 generator.emitProfileType(value.get(), divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00002044 return generator.move(dst, oldValue);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002045}
2046
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002047RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002048{
ggaren@apple.com20c0b6c2013-04-04 18:31:37 +00002049 if (dst == generator.ignoredResult())
2050 return PrefixNode::emitDot(generator, dst);
2051
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002052 ASSERT(m_expr->isDotAccessorNode());
2053 DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
2054 ExpressionNode* baseNode = dotAccessor->base();
sbarati@apple.com23315d62016-05-09 20:17:23 +00002055 bool baseIsSuper = baseNode->isSuperNode();
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002056 const Identifier& ident = dotAccessor->identifier();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002057
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002058 RefPtr<RegisterID> base = generator.emitNode(baseNode);
2059
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002060 generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00002061 RefPtr<RegisterID> value;
2062 RefPtr<RegisterID> thisValue;
2063 if (baseIsSuper) {
2064 thisValue = generator.ensureThis();
2065 value = generator.emitGetById(generator.newTemporary(), base.get(), thisValue.get(), ident);
2066 } else
2067 value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
barraclough@apple.com9b6b67b2012-09-06 02:02:54 +00002068 RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002069 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00002070 if (baseIsSuper)
2071 generator.emitPutById(base.get(), thisValue.get(), ident, value.get());
2072 else
2073 generator.emitPutById(base.get(), ident, value.get());
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002074 generator.emitProfileType(value.get(), divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00002075 return generator.move(dst, oldValue);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002076}
2077
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002078RegisterID* PostfixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002079{
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002080 if (m_expr->isResolveNode())
2081 return emitResolve(generator, dst);
2082
2083 if (m_expr->isBracketAccessorNode())
2084 return emitBracket(generator, dst);
2085
2086 if (m_expr->isDotAccessorNode())
2087 return emitDot(generator, dst);
2088
ross.kirsling@sony.comfacf59d2019-05-16 20:08:22 +00002089 ASSERT(m_expr->isFunctionCall());
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00002090 return emitThrowReferenceError(generator, m_operator == Operator::PlusPlus
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00002091 ? "Postfix ++ operator applied to value that is not a reference."_s
2092 : "Postfix -- operator applied to value that is not a reference."_s);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002093}
2094
2095// ------------------------------ DeleteResolveNode -----------------------------------
2096
2097RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2098{
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002099 Variable var = generator.variable(m_ident);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002100 if (var.local()) {
2101 generator.emitTDZCheckIfNecessary(var, var.local(), nullptr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002102 return generator.emitLoad(generator.finalDestination(dst), false);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002103 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002104
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002105 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002106 RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002107 generator.emitTDZCheckIfNecessary(var, nullptr, base.get());
oliver@apple.com58c86752013-07-25 04:02:40 +00002108 return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002109}
2110
2111// ------------------------------ DeleteBracketNode -----------------------------------
2112
2113RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2114{
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00002115 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002116 RefPtr<RegisterID> r0 = generator.emitNode(m_base);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002117
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00002118 if (m_base->isOptionalChainBase())
2119 generator.emitOptionalCheck(r0.get());
2120
2121 RefPtr<RegisterID> r1 = generator.emitNode(m_subscript);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002122 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00002123 if (m_base->isSuperNode())
2124 return emitThrowReferenceError(generator, "Cannot delete a super property");
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00002125 return generator.emitDeleteByVal(finalDest.get(), r0.get(), r1.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002126}
2127
2128// ------------------------------ DeleteDotNode -----------------------------------
2129
2130RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2131{
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00002132 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002133 RefPtr<RegisterID> r0 = generator.emitNode(m_base);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002134
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00002135 if (m_base->isOptionalChainBase())
2136 generator.emitOptionalCheck(r0.get());
2137
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002138 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00002139 if (m_base->isSuperNode())
2140 return emitThrowReferenceError(generator, "Cannot delete a super property");
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00002141 return generator.emitDeleteById(finalDest.get(), r0.get(), m_ident);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002142}
2143
2144// ------------------------------ DeleteValueNode -----------------------------------
2145
2146RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2147{
2148 generator.emitNode(generator.ignoredResult(), m_expr);
2149
2150 // delete on a non-location expression ignores the value and returns true
2151 return generator.emitLoad(generator.finalDestination(dst), true);
2152}
2153
2154// ------------------------------ VoidNode -------------------------------------
2155
2156RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2157{
2158 if (dst == generator.ignoredResult()) {
2159 generator.emitNode(generator.ignoredResult(), m_expr);
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00002160 return nullptr;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002161 }
2162 RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
2163 return generator.emitLoad(dst, jsUndefined());
2164}
2165
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002166// ------------------------------ TypeOfResolveNode -----------------------------------
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002167
2168RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2169{
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002170 Variable var = generator.variable(m_ident);
2171 if (RegisterID* local = var.local()) {
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002172 generator.emitTDZCheckIfNecessary(var, local, nullptr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002173 if (dst == generator.ignoredResult())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00002174 return nullptr;
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002175 return generator.emitTypeOf(generator.finalDestination(dst), local);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002176 }
2177
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002178 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
2179 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002180 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002181 if (dst == generator.ignoredResult())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00002182 return nullptr;
oliver@apple.com58c86752013-07-25 04:02:40 +00002183 return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002184}
2185
2186// ------------------------------ TypeOfValueNode -----------------------------------
2187
2188RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2189{
2190 if (dst == generator.ignoredResult()) {
2191 generator.emitNode(generator.ignoredResult(), m_expr);
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00002192 return nullptr;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002193 }
2194 RefPtr<RegisterID> src = generator.emitNode(m_expr);
2195 return generator.emitTypeOf(generator.finalDestination(dst), src.get());
2196}
2197
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002198// ------------------------------ PrefixNode ----------------------------------
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002199
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002200RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002201{
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002202 ASSERT(m_expr->isResolveNode());
2203 ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
2204 const Identifier& ident = resolve->identifier();
2205
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002206 Variable var = generator.variable(ident);
2207 if (RegisterID* local = var.local()) {
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002208 generator.emitTDZCheckIfNecessary(var, local, nullptr);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002209 RefPtr<RegisterID> localReg = local;
2210 if (var.isReadOnly()) {
saambarati1@gmail.come4556722015-07-19 16:57:44 +00002211 generator.emitReadOnlyExceptionIfNeeded(var);
keith_miller@apple.com35210892018-06-01 18:11:36 +00002212 localReg = generator.move(generator.tempDestination(dst), localReg.get());
ysuzuki@apple.comcdbe02a2019-05-03 18:54:44 +00002213 } else if (generator.shouldEmitTypeProfilerHooks()) {
fpizlo@apple.com0309686b2013-12-02 19:49:43 +00002214 RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
keith_miller@apple.com35210892018-06-01 18:11:36 +00002215 generator.move(tempDst.get(), localReg.get());
fpizlo@apple.com0309686b2013-12-02 19:49:43 +00002216 emitIncOrDec(generator, tempDst.get(), m_operator);
keith_miller@apple.com35210892018-06-01 18:11:36 +00002217 generator.move(localReg.get(), tempDst.get());
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002218 generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00002219 return generator.move(dst, tempDst.get());
fpizlo@apple.com0309686b2013-12-02 19:49:43 +00002220 }
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002221 emitIncOrDec(generator, localReg.get(), m_operator);
keith_miller@apple.com35210892018-06-01 18:11:36 +00002222 return generator.move(dst, localReg.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002223 }
2224
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002225 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002226 RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
2227 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002228 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
saambarati1@gmail.come4556722015-07-19 16:57:44 +00002229 if (var.isReadOnly()) {
2230 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2231 if (threwException)
2232 return value.get();
2233 }
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002234
oliver@apple.com58c86752013-07-25 04:02:40 +00002235 emitIncOrDec(generator, value.get(), m_operator);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00002236 if (!var.isReadOnly()) {
sbarati@apple.come67fd782016-04-19 01:38:30 +00002237 generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00002238 generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
2239 }
keith_miller@apple.com35210892018-06-01 18:11:36 +00002240 return generator.move(dst, value.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002241}
2242
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002243RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002244{
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002245 ASSERT(m_expr->isBracketAccessorNode());
2246 BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
2247 ExpressionNode* baseNode = bracketAccessor->base();
2248 ExpressionNode* subscript = bracketAccessor->subscript();
2249
barraclough@apple.come3aa3f52012-09-06 00:55:46 +00002250 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00002251 RefPtr<RegisterID> property = generator.emitNodeForProperty(subscript);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002252 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2253
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002254 generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00002255 RegisterID* value;
2256 RefPtr<RegisterID> thisValue;
2257 if (baseNode->isSuperNode()) {
2258 thisValue = generator.ensureThis();
2259 value = generator.emitGetByVal(propDst.get(), base.get(), thisValue.get(), property.get());
2260 } else
2261 value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
ggaren@apple.comf3036112013-04-27 23:14:04 +00002262 emitIncOrDec(generator, value, m_operator);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002263 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00002264 if (baseNode->isSuperNode())
2265 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value);
2266 else
2267 generator.emitPutByVal(base.get(), property.get(), value);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002268 generator.emitProfileType(value, divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00002269 return generator.move(dst, propDst.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002270}
2271
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002272RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002273{
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002274 ASSERT(m_expr->isDotAccessorNode());
2275 DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
2276 ExpressionNode* baseNode = dotAccessor->base();
2277 const Identifier& ident = dotAccessor->identifier();
2278
2279 RefPtr<RegisterID> base = generator.emitNode(baseNode);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002280 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2281
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002282 generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00002283 RegisterID* value;
2284 RefPtr<RegisterID> thisValue;
2285 if (baseNode->isSuperNode()) {
2286 thisValue = generator.ensureThis();
2287 value = generator.emitGetById(propDst.get(), base.get(), thisValue.get(), ident);
2288 } else
2289 value = generator.emitGetById(propDst.get(), base.get(), ident);
ggaren@apple.comf3036112013-04-27 23:14:04 +00002290 emitIncOrDec(generator, value, m_operator);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002291 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00002292 if (baseNode->isSuperNode())
2293 generator.emitPutById(base.get(), thisValue.get(), ident, value);
2294 else
2295 generator.emitPutById(base.get(), ident, value);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002296 generator.emitProfileType(value, divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00002297 return generator.move(dst, propDst.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002298}
2299
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002300RegisterID* PrefixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002301{
barraclough@apple.comff7867a2012-09-05 23:00:29 +00002302 if (m_expr->isResolveNode())
2303 return emitResolve(generator, dst);
2304
2305 if (m_expr->isBracketAccessorNode())
2306 return emitBracket(generator, dst);
2307
2308 if (m_expr->isDotAccessorNode())
2309 return emitDot(generator, dst);
2310
ross.kirsling@sony.comfacf59d2019-05-16 20:08:22 +00002311 ASSERT(m_expr->isFunctionCall());
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00002312 return emitThrowReferenceError(generator, m_operator == Operator::PlusPlus
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00002313 ? "Prefix ++ operator applied to value that is not a reference."_s
2314 : "Prefix -- operator applied to value that is not a reference."_s);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002315}
2316
2317// ------------------------------ Unary Operation Nodes -----------------------------------
2318
2319RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2320{
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002321 RefPtr<RegisterID> src = generator.emitNode(m_expr);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002322 generator.emitExpressionInfo(position(), position(), position());
rmorisset@apple.com694598d2019-11-13 20:07:29 +00002323 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), m_expr->resultDescriptor());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002324}
2325
utatane.tea@gmail.comdb32c542016-06-30 15:26:47 +00002326// ------------------------------ UnaryPlusNode -----------------------------------
2327
2328RegisterID* UnaryPlusNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2329{
2330 ASSERT(opcodeID() == op_to_number);
2331 RefPtr<RegisterID> src = generator.emitNode(expr());
2332 generator.emitExpressionInfo(position(), position(), position());
2333 return generator.emitToNumber(generator.finalDestination(dst), src.get());
2334}
barraclough@apple.coma6bdfc82012-02-27 18:26:23 +00002335
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002336// ------------------------------ LogicalNotNode -----------------------------------
2337
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00002338void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002339{
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00002340 if (UNLIKELY(needsDebugHook()))
2341 generator.emitDebugHook(this);
2342
2343 // Reverse the true and false targets.
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00002344 generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002345}
2346
2347
2348// ------------------------------ Binary Operation Nodes -----------------------------------
2349
2350// BinaryOpNode::emitStrcat:
2351//
2352// This node generates an op_strcat operation. This opcode can handle concatenation of three or
2353// more values, where we can determine a set of separate op_add operations would be operating on
2354// string values.
2355//
2356// This function expects to be operating on a graph of AST nodes looking something like this:
2357//
2358// (a)... (b)
2359// \ /
2360// (+) (c)
2361// \ /
2362// [d] ((+))
2363// \ /
2364// [+=]
2365//
2366// The assignment operation is optional, if it exists the register holding the value on the
2367// lefthand side of the assignment should be passing as the optional 'lhs' argument.
2368//
2369// The method should be called on the node at the root of the tree of regular binary add
2370// operations (marked in the diagram with a double set of parentheses). This node must
2371// be performing a string concatenation (determined by statically detecting that at least
2372// one child must be a string).
2373//
2374// Since the minimum number of values being concatenated together is expected to be 3, if
2375// a lhs to a concatenating assignment is not provided then the root add should have at
2376// least one left child that is also an add that can be determined to be operating on strings.
2377//
2378RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
2379{
2380 ASSERT(isAdd());
2381 ASSERT(resultDescriptor().definitelyIsString());
2382
2383 // Create a list of expressions for all the adds in the tree of nodes we can convert into
2384 // a string concatenation. The rightmost node (c) is added first. The rightmost node is
2385 // added first, and the leftmost child is never added, so the vector produced for the
2386 // example above will be [ c, b ].
2387 Vector<ExpressionNode*, 16> reverseExpressionList;
2388 reverseExpressionList.append(m_expr2);
2389
2390 // Examine the left child of the add. So long as this is a string add, add its right-child
2391 // to the list, and keep processing along the left fork.
2392 ExpressionNode* leftMostAddChild = m_expr1;
2393 while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
2394 reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
2395 leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
2396 }
2397
2398 Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
2399
2400 // If there is an assignment, allocate a temporary to hold the lhs after conversion.
2401 // We could possibly avoid this (the lhs is converted last anyway, we could let the
2402 // op_strcat node handle its conversion if required).
2403 if (lhs)
2404 temporaryRegisters.append(generator.newTemporary());
2405
2406 // Emit code for the leftmost node ((a) in the example).
2407 temporaryRegisters.append(generator.newTemporary());
2408 RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
2409 generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
2410
2411 // Note on ordering of conversions:
2412 //
2413 // We maintain the same ordering of conversions as we would see if the concatenations
2414 // was performed as a sequence of adds (otherwise this optimization could change
2415 // behaviour should an object have been provided a valueOf or toString method).
2416 //
2417 // Considering the above example, the sequnce of execution is:
2418 // * evaluate operand (a)
2419 // * evaluate operand (b)
2420 // * convert (a) to primitive <- (this would be triggered by the first add)
2421 // * convert (b) to primitive <- (ditto)
2422 // * evaluate operand (c)
2423 // * convert (c) to primitive <- (this would be triggered by the second add)
2424 // And optionally, if there is an assignment:
2425 // * convert (d) to primitive <- (this would be triggered by the assigning addition)
2426 //
2427 // As such we do not plant an op to convert the leftmost child now. Instead, use
2428 // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
2429 // once the second node has been generated. However, if the leftmost child is an
2430 // immediate we can trivially determine that no conversion will be required.
2431 // If this is the case
2432 if (leftMostAddChild->isString())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00002433 leftMostAddChildTempRegister = nullptr;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002434
2435 while (reverseExpressionList.size()) {
2436 ExpressionNode* node = reverseExpressionList.last();
2437 reverseExpressionList.removeLast();
2438
2439 // Emit the code for the current node.
2440 temporaryRegisters.append(generator.newTemporary());
2441 generator.emitNode(temporaryRegisters.last().get(), node);
2442
2443 // On the first iteration of this loop, when we first reach this point we have just
2444 // generated the second node, which means it is time to convert the leftmost operand.
2445 if (leftMostAddChildTempRegister) {
2446 generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00002447 leftMostAddChildTempRegister = nullptr; // Only do this once.
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002448 }
2449 // Plant a conversion for this node, if necessary.
2450 if (!node->isString())
2451 generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
2452 }
2453 ASSERT(temporaryRegisters.size() >= 3);
2454
2455 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
2456 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
2457 if (emitExpressionInfoForMe)
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002458 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002459 // If there is an assignment convert the lhs now. This will also copy lhs to
2460 // the temporary register we allocated for it.
2461 if (lhs)
2462 generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
2463
2464 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
2465}
2466
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00002467void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00002468{
2469 TriState branchCondition;
2470 ExpressionNode* branchExpression;
2471 tryFoldToBranch(generator, branchCondition, branchExpression);
2472
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00002473 if (UNLIKELY(needsDebugHook())) {
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +00002474 if (branchCondition != TriState::Indeterminate)
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00002475 generator.emitDebugHook(this);
2476 }
2477
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +00002478 if (branchCondition == TriState::Indeterminate)
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00002479 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +00002480 else if (branchCondition == TriState::True)
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00002481 generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode);
2482 else
2483 generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode));
2484}
2485
2486static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant)
2487{
2488 ResultType expressionType = branchExpression->resultDescriptor();
2489
2490 if (expressionType.definitelyIsBoolean() && constant.isBoolean())
2491 return true;
2492 else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1))
2493 return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch.
2494 else if (expressionType.isInt32() && constant.isInt32() && constant.asInt32() == 0)
2495 return true;
2496
2497 return false;
2498}
2499
2500void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression)
2501{
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +00002502 branchCondition = TriState::Indeterminate;
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00002503 branchExpression = nullptr;
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00002504
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00002505 ConstantNode* constant = nullptr;
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00002506 if (m_expr1->isConstant()) {
2507 constant = static_cast<ConstantNode*>(m_expr1);
2508 branchExpression = m_expr2;
2509 } else if (m_expr2->isConstant()) {
2510 constant = static_cast<ConstantNode*>(m_expr2);
2511 branchExpression = m_expr1;
2512 }
2513
2514 if (!constant)
2515 return;
2516 ASSERT(branchExpression);
2517
2518 OpcodeID opcodeID = this->opcodeID();
2519 JSValue value = constant->jsValue(generator);
2520 bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
2521 if (!canFoldToBranch)
2522 return;
2523
2524 if (opcodeID == op_eq || opcodeID == op_stricteq)
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +00002525 branchCondition = triState(value.pureToBoolean() != TriState::False);
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00002526 else if (opcodeID == op_neq || opcodeID == op_nstricteq)
ross.kirsling@sony.com184d48b2020-05-01 05:38:06 +00002527 branchCondition = triState(value.pureToBoolean() == TriState::False);
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00002528}
2529
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002530RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2531{
2532 OpcodeID opcodeID = this->opcodeID();
2533
utatane.tea@gmail.coma1264de2017-10-14 15:35:48 +00002534 if (opcodeID == op_less || opcodeID == op_lesseq || opcodeID == op_greater || opcodeID == op_greatereq) {
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00002535 auto isUInt32 = [&] (ExpressionNode* node) -> Optional<UInt32Result> {
utatane.tea@gmail.coma1264de2017-10-14 15:35:48 +00002536 if (node->isBinaryOpNode() && static_cast<BinaryOpNode*>(node)->opcodeID() == op_urshift)
2537 return UInt32Result::UInt32;
2538 if (node->isNumber() && static_cast<NumberNode*>(node)->isIntegerNode()) {
utatane.tea@gmail.comacb55c22017-10-20 07:35:16 +00002539 auto value = jsNumber(static_cast<NumberNode*>(node)->value());
2540 if (value.isInt32() && value.asInt32() >= 0)
utatane.tea@gmail.coma1264de2017-10-14 15:35:48 +00002541 return UInt32Result::Constant;
2542 }
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00002543 return WTF::nullopt;
utatane.tea@gmail.coma1264de2017-10-14 15:35:48 +00002544 };
2545 auto leftResult = isUInt32(m_expr1);
2546 auto rightResult = isUInt32(m_expr2);
2547 if ((leftResult && rightResult) && (leftResult.value() == UInt32Result::UInt32 || rightResult.value() == UInt32Result::UInt32)) {
2548 auto* left = m_expr1;
2549 auto* right = m_expr2;
2550 if (left->isBinaryOpNode()) {
2551 ASSERT(static_cast<BinaryOpNode*>(left)->opcodeID() == op_urshift);
2552 static_cast<BinaryOpNode*>(left)->m_shouldToUnsignedResult = false;
2553 }
2554 if (right->isBinaryOpNode()) {
2555 ASSERT(static_cast<BinaryOpNode*>(right)->opcodeID() == op_urshift);
2556 static_cast<BinaryOpNode*>(right)->m_shouldToUnsignedResult = false;
2557 }
2558 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
2559 RefPtr<RegisterID> src2 = generator.emitNode(right);
2560 generator.emitExpressionInfo(position(), position(), position());
2561
2562 // Since the both sides only accept Int32, replacing operands is not observable to users.
2563 bool replaceOperands = false;
2564 OpcodeID resultOp = opcodeID;
2565 switch (opcodeID) {
2566 case op_less:
2567 resultOp = op_below;
2568 break;
2569 case op_lesseq:
2570 resultOp = op_beloweq;
2571 break;
2572 case op_greater:
2573 resultOp = op_below;
2574 replaceOperands = true;
2575 break;
2576 case op_greatereq:
2577 resultOp = op_beloweq;
2578 replaceOperands = true;
2579 break;
2580 default:
2581 RELEASE_ASSERT_NOT_REACHED();
2582 }
2583 OperandTypes operandTypes(left->resultDescriptor(), right->resultDescriptor());
2584 if (replaceOperands) {
2585 std::swap(src1, src2);
2586 operandTypes = OperandTypes(right->resultDescriptor(), left->resultDescriptor());
2587 }
2588 return generator.emitBinaryOp(resultOp, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), operandTypes);
2589 }
2590 }
2591
mark.lam@apple.com0e3a6ac2013-07-24 00:56:52 +00002592 if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString()) {
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002593 generator.emitExpressionInfo(position(), position(), position());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002594 return emitStrcat(generator, dst);
mark.lam@apple.com0e3a6ac2013-07-24 00:56:52 +00002595 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002596
2597 if (opcodeID == op_neq) {
2598 if (m_expr1->isNull() || m_expr2->isNull()) {
2599 RefPtr<RegisterID> src = generator.tempDestination(dst);
2600 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002601 return generator.emitUnaryOp<OpNeqNull>(generator.finalDestination(dst, src.get()), src.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002602 }
2603 }
2604
oliver@apple.comece74042012-12-01 00:50:39 +00002605 ExpressionNode* left = m_expr1;
2606 ExpressionNode* right = m_expr2;
2607 if (opcodeID == op_neq || opcodeID == op_nstricteq) {
2608 if (left->isString())
2609 std::swap(left, right);
2610 }
2611
2612 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
rniwa@webkit.org679fb98f2015-01-22 02:06:33 +00002613 bool wasTypeof = generator.lastOpcodeID() == op_typeof;
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002614 RefPtr<RegisterID> src2 = generator.emitNode(right);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002615 generator.emitExpressionInfo(position(), position(), position());
oliver@apple.comece74042012-12-01 00:50:39 +00002616 if (wasTypeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
bfulgham@webkit.org31940df2012-11-14 19:26:04 +00002617 RefPtr<RegisterID> tmp = generator.tempDestination(dst);
2618 if (opcodeID == op_neq)
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002619 generator.emitEqualityOp<OpEq>(generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
bfulgham@webkit.org31940df2012-11-14 19:26:04 +00002620 else if (opcodeID == op_nstricteq)
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002621 generator.emitEqualityOp<OpStricteq>(generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
bfulgham@webkit.org31940df2012-11-14 19:26:04 +00002622 else
oliver@apple.com5598c182013-01-23 22:25:07 +00002623 RELEASE_ASSERT_NOT_REACHED();
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002624 return generator.emitUnaryOp<OpNot>(generator.finalDestination(dst, tmp.get()), tmp.get());
bfulgham@webkit.org31940df2012-11-14 19:26:04 +00002625 }
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002626 RegisterID* result = generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
utatane.tea@gmail.coma1264de2017-10-14 15:35:48 +00002627 if (m_shouldToUnsignedResult) {
2628 if (opcodeID == op_urshift && dst != generator.ignoredResult())
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002629 return generator.emitUnaryOp<OpUnsigned>(result, result);
utatane.tea@gmail.coma1264de2017-10-14 15:35:48 +00002630 }
fpizlo@apple.com9089acb2013-12-14 06:33:42 +00002631 return result;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002632}
2633
2634RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2635{
2636 if (m_expr1->isNull() || m_expr2->isNull()) {
2637 RefPtr<RegisterID> src = generator.tempDestination(dst);
2638 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002639 return generator.emitUnaryOp<OpEqNull>(generator.finalDestination(dst, src.get()), src.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002640 }
2641
oliver@apple.comece74042012-12-01 00:50:39 +00002642 ExpressionNode* left = m_expr1;
2643 ExpressionNode* right = m_expr2;
2644 if (left->isString())
2645 std::swap(left, right);
2646
2647 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002648 RefPtr<RegisterID> src2 = generator.emitNode(right);
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002649 return generator.emitEqualityOp<OpEq>(generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002650}
2651
2652RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2653{
oliver@apple.comece74042012-12-01 00:50:39 +00002654 ExpressionNode* left = m_expr1;
2655 ExpressionNode* right = m_expr2;
2656 if (left->isString())
2657 std::swap(left, right);
2658
2659 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002660 RefPtr<RegisterID> src2 = generator.emitNode(right);
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002661 return generator.emitEqualityOp<OpStricteq>(generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002662}
2663
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002664RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2665{
2666 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002667 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002668 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00002669 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002670}
2671
2672RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2673{
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00002674 RefPtr<RegisterID> hasInstanceValue = generator.newTemporary();
2675 RefPtr<RegisterID> isObject = generator.newTemporary();
2676 RefPtr<RegisterID> isCustom = generator.newTemporary();
barraclough@apple.comb46d57b42012-09-22 00:43:03 +00002677 RefPtr<RegisterID> prototype = generator.newTemporary();
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00002678 RefPtr<RegisterID> value = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
2679 RefPtr<RegisterID> constructor = generator.emitNode(m_expr2);
2680 RefPtr<RegisterID> dstReg = generator.finalDestination(dst, value.get());
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00002681 Ref<Label> custom = generator.newLabel();
2682 Ref<Label> done = generator.newLabel();
2683 Ref<Label> typeError = generator.newLabel();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002684
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002685 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00002686 generator.emitIsObject(isObject.get(), constructor.get());
2687 generator.emitJumpIfFalse(isObject.get(), typeError.get());
barraclough@apple.com8da6d972010-11-16 21:11:26 +00002688
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002689 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
mark.lam@apple.com5ba07792019-08-27 22:14:52 +00002690 generator.emitGetById(hasInstanceValue.get(), constructor.get(), generator.vm().propertyNames->hasInstanceSymbol);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002691
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002692 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00002693 generator.emitOverridesHasInstance(isCustom.get(), constructor.get(), hasInstanceValue.get());
2694
2695 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2696 generator.emitJumpIfTrue(isCustom.get(), custom.get());
2697
2698 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
mark.lam@apple.com5ba07792019-08-27 22:14:52 +00002699 generator.emitGetById(prototype.get(), constructor.get(), generator.vm().propertyNames->prototype);
keith_miller@apple.comcb11fe42015-12-18 00:37:35 +00002700
2701 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2702 generator.emitInstanceOf(dstReg.get(), value.get(), prototype.get());
2703
2704 generator.emitJump(done.get());
2705
2706 generator.emitLabel(typeError.get());
2707 generator.emitThrowTypeError("Right hand side of instanceof is not an object");
2708
2709 generator.emitLabel(custom.get());
2710
2711 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2712 generator.emitInstanceOfCustom(dstReg.get(), value.get(), constructor.get(), hasInstanceValue.get());
2713
2714 generator.emitLabel(done.get());
2715
2716 return dstReg.get();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002717}
2718
keith_miller@apple.com6fc2fb72017-02-09 00:02:20 +00002719// ------------------------------ InNode ----------------------------
2720
2721RegisterID* InNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2722{
utatane.tea@gmail.com235f2b92018-05-22 04:54:31 +00002723 if (isNonIndexStringElement(*m_expr1)) {
2724 RefPtr<RegisterID> base = generator.emitNode(m_expr2);
2725 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2726 return generator.emitInById(generator.finalDestination(dst, base.get()), base.get(), static_cast<StringNode*>(m_expr1)->value());
2727 }
2728
keith_miller@apple.com6fc2fb72017-02-09 00:02:20 +00002729 RefPtr<RegisterID> key = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
2730 RefPtr<RegisterID> base = generator.emitNode(m_expr2);
2731 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
utatane.tea@gmail.com235f2b92018-05-22 04:54:31 +00002732 return generator.emitInByVal(generator.finalDestination(dst, key.get()), key.get(), base.get());
keith_miller@apple.com6fc2fb72017-02-09 00:02:20 +00002733}
2734
2735
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002736// ------------------------------ LogicalOpNode ----------------------------
2737
2738RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2739{
2740 RefPtr<RegisterID> temp = generator.tempDestination(dst);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00002741 Ref<Label> target = generator.newLabel();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002742
2743 generator.emitNode(temp.get(), m_expr1);
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00002744 if (m_operator == LogicalOperator::And)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002745 generator.emitJumpIfFalse(temp.get(), target.get());
2746 else
2747 generator.emitJumpIfTrue(temp.get(), target.get());
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00002748 generator.emitNodeInTailPosition(temp.get(), m_expr2);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002749 generator.emitLabel(target.get());
2750
keith_miller@apple.com35210892018-06-01 18:11:36 +00002751 return generator.move(dst, temp.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002752}
2753
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00002754void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002755{
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00002756 if (UNLIKELY(needsDebugHook()))
2757 generator.emitDebugHook(this);
2758
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00002759 Ref<Label> afterExpr1 = generator.newLabel();
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00002760 if (m_operator == LogicalOperator::And)
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00002761 generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, FallThroughMeansTrue);
2762 else
2763 generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), FallThroughMeansFalse);
2764 generator.emitLabel(afterExpr1.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002765
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00002766 generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMode);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002767}
2768
ross.kirsling@sony.comb4b72e972019-07-25 07:50:46 +00002769// ------------------------------ CoalesceNode ----------------------------
2770
2771RegisterID* CoalesceNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2772{
2773 RefPtr<RegisterID> temp = generator.tempDestination(dst);
ross.kirsling@sony.com9b5e50f2019-08-26 21:09:35 +00002774 Ref<Label> endLabel = generator.newLabel();
ross.kirsling@sony.comb4b72e972019-07-25 07:50:46 +00002775
ross.kirsling@sony.com9b5e50f2019-08-26 21:09:35 +00002776 if (m_hasAbsorbedOptionalChain)
2777 generator.pushOptionalChainTarget();
ross.kirsling@sony.comb4b72e972019-07-25 07:50:46 +00002778 generator.emitNode(temp.get(), m_expr1);
ross.kirsling@sony.com9b5e50f2019-08-26 21:09:35 +00002779 generator.emitJumpIfFalse(generator.emitIsUndefinedOrNull(generator.newTemporary(), temp.get()), endLabel.get());
ross.kirsling@sony.comb4b72e972019-07-25 07:50:46 +00002780
ross.kirsling@sony.com9b5e50f2019-08-26 21:09:35 +00002781 if (m_hasAbsorbedOptionalChain)
2782 generator.popOptionalChainTarget();
2783 generator.emitNodeInTailPosition(temp.get(), m_expr2);
2784
2785 generator.emitLabel(endLabel.get());
ross.kirsling@sony.comb4b72e972019-07-25 07:50:46 +00002786 return generator.move(dst, temp.get());
2787}
2788
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00002789// ------------------------------ OptionalChainNode ----------------------------
2790
2791RegisterID* OptionalChainNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2792{
2793 RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
2794
2795 if (m_isOutermost)
2796 generator.pushOptionalChainTarget();
2797 generator.emitNodeInTailPosition(finalDest.get(), m_expr);
2798 if (m_isOutermost)
ross.kirsling@sony.com9b5e50f2019-08-26 21:09:35 +00002799 generator.popOptionalChainTarget(finalDest.get(), m_expr->isDeleteNode());
ross.kirsling@sony.com2af340f2019-08-18 05:54:13 +00002800
2801 return finalDest.get();
2802}
2803
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002804// ------------------------------ ConditionalNode ------------------------------
2805
2806RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2807{
2808 RefPtr<RegisterID> newDst = generator.finalDestination(dst);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00002809 Ref<Label> beforeElse = generator.newLabel();
2810 Ref<Label> afterElse = generator.newLabel();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002811
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00002812 Ref<Label> beforeThen = generator.newLabel();
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00002813 generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
2814 generator.emitLabel(beforeThen.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002815
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00002816 generator.emitProfileControlFlow(m_expr1->startOffset());
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00002817 generator.emitNodeInTailPosition(newDst.get(), m_expr1);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002818 generator.emitJump(afterElse.get());
2819
2820 generator.emitLabel(beforeElse.get());
saambarati1@gmail.com15952502015-02-23 22:10:51 +00002821 generator.emitProfileControlFlow(m_expr1->endOffset() + 1);
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00002822 generator.emitNodeInTailPosition(newDst.get(), m_expr2);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002823
2824 generator.emitLabel(afterElse.get());
2825
saambarati1@gmail.com15952502015-02-23 22:10:51 +00002826 generator.emitProfileControlFlow(m_expr2->endOffset() + 1);
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00002827
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002828 return newDst.get();
2829}
2830
2831// ------------------------------ ReadModifyResolveNode -----------------------------------
2832
2833// FIXME: should this be moved to be a method on BytecodeGenerator?
drousso@apple.comd7cee3a2020-04-10 21:50:10 +00002834static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = nullptr, Variable* emitReadOnlyExceptionIfNeededForMe = nullptr)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002835{
2836 OpcodeID opcodeID;
2837 switch (oper) {
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00002838 case Operator::MultEq:
2839 opcodeID = op_mul;
2840 break;
2841 case Operator::DivEq:
2842 opcodeID = op_div;
2843 break;
2844 case Operator::PlusEq:
drousso@apple.comd7cee3a2020-04-10 21:50:10 +00002845 if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString()) {
2846 RegisterID* result = static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
2847 if (emitReadOnlyExceptionIfNeededForMe)
2848 generator.emitReadOnlyExceptionIfNeeded(*emitReadOnlyExceptionIfNeededForMe);
2849 return result;
2850 }
2851
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00002852 opcodeID = op_add;
2853 break;
2854 case Operator::MinusEq:
2855 opcodeID = op_sub;
2856 break;
2857 case Operator::LShift:
2858 opcodeID = op_lshift;
2859 break;
2860 case Operator::RShift:
2861 opcodeID = op_rshift;
2862 break;
2863 case Operator::URShift:
2864 opcodeID = op_urshift;
2865 break;
2866 case Operator::BitAndEq:
2867 opcodeID = op_bitand;
2868 break;
2869 case Operator::BitXOrEq:
2870 opcodeID = op_bitxor;
2871 break;
2872 case Operator::BitOrEq:
2873 opcodeID = op_bitor;
2874 break;
2875 case Operator::ModEq:
2876 opcodeID = op_mod;
2877 break;
2878 case Operator::PowEq:
2879 opcodeID = op_pow;
2880 break;
2881 default:
2882 RELEASE_ASSERT_NOT_REACHED();
2883 return dst;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002884 }
2885
2886 RegisterID* src2 = generator.emitNode(m_right);
2887
drousso@apple.comd7cee3a2020-04-10 21:50:10 +00002888 if (emitReadOnlyExceptionIfNeededForMe) {
2889 bool threwException = generator.emitReadOnlyExceptionIfNeeded(*emitReadOnlyExceptionIfNeededForMe);
2890 if (threwException)
2891 return src2;
2892 }
2893
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002894 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
2895 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
2896 if (emitExpressionInfoForMe)
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002897 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
drousso@apple.comd7cee3a2020-04-10 21:50:10 +00002898
fpizlo@apple.com9089acb2013-12-14 06:33:42 +00002899 RegisterID* result = generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00002900 if (oper == Operator::URShift)
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00002901 return generator.emitUnaryOp<OpUnsigned>(result, result);
fpizlo@apple.com9089acb2013-12-14 06:33:42 +00002902 return result;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002903}
2904
2905RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2906{
fpizlo@apple.com3378c482014-07-27 23:14:40 +00002907 JSTextPosition newDivot = divotStart() + m_ident.length();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002908 Variable var = generator.variable(m_ident);
2909 if (RegisterID* local = var.local()) {
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002910 generator.emitTDZCheckIfNecessary(var, local, nullptr);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002911 if (var.isReadOnly()) {
drousso@apple.comd7cee3a2020-04-10 21:50:10 +00002912 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), nullptr, &var);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002913 generator.emitProfileType(result, divotStart(), divotEnd());
2914 return result;
ggaren@apple.com6e309822012-09-05 21:44:43 +00002915 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002916
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002917 if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002918 RefPtr<RegisterID> result = generator.newTemporary();
keith_miller@apple.com35210892018-06-01 18:11:36 +00002919 generator.move(result.get(), local);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002920 emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
keith_miller@apple.com35210892018-06-01 18:11:36 +00002921 generator.move(local, result.get());
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002922 generator.emitProfileType(local, divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00002923 return generator.move(dst, result.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002924 }
2925
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002926 RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00002927 generator.emitProfileType(result, divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00002928 return generator.move(dst, result);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002929 }
2930
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00002931 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00002932 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2933 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00002934 generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
drousso@apple.comd7cee3a2020-04-10 21:50:10 +00002935 RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this, var.isReadOnly() ? &var : nullptr);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00002936 RegisterID* returnResult = result.get();
2937 if (!var.isReadOnly()) {
sbarati@apple.come67fd782016-04-19 01:38:30 +00002938 returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00002939 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
2940 }
commit-queue@webkit.orgeafc9b32014-08-14 23:59:44 +00002941 return returnResult;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00002942}
2943
drousso@apple.comfaedbc82020-04-15 07:02:55 +00002944// ------------------------------ ShortCircuitReadModifyResolveNode -----------------------------------
2945
2946static ALWAYS_INLINE void emitShortCircuitAssignment(BytecodeGenerator& generator, RegisterID* value, Operator oper, Label& afterAssignment)
2947{
2948 switch (oper) {
drousso@apple.com0603a9b2020-04-17 19:46:55 +00002949 case Operator::CoalesceEq:
drousso@apple.comfaedbc82020-04-15 07:02:55 +00002950 generator.emitJumpIfFalse(generator.emitIsUndefinedOrNull(generator.newTemporary(), value), afterAssignment);
2951 break;
2952
2953 case Operator::OrEq:
2954 generator.emitJumpIfTrue(value, afterAssignment);
2955 break;
2956
2957 case Operator::AndEq:
2958 generator.emitJumpIfFalse(value, afterAssignment);
2959 break;
2960
2961 default:
2962 RELEASE_ASSERT_NOT_REACHED();
2963 break;
2964 }
2965}
2966
2967RegisterID* ShortCircuitReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2968{
2969 JSTextPosition newDivot = divotStart() + m_ident.length();
2970
2971 Variable var = generator.variable(m_ident);
2972 bool isReadOnly = var.isReadOnly();
2973
2974 if (RefPtr<RegisterID> local = var.local()) {
2975 generator.emitTDZCheckIfNecessary(var, local.get(), nullptr);
2976
2977 if (isReadOnly) {
2978 RefPtr<RegisterID> result = local;
2979
2980 Ref<Label> afterAssignment = generator.newLabel();
2981 emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
2982
2983 result = generator.emitNode(result.get(), m_right); // Execute side effects first.
2984 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2985
2986 if (!threwException)
2987 generator.emitProfileType(result.get(), divotStart(), divotEnd());
2988
2989 generator.emitLabel(afterAssignment.get());
2990 return generator.move(dst, result.get());
2991 }
2992
2993 if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
2994 RefPtr<RegisterID> result = generator.tempDestination(dst);
2995 generator.move(result.get(), local.get());
2996
2997 Ref<Label> afterAssignment = generator.newLabel();
2998 emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
2999
3000 result = generator.emitNode(result.get(), m_right);
3001 generator.move(local.get(), result.get());
3002 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
3003
3004 generator.emitLabel(afterAssignment.get());
3005 return generator.move(dst, result.get());
3006 }
3007
3008 RefPtr<RegisterID> result = local;
3009
3010 Ref<Label> afterAssignment = generator.newLabel();
3011 emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
3012
3013 result = generator.emitNode(result.get(), m_right);
3014 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
3015
3016 generator.emitLabel(afterAssignment.get());
3017 return generator.move(dst, result.get());
3018 }
3019
3020 generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
3021 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
3022
3023 RefPtr<RegisterID> result = generator.emitGetFromScope(generator.tempDestination(dst), scope.get(), var, ThrowIfNotFound);
3024 generator.emitTDZCheckIfNecessary(var, result.get(), nullptr);
3025
3026 Ref<Label> afterAssignment = generator.newLabel();
3027 emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
3028
3029 result = generator.emitNode(result.get(), m_right); // Execute side effects first.
3030
3031 bool threwException = isReadOnly ? generator.emitReadOnlyExceptionIfNeeded(var) : false;
3032
3033 if (!threwException)
3034 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
3035
3036 if (!isReadOnly) {
3037 result = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
3038 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
3039 }
3040
3041 generator.emitLabel(afterAssignment.get());
3042 return generator.move(dst, result.get());
3043}
3044
3045// ------------------------------ AssignResolveNode -----------------------------------
3046
sbarati@apple.come67fd782016-04-19 01:38:30 +00003047static InitializationMode initializationModeForAssignmentContext(AssignmentContext assignmentContext)
3048{
3049 switch (assignmentContext) {
3050 case AssignmentContext::DeclarationStatement:
3051 return InitializationMode::Initialization;
3052 case AssignmentContext::ConstDeclarationStatement:
3053 return InitializationMode::ConstInitialization;
3054 case AssignmentContext::AssignmentExpression:
3055 return InitializationMode::NotInitialization;
3056 }
3057
3058 ASSERT_NOT_REACHED();
3059 return InitializationMode::NotInitialization;
3060}
3061
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003062RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3063{
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003064 Variable var = generator.variable(m_ident);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00003065 bool isReadOnly = var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement;
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003066 if (RegisterID* local = var.local()) {
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003067 RegisterID* result = nullptr;
3068 if (m_assignmentContext == AssignmentContext::AssignmentExpression)
3069 generator.emitTDZCheckIfNecessary(var, local, nullptr);
saambarati1@gmail.come4556722015-07-19 16:57:44 +00003070
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00003071 if (isReadOnly) {
saambarati1@gmail.com52f68592015-07-28 21:39:34 +00003072 result = generator.emitNode(dst, m_right); // Execute side effects first.
saambarati1@gmail.come4556722015-07-19 16:57:44 +00003073 generator.emitReadOnlyExceptionIfNeeded(var);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003074 generator.emitProfileType(result, var, divotStart(), divotEnd());
3075 } else if (var.isSpecial()) {
fpizlo@apple.com0309686b2013-12-02 19:49:43 +00003076 RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
3077 generator.emitNode(tempDst.get(), m_right);
keith_miller@apple.com35210892018-06-01 18:11:36 +00003078 generator.move(local, tempDst.get());
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003079 generator.emitProfileType(local, var, divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00003080 result = generator.move(dst, tempDst.get());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003081 } else {
3082 RegisterID* right = generator.emitNode(local, m_right);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003083 generator.emitProfileType(right, var, divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00003084 result = generator.move(dst, right);
fpizlo@apple.com0309686b2013-12-02 19:49:43 +00003085 }
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003086
saambarati1@gmail.come4556722015-07-19 16:57:44 +00003087 if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003088 generator.liftTDZCheckIfPossible(var);
3089 return result;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003090 }
3091
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00003092 if (generator.ecmaMode().isStrict())
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003093 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003094 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003095 if (m_assignmentContext == AssignmentContext::AssignmentExpression)
3096 generator.emitTDZCheckIfNecessary(var, nullptr, scope.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003097 if (dst == generator.ignoredResult())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00003098 dst = nullptr;
drousso@apple.com16074362020-04-10 00:28:11 +00003099 RefPtr<RegisterID> result = generator.emitNode(dst, m_right); // Execute side effects first.
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00003100 if (isReadOnly) {
saambarati1@gmail.come4556722015-07-19 16:57:44 +00003101 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
3102 if (threwException)
drousso@apple.com16074362020-04-10 00:28:11 +00003103 return result.get();
saambarati1@gmail.come4556722015-07-19 16:57:44 +00003104 }
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003105 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00003106 RegisterID* returnResult = result.get();
3107 if (!isReadOnly) {
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00003108 returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, initializationModeForAssignmentContext(m_assignmentContext));
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00003109 generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
3110 }
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003111
saambarati1@gmail.come4556722015-07-19 16:57:44 +00003112 if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003113 generator.liftTDZCheckIfPossible(var);
commit-queue@webkit.orgeafc9b32014-08-14 23:59:44 +00003114 return returnResult;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003115}
3116
3117// ------------------------------ AssignDotNode -----------------------------------
3118
3119RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3120{
3121 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
3122 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00003123 RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003124 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00003125 RefPtr<RegisterID> forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.move(generator.tempDestination(result.get()), result.get());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003126 if (m_base->isSuperNode()) {
3127 RefPtr<RegisterID> thisValue = generator.ensureThis();
3128 generator.emitPutById(base.get(), thisValue.get(), m_ident, forwardResult.get());
3129 } else
3130 generator.emitPutById(base.get(), m_ident, forwardResult.get());
3131 generator.emitProfileType(forwardResult.get(), divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00003132 return generator.move(dst, forwardResult.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003133}
3134
3135// ------------------------------ ReadModifyDotNode -----------------------------------
3136
3137RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3138{
3139 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
3140
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003141 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003142 RefPtr<RegisterID> value;
3143 RefPtr<RegisterID> thisValue;
3144 if (m_base->isSuperNode()) {
3145 thisValue = generator.ensureThis();
3146 value = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), m_ident);
3147 } else
3148 value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00003149 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003150
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003151 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003152 RegisterID* ret;
3153 if (m_base->isSuperNode())
3154 ret = generator.emitPutById(base.get(), thisValue.get(), m_ident, updatedValue);
3155 else
3156 ret = generator.emitPutById(base.get(), m_ident, updatedValue);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003157 generator.emitProfileType(updatedValue, divotStart(), divotEnd());
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00003158 return ret;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003159}
3160
drousso@apple.comfaedbc82020-04-15 07:02:55 +00003161// ------------------------------ ShortCircuitReadModifyDotNode -----------------------------------
3162
3163RegisterID* ShortCircuitReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3164{
3165 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
3166 RefPtr<RegisterID> thisValue;
3167
3168 RefPtr<RegisterID> result;
3169
3170 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
3171 if (m_base->isSuperNode()) {
3172 thisValue = generator.ensureThis();
3173 result = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), m_ident);
3174 } else
3175 result = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
3176
3177 Ref<Label> afterAssignment = generator.newLabel();
3178 emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
3179
3180 result = generator.emitNode(result.get(), m_right);
3181 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
3182 if (m_base->isSuperNode())
3183 result = generator.emitPutById(base.get(), thisValue.get(), m_ident, result.get());
3184 else
3185 result = generator.emitPutById(base.get(), m_ident, result.get());
3186 generator.emitProfileType(result.get(), divotStart(), divotEnd());
3187
3188 generator.emitLabel(afterAssignment.get());
3189 return generator.move(dst, result.get());
3190}
3191
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003192// ------------------------------ AssignErrorNode -----------------------------------
3193
3194RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3195{
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00003196 return emitThrowReferenceError(generator, "Left side of assignment is not a reference."_s);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003197}
3198
3199// ------------------------------ AssignBracketNode -----------------------------------
3200
3201RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3202{
3203 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00003204 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSideForProperty(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003205 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
ggaren@apple.com3e6693a2015-01-13 19:42:36 +00003206 RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003207
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003208 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00003209 RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.move(generator.tempDestination(result.get()), result.get());
akling@apple.come09d0422014-11-13 19:18:43 +00003210
sbarati@apple.com23315d62016-05-09 20:17:23 +00003211 if (isNonIndexStringElement(*m_subscript)) {
3212 if (m_base->isSuperNode()) {
3213 RefPtr<RegisterID> thisValue = generator.ensureThis();
3214 generator.emitPutById(base.get(), thisValue.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
3215 } else
3216 generator.emitPutById(base.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
3217 } else {
3218 if (m_base->isSuperNode()) {
3219 RefPtr<RegisterID> thisValue = generator.ensureThis();
3220 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), forwardResult);
3221 } else
3222 generator.emitPutByVal(base.get(), property.get(), forwardResult);
3223 }
akling@apple.come09d0422014-11-13 19:18:43 +00003224
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003225 generator.emitProfileType(forwardResult, divotStart(), divotEnd());
keith_miller@apple.com35210892018-06-01 18:11:36 +00003226 return generator.move(dst, forwardResult);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003227}
3228
3229// ------------------------------ ReadModifyBracketNode -----------------------------------
3230
3231RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3232{
3233 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00003234 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSideForProperty(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003235
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003236 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003237 RefPtr<RegisterID> value;
3238 RefPtr<RegisterID> thisValue;
3239 if (m_base->isSuperNode()) {
3240 thisValue = generator.ensureThis();
3241 value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisValue.get(), property.get());
3242 } else
3243 value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
ross.kirsling@sony.com6c341cd2020-03-28 02:47:07 +00003244 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003245
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003246 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003247 if (m_base->isSuperNode())
3248 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), updatedValue);
3249 else
3250 generator.emitPutByVal(base.get(), property.get(), updatedValue);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003251 generator.emitProfileType(updatedValue, divotStart(), divotEnd());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003252
3253 return updatedValue;
3254}
3255
drousso@apple.comfaedbc82020-04-15 07:02:55 +00003256// ------------------------------ ShortCircuitReadModifyBracketNode -----------------------------------
3257
3258RegisterID* ShortCircuitReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3259{
3260 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
3261 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSideForProperty(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
3262 RefPtr<RegisterID> thisValue;
3263
3264 RefPtr<RegisterID> result;
3265
3266 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
3267 if (m_base->isSuperNode()) {
3268 thisValue = generator.ensureThis();
3269 result = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisValue.get(), property.get());
3270 } else
3271 result = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
3272
3273 Ref<Label> afterAssignment = generator.newLabel();
3274 emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
3275
3276 result = generator.emitNode(result.get(), m_right);
3277 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
3278 if (m_base->isSuperNode())
3279 result = generator.emitPutByVal(base.get(), thisValue.get(), property.get(), result.get());
3280 else
3281 result = generator.emitPutByVal(base.get(), property.get(), result.get());
3282 generator.emitProfileType(result.get(), divotStart(), divotEnd());
3283
3284 generator.emitLabel(afterAssignment.get());
3285 return generator.move(dst, result.get());
3286}
3287
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003288// ------------------------------ CommaNode ------------------------------------
3289
3290RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3291{
drousso@apple.comec9e9eb2020-04-22 17:24:14 +00003292 DebugHookType debugHookType = isOnlyChildOfStatement() ? WillExecuteStatement : WillExecuteExpression;
3293
ggaren@apple.com86cb7be2014-12-09 01:53:53 +00003294 CommaNode* node = this;
drousso@apple.com64b4b7d2020-04-09 05:10:27 +00003295 for (; node->next(); node = node->next()) {
drousso@apple.comec9e9eb2020-04-22 17:24:14 +00003296 generator.emitDebugHook(debugHookType, node->m_expr->position());
ggaren@apple.com86cb7be2014-12-09 01:53:53 +00003297 generator.emitNode(generator.ignoredResult(), node->m_expr);
drousso@apple.com64b4b7d2020-04-09 05:10:27 +00003298 }
drousso@apple.comec9e9eb2020-04-22 17:24:14 +00003299 generator.emitDebugHook(debugHookType, node->m_expr->position());
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00003300 return generator.emitNodeInTailPosition(dst, node->m_expr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003301}
3302
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003303// ------------------------------ SourceElements -------------------------------
3304
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003305inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3306{
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00003307 StatementNode* lastStatementWithCompletionValue = nullptr;
3308 if (generator.shouldBeConcernedWithCompletionValue()) {
3309 for (StatementNode* statement = m_head; statement; statement = statement->next()) {
3310 if (statement->hasCompletionValue())
3311 lastStatementWithCompletionValue = statement;
3312 }
3313 }
3314
3315 for (StatementNode* statement = m_head; statement; statement = statement->next()) {
3316 if (statement == lastStatementWithCompletionValue)
3317 generator.emitLoad(dst, jsUndefined());
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00003318 generator.emitNodeInTailPosition(dst, statement);
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00003319 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003320}
3321
3322// ------------------------------ BlockNode ------------------------------------
3323
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003324void BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003325{
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003326 if (!m_statements)
3327 return;
sbarati@apple.combdbba812015-12-19 00:19:41 +00003328 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003329 m_statements->emitBytecode(generator, dst);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003330 generator.popLexicalScope(this);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003331}
3332
3333// ------------------------------ EmptyStatementNode ---------------------------
3334
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003335void EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003336{
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003337 RELEASE_ASSERT(needsDebugHook());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003338}
3339
3340// ------------------------------ DebuggerStatementNode ---------------------------
3341
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003342void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003343{
drousso@apple.comf8607162020-02-06 02:19:10 +00003344 generator.emitDebugHook(DidReachDebuggerStatement, position());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003345}
3346
3347// ------------------------------ ExprStatementNode ----------------------------
3348
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003349void ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003350{
3351 ASSERT(m_expr);
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003352 generator.emitNode(dst, m_expr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003353}
3354
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003355// ------------------------------ DeclarationStatement ----------------------------
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003356
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003357void DeclarationStatement::emitBytecode(BytecodeGenerator& generator, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003358{
3359 ASSERT(m_expr);
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003360 generator.emitNode(m_expr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003361}
3362
commit-queue@webkit.org200ce5b2014-08-18 19:11:41 +00003363// ------------------------------ EmptyVarExpression ----------------------------
3364
3365RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3366{
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003367 // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
ysuzuki@apple.comcdbe02a2019-05-03 18:54:44 +00003368 if (!generator.shouldEmitTypeProfilerHooks())
commit-queue@webkit.org200ce5b2014-08-18 19:11:41 +00003369 return nullptr;
3370
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003371 Variable var = generator.variable(m_ident);
3372 if (RegisterID* local = var.local())
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +00003373 generator.emitProfileType(local, var, position(), position() + m_ident.length());
commit-queue@webkit.org200ce5b2014-08-18 19:11:41 +00003374 else {
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003375 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
3376 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +00003377 generator.emitProfileType(value.get(), var, position(), position() + m_ident.length());
commit-queue@webkit.org200ce5b2014-08-18 19:11:41 +00003378 }
3379
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003380 return nullptr;
3381}
3382
3383// ------------------------------ EmptyLetExpression ----------------------------
3384
3385RegisterID* EmptyLetExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3386{
3387 // Lexical declarations like 'let' must move undefined into their variables so we don't
3388 // get TDZ errors for situations like this: `let x; x;`
3389 Variable var = generator.variable(m_ident);
3390 if (RegisterID* local = var.local()) {
3391 generator.emitLoad(local, jsUndefined());
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +00003392 generator.emitProfileType(local, var, position(), position() + m_ident.length());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003393 } else {
3394 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
3395 RefPtr<RegisterID> value = generator.emitLoad(nullptr, jsUndefined());
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00003396 generator.emitPutToScope(scope.get(), var, value.get(), generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::Initialization);
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +00003397 generator.emitProfileType(value.get(), var, position(), position() + m_ident.length());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003398 }
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003399
sbarati@apple.coma5cf2f12016-03-29 22:11:24 +00003400 generator.liftTDZCheckIfPossible(var);
3401
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003402 // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
commit-queue@webkit.org200ce5b2014-08-18 19:11:41 +00003403 return nullptr;
3404}
3405
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003406// ------------------------------ IfElseNode ---------------------------------------
fpizlo@apple.com335ba392013-04-26 00:40:27 +00003407
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003408static inline StatementNode* singleStatement(StatementNode* statementNode)
fpizlo@apple.com335ba392013-04-26 00:40:27 +00003409{
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003410 if (statementNode->isBlock())
3411 return static_cast<BlockNode*>(statementNode)->singleStatement();
3412 return statementNode;
fpizlo@apple.com335ba392013-04-26 00:40:27 +00003413}
3414
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003415bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock,
3416 Label*& trueTarget, FallThroughMode& fallThroughMode)
3417{
3418 StatementNode* singleStatement = JSC::singleStatement(ifBlock);
3419 if (!singleStatement)
3420 return false;
3421
3422 if (singleStatement->isBreak()) {
3423 BreakNode* breakNode = static_cast<BreakNode*>(singleStatement);
3424 Label* target = breakNode->trivialTarget(generator);
3425 if (!target)
3426 return false;
3427 trueTarget = target;
3428 fallThroughMode = FallThroughMeansFalse;
3429 return true;
3430 }
3431
3432 if (singleStatement->isContinue()) {
3433 ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement);
3434 Label* target = continueNode->trivialTarget(generator);
3435 if (!target)
3436 return false;
3437 trueTarget = target;
3438 fallThroughMode = FallThroughMeansFalse;
3439 return true;
3440 }
3441
3442 return false;
3443}
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003444
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003445void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003446{
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00003447 if (generator.shouldBeConcernedWithCompletionValue()) {
3448 if (m_ifBlock->hasEarlyBreakOrContinue() || (m_elseBlock && m_elseBlock->hasEarlyBreakOrContinue()))
3449 generator.emitLoad(dst, jsUndefined());
3450 }
3451
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003452 Ref<Label> beforeThen = generator.newLabel();
3453 Ref<Label> beforeElse = generator.newLabel();
3454 Ref<Label> afterElse = generator.newLabel();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003455
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003456 Label* trueTarget = beforeThen.ptr();
3457 Label& falseTarget = beforeElse.get();
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003458 FallThroughMode fallThroughMode = FallThroughMeansTrue;
3459 bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode);
3460
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003461 generator.emitNodeInConditionContext(m_condition, *trueTarget, falseTarget, fallThroughMode);
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00003462 generator.emitLabel(beforeThen.get());
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003463 generator.emitProfileControlFlow(m_ifBlock->startOffset());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003464
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003465 if (!didFoldIfBlock) {
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00003466 generator.emitNodeInTailPosition(dst, m_ifBlock);
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003467 if (m_elseBlock)
3468 generator.emitJump(afterElse.get());
3469 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003470
3471 generator.emitLabel(beforeElse.get());
3472
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003473 if (m_elseBlock) {
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003474 generator.emitProfileControlFlow(m_ifBlock->endOffset() + (m_ifBlock->isBlock() ? 1 : 0));
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00003475 generator.emitNodeInTailPosition(dst, m_elseBlock);
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003476 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003477
3478 generator.emitLabel(afterElse.get());
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003479 StatementNode* endingBlock = m_elseBlock ? m_elseBlock : m_ifBlock;
3480 generator.emitProfileControlFlow(endingBlock->endOffset() + (endingBlock->isBlock() ? 1 : 0));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003481}
3482
3483// ------------------------------ DoWhileNode ----------------------------------
3484
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003485void DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003486{
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00003487 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
3488 generator.emitLoad(dst, jsUndefined());
3489
utatane.tea@gmail.com276d22b2017-04-29 16:32:59 +00003490 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003491
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003492 Ref<Label> topOfLoop = generator.newLabel();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003493 generator.emitLabel(topOfLoop.get());
fpizlo@apple.coma71ab052011-09-13 05:35:53 +00003494 generator.emitLoopHint();
commit-queue@webkit.org1b331cb2012-08-06 03:16:46 +00003495
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00003496 generator.emitNodeInTailPosition(dst, m_statement);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003497
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003498 generator.emitLabel(*scope->continueTarget());
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00003499 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003500
3501 generator.emitLabel(scope->breakTarget());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003502}
3503
3504// ------------------------------ WhileNode ------------------------------------
3505
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003506void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003507{
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00003508 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
3509 generator.emitLoad(dst, jsUndefined());
3510
utatane.tea@gmail.com276d22b2017-04-29 16:32:59 +00003511 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003512 Ref<Label> topOfLoop = generator.newLabel();
fpizlo@apple.comda27d042012-05-20 10:00:08 +00003513
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00003514 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
fpizlo@apple.comda27d042012-05-20 10:00:08 +00003515
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003516 generator.emitLabel(topOfLoop.get());
fpizlo@apple.coma71ab052011-09-13 05:35:53 +00003517 generator.emitLoopHint();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003518
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003519 generator.emitProfileControlFlow(m_statement->startOffset());
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00003520 generator.emitNodeInTailPosition(dst, m_statement);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003521
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003522 generator.emitLabel(*scope->continueTarget());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003523
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00003524 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003525
3526 generator.emitLabel(scope->breakTarget());
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003527
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003528 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003529}
3530
3531// ------------------------------ ForNode --------------------------------------
3532
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003533void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003534{
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00003535 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
3536 generator.emitLoad(dst, jsUndefined());
3537
utatane.tea@gmail.com276d22b2017-04-29 16:32:59 +00003538 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003539
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003540 RegisterID* forLoopSymbolTable = nullptr;
sbarati@apple.combdbba812015-12-19 00:19:41 +00003541 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003542
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003543 if (m_expr1)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003544 generator.emitNode(generator.ignoredResult(), m_expr1);
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00003545
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003546 Ref<Label> topOfLoop = generator.newLabel();
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003547 if (m_expr2)
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00003548 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
fpizlo@apple.comda27d042012-05-20 10:00:08 +00003549
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003550 generator.emitLabel(topOfLoop.get());
fpizlo@apple.coma71ab052011-09-13 05:35:53 +00003551 generator.emitLoopHint();
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003552 generator.emitProfileControlFlow(m_statement->startOffset());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003553
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00003554 generator.emitNodeInTailPosition(dst, m_statement);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003555
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003556 generator.emitLabel(*scope->continueTarget());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003557 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003558 if (m_expr3)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003559 generator.emitNode(generator.ignoredResult(), m_expr3);
3560
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003561 if (m_expr2)
ggaren@apple.comd7cf35d2013-03-29 19:12:18 +00003562 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003563 else
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003564 generator.emitJump(topOfLoop.get());
3565
3566 generator.emitLabel(scope->breakTarget());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003567 generator.popLexicalScope(this);
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003568 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003569}
3570
3571// ------------------------------ ForInNode ------------------------------------
3572
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003573RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003574{
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003575 if (m_lexpr->isResolveNode()) {
3576 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003577 return generator.variable(ident).local();
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003578 }
3579
saambarati1@gmail.comcc3bcb62015-07-02 23:53:10 +00003580 if (m_lexpr->isDestructuringNode()) {
3581 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003582 auto binding = assignNode->bindings();
3583 if (!binding->isBindingNode())
3584 return nullptr;
3585
3586 auto simpleBinding = static_cast<BindingNode*>(binding);
3587 const Identifier& ident = simpleBinding->boundProperty();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003588 Variable var = generator.variable(ident);
3589 if (var.isSpecial())
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003590 return nullptr;
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003591 return var.local();
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003592 }
3593
3594 return nullptr;
3595}
3596
3597void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
3598{
sbarati@apple.com180ae512017-07-06 18:43:41 +00003599 auto lambdaEmitResolveVariable = [&] (const Identifier& ident) {
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003600 Variable var = generator.variable(ident);
commit-queue@webkit.orge7874f42016-08-17 23:57:03 +00003601 if (RegisterID* local = var.local()) {
3602 if (var.isReadOnly())
3603 generator.emitReadOnlyExceptionIfNeeded(var);
keith_miller@apple.com35210892018-06-01 18:11:36 +00003604 generator.move(local, propertyName);
commit-queue@webkit.orge7874f42016-08-17 23:57:03 +00003605 } else {
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00003606 if (generator.ecmaMode().isStrict())
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003607 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
commit-queue@webkit.orge7874f42016-08-17 23:57:03 +00003608 if (var.isReadOnly())
3609 generator.emitReadOnlyExceptionIfNeeded(var);
mark.lam@apple.com4a23c922017-03-11 01:38:22 +00003610 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003611 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00003612 generator.emitPutToScope(scope.get(), var, propertyName, generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003613 }
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +00003614 generator.emitProfileType(propertyName, var, m_lexpr->position(), m_lexpr->position() + ident.length());
gskachkov@gmail.comad01d6b2016-08-24 13:35:38 +00003615 };
3616
3617 if (m_lexpr->isResolveNode()) {
3618 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
3619 lambdaEmitResolveVariable(ident);
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003620 return;
3621 }
gskachkov@gmail.comad01d6b2016-08-24 13:35:38 +00003622
3623 if (m_lexpr->isAssignResolveNode()) {
3624 const Identifier& ident = static_cast<AssignResolveNode*>(m_lexpr)->identifier();
3625 lambdaEmitResolveVariable(ident);
3626 return;
3627 }
3628
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003629 if (m_lexpr->isDotAccessorNode()) {
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003630 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
3631 const Identifier& ident = assignNode->identifier();
sbarati@apple.com23315d62016-05-09 20:17:23 +00003632 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003633 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003634 if (assignNode->base()->isSuperNode()) {
3635 RefPtr<RegisterID> thisValue = generator.ensureThis();
3636 generator.emitPutById(base.get(), thisValue.get(), ident, propertyName);
3637 } else
3638 generator.emitPutById(base.get(), ident, propertyName);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003639 generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003640 return;
3641 }
3642 if (m_lexpr->isBracketAccessorNode()) {
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003643 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003644 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00003645 RefPtr<RegisterID> subscript = generator.emitNodeForProperty(assignNode->subscript());
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00003646 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003647 if (assignNode->base()->isSuperNode()) {
3648 RefPtr<RegisterID> thisValue = generator.ensureThis();
3649 generator.emitPutByVal(base.get(), thisValue.get(), subscript.get(), propertyName);
3650 } else
3651 generator.emitPutByVal(base.get(), subscript.get(), propertyName);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003652 generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003653 return;
oliver@apple.comd055db62013-10-02 19:11:04 +00003654 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003655
saambarati1@gmail.comcc3bcb62015-07-02 23:53:10 +00003656 if (m_lexpr->isDestructuringNode()) {
3657 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003658 auto binding = assignNode->bindings();
3659 if (!binding->isBindingNode()) {
3660 assignNode->bindings()->bindValue(generator, propertyName);
3661 return;
3662 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003663
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003664 auto simpleBinding = static_cast<BindingNode*>(binding);
3665 const Identifier& ident = simpleBinding->boundProperty();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003666 Variable var = generator.variable(ident);
3667 if (!var.local() || var.isSpecial()) {
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003668 assignNode->bindings()->bindValue(generator, propertyName);
3669 return;
3670 }
keith_miller@apple.com35210892018-06-01 18:11:36 +00003671 generator.move(var.local(), propertyName);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003672 generator.emitProfileType(propertyName, var, simpleBinding->divotStart(), simpleBinding->divotEnd());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003673 return;
3674 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003675
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003676 RELEASE_ASSERT_NOT_REACHED();
3677}
3678
commit-queue@webkit.org3057eed2016-09-21 22:52:37 +00003679void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003680{
gskachkov@gmail.comad01d6b2016-08-24 13:35:38 +00003681 if (!m_lexpr->isAssignResolveNode() && !m_lexpr->isAssignmentLocation()) {
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00003682 emitThrowReferenceError(generator, "Left side of for-in statement is not a reference."_s);
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003683 return;
3684 }
3685
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00003686 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
3687 generator.emitLoad(dst, jsUndefined());
3688
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003689 Ref<Label> end = generator.newLabel();
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003690
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003691 RegisterID* forLoopSymbolTable = nullptr;
sbarati@apple.combdbba812015-12-19 00:19:41 +00003692 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003693
gskachkov@gmail.comad01d6b2016-08-24 13:35:38 +00003694 if (m_lexpr->isAssignResolveNode())
3695 generator.emitNode(generator.ignoredResult(), m_lexpr);
3696
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003697 RefPtr<RegisterID> base = generator.newTemporary();
3698 RefPtr<RegisterID> length;
msaboff@apple.comb644c252015-03-24 10:05:21 +00003699 RefPtr<RegisterID> enumerator;
gskachkov@gmail.comad01d6b2016-08-24 13:35:38 +00003700
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003701 generator.emitNode(base.get(), m_expr);
3702 RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
msaboff@apple.comb644c252015-03-24 10:05:21 +00003703 RefPtr<RegisterID> enumeratorIndex;
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003704
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003705 // Pause at the assignment expression for each for..in iteration.
3706 generator.emitDebugHook(m_lexpr);
3707
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003708 int profilerStartOffset = m_statement->startOffset();
3709 int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
msaboff@apple.comb644c252015-03-24 10:05:21 +00003710
3711 enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
3712
mark.lam@apple.comd55adc12018-05-26 00:23:57 +00003713 BytecodeGenerator::PreservedTDZStack preservedTDZStack;
3714 generator.preserveTDZStack(preservedTDZStack);
3715
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003716 // Indexed property loop.
3717 {
utatane.tea@gmail.com276d22b2017-04-29 16:32:59 +00003718 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003719 Ref<Label> loopStart = generator.newLabel();
3720 Ref<Label> loopEnd = generator.newLabel();
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003721
msaboff@apple.comb644c252015-03-24 10:05:21 +00003722 length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003723 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
3724 RefPtr<RegisterID> propertyName = generator.newTemporary();
3725
3726 generator.emitLabel(loopStart.get());
3727 generator.emitLoopHint();
3728
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00003729 RefPtr<RegisterID> result = generator.emitEqualityOp<OpLess>(generator.newTemporary(), i.get(), length.get());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003730 generator.emitJumpIfFalse(result.get(), loopEnd.get());
3731 generator.emitHasIndexedProperty(result.get(), base.get(), i.get());
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003732 generator.emitJumpIfFalse(result.get(), *scope->continueTarget());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003733
3734 generator.emitToIndexString(propertyName.get(), i.get());
3735 this->emitLoopHeader(generator, propertyName.get());
3736
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003737 generator.emitProfileControlFlow(profilerStartOffset);
saambarati1@gmail.comd60d9412015-01-20 04:47:55 +00003738
fpizlo@apple.comcaf35052014-08-20 02:38:46 +00003739 generator.pushIndexedForInScope(local.get(), i.get());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003740 generator.emitNode(dst, m_statement);
3741 generator.popIndexedForInScope(local.get());
3742
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003743 generator.emitProfileControlFlow(profilerEndOffset);
saambarati1@gmail.comd60d9412015-01-20 04:47:55 +00003744
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003745 generator.emitLabel(*scope->continueTarget());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003746 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003747 generator.emitInc(i.get());
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003748 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration.
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003749 generator.emitJump(loopStart.get());
3750
3751 generator.emitLabel(scope->breakTarget());
3752 generator.emitJump(end.get());
3753 generator.emitLabel(loopEnd.get());
3754 }
mark.lam@apple.comd55adc12018-05-26 00:23:57 +00003755 generator.restoreTDZStack(preservedTDZStack);
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003756
3757 // Structure property loop.
3758 {
utatane.tea@gmail.com276d22b2017-04-29 16:32:59 +00003759 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003760 Ref<Label> loopStart = generator.newLabel();
3761 Ref<Label> loopEnd = generator.newLabel();
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003762
msaboff@apple.comb644c252015-03-24 10:05:21 +00003763 enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003764 RefPtr<RegisterID> propertyName = generator.newTemporary();
msaboff@apple.comb644c252015-03-24 10:05:21 +00003765 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003766
3767 generator.emitLabel(loopStart.get());
3768 generator.emitLoopHint();
3769
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00003770 RefPtr<RegisterID> result = generator.emitUnaryOp<OpEqNull>(generator.newTemporary(), propertyName.get());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003771 generator.emitJumpIfTrue(result.get(), loopEnd.get());
msaboff@apple.comb644c252015-03-24 10:05:21 +00003772 generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003773 generator.emitJumpIfFalse(result.get(), *scope->continueTarget());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003774
3775 this->emitLoopHeader(generator, propertyName.get());
3776
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003777 generator.emitProfileControlFlow(profilerStartOffset);
saambarati1@gmail.comd60d9412015-01-20 04:47:55 +00003778
msaboff@apple.comb644c252015-03-24 10:05:21 +00003779 generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003780 generator.emitNode(dst, m_statement);
3781 generator.popStructureForInScope(local.get());
3782
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003783 generator.emitProfileControlFlow(profilerEndOffset);
saambarati1@gmail.comd60d9412015-01-20 04:47:55 +00003784
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003785 generator.emitLabel(*scope->continueTarget());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003786 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
msaboff@apple.comb644c252015-03-24 10:05:21 +00003787 generator.emitInc(enumeratorIndex.get());
3788 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003789 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration.
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003790 generator.emitJump(loopStart.get());
3791
3792 generator.emitLabel(scope->breakTarget());
3793 generator.emitJump(end.get());
3794 generator.emitLabel(loopEnd.get());
3795 }
mark.lam@apple.comd55adc12018-05-26 00:23:57 +00003796 generator.restoreTDZStack(preservedTDZStack);
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003797
3798 // Generic property loop.
3799 {
utatane.tea@gmail.com276d22b2017-04-29 16:32:59 +00003800 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003801 Ref<Label> loopStart = generator.newLabel();
3802 Ref<Label> loopEnd = generator.newLabel();
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003803
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003804 RefPtr<RegisterID> propertyName = generator.newTemporary();
3805
msaboff@apple.comb644c252015-03-24 10:05:21 +00003806 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003807
3808 generator.emitLabel(loopStart.get());
3809 generator.emitLoopHint();
3810
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00003811 RefPtr<RegisterID> result = generator.emitUnaryOp<OpEqNull>(generator.newTemporary(), propertyName.get());
msaboff@apple.comb644c252015-03-24 10:05:21 +00003812 generator.emitJumpIfTrue(result.get(), loopEnd.get());
3813
3814 generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003815 generator.emitJumpIfFalse(result.get(), *scope->continueTarget());
msaboff@apple.comb644c252015-03-24 10:05:21 +00003816
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003817 this->emitLoopHeader(generator, propertyName.get());
3818
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003819 generator.emitProfileControlFlow(profilerStartOffset);
saambarati1@gmail.comd60d9412015-01-20 04:47:55 +00003820
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003821 generator.emitNode(dst, m_statement);
3822
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003823 generator.emitLabel(*scope->continueTarget());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003824 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
msaboff@apple.comb644c252015-03-24 10:05:21 +00003825 generator.emitInc(enumeratorIndex.get());
3826 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
joepeck@webkit.orgb5fbd452016-10-12 18:47:48 +00003827 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration.
msaboff@apple.comb644c252015-03-24 10:05:21 +00003828 generator.emitJump(loopStart.get());
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003829
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003830 generator.emitLabel(scope->breakTarget());
3831 generator.emitJump(end.get());
3832 generator.emitLabel(loopEnd.get());
3833 }
3834
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003835 generator.emitLabel(end.get());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003836 generator.popLexicalScope(this);
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003837 generator.emitProfileControlFlow(profilerEndOffset);
fpizlo@apple.coma398a562014-08-06 21:32:55 +00003838}
3839
oliver@apple.com20a9bf02013-10-04 20:35:24 +00003840// ------------------------------ ForOfNode ------------------------------------
oliver@apple.com20a9bf02013-10-04 20:35:24 +00003841void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3842{
oliver@apple.com313fcd62014-03-25 20:06:07 +00003843 if (!m_lexpr->isAssignmentLocation()) {
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00003844 emitThrowReferenceError(generator, "Left side of for-of statement is not a reference."_s);
oliver@apple.com20a9bf02013-10-04 20:35:24 +00003845 return;
3846 }
utatane.tea@gmail.combc074492015-04-01 09:36:15 +00003847
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00003848 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
3849 generator.emitLoad(dst, jsUndefined());
3850
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003851 RegisterID* forLoopSymbolTable = nullptr;
sbarati@apple.combdbba812015-12-19 00:19:41 +00003852 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
utatane.tea@gmail.comb67c9082018-07-21 13:10:43 +00003853 auto extractor = scopedLambda<void(BytecodeGenerator&, RegisterID*)>([this, dst](BytecodeGenerator& generator, RegisterID* value)
oliver@apple.com20a9bf02013-10-04 20:35:24 +00003854 {
oliver@apple.com72f8a822013-10-17 01:02:34 +00003855 if (m_lexpr->isResolveNode()) {
3856 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00003857 Variable var = generator.variable(ident);
commit-queue@webkit.orge7874f42016-08-17 23:57:03 +00003858 if (RegisterID* local = var.local()) {
3859 if (var.isReadOnly())
3860 generator.emitReadOnlyExceptionIfNeeded(var);
keith_miller@apple.com35210892018-06-01 18:11:36 +00003861 generator.move(local, value);
commit-queue@webkit.orge7874f42016-08-17 23:57:03 +00003862 } else {
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00003863 if (generator.ecmaMode().isStrict())
oliver@apple.com72f8a822013-10-17 01:02:34 +00003864 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
commit-queue@webkit.orge7874f42016-08-17 23:57:03 +00003865 if (var.isReadOnly())
3866 generator.emitReadOnlyExceptionIfNeeded(var);
mark.lam@apple.com4a23c922017-03-11 01:38:22 +00003867 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
oliver@apple.com20a9bf02013-10-04 20:35:24 +00003868 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00003869 generator.emitPutToScope(scope.get(), var, value, generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
oliver@apple.com72f8a822013-10-17 01:02:34 +00003870 }
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +00003871 generator.emitProfileType(value, var, m_lexpr->position(), m_lexpr->position() + ident.length());
oliver@apple.com72f8a822013-10-17 01:02:34 +00003872 } else if (m_lexpr->isDotAccessorNode()) {
3873 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
3874 const Identifier& ident = assignNode->identifier();
3875 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
3876
3877 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003878 if (assignNode->base()->isSuperNode()) {
3879 RefPtr<RegisterID> thisValue = generator.ensureThis();
3880 generator.emitPutById(base.get(), thisValue.get(), ident, value);
3881 } else
3882 generator.emitPutById(base.get(), ident, value);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003883 generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
oliver@apple.com72f8a822013-10-17 01:02:34 +00003884 } else if (m_lexpr->isBracketAccessorNode()) {
3885 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
3886 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00003887 RegisterID* subscript = generator.emitNodeForProperty(assignNode->subscript());
oliver@apple.com72f8a822013-10-17 01:02:34 +00003888
3889 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00003890 if (assignNode->base()->isSuperNode()) {
3891 RefPtr<RegisterID> thisValue = generator.ensureThis();
3892 generator.emitPutByVal(base.get(), thisValue.get(), subscript, value);
3893 } else
3894 generator.emitPutByVal(base.get(), subscript, value);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003895 generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
oliver@apple.com72f8a822013-10-17 01:02:34 +00003896 } else {
saambarati1@gmail.comcc3bcb62015-07-02 23:53:10 +00003897 ASSERT(m_lexpr->isDestructuringNode());
3898 DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
oliver@apple.com47784d62013-10-25 21:31:36 +00003899 assignNode->bindings()->bindValue(generator, value);
oliver@apple.com20a9bf02013-10-04 20:35:24 +00003900 }
saambarati1@gmail.comd60d9412015-01-20 04:47:55 +00003901 generator.emitProfileControlFlow(m_statement->startOffset());
oliver@apple.com72f8a822013-10-17 01:02:34 +00003902 generator.emitNode(dst, m_statement);
utatane.tea@gmail.comb67c9082018-07-21 13:10:43 +00003903 });
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00003904 generator.emitEnumeration(this, m_expr, extractor, this, forLoopSymbolTable);
3905 generator.popLexicalScope(this);
saambarati1@gmail.com15952502015-02-23 22:10:51 +00003906 generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
oliver@apple.com20a9bf02013-10-04 20:35:24 +00003907}
3908
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003909// ------------------------------ ContinueNode ---------------------------------
3910
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003911Label* ContinueNode::trivialTarget(BytecodeGenerator& generator)
3912{
3913 if (generator.shouldEmitDebugHooks())
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003914 return nullptr;
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003915
utatane.tea@gmail.com0f553b12017-08-17 12:15:48 +00003916 LabelScope* scope = generator.continueTarget(m_ident);
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003917 ASSERT(scope);
3918
saambarati1@gmail.com3fff23c2015-07-19 00:36:45 +00003919 if (generator.labelScopeDepth() != scope->scopeDepth())
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003920 return nullptr;
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003921
3922 return scope->continueTarget();
3923}
3924
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003925void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003926{
utatane.tea@gmail.com0f553b12017-08-17 12:15:48 +00003927 LabelScope* scope = generator.continueTarget(m_ident);
barraclough@apple.com7e6bd6d2011-01-10 20:20:15 +00003928 ASSERT(scope);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003929
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003930 bool hasFinally = generator.emitJumpViaFinallyIfNeeded(scope->scopeDepth(), *scope->continueTarget());
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00003931 if (!hasFinally) {
3932 int lexicalScopeIndex = generator.labelScopeDepthToLexicalScopeIndex(scope->scopeDepth());
3933 generator.restoreScopeRegister(lexicalScopeIndex);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003934 generator.emitJump(*scope->continueTarget());
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00003935 }
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003936
3937 generator.emitProfileControlFlow(endOffset());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003938}
3939
3940// ------------------------------ BreakNode ------------------------------------
3941
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003942Label* BreakNode::trivialTarget(BytecodeGenerator& generator)
3943{
3944 if (generator.shouldEmitDebugHooks())
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003945 return nullptr;
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003946
utatane.tea@gmail.com0f553b12017-08-17 12:15:48 +00003947 LabelScope* scope = generator.breakTarget(m_ident);
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003948 ASSERT(scope);
3949
saambarati1@gmail.com3fff23c2015-07-19 00:36:45 +00003950 if (generator.labelScopeDepth() != scope->scopeDepth())
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003951 return nullptr;
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003952
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00003953 return &scope->breakTarget();
ggaren@apple.com81c68cc2013-04-27 06:43:33 +00003954}
3955
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003956void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003957{
utatane.tea@gmail.com0f553b12017-08-17 12:15:48 +00003958 LabelScope* scope = generator.breakTarget(m_ident);
barraclough@apple.com7e6bd6d2011-01-10 20:20:15 +00003959 ASSERT(scope);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003960
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00003961 bool hasFinally = generator.emitJumpViaFinallyIfNeeded(scope->scopeDepth(), scope->breakTarget());
3962 if (!hasFinally) {
3963 int lexicalScopeIndex = generator.labelScopeDepthToLexicalScopeIndex(scope->scopeDepth());
3964 generator.restoreScopeRegister(lexicalScopeIndex);
3965 generator.emitJump(scope->breakTarget());
3966 }
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003967
3968 generator.emitProfileControlFlow(endOffset());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003969}
3970
3971// ------------------------------ ReturnNode -----------------------------------
3972
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00003973void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003974{
barraclough@apple.com7e6bd6d2011-01-10 20:20:15 +00003975 ASSERT(generator.codeType() == FunctionCode);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003976
3977 if (dst == generator.ignoredResult())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00003978 dst = nullptr;
ggaren@apple.comb4787ec2013-03-29 00:09:56 +00003979
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00003980 RefPtr<RegisterID> returnRegister = m_value ? generator.emitNodeInTailPosition(dst, m_value) : generator.emitLoad(dst, jsUndefined());
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00003981
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00003982 generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, divotStart(), divotEnd());
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00003983
3984 bool hasFinally = generator.emitReturnViaFinallyIfNeeded(returnRegister.get());
3985 if (!hasFinally) {
gskachkov@gmail.comab749fd2017-08-23 17:05:33 +00003986 if (generator.parseMode() == SourceParseMode::AsyncGeneratorBodyMode) {
keith_miller@apple.com35210892018-06-01 18:11:36 +00003987 returnRegister = generator.move(generator.newTemporary(), returnRegister.get());
gskachkov@gmail.comab749fd2017-08-23 17:05:33 +00003988 generator.emitAwait(returnRegister.get());
3989 }
3990
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00003991 generator.emitWillLeaveCallFrameDebugHook();
3992 generator.emitReturn(returnRegister.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00003993 }
ggaren@apple.comb4787ec2013-03-29 00:09:56 +00003994
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00003995 generator.emitProfileControlFlow(endOffset());
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003996 // Emitting an unreachable return here is needed in case this op_profile_control_flow is the
3997 // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode.
ysuzuki@apple.comcdbe02a2019-05-03 18:54:44 +00003998 if (generator.shouldEmitControlFlowProfilerHooks())
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00003999 generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004000}
4001
4002// ------------------------------ WithNode -------------------------------------
4003
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004004void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004005{
ggaren@apple.com170d6f22012-09-02 21:27:23 +00004006 RefPtr<RegisterID> scope = generator.emitNode(m_expr);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00004007 generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
saambarati1@gmail.come85426c2015-08-07 17:41:22 +00004008 generator.emitPushWithScope(scope.get());
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00004009 if (generator.shouldBeConcernedWithCompletionValue() && m_statement->hasEarlyBreakOrContinue())
4010 generator.emitLoad(dst, jsUndefined());
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00004011 generator.emitNodeInTailPosition(dst, m_statement);
saambarati1@gmail.come85426c2015-08-07 17:41:22 +00004012 generator.emitPopWithScope();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004013}
4014
4015// ------------------------------ CaseClauseNode --------------------------------
4016
4017inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
4018{
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00004019 generator.emitProfileControlFlow(m_startOffset);
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004020 if (!m_statements)
4021 return;
4022 m_statements->emitBytecode(generator, dst);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004023}
4024
4025// ------------------------------ CaseBlockNode --------------------------------
4026
4027enum SwitchKind {
4028 SwitchUnset = 0,
4029 SwitchNumber = 1,
4030 SwitchString = 2,
4031 SwitchNeither = 3
4032};
4033
4034static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
4035{
4036 for (; list; list = list->getNext()) {
4037 ExpressionNode* clauseExpression = list->getClause()->expr();
4038 literalVector.append(clauseExpression);
4039 if (clauseExpression->isNumber()) {
4040 double value = static_cast<NumberNode*>(clauseExpression)->value();
4041 int32_t intVal = static_cast<int32_t>(value);
4042 if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
4043 typeForTable = SwitchNeither;
4044 break;
4045 }
4046 if (intVal < min_num)
4047 min_num = intVal;
4048 if (intVal > max_num)
4049 max_num = intVal;
4050 typeForTable = SwitchNumber;
4051 continue;
4052 }
4053 if (clauseExpression->isString()) {
4054 if (typeForTable & ~SwitchString) {
4055 typeForTable = SwitchNeither;
4056 break;
4057 }
benjamin@webkit.orgc9b7a202012-09-08 05:46:29 +00004058 const String& value = static_cast<StringNode*>(clauseExpression)->value().string();
barraclough@apple.comc2527d62010-08-11 19:52:41 +00004059 if (singleCharacterSwitch &= value.length() == 1) {
msaboff@apple.comaeb7a4a2011-09-01 20:04:34 +00004060 int32_t intVal = value[0];
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004061 if (intVal < min_num)
4062 min_num = intVal;
4063 if (intVal > max_num)
4064 max_num = intVal;
4065 }
4066 typeForTable = SwitchString;
4067 continue;
4068 }
4069 typeForTable = SwitchNeither;
4070 break;
4071 }
4072}
ggaren@apple.com18bbb012013-01-30 05:43:47 +00004073
4074static inline size_t length(ClauseListNode* list1, ClauseListNode* list2)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004075{
ggaren@apple.com18bbb012013-01-30 05:43:47 +00004076 size_t length = 0;
4077 for (ClauseListNode* node = list1; node; node = node->getNext())
4078 ++length;
4079 for (ClauseListNode* node = list2; node; node = node->getNext())
4080 ++length;
4081 return length;
4082}
4083
4084SwitchInfo::SwitchType CaseBlockNode::tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
4085{
4086 if (length(m_list1, m_list2) < s_tableSwitchMinimum)
4087 return SwitchInfo::SwitchNone;
4088
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004089 SwitchKind typeForTable = SwitchUnset;
4090 bool singleCharacterSwitch = true;
4091
4092 processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
4093 processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
4094
4095 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
4096 return SwitchInfo::SwitchNone;
4097
4098 if (typeForTable == SwitchNumber) {
4099 int32_t range = max_num - min_num;
4100 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
4101 return SwitchInfo::SwitchImmediate;
4102 return SwitchInfo::SwitchNone;
4103 }
4104
4105 ASSERT(typeForTable == SwitchString);
4106
4107 if (singleCharacterSwitch) {
4108 int32_t range = max_num - min_num;
4109 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
4110 return SwitchInfo::SwitchCharacter;
4111 }
4112
4113 return SwitchInfo::SwitchString;
4114}
4115
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004116void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004117{
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004118 Vector<Ref<Label>, 8> labelVector;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004119 Vector<ExpressionNode*, 8> literalVector;
4120 int32_t min_num = std::numeric_limits<int32_t>::max();
4121 int32_t max_num = std::numeric_limits<int32_t>::min();
ggaren@apple.com18bbb012013-01-30 05:43:47 +00004122 SwitchInfo::SwitchType switchType = tryTableSwitch(literalVector, min_num, max_num);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004123
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004124 Ref<Label> defaultLabel = generator.newLabel();
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004125 if (switchType != SwitchInfo::SwitchNone) {
4126 // Prepare the various labels
4127 for (uint32_t i = 0; i < literalVector.size(); i++)
4128 labelVector.append(generator.newLabel());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004129 generator.beginSwitch(switchExpression, switchType);
4130 } else {
4131 // Setup jumps
4132 for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
4133 RefPtr<RegisterID> clauseVal = generator.newTemporary();
4134 generator.emitNode(clauseVal.get(), list->getClause()->expr());
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00004135 generator.emitBinaryOp<OpStricteq>(clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004136 labelVector.append(generator.newLabel());
4137 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
4138 }
4139
4140 for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
4141 RefPtr<RegisterID> clauseVal = generator.newTemporary();
4142 generator.emitNode(clauseVal.get(), list->getClause()->expr());
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00004143 generator.emitBinaryOp<OpStricteq>(clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004144 labelVector.append(generator.newLabel());
4145 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
4146 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004147 generator.emitJump(defaultLabel.get());
4148 }
4149
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004150 size_t i = 0;
4151 for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
4152 generator.emitLabel(labelVector[i++].get());
4153 list->getClause()->emitBytecode(generator, dst);
4154 }
4155
4156 if (m_defaultClause) {
4157 generator.emitLabel(defaultLabel.get());
4158 m_defaultClause->emitBytecode(generator, dst);
4159 }
4160
4161 for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
4162 generator.emitLabel(labelVector[i++].get());
4163 list->getClause()->emitBytecode(generator, dst);
4164 }
4165 if (!m_defaultClause)
4166 generator.emitLabel(defaultLabel.get());
4167
4168 ASSERT(i == labelVector.size());
4169 if (switchType != SwitchInfo::SwitchNone) {
4170 ASSERT(labelVector.size() == literalVector.size());
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004171 generator.endSwitch(labelVector.size(), labelVector, literalVector.data(), defaultLabel.get(), min_num, max_num);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004172 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004173}
4174
4175// ------------------------------ SwitchNode -----------------------------------
4176
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004177void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004178{
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00004179 if (generator.shouldBeConcernedWithCompletionValue())
4180 generator.emitLoad(dst, jsUndefined());
4181
utatane.tea@gmail.com276d22b2017-04-29 16:32:59 +00004182 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004183
4184 RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00004185
sbarati@apple.combdbba812015-12-19 00:19:41 +00004186 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::DoNotOptimize, BytecodeGenerator::NestedScopeType::IsNested);
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004187 m_block->emitBytecodeForBlock(generator, r0.get(), dst);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00004188 generator.popLexicalScope(this);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004189
4190 generator.emitLabel(scope->breakTarget());
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00004191 generator.emitProfileControlFlow(endOffset());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004192}
4193
4194// ------------------------------ LabelNode ------------------------------------
4195
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004196void LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004197{
barraclough@apple.com7e6bd6d2011-01-10 20:20:15 +00004198 ASSERT(!generator.breakTarget(m_name));
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004199
utatane.tea@gmail.com276d22b2017-04-29 16:32:59 +00004200 Ref<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +00004201 generator.emitNodeInTailPosition(dst, m_statement);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004202
4203 generator.emitLabel(scope->breakTarget());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004204}
4205
4206// ------------------------------ ThrowNode ------------------------------------
4207
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004208void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004209{
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004210 if (dst == generator.ignoredResult())
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00004211 dst = nullptr;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004212 RefPtr<RegisterID> expr = generator.emitNode(m_expr);
mark.lam@apple.com3b256ca2013-07-30 17:01:40 +00004213 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004214 generator.emitThrow(expr.get());
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00004215
4216 generator.emitProfileControlFlow(endOffset());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004217}
4218
4219// ------------------------------ TryNode --------------------------------------
4220
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004221void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004222{
4223 // NOTE: The catch and finally blocks must be labeled explicitly, so the
4224 // optimizer knows they may be jumped to from anywhere.
4225
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00004226 if (generator.shouldBeConcernedWithCompletionValue() && m_tryBlock->hasEarlyBreakOrContinue())
4227 generator.emitLoad(dst, jsUndefined());
4228
fpizlo@apple.comb08ed272012-08-27 00:49:25 +00004229 ASSERT(m_catchBlock || m_finallyBlock);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004230
4231 RefPtr<Label> catchLabel;
4232 RefPtr<Label> catchEndLabel;
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004233 RefPtr<Label> finallyLabel;
4234 RefPtr<Label> finallyEndLabel;
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004235 Optional<FinallyContext> finallyContext;
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004236
4237 if (m_finallyBlock) {
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004238 finallyLabel = generator.newLabel();
4239 finallyEndLabel = generator.newLabel();
4240
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004241 finallyContext.emplace(generator, *finallyLabel);
4242 generator.pushFinallyControlFlowScope(finallyContext.value());
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004243 }
4244 if (m_catchBlock) {
4245 catchLabel = generator.newLabel();
4246 catchEndLabel = generator.newLabel();
4247 }
4248
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004249 Ref<Label> tryLabel = generator.newEmittedLabel();
4250 Label& tryHandlerLabel = m_catchBlock ? *catchLabel : *finallyLabel;
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004251 HandlerType tryHandlerType = m_catchBlock ? HandlerType::Catch : HandlerType::Finally;
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004252 TryData* tryData = generator.pushTry(tryLabel.get(), tryHandlerLabel, tryHandlerType);
sbarati@apple.com60a3be72017-08-25 18:26:15 +00004253 TryData* finallyTryData = nullptr;
4254 if (!m_catchBlock && m_finallyBlock)
4255 finallyTryData = tryData;
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004256
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004257 generator.emitNode(dst, m_tryBlock);
4258
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004259 if (m_finallyBlock)
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004260 generator.emitJump(*finallyLabel);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004261 else
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004262 generator.emitJump(*catchEndLabel);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004263
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004264 Ref<Label> tryEndLabel = generator.newEmittedLabel();
4265 generator.popTry(tryData, tryEndLabel.get());
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004266
4267 if (m_catchBlock) {
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004268 // Uncaught exception path: the catch block.
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004269 generator.emitLabel(*catchLabel);
mark.lam@apple.com6ed08272015-06-05 18:52:12 +00004270 RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004271 RegisterID* completionTypeRegister = m_finallyBlock ? finallyContext->completionTypeRegister() : nullptr;
4272 generator.emitOutOfLineCatchHandler(thrownValueRegister.get(), completionTypeRegister, tryData);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004273 generator.restoreScopeRegister();
4274
fpizlo@apple.comb08ed272012-08-27 00:49:25 +00004275 if (m_finallyBlock) {
4276 // If the catch block throws an exception and we have a finally block, then the finally
4277 // block should "catch" that exception.
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004278 finallyTryData = generator.pushTry(*catchLabel, *finallyLabel, HandlerType::Finally);
fpizlo@apple.comb08ed272012-08-27 00:49:25 +00004279 }
msaboff@apple.comc5b95392014-10-31 21:27:10 +00004280
utatane.tea@gmail.comc2a96e22017-07-31 16:15:32 +00004281 if (m_catchPattern) {
4282 generator.emitPushCatchScope(m_lexicalVariables);
4283 m_catchPattern->bindValue(generator, thrownValueRegister.get());
4284 }
4285
saambarati1@gmail.com15952502015-02-23 22:10:51 +00004286 generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
basile_clement@apple.comfb3c1562015-09-04 03:05:46 +00004287 if (m_finallyBlock)
4288 generator.emitNode(dst, m_catchBlock);
4289 else
4290 generator.emitNodeInTailPosition(dst, m_catchBlock);
msaboff@apple.com78461ac2016-06-02 04:07:14 +00004291 generator.emitLoad(thrownValueRegister.get(), jsUndefined());
utatane.tea@gmail.comc2a96e22017-07-31 16:15:32 +00004292
4293 if (m_catchPattern)
4294 generator.emitPopCatchScope(m_lexicalVariables);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004295
4296 if (m_finallyBlock) {
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004297 generator.emitLoad(finallyContext->completionTypeRegister(), CompletionType::Normal);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004298 generator.emitJump(*finallyLabel);
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004299 generator.popTry(finallyTryData, *finallyLabel);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004300 }
4301
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004302 generator.emitLabel(*catchEndLabel);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004303 generator.emitProfileControlFlow(m_catchBlock->endOffset() + 1);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004304 }
4305
4306 if (m_finallyBlock) {
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004307 generator.popFinallyControlFlowScope();
fpizlo@apple.comdd58bf92012-04-04 04:25:56 +00004308
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004309 // Entry to the finally block for CompletionType::Throw to be generated later.
4310 generator.emitOutOfLineFinallyHandler(finallyContext->completionValueRegister(), finallyContext->completionTypeRegister(), finallyTryData);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004311
4312 // Entry to the finally block for CompletionTypes other than Throw.
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004313 generator.emitLabel(*finallyLabel);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004314 generator.restoreScopeRegister();
4315
saambarati1@gmail.com15952502015-02-23 22:10:51 +00004316 int finallyStartOffset = m_catchBlock ? m_catchBlock->endOffset() + 1 : m_tryBlock->endOffset() + 1;
saambarati1@gmail.comd60d9412015-01-20 04:47:55 +00004317 generator.emitProfileControlFlow(finallyStartOffset);
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00004318 generator.emitNodeInTailPosition(m_finallyBlock);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004319
mark.lam@apple.com5100e112019-03-07 05:09:53 +00004320 generator.emitFinallyCompletion(finallyContext.value(), *finallyEndLabel);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004321 generator.emitLabel(*finallyEndLabel);
saambarati1@gmail.com15952502015-02-23 22:10:51 +00004322 generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
mark.lam@apple.com8bdb8db2016-12-22 22:48:32 +00004323 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004324}
4325
4326// ------------------------------ ScopeNode -----------------------------
4327
4328inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
4329{
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004330 if (!m_statements)
4331 return;
4332 m_statements->emitBytecode(generator, dst);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004333}
4334
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004335static void emitProgramNodeBytecode(BytecodeGenerator& generator, ScopeNode& scopeNode)
4336{
4337 generator.emitDebugHook(WillExecuteProgram, scopeNode.startLine(), scopeNode.startStartOffset(), scopeNode.startLineStartOffset());
4338
4339 RefPtr<RegisterID> dstRegister = generator.newTemporary();
4340 generator.emitLoad(dstRegister.get(), jsUndefined());
4341 generator.emitProfileControlFlow(scopeNode.startStartOffset());
4342 scopeNode.emitStatementsBytecode(generator, dstRegister.get());
4343
4344 generator.emitDebugHook(DidExecuteProgram, scopeNode.lastLine(), scopeNode.startOffset(), scopeNode.lineStartOffset());
4345 generator.emitEnd(dstRegister.get());
4346}
4347
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004348// ------------------------------ ProgramNode -----------------------------
4349
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004350void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004351{
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004352 emitProgramNodeBytecode(generator, *this);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004353}
4354
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004355// ------------------------------ ModuleProgramNode --------------------
4356
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004357void ModuleProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004358{
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004359 emitProgramNodeBytecode(generator, *this);
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004360}
4361
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004362// ------------------------------ EvalNode -----------------------------
4363
ggaren@apple.comd786e6b2013-04-04 23:16:20 +00004364void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004365{
mark.lam@apple.come72693d2013-09-24 23:52:57 +00004366 generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004367
4368 RefPtr<RegisterID> dstRegister = generator.newTemporary();
4369 generator.emitLoad(dstRegister.get(), jsUndefined());
4370 emitStatementsBytecode(generator, dstRegister.get());
4371
mark.lam@apple.come72693d2013-09-24 23:52:57 +00004372 generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004373 generator.emitEnd(dstRegister.get());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004374}
4375
ggaren@apple.come7afe402015-08-10 20:24:35 +00004376// ------------------------------ FunctionNode -----------------------------
ggaren@apple.com6f851d72014-12-04 23:47:49 +00004377
4378void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004379{
ysuzuki@apple.comcdbe02a2019-05-03 18:54:44 +00004380 if (generator.shouldEmitTypeProfilerHooks()) {
utatane.tea@gmail.com3e031ac2017-03-16 05:12:53 +00004381 // If the parameter list is non simple one, it is handled in bindValue's code.
4382 if (m_parameters->isSimpleParameterList()) {
4383 for (size_t i = 0; i < m_parameters->size(); i++) {
4384 BindingNode* bindingNode = static_cast<BindingNode*>(m_parameters->at(i).first);
4385 RegisterID reg(CallFrame::argumentOffset(i));
4386 generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, bindingNode->divotStart(), bindingNode->divotEnd());
4387 }
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00004388 }
4389 }
4390
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00004391 generator.emitProfileControlFlow(startStartOffset());
mark.lam@apple.come72693d2013-09-24 23:52:57 +00004392 generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset());
barraclough@apple.comb467c4c2010-07-13 20:34:11 +00004393
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004394 switch (generator.parseMode()) {
commit-queue@webkit.org67795122017-04-25 06:52:04 +00004395 case SourceParseMode::GeneratorWrapperFunctionMode:
gskachkov@gmail.comab749fd2017-08-23 17:05:33 +00004396 case SourceParseMode::GeneratorWrapperMethodMode:
4397 case SourceParseMode::AsyncGeneratorWrapperMethodMode:
4398 case SourceParseMode::AsyncGeneratorWrapperFunctionMode: {
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004399 StatementNode* singleStatement = this->singleStatement();
4400 ASSERT(singleStatement->isExprStatement());
4401 ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement);
4402 ExpressionNode* expr = exprStatement->expr();
4403 ASSERT(expr->isFuncExprNode());
4404 FuncExprNode* funcExpr = static_cast<FuncExprNode*>(expr);
barraclough@apple.comb467c4c2010-07-13 20:34:11 +00004405
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004406 RefPtr<RegisterID> next = generator.newTemporary();
4407 generator.emitNode(next.get(), funcExpr);
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004408
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004409 if (generator.superBinding() == SuperBinding::Needed) {
4410 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
4411 emitPutHomeObject(generator, next.get(), homeObject.get());
4412 }
4413
gskachkov@gmail.comab749fd2017-08-23 17:05:33 +00004414 if (isGeneratorWrapperParseMode(generator.parseMode()))
4415 generator.emitPutGeneratorFields(next.get());
4416 else {
utatane.tea@gmail.comf01ed192018-07-16 18:49:22 +00004417 ASSERT(isAsyncGeneratorWrapperParseMode(generator.parseMode()));
gskachkov@gmail.com74547a82017-09-23 15:05:53 +00004418 generator.emitPutAsyncGeneratorFields(next.get());
gskachkov@gmail.comab749fd2017-08-23 17:05:33 +00004419 }
4420
mark.lam@apple.comfa35e782013-11-19 21:55:16 +00004421 ASSERT(startOffset() >= lineStartOffset());
4422 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004423 generator.emitReturn(generator.generatorRegister());
4424 break;
4425 }
4426
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004427 case SourceParseMode::AsyncFunctionMode:
4428 case SourceParseMode::AsyncMethodMode:
4429 case SourceParseMode::AsyncArrowFunctionMode: {
4430 StatementNode* singleStatement = this->singleStatement();
4431 ASSERT(singleStatement->isExprStatement());
4432 ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement);
4433 ExpressionNode* expr = exprStatement->expr();
4434 ASSERT(expr->isFuncExprNode());
4435 FuncExprNode* funcExpr = static_cast<FuncExprNode*>(expr);
4436
4437 RefPtr<RegisterID> next = generator.newTemporary();
4438 generator.emitNode(next.get(), funcExpr);
4439
gskachkov@gmail.comc78531a2017-01-10 21:13:33 +00004440 if (generator.superBinding() == SuperBinding::Needed || (generator.parseMode() == SourceParseMode::AsyncArrowFunctionMode && generator.isSuperUsedInInnerArrowFunction())) {
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004441 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
4442 emitPutHomeObject(generator, next.get(), homeObject.get());
4443 }
gskachkov@gmail.com48a2a9a2017-01-19 17:10:31 +00004444
4445 if (generator.parseMode() == SourceParseMode::AsyncArrowFunctionMode && generator.isThisUsedInInnerArrowFunction())
4446 generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004447
4448 generator.emitPutGeneratorFields(next.get());
4449
4450 ASSERT(startOffset() >= lineStartOffset());
4451 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
4452
caitp@igalia.com5f1b4ea2016-11-15 04:28:45 +00004453 // load and call @asyncFunctionResume
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00004454 RefPtr<RegisterID> asyncFunctionResume = generator.moveLinkTimeConstant(nullptr, LinkTimeConstant::asyncFunctionResume);
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004455
caitp@igalia.com5f1b4ea2016-11-15 04:28:45 +00004456 CallArguments args(generator, nullptr, 4);
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004457 unsigned argumentCount = 0;
4458 generator.emitLoad(args.thisRegister(), jsUndefined());
keith_miller@apple.com35210892018-06-01 18:11:36 +00004459 generator.move(args.argumentRegister(argumentCount++), generator.generatorRegister());
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00004460 generator.move(args.argumentRegister(argumentCount++), generator.promiseRegister());
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004461 generator.emitLoad(args.argumentRegister(argumentCount++), jsUndefined());
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00004462 generator.emitLoad(args.argumentRegister(argumentCount++), jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode)));
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004463 // JSTextPosition(int _line, int _offset, int _lineStartOffset)
4464 JSTextPosition divot(firstLine(), startOffset(), lineStartOffset());
4465
4466 RefPtr<RegisterID> result = generator.newTemporary();
caitp@igalia.com5f1b4ea2016-11-15 04:28:45 +00004467 generator.emitCallInTailPosition(result.get(), asyncFunctionResume.get(), NoExpectedFunction, args, divot, divot, divot, DebuggableCall::No);
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004468 generator.emitReturn(result.get());
4469 break;
4470 }
4471
gskachkov@gmail.comab749fd2017-08-23 17:05:33 +00004472 case SourceParseMode::AsyncGeneratorBodyMode:
caitp@igalia.com04d4f602016-10-28 16:37:38 +00004473 case SourceParseMode::AsyncArrowFunctionBodyMode:
4474 case SourceParseMode::AsyncFunctionBodyMode:
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004475 case SourceParseMode::GeneratorBodyMode: {
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004476 Ref<Label> generatorBodyLabel = generator.newLabel();
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004477 {
4478 RefPtr<RegisterID> condition = generator.newTemporary();
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00004479 generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode))));
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004480 generator.emitJumpIfTrue(condition.get(), generatorBodyLabel.get());
4481
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004482 Ref<Label> throwLabel = generator.newLabel();
ysuzuki@apple.com8bb1b392019-09-18 05:02:45 +00004483 generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ThrowMode))));
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004484 generator.emitJumpIfTrue(condition.get(), throwLabel.get());
4485
4486 generator.emitReturn(generator.generatorValueRegister());
4487
4488 generator.emitLabel(throwLabel.get());
4489 generator.emitThrow(generator.generatorValueRegister());
4490 }
4491
4492 generator.emitLabel(generatorBodyLabel.get());
4493
4494 emitStatementsBytecode(generator, generator.ignoredResult());
4495
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004496 Ref<Label> done = generator.newLabel();
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004497 generator.emitLabel(done.get());
4498 generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004499 break;
4500 }
4501
4502 default: {
4503 emitStatementsBytecode(generator, generator.ignoredResult());
4504
4505 StatementNode* singleStatement = this->singleStatement();
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00004506 ReturnNode* returnNode = nullptr;
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004507
4508 // Check for a return statement at the end of a function composed of a single block.
4509 if (singleStatement && singleStatement->isBlock()) {
4510 StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
4511 if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
4512 returnNode = static_cast<ReturnNode*>(lastStatementInBlock);
4513 }
4514
4515 // If there is no return we must automatically insert one.
4516 if (!returnNode) {
sbarati@apple.com8a1620b62016-08-03 01:28:16 +00004517 if (generator.constructorKind() == ConstructorKind::Extends && generator.needsToUpdateArrowFunctionContext() && generator.isSuperCallUsedInInnerArrowFunction())
commit-queue@webkit.orgb2610c02015-12-08 20:24:04 +00004518 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); // Arrow function can invoke 'super' in constructor and before leave constructor we need load 'this' from lexical arrow function environment
4519
ysuzuki@apple.com48d4e532019-09-05 01:23:46 +00004520 RegisterID* r0 = nullptr;
4521 if (generator.isConstructor() && generator.constructorKind() != ConstructorKind::Naked)
4522 r0 = generator.thisRegister();
4523 else
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00004524 r0 = generator.emitLoad(nullptr, jsUndefined());
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004525 generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code.
4526 ASSERT(startOffset() >= lineStartOffset());
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00004527 generator.emitWillLeaveCallFrameDebugHook();
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004528 generator.emitReturn(r0);
4529 return;
4530 }
4531 break;
4532 }
barraclough@apple.comb467c4c2010-07-13 20:34:11 +00004533 }
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004534}
4535
4536// ------------------------------ FuncDeclNode ---------------------------------
4537
sbarati@apple.come86176c2016-04-07 21:01:42 +00004538void FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004539{
sbarati@apple.come86176c2016-04-07 21:01:42 +00004540 generator.hoistSloppyModeFunctionIfNecessary(metadata()->ident());
mjs@apple.comaed3cef2009-12-09 01:29:52 +00004541}
4542
4543// ------------------------------ FuncExprNode ---------------------------------
4544
4545RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
4546{
4547 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
4548}
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +00004549
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +00004550// ------------------------------ ArrowFuncExprNode ---------------------------------
4551
4552RegisterID* ArrowFuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
4553{
4554 return generator.emitNewArrowFunctionExpression(generator.finalDestination(dst), this);
4555}
utatane.tea@gmail.comf2fde6a2015-11-02 05:46:17 +00004556
mark.lam@apple.com43137872016-03-17 14:58:57 +00004557// ------------------------------ MethodDefinitionNode ---------------------------------
4558
4559RegisterID* MethodDefinitionNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
4560{
4561 return generator.emitNewMethodDefinition(generator.finalDestination(dst), this);
4562}
4563
utatane.tea@gmail.comf2fde6a2015-11-02 05:46:17 +00004564// ------------------------------ YieldExprNode --------------------------------
4565
4566RegisterID* YieldExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
4567{
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004568 if (!delegate()) {
4569 RefPtr<RegisterID> arg = nullptr;
4570 if (argument()) {
4571 arg = generator.newTemporary();
4572 generator.emitNode(arg.get(), argument());
4573 } else
4574 arg = generator.emitLoad(nullptr, jsUndefined());
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00004575 RefPtr<RegisterID> value = generator.emitYield(arg.get(), JSAsyncGenerator::AsyncGeneratorSuspendReason::Yield);
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004576 if (dst == generator.ignoredResult())
4577 return nullptr;
keith_miller@apple.com35210892018-06-01 18:11:36 +00004578 return generator.move(generator.finalDestination(dst), value.get());
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004579 }
4580 RefPtr<RegisterID> arg = generator.newTemporary();
4581 generator.emitNode(arg.get(), argument());
4582 RefPtr<RegisterID> value = generator.emitDelegateYield(arg.get(), this);
utatane.tea@gmail.comf2fde6a2015-11-02 05:46:17 +00004583 if (dst == generator.ignoredResult())
utatane.tea@gmail.comfdd9bf42015-12-02 03:16:28 +00004584 return nullptr;
keith_miller@apple.com35210892018-06-01 18:11:36 +00004585 return generator.move(generator.finalDestination(dst), value.get());
utatane.tea@gmail.comf2fde6a2015-11-02 05:46:17 +00004586}
4587
caitp@igalia.com0096c962016-09-23 22:24:27 +00004588// ------------------------------ AwaitExprNode --------------------------------
4589
4590RegisterID* AwaitExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
4591{
4592 RefPtr<RegisterID> arg = generator.newTemporary();
4593 generator.emitNode(arg.get(), argument());
ysuzuki@apple.comfcfff832019-10-02 21:23:09 +00004594 RefPtr<RegisterID> value = generator.emitYield(arg.get(), JSAsyncGenerator::AsyncGeneratorSuspendReason::Await);
caitp@igalia.com0096c962016-09-23 22:24:27 +00004595 if (dst == generator.ignoredResult())
4596 return nullptr;
keith_miller@apple.com35210892018-06-01 18:11:36 +00004597 return generator.move(generator.finalDestination(dst), value.get());
caitp@igalia.com0096c962016-09-23 22:24:27 +00004598}
4599
caitp@igalia.comce715b22020-01-16 00:09:50 +00004600// ------------------------------ DefineFieldNode ---------------------------------
4601
4602void DefineFieldNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
4603{
4604 RefPtr<RegisterID> value = generator.newTemporary();
4605
4606 if (!m_assign)
4607 generator.emitLoad(value.get(), jsUndefined());
4608 else {
4609 generator.emitNode(value.get(), m_assign);
ross.kirsling@sony.com45f6de02020-02-18 20:01:20 +00004610 if (m_ident && generator.shouldSetFunctionName(m_assign))
4611 generator.emitSetFunctionName(value.get(), *m_ident);
caitp@igalia.comce715b22020-01-16 00:09:50 +00004612 }
4613
4614 switch (m_type) {
4615 case DefineFieldNode::Type::Name: {
4616 // FIXME: Improve performance of public class fields
4617 // https://bugs.webkit.org/show_bug.cgi?id=198330
4618 RefPtr<RegisterID> propertyName = generator.emitLoad(nullptr, *m_ident);
4619 generator.emitCallDefineProperty(generator.thisRegister(), propertyName.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable | BytecodeGenerator::PropertyEnumerable, m_position);
4620 break;
4621 }
4622 case DefineFieldNode::Type::ComputedName: {
4623 // FIXME: Improve performance of public class fields
4624 // https://bugs.webkit.org/show_bug.cgi?id=198330
4625
4626 // For ComputedNames, the expression has already been evaluated earlier during evaluation of a ClassExprNode.
4627 // Here, `m_ident` refers to an integer ID in a class lexical scope, containing the value already converted to an Expression.
4628 Variable var = generator.variable(*m_ident);
4629 ASSERT_WITH_MESSAGE(!var.local(), "Computed names must be stored in captured variables");
4630
4631 generator.emitExpressionInfo(position(), position(), position() + 1);
4632 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), var);
4633 RefPtr<RegisterID> privateName = generator.newTemporary();
4634 generator.emitGetFromScope(privateName.get(), scope.get(), var, ThrowIfNotFound);
keith_miller@apple.com984cfcc2020-01-30 19:04:13 +00004635 generator.emitProfileType(privateName.get(), var, m_position, m_position + m_ident->length());
caitp@igalia.comce715b22020-01-16 00:09:50 +00004636 generator.emitCallDefineProperty(generator.thisRegister(), privateName.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable | BytecodeGenerator::PropertyEnumerable, m_position);
4637 break;
4638 }
4639 }
4640}
4641
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +00004642// ------------------------------ ClassDeclNode ---------------------------------
4643
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00004644void ClassDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +00004645{
commit-queue@webkit.orgf292e812017-09-05 17:43:51 +00004646 generator.emitNode(m_classDeclaration);
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +00004647}
4648
4649// ------------------------------ ClassExprNode ---------------------------------
4650
4651RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
4652{
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00004653 StrictModeScope strictModeScope(generator);
4654
caitp@igalia.comce715b22020-01-16 00:09:50 +00004655 if (m_needsLexicalScope)
sbarati@apple.combdbba812015-12-19 00:19:41 +00004656 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
utatane.tea@gmail.com0a4a7f82015-10-15 14:35:12 +00004657
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00004658 RefPtr<RegisterID> superclass;
4659 if (m_classHeritage) {
4660 superclass = generator.newTemporary();
4661 generator.emitNode(superclass.get(), m_classHeritage);
4662 }
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +00004663
ysuzuki@apple.comaa62f022019-06-22 07:16:34 +00004664 RefPtr<RegisterID> constructor = generator.tempDestination(dst);
gskachkov@gmail.com82b84582017-01-20 11:43:24 +00004665 bool needsHomeObject = false;
rniwa@webkit.orgd81805e2015-03-17 04:02:52 +00004666
caitp@igalia.comce715b22020-01-16 00:09:50 +00004667 auto needsClassFieldInitializer = this->hasInstanceFields() ? NeedsClassFieldInitializer::Yes : NeedsClassFieldInitializer::No;
4668
mark.lam@apple.com4b79ce72016-03-11 21:08:08 +00004669 if (m_constructorExpression) {
4670 ASSERT(m_constructorExpression->isFuncExprNode());
4671 FunctionMetadataNode* metadata = static_cast<FuncExprNode*>(m_constructorExpression)->metadata();
4672 metadata->setEcmaName(ecmaName());
4673 metadata->setClassSource(m_classSource);
caitp@igalia.comce715b22020-01-16 00:09:50 +00004674 metadata->setNeedsClassFieldInitializer(needsClassFieldInitializer == NeedsClassFieldInitializer::Yes);
ysuzuki@apple.comaa62f022019-06-22 07:16:34 +00004675 constructor = generator.emitNode(constructor.get(), m_constructorExpression);
gskachkov@gmail.comf92fe152017-06-20 10:27:41 +00004676 needsHomeObject = m_classHeritage || metadata->superBinding() == SuperBinding::Needed;
4677 } else
caitp@igalia.comce715b22020-01-16 00:09:50 +00004678 constructor = generator.emitNewDefaultConstructor(constructor.get(), m_classHeritage ? ConstructorKind::Extends : ConstructorKind::Base, m_name, ecmaName(), m_classSource, needsClassFieldInitializer);
rniwa@webkit.orgd81805e2015-03-17 04:02:52 +00004679
rniwa@webkit.org49d0cc12015-04-25 22:03:30 +00004680 const auto& propertyNames = generator.propertyNames();
4681 RefPtr<RegisterID> prototype = generator.emitNewObject(generator.newTemporary());
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +00004682
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00004683 if (superclass) {
rniwa@webkit.org33c69e42015-03-31 01:59:31 +00004684 RefPtr<RegisterID> protoParent = generator.newTemporary();
4685 generator.emitLoad(protoParent.get(), jsNull());
4686
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00004687 RefPtr<RegisterID> tempRegister = generator.newTemporary();
rniwa@webkit.orgd115b7f2015-05-04 19:23:24 +00004688
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004689 Ref<Label> superclassIsUndefinedLabel = generator.newLabel();
rniwa@webkit.orgd115b7f2015-05-04 19:23:24 +00004690 generator.emitJumpIfTrue(generator.emitIsUndefined(tempRegister.get(), superclass.get()), superclassIsUndefinedLabel.get());
4691
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004692 Ref<Label> superclassIsNullLabel = generator.newLabel();
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00004693 generator.emitJumpIfTrue(generator.emitUnaryOp<OpEqNull>(tempRegister.get(), superclass.get()), superclassIsNullLabel.get());
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00004694
shvaikalesh@gmail.com087fc322020-05-13 06:41:34 +00004695 Ref<Label> superclassIsConstructorLabel = generator.newLabel();
4696 generator.emitJumpIfTrue(generator.emitIsConstructor(tempRegister.get(), superclass.get()), superclassIsConstructorLabel.get());
rniwa@webkit.orgd115b7f2015-05-04 19:23:24 +00004697 generator.emitLabel(superclassIsUndefinedLabel.get());
shvaikalesh@gmail.com087fc322020-05-13 06:41:34 +00004698 generator.emitThrowTypeError("The superclass is not a constructor."_s);
4699 generator.emitLabel(superclassIsConstructorLabel.get());
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00004700 generator.emitGetById(protoParent.get(), superclass.get(), generator.propertyNames().prototype);
4701
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004702 Ref<Label> protoParentIsObjectOrNullLabel = generator.newLabel();
tzagallo@apple.com3474dd02018-10-29 13:16:03 +00004703 generator.emitJumpIfTrue(generator.emitUnaryOp<OpIsObjectOrNull>(tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
4704 generator.emitJumpIfTrue(generator.emitUnaryOp<OpIsFunction>(tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00004705 generator.emitThrowTypeError("The value of the superclass's prototype property is not an object."_s);
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00004706 generator.emitLabel(protoParentIsObjectOrNullLabel.get());
4707
4708 generator.emitDirectPutById(constructor.get(), generator.propertyNames().underscoreProto, superclass.get(), PropertyNode::Unknown);
rniwa@webkit.org33c69e42015-03-31 01:59:31 +00004709 generator.emitLabel(superclassIsNullLabel.get());
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00004710 generator.emitDirectPutById(prototype.get(), generator.propertyNames().underscoreProto, protoParent.get(), PropertyNode::Unknown);
rniwa@webkit.org059ef9b2015-03-09 23:47:06 +00004711 }
4712
gskachkov@gmail.com82b84582017-01-20 11:43:24 +00004713 if (needsHomeObject)
4714 emitPutHomeObject(generator, constructor.get(), prototype.get());
4715
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00004716 RefPtr<RegisterID> constructorNameRegister = generator.emitLoad(nullptr, propertyNames.constructor);
rniwa@webkit.org49d0cc12015-04-25 22:03:30 +00004717 generator.emitCallDefineProperty(prototype.get(), constructorNameRegister.get(), constructor.get(), nullptr, nullptr,
utatane.tea@gmail.com4a9d9562016-10-04 22:51:38 +00004718 BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
rniwa@webkit.org49d0cc12015-04-25 22:03:30 +00004719
utatane.tea@gmail.comf7db5592016-10-04 19:31:24 +00004720 RefPtr<RegisterID> prototypeNameRegister = generator.emitLoad(nullptr, propertyNames.prototype);
utatane.tea@gmail.com4a9d9562016-10-04 22:51:38 +00004721 generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0, m_position);
rniwa@webkit.org49d0cc12015-04-25 22:03:30 +00004722
caitp@igalia.comce715b22020-01-16 00:09:50 +00004723 if (m_classElements) {
4724 Vector<JSTextPosition> instanceFieldLocations;
4725 generator.emitDefineClassElements(m_classElements, constructor.get(), prototype.get(), instanceFieldLocations);
4726 if (!instanceFieldLocations.isEmpty()) {
4727 RefPtr<RegisterID> instanceFieldInitializer = generator.emitNewInstanceFieldInitializerFunction(generator.newTemporary(), WTFMove(instanceFieldLocations), m_classHeritage);
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +00004728
caitp@igalia.comce715b22020-01-16 00:09:50 +00004729 // FIXME: Skip this if the initializer function isn't going to need a home object (no eval or super properties)
4730 // https://bugs.webkit.org/show_bug.cgi?id=196867
4731 emitPutHomeObject(generator, instanceFieldInitializer.get(), prototype.get());
4732
4733 generator.emitDirectPutById(constructor.get(), generator.propertyNames().builtinNames().instanceFieldInitializerPrivateName(), instanceFieldInitializer.get(), PropertyNode::Unknown);
4734 }
4735 }
4736
4737 if (m_needsLexicalScope) {
4738 if (!m_name.isNull()) {
4739 Variable classNameVar = generator.variable(m_name);
4740 RELEASE_ASSERT(classNameVar.isResolved());
4741 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, classNameVar);
4742 generator.emitPutToScope(scope.get(), classNameVar, constructor.get(), ThrowIfNotFound, InitializationMode::Initialization);
4743 }
utatane.tea@gmail.com0a4a7f82015-10-15 14:35:12 +00004744 generator.popLexicalScope(this);
4745 }
4746
ysuzuki@apple.comaa62f022019-06-22 07:16:34 +00004747 return generator.move(generator.finalDestination(dst, constructor.get()), constructor.get());
rniwa@webkit.org65c9b0d2015-01-29 22:59:19 +00004748}
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004749
4750// ------------------------------ ImportDeclarationNode -----------------------
4751
4752void ImportDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
4753{
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004754 // Do nothing at runtime.
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004755}
4756
4757// ------------------------------ ExportAllDeclarationNode --------------------
4758
4759void ExportAllDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
4760{
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004761 // Do nothing at runtime.
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004762}
4763
4764// ------------------------------ ExportDefaultDeclarationNode ----------------
4765
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004766void ExportDefaultDeclarationNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004767{
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004768 ASSERT(m_declaration);
4769 generator.emitNode(dst, m_declaration);
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004770}
4771
4772// ------------------------------ ExportLocalDeclarationNode ------------------
4773
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004774void ExportLocalDeclarationNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004775{
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004776 ASSERT(m_declaration);
4777 generator.emitNode(dst, m_declaration);
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004778}
4779
4780// ------------------------------ ExportNamedDeclarationNode ------------------
4781
4782void ExportNamedDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
4783{
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +00004784 // Do nothing at runtime.
utatane.tea@gmail.com9f9c9752015-08-04 21:26:49 +00004785}
4786
saambarati1@gmail.comcc3bcb62015-07-02 23:53:10 +00004787// ------------------------------ DestructuringAssignmentNode -----------------
4788RegisterID* DestructuringAssignmentNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
oliver@apple.comd055db62013-10-02 19:11:04 +00004789{
4790 if (RegisterID* result = m_bindings->emitDirectBinding(generator, dst, m_initializer))
4791 return result;
4792 RefPtr<RegisterID> initializer = generator.tempDestination(dst);
4793 generator.emitNode(initializer.get(), m_initializer);
oliver@apple.com47784d62013-10-25 21:31:36 +00004794 m_bindings->bindValue(generator, initializer.get());
keith_miller@apple.com35210892018-06-01 18:11:36 +00004795 return generator.move(dst, initializer.get());
oliver@apple.comd055db62013-10-02 19:11:04 +00004796}
4797
saambarati1@gmail.com174581a2015-06-18 12:35:32 +00004798static void assignDefaultValueIfUndefined(BytecodeGenerator& generator, RegisterID* maybeUndefined, ExpressionNode* defaultValue)
4799{
4800 ASSERT(defaultValue);
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004801 Ref<Label> isNotUndefined = generator.newLabel();
saambarati1@gmail.com174581a2015-06-18 12:35:32 +00004802 generator.emitJumpIfFalse(generator.emitIsUndefined(generator.newTemporary(), maybeUndefined), isNotUndefined.get());
4803 generator.emitNode(maybeUndefined, defaultValue);
4804 generator.emitLabel(isNotUndefined.get());
4805}
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004806
oliver@apple.com47784d62013-10-25 21:31:36 +00004807void ArrayPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
oliver@apple.comd055db62013-10-02 19:11:04 +00004808{
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004809 RefPtr<RegisterID> iterator = generator.newTemporary();
4810 {
4811 generator.emitGetById(iterator.get(), rhs, generator.propertyNames().iteratorSymbol);
4812 CallArguments args(generator, nullptr);
keith_miller@apple.com35210892018-06-01 18:11:36 +00004813 generator.move(args.thisRegister(), rhs);
joepeck@webkit.orgbb70ac62016-09-30 19:22:37 +00004814 generator.emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd(), DebuggableCall::No);
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004815 }
keith_miller@apple.come7c24612017-09-23 02:08:04 +00004816 RefPtr<RegisterID> nextMethod = generator.emitGetById(generator.newTemporary(), iterator.get(), generator.propertyNames().next);
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004817
utatane.tea@gmail.coma5c94332015-06-23 00:51:44 +00004818 if (m_targetPatterns.isEmpty()) {
keith_miller@apple.comd06760d2020-04-18 21:45:34 +00004819 generator.emitIteratorGenericClose(iterator.get(), this);
utatane.tea@gmail.coma5c94332015-06-23 00:51:44 +00004820 return;
4821 }
4822
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004823 RefPtr<RegisterID> done;
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004824 for (auto& target : m_targetPatterns) {
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004825 switch (target.bindingType) {
4826 case BindingType::Elision:
4827 case BindingType::Element: {
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004828 Ref<Label> iterationSkipped = generator.newLabel();
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004829 if (!done)
4830 done = generator.newTemporary();
4831 else
4832 generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004833
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004834 RefPtr<RegisterID> value = generator.newTemporary();
keith_miller@apple.comd06760d2020-04-18 21:45:34 +00004835 generator.emitIteratorGenericNext(value.get(), nextMethod.get(), iterator.get(), this);
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004836 generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004837 generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
4838 generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004839
4840 {
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004841 Ref<Label> valueIsSet = generator.newLabel();
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004842 generator.emitJump(valueIsSet.get());
4843 generator.emitLabel(iterationSkipped.get());
4844 generator.emitLoad(value.get(), jsUndefined());
4845 generator.emitLabel(valueIsSet.get());
4846 }
4847
4848 if (target.bindingType == BindingType::Element) {
4849 if (target.defaultValue)
4850 assignDefaultValueIfUndefined(generator, value.get(), target.defaultValue);
4851 target.pattern->bindValue(generator, value.get());
4852 }
4853 break;
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004854 }
4855
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004856 case BindingType::RestElement: {
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +00004857 RefPtr<RegisterID> array = generator.emitNewArray(generator.newTemporary(), nullptr, 0, ArrayWithUndecided);
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004858
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004859 Ref<Label> iterationDone = generator.newLabel();
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004860 if (!done)
4861 done = generator.newTemporary();
4862 else
4863 generator.emitJumpIfTrue(done.get(), iterationDone.get());
4864
4865 RefPtr<RegisterID> index = generator.newTemporary();
4866 generator.emitLoad(index.get(), jsNumber(0));
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004867 Ref<Label> loopStart = generator.newLabel();
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004868 generator.emitLabel(loopStart.get());
4869
4870 RefPtr<RegisterID> value = generator.newTemporary();
keith_miller@apple.comd06760d2020-04-18 21:45:34 +00004871 generator.emitIteratorGenericNext(value.get(), nextMethod.get(), iterator.get(), this);
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004872 generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
4873 generator.emitJumpIfTrue(done.get(), iterationDone.get());
4874 generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
4875
4876 generator.emitDirectPutByVal(array.get(), index.get(), value.get());
4877 generator.emitInc(index.get());
4878 generator.emitJump(loopStart.get());
4879
4880 generator.emitLabel(iterationDone.get());
4881 target.pattern->bindValue(generator, array.get());
4882 break;
4883 }
4884 }
oliver@apple.comd055db62013-10-02 19:11:04 +00004885 }
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004886
utatane.tea@gmail.com6f1b3f32017-02-16 07:56:48 +00004887 Ref<Label> iteratorClosed = generator.newLabel();
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004888 generator.emitJumpIfTrue(done.get(), iteratorClosed.get());
keith_miller@apple.comd06760d2020-04-18 21:45:34 +00004889 generator.emitIteratorGenericClose(iterator.get(), this);
utatane.tea@gmail.com5210f302015-06-20 11:04:27 +00004890 generator.emitLabel(iteratorClosed.get());
oliver@apple.comd055db62013-10-02 19:11:04 +00004891}
4892
4893RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
4894{
oliver@apple.comd055db62013-10-02 19:11:04 +00004895 if (!rhs->isSimpleArray())
fpizlo@apple.com1d81e2e2016-02-09 20:18:31 +00004896 return nullptr;
4897
4898 ElementNode* elementNodes = static_cast<ArrayNode*>(rhs)->elements();
4899 Vector<ExpressionNode*> elements;
4900 for (; elementNodes; elementNodes = elementNodes->next()) {
4901 ExpressionNode* value = elementNodes->value();
4902 if (value->isSpreadExpression())
4903 return nullptr;
4904 elements.append(value);
4905 }
oliver@apple.com47784d62013-10-25 21:31:36 +00004906
oliver@apple.com2bae57a2013-11-12 20:55:29 +00004907 RefPtr<RegisterID> resultRegister;
utatane.tea@gmail.comfd33c1e2018-06-27 10:05:50 +00004908 if (dst != generator.ignoredResult())
keith_miller@apple.comc02f5d32018-05-22 18:04:31 +00004909 resultRegister = generator.emitNewArray(generator.newTemporary(), nullptr, 0, ArrayWithUndecided);
oliver@apple.comd055db62013-10-02 19:11:04 +00004910 if (m_targetPatterns.size() != elements.size())
fpizlo@apple.com1d81e2e2016-02-09 20:18:31 +00004911 return nullptr;
oliver@apple.comd055db62013-10-02 19:11:04 +00004912 Vector<RefPtr<RegisterID>> registers;
4913 registers.reserveCapacity(m_targetPatterns.size());
4914 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
4915 registers.uncheckedAppend(generator.newTemporary());
4916 generator.emitNode(registers.last().get(), elements[i]);
saambarati1@gmail.com174581a2015-06-18 12:35:32 +00004917 if (m_targetPatterns[i].defaultValue)
4918 assignDefaultValueIfUndefined(generator, registers.last().get(), m_targetPatterns[i].defaultValue);
utatane.tea@gmail.com1edb3192018-03-22 15:40:57 +00004919 if (resultRegister) {
4920 RefPtr<RegisterID> index = generator.emitLoad(nullptr, jsNumber(i));
4921 generator.emitDirectPutByVal(resultRegister.get(), index.get(), registers.last().get());
4922 }
oliver@apple.comd055db62013-10-02 19:11:04 +00004923 }
4924
4925 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
saambarati1@gmail.com174581a2015-06-18 12:35:32 +00004926 if (m_targetPatterns[i].pattern)
4927 m_targetPatterns[i].pattern->bindValue(generator, registers[i].get());
oliver@apple.comd055db62013-10-02 19:11:04 +00004928 }
oliver@apple.com2bae57a2013-11-12 20:55:29 +00004929 if (resultRegister)
utatane.tea@gmail.comfd33c1e2018-06-27 10:05:50 +00004930 return generator.move(generator.finalDestination(dst, resultRegister.get()), resultRegister.get());
oliver@apple.com47784d62013-10-25 21:31:36 +00004931 return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
oliver@apple.comd055db62013-10-02 19:11:04 +00004932}
4933
4934void ArrayPatternNode::toString(StringBuilder& builder) const
4935{
4936 builder.append('[');
4937 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004938 const auto& target = m_targetPatterns[i];
4939
4940 switch (target.bindingType) {
4941 case BindingType::Elision:
oliver@apple.comd055db62013-10-02 19:11:04 +00004942 builder.append(',');
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004943 break;
4944
4945 case BindingType::Element:
4946 target.pattern->toString(builder);
4947 if (i < m_targetPatterns.size() - 1)
4948 builder.append(',');
4949 break;
4950
4951 case BindingType::RestElement:
commit-queue@webkit.org57101852016-08-12 00:33:47 +00004952 builder.appendLiteral("...");
utatane.tea@gmail.com412d7612015-06-26 03:13:25 +00004953 target.pattern->toString(builder);
4954 break;
oliver@apple.comd055db62013-10-02 19:11:04 +00004955 }
oliver@apple.comd055db62013-10-02 19:11:04 +00004956 }
4957 builder.append(']');
4958}
4959
4960void ArrayPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
4961{
4962 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
saambarati1@gmail.comc497d152015-07-17 18:48:30 +00004963 if (DestructuringPatternNode* node = m_targetPatterns[i].pattern)
oliver@apple.comd055db62013-10-02 19:11:04 +00004964 node->collectBoundIdentifiers(identifiers);
4965 }
4966}
4967
4968void ObjectPatternNode::toString(StringBuilder& builder) const
4969{
4970 builder.append('{');
4971 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
antti@apple.comf3e3f5e2015-03-02 21:51:13 +00004972 if (m_targetPatterns[i].wasString)
akling@apple.coma9904fb2015-05-08 08:44:23 +00004973 builder.appendQuotedJSONString(m_targetPatterns[i].propertyName.string());
antti@apple.comf3e3f5e2015-03-02 21:51:13 +00004974 else
oliver@apple.comd055db62013-10-02 19:11:04 +00004975 builder.append(m_targetPatterns[i].propertyName.string());
commit-queue@webkit.org29e710c2014-08-29 21:33:30 +00004976 builder.append(':');
oliver@apple.comd055db62013-10-02 19:11:04 +00004977 m_targetPatterns[i].pattern->toString(builder);
4978 if (i < m_targetPatterns.size() - 1)
4979 builder.append(',');
4980 }
4981 builder.append('}');
4982}
4983
oliver@apple.com47784d62013-10-25 21:31:36 +00004984void ObjectPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
oliver@apple.comd055db62013-10-02 19:11:04 +00004985{
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00004986 generator.emitRequireObjectCoercible(rhs, "Right side of assignment cannot be destructured"_s);
mark.lam@apple.comcf0bf6c2017-05-16 00:21:59 +00004987
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00004988 RefPtr<RegisterID> excludedList;
4989 IdentifierSet excludedSet;
4990 RefPtr<RegisterID> addMethod;
4991 if (m_containsRestElement && m_containsComputedProperty) {
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00004992 RefPtr<RegisterID> setConstructor = generator.moveLinkTimeConstant(nullptr, LinkTimeConstant::Set);
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00004993
4994 CallArguments args(generator, nullptr, 0);
4995 excludedList = generator.emitConstruct(generator.newTemporary(), setConstructor.get(), setConstructor.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd());
4996
4997 addMethod = generator.emitGetById(generator.newTemporary(), excludedList.get(), generator.propertyNames().builtinNames().addPrivateName());
4998 }
4999
msaboff@apple.com983e6212019-07-03 06:01:12 +00005000 BytecodeGenerator::PreservedTDZStack preservedTDZStack;
5001 generator.preserveTDZStack(preservedTDZStack);
5002
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00005003 for (size_t i = 0; i < m_targetPatterns.size(); i++) {
5004 const auto& target = m_targetPatterns[i];
5005 if (target.bindingType == BindingType::Element) {
5006 RefPtr<RegisterID> temp = generator.newTemporary();
5007 RefPtr<RegisterID> propertyName;
5008 if (!target.propertyExpression) {
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00005009 Optional<uint32_t> optionalIndex = parseIndex(target.propertyName);
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00005010 if (!optionalIndex)
5011 generator.emitGetById(temp.get(), rhs, target.propertyName);
5012 else {
5013 RefPtr<RegisterID> propertyIndex = generator.emitLoad(nullptr, jsNumber(optionalIndex.value()));
5014 generator.emitGetByVal(temp.get(), rhs, propertyIndex.get());
5015 }
5016 } else {
5017 propertyName = generator.emitNodeForProperty(target.propertyExpression);
5018 generator.emitGetByVal(temp.get(), rhs, propertyName.get());
5019 }
5020
5021 if (m_containsRestElement) {
5022 if (m_containsComputedProperty) {
5023 if (!target.propertyExpression)
5024 propertyName = generator.emitLoad(nullptr, target.propertyName);
5025
5026 CallArguments args(generator, nullptr, 1);
keith_miller@apple.com35210892018-06-01 18:11:36 +00005027 generator.move(args.thisRegister(), excludedList.get());
5028 generator.move(args.argumentRegister(0), propertyName.get());
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00005029 generator.emitCall(generator.newTemporary(), addMethod.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd(), DebuggableCall::No);
5030 } else
5031 excludedSet.add(target.propertyName.impl());
5032 }
5033
5034 if (target.defaultValue)
5035 assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
5036 target.pattern->bindValue(generator, temp.get());
5037 } else {
5038 ASSERT(target.bindingType == BindingType::RestElement);
5039 ASSERT(i == m_targetPatterns.size() - 1);
5040 RefPtr<RegisterID> newObject = generator.emitNewObject(generator.newTemporary());
5041
5042 // load and call @copyDataProperties
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00005043 RefPtr<RegisterID> copyDataProperties = generator.moveLinkTimeConstant(nullptr, LinkTimeConstant::copyDataProperties);
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00005044
5045 CallArguments args(generator, nullptr, 3);
5046 generator.emitLoad(args.thisRegister(), jsUndefined());
keith_miller@apple.com35210892018-06-01 18:11:36 +00005047 generator.move(args.argumentRegister(0), newObject.get());
5048 generator.move(args.argumentRegister(1), rhs);
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00005049 if (m_containsComputedProperty)
keith_miller@apple.com35210892018-06-01 18:11:36 +00005050 generator.move(args.argumentRegister(2), excludedList.get());
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00005051 else {
5052 RefPtr<RegisterID> excludedSetReg = generator.emitLoad(generator.newTemporary(), excludedSet);
keith_miller@apple.com35210892018-06-01 18:11:36 +00005053 generator.move(args.argumentRegister(2), excludedSetReg.get());
ticaiolima@gmail.com9df92eb2017-06-28 03:05:47 +00005054 }
5055
5056 RefPtr<RegisterID> result = generator.newTemporary();
5057 generator.emitCall(result.get(), copyDataProperties.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd(), DebuggableCall::No);
5058 target.pattern->bindValue(generator, result.get());
5059 }
oliver@apple.comd055db62013-10-02 19:11:04 +00005060 }
msaboff@apple.com983e6212019-07-03 06:01:12 +00005061
5062 generator.restoreTDZStack(preservedTDZStack);
oliver@apple.comd055db62013-10-02 19:11:04 +00005063}
5064
5065void ObjectPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
5066{
5067 for (size_t i = 0; i < m_targetPatterns.size(); i++)
5068 m_targetPatterns[i].pattern->collectBoundIdentifiers(identifiers);
5069}
5070
oliver@apple.com47784d62013-10-25 21:31:36 +00005071void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
oliver@apple.comd055db62013-10-02 19:11:04 +00005072{
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00005073 Variable var = generator.variable(m_boundProperty);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00005074 bool isReadOnly = var.isReadOnly() && m_bindingContext != AssignmentContext::ConstDeclarationStatement;
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00005075 if (RegisterID* local = var.local()) {
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00005076 if (m_bindingContext == AssignmentContext::AssignmentExpression)
5077 generator.emitTDZCheckIfNecessary(var, local, nullptr);
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00005078 if (isReadOnly) {
5079 generator.emitReadOnlyExceptionIfNeeded(var);
5080 return;
oliver@apple.comd055db62013-10-02 19:11:04 +00005081 }
keith_miller@apple.com35210892018-06-01 18:11:36 +00005082 generator.move(local, value);
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00005083 generator.emitProfileType(local, var, divotStart(), divotEnd());
saambarati1@gmail.come4556722015-07-19 16:57:44 +00005084 if (m_bindingContext == AssignmentContext::DeclarationStatement || m_bindingContext == AssignmentContext::ConstDeclarationStatement)
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00005085 generator.liftTDZCheckIfPossible(var);
oliver@apple.comd055db62013-10-02 19:11:04 +00005086 return;
5087 }
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00005088 if (generator.ecmaMode().isStrict())
akling@apple.combdf5d1d2014-01-21 01:10:29 +00005089 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
mark.lam@apple.com4a23c922017-03-11 01:38:22 +00005090 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
akling@apple.combdf5d1d2014-01-21 01:10:29 +00005091 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00005092 if (m_bindingContext == AssignmentContext::AssignmentExpression)
mark.lam@apple.com4a23c922017-03-11 01:38:22 +00005093 generator.emitTDZCheckIfNecessary(var, nullptr, scope.get());
saambarati1@gmail.com6541a1e2015-08-25 18:40:14 +00005094 if (isReadOnly) {
5095 generator.emitReadOnlyExceptionIfNeeded(var);
5096 return;
saambarati1@gmail.come4556722015-07-19 16:57:44 +00005097 }
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00005098 generator.emitPutToScope(scope.get(), var, value, generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, initializationModeForAssignmentContext(m_bindingContext));
saambarati1@gmail.comf07b1bc2015-07-28 22:39:12 +00005099 generator.emitProfileType(value, var, divotStart(), divotEnd());
saambarati1@gmail.come4556722015-07-19 16:57:44 +00005100 if (m_bindingContext == AssignmentContext::DeclarationStatement || m_bindingContext == AssignmentContext::ConstDeclarationStatement)
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +00005101 generator.liftTDZCheckIfPossible(var);
oliver@apple.comd055db62013-10-02 19:11:04 +00005102 return;
5103}
5104
5105void BindingNode::toString(StringBuilder& builder) const
5106{
5107 builder.append(m_boundProperty.string());
5108}
5109
5110void BindingNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
5111{
5112 identifiers.append(m_boundProperty);
5113}
commit-queue@webkit.org88a74762015-11-19 22:54:46 +00005114
5115void AssignmentElementNode::collectBoundIdentifiers(Vector<Identifier>&) const
5116{
5117}
5118
5119void AssignmentElementNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
5120{
5121 if (m_assignmentTarget->isResolveNode()) {
5122 ResolveNode* lhs = static_cast<ResolveNode*>(m_assignmentTarget);
5123 Variable var = generator.variable(lhs->identifier());
5124 bool isReadOnly = var.isReadOnly();
5125 if (RegisterID* local = var.local()) {
5126 generator.emitTDZCheckIfNecessary(var, local, nullptr);
5127
5128 if (isReadOnly)
5129 generator.emitReadOnlyExceptionIfNeeded(var);
5130 else {
keith_miller@apple.com35210892018-06-01 18:11:36 +00005131 generator.move(local, value);
commit-queue@webkit.org88a74762015-11-19 22:54:46 +00005132 generator.emitProfileType(local, divotStart(), divotEnd());
5133 }
5134 return;
5135 }
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00005136 if (generator.ecmaMode().isStrict())
commit-queue@webkit.org88a74762015-11-19 22:54:46 +00005137 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
5138 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
5139 generator.emitTDZCheckIfNecessary(var, nullptr, scope.get());
5140 if (isReadOnly) {
5141 bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
5142 if (threwException)
5143 return;
5144 }
5145 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
5146 if (!isReadOnly) {
tzagallo@apple.coma6b8c342020-04-07 22:32:21 +00005147 generator.emitPutToScope(scope.get(), var, value, generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
commit-queue@webkit.org88a74762015-11-19 22:54:46 +00005148 generator.emitProfileType(value, var, divotStart(), divotEnd());
5149 }
5150 } else if (m_assignmentTarget->isDotAccessorNode()) {
5151 DotAccessorNode* lhs = static_cast<DotAccessorNode*>(m_assignmentTarget);
5152 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(lhs->base(), true, false);
5153 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00005154 if (lhs->base()->isSuperNode()) {
5155 RefPtr<RegisterID> thisValue = generator.ensureThis();
5156 generator.emitPutById(base.get(), thisValue.get(), lhs->identifier(), value);
5157 } else
5158 generator.emitPutById(base.get(), lhs->identifier(), value);
commit-queue@webkit.org88a74762015-11-19 22:54:46 +00005159 generator.emitProfileType(value, divotStart(), divotEnd());
5160 } else if (m_assignmentTarget->isBracketAccessorNode()) {
5161 BracketAccessorNode* lhs = static_cast<BracketAccessorNode*>(m_assignmentTarget);
5162 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(lhs->base(), true, false);
utatane.tea@gmail.com1456b252017-05-22 05:33:47 +00005163 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSideForProperty(lhs->subscript(), true, false);
commit-queue@webkit.org88a74762015-11-19 22:54:46 +00005164 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
sbarati@apple.com23315d62016-05-09 20:17:23 +00005165 if (lhs->base()->isSuperNode()) {
5166 RefPtr<RegisterID> thisValue = generator.ensureThis();
5167 generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value);
5168 } else
5169 generator.emitPutByVal(base.get(), property.get(), value);
commit-queue@webkit.org88a74762015-11-19 22:54:46 +00005170 generator.emitProfileType(value, divotStart(), divotEnd());
5171 }
5172}
5173
5174void AssignmentElementNode::toString(StringBuilder& builder) const
5175{
5176 if (m_assignmentTarget->isResolveNode())
5177 builder.append(static_cast<ResolveNode*>(m_assignmentTarget)->identifier().string());
5178}
5179
sbarati@apple.comc0722da2015-11-20 02:37:47 +00005180void RestParameterNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
5181{
sbarati@apple.com6a686122016-08-03 07:50:40 +00005182 m_pattern->collectBoundIdentifiers(identifiers);
sbarati@apple.comc0722da2015-11-20 02:37:47 +00005183}
sbarati@apple.com6a686122016-08-03 07:50:40 +00005184
sbarati@apple.comc0722da2015-11-20 02:37:47 +00005185void RestParameterNode::toString(StringBuilder& builder) const
5186{
commit-queue@webkit.org57101852016-08-12 00:33:47 +00005187 builder.appendLiteral("...");
sbarati@apple.com6a686122016-08-03 07:50:40 +00005188 m_pattern->toString(builder);
sbarati@apple.comc0722da2015-11-20 02:37:47 +00005189}
sbarati@apple.com6a686122016-08-03 07:50:40 +00005190
sbarati@apple.comc0722da2015-11-20 02:37:47 +00005191void RestParameterNode::bindValue(BytecodeGenerator&, RegisterID*) const
5192{
5193 RELEASE_ASSERT_NOT_REACHED();
5194}
sbarati@apple.com6a686122016-08-03 07:50:40 +00005195
sbarati@apple.comc0722da2015-11-20 02:37:47 +00005196void RestParameterNode::emit(BytecodeGenerator& generator)
5197{
sbarati@apple.com6a686122016-08-03 07:50:40 +00005198 RefPtr<RegisterID> temp = generator.newTemporary();
5199 generator.emitRestParameter(temp.get(), m_numParametersToSkip);
5200 m_pattern->bindValue(generator, temp.get());
sbarati@apple.comc0722da2015-11-20 02:37:47 +00005201}
5202
5203
oliver@apple.com72f8a822013-10-17 01:02:34 +00005204RegisterID* SpreadExpressionNode::emitBytecode(BytecodeGenerator&, RegisterID*)
5205{
5206 RELEASE_ASSERT_NOT_REACHED();
ross.kirsling@sony.com2abe6c62020-05-11 02:36:05 +00005207 return nullptr;
oliver@apple.com72f8a822013-10-17 01:02:34 +00005208}
mjs@apple.comaed3cef2009-12-09 01:29:52 +00005209
ticaiolima@gmail.comf62044c2017-07-13 07:11:45 +00005210RegisterID* ObjectSpreadExpressionNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
5211{
5212 RefPtr<RegisterID> src = generator.newTemporary();
5213 generator.emitNode(src.get(), m_expression);
5214
5215 // load and call @copyDataPropertiesNoExclusions
ysuzuki@apple.com02fb9222019-11-05 02:52:02 +00005216 RefPtr<RegisterID> copyDataProperties = generator.moveLinkTimeConstant(nullptr, LinkTimeConstant::copyDataPropertiesNoExclusions);
ticaiolima@gmail.comf62044c2017-07-13 07:11:45 +00005217
5218 CallArguments args(generator, nullptr, 2);
5219 generator.emitLoad(args.thisRegister(), jsUndefined());
keith_miller@apple.com35210892018-06-01 18:11:36 +00005220 generator.move(args.argumentRegister(0), dst);
5221 generator.move(args.argumentRegister(1), src.get());
ticaiolima@gmail.comf62044c2017-07-13 07:11:45 +00005222
5223 generator.emitCall(generator.newTemporary(), copyDataProperties.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd(), DebuggableCall::No);
5224
5225 return dst;
5226}
5227
mjs@apple.comaed3cef2009-12-09 01:29:52 +00005228} // namespace JSC