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