]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecompiler/BytecodeGenerator.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecompiler / BytecodeGenerator.cpp
CommitLineData
9dae56ea 1/*
ed1e77d3 2 * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
9dae56ea 3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
93a37866 4 * Copyright (C) 2012 Igalia, S.L.
9dae56ea
A
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
81345200 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
9dae56ea
A
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "BytecodeGenerator.h"
33
ed1e77d3 34#include "BuiltinExecutables.h"
9dae56ea 35#include "Interpreter.h"
93a37866 36#include "JSFunction.h"
ed1e77d3 37#include "JSLexicalEnvironment.h"
93a37866 38#include "JSNameScope.h"
ed1e77d3 39#include "JSTemplateRegistryKey.h"
6fe7ccc8 40#include "LowLevelInterpreter.h"
81345200 41#include "JSCInlines.h"
93a37866 42#include "Options.h"
81345200 43#include "StackAlignment.h"
6fe7ccc8 44#include "StrongInlines.h"
93a37866 45#include "UnlinkedCodeBlock.h"
81345200
A
46#include "UnlinkedInstructionStream.h"
47#include <wtf/StdLibExtras.h>
93a37866 48#include <wtf/text/WTFString.h>
9dae56ea
A
49
50using namespace std;
51
52namespace JSC {
53
6fe7ccc8
A
54void Label::setLocation(unsigned location)
55{
56 m_location = location;
57
58 unsigned size = m_unresolvedJumps.size();
59 for (unsigned i = 0; i < size; ++i)
ed1e77d3 60 m_generator.instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
6fe7ccc8 61}
9dae56ea 62
93a37866 63ParserError BytecodeGenerator::generate()
9dae56ea 64{
6fe7ccc8
A
65 SamplingRegion samplingRegion("Bytecode Generation");
66
81345200 67 m_codeBlock->setThisRegister(m_thisRegister.virtualRegister());
ed1e77d3
A
68
69 // If we have declared a variable named "arguments" and we are using arguments then we should
70 // perform that assignment now.
71 if (m_needToInitializeArguments)
72 initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
73
74 for (size_t i = 0; i < m_destructuringParameters.size(); i++) {
75 auto& entry = m_destructuringParameters[i];
81345200
A
76 entry.second->bindValue(*this, entry.first.get());
77 }
9dae56ea 78
ed1e77d3
A
79 {
80 RefPtr<RegisterID> temp = newTemporary();
81 RefPtr<RegisterID> globalScope = scopeRegister(); // FIXME: With lexical scoping, this won't always be the global object: https://bugs.webkit.org/show_bug.cgi?id=142944
82 for (auto functionPair : m_functionsToInitialize) {
83 FunctionBodyNode* functionBody = functionPair.first;
84 FunctionVariableType functionType = functionPair.second;
85 emitNewFunction(temp.get(), functionBody);
86 if (functionType == NormalFunctionVariable)
87 initializeVariable(variable(functionBody->ident()) , temp.get());
88 else if (functionType == GlobalFunctionVariable)
89 emitPutToScope(globalScope.get(), Variable(functionBody->ident()), temp.get(), ThrowIfNotFound);
90 else
91 RELEASE_ASSERT_NOT_REACHED();
92 }
93 }
94
95 bool callingClassConstructor = constructorKind() != ConstructorKind::None && !isConstructor();
96 if (!callingClassConstructor)
97 m_scopeNode->emitBytecode(*this);
9dae56ea 98
93a37866 99 m_staticPropertyAnalyzer.kill();
9dae56ea 100
93a37866
A
101 for (unsigned i = 0; i < m_tryRanges.size(); ++i) {
102 TryRange& range = m_tryRanges[i];
103 int start = range.start->bind();
104 int end = range.end->bind();
105
106 // This will happen for empty try blocks and for some cases of finally blocks:
107 //
108 // try {
109 // try {
110 // } finally {
111 // return 42;
112 // // *HERE*
113 // }
114 // } finally {
115 // print("things");
116 // }
117 //
118 // The return will pop scopes to execute the outer finally block. But this includes
119 // popping the try context for the inner try. The try context is live in the fall-through
120 // part of the finally block not because we will emit a handler that overlaps the finally,
121 // but because we haven't yet had a chance to plant the catch target. Then when we finish
122 // emitting code for the outer finally block, we repush the try contex, this time with a
123 // new start index. But that means that the start index for the try range corresponding
124 // to the inner-finally-following-the-return (marked as "*HERE*" above) will be greater
125 // than the end index of the try block. This is harmless since end < start handlers will
126 // never get matched in our logic, but we do the runtime a favor and choose to not emit
127 // such handlers at all.
128 if (end <= start)
129 continue;
130
131 ASSERT(range.tryData->targetScopeDepth != UINT_MAX);
ed1e77d3
A
132 ASSERT(range.tryData->handlerType != HandlerType::Illegal);
133 UnlinkedHandlerInfo info(static_cast<uint32_t>(start), static_cast<uint32_t>(end),
134 static_cast<uint32_t>(range.tryData->target->bind()), range.tryData->targetScopeDepth,
135 range.tryData->handlerType);
93a37866
A
136 m_codeBlock->addExceptionHandler(info);
137 }
138
81345200 139 m_codeBlock->setInstructions(std::make_unique<UnlinkedInstructionStream>(m_instructions));
9dae56ea
A
140
141 m_codeBlock->shrinkToFit();
14957cd0 142
ed1e77d3
A
143 if (m_codeBlock->symbolTable() && !m_codeBlock->vm()->typeProfiler())
144 m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneScopePart(*m_codeBlock->vm()));
81345200 145
14957cd0 146 if (m_expressionTooDeep)
93a37866
A
147 return ParserError(ParserError::OutOfMemory);
148 return ParserError(ParserError::ErrorNone);
9dae56ea
A
149}
150
81345200
A
151BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
152 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
153 , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
9dae56ea 154 , m_scopeNode(programNode)
93a37866 155 , m_codeBlock(vm, codeBlock)
6fe7ccc8 156 , m_thisRegister(CallFrame::thisArgumentOffset())
9dae56ea 157 , m_codeType(GlobalCode)
93a37866 158 , m_vm(&vm)
9dae56ea 159{
ed1e77d3
A
160 for (auto& constantRegister : m_linkTimeConstantRegisters)
161 constantRegister = nullptr;
162
6fe7ccc8 163 m_codeBlock->setNumParameters(1); // Allocate space for "this"
9dae56ea 164
93a37866 165 emitOpcode(op_enter);
9dae56ea 166
ed1e77d3
A
167 allocateAndEmitScope();
168
9dae56ea
A
169 const VarStack& varStack = programNode->varStack();
170 const FunctionStack& functionStack = programNode->functionStack();
14957cd0 171
6fe7ccc8
A
172 for (size_t i = 0; i < functionStack.size(); ++i) {
173 FunctionBodyNode* function = functionStack[i];
ed1e77d3 174 m_functionsToInitialize.append(std::make_pair(function, GlobalFunctionVariable));
6fe7ccc8 175 }
9dae56ea 176
93a37866 177 for (size_t i = 0; i < varStack.size(); ++i)
81345200 178 codeBlock->addVariableDeclaration(varStack[i].first, !!(varStack[i].second & DeclarationStacks::IsConstant));
93a37866 179
9dae56ea
A
180}
181
ed1e77d3 182BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
81345200
A
183 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
184 , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
93a37866 185 , m_symbolTable(codeBlock->symbolTable())
ed1e77d3 186 , m_scopeNode(functionNode)
93a37866 187 , m_codeBlock(vm, codeBlock)
9dae56ea 188 , m_codeType(FunctionCode)
93a37866 189 , m_vm(&vm)
81345200 190 , m_isBuiltinFunction(codeBlock->isBuiltinFunction())
9dae56ea 191{
ed1e77d3
A
192 for (auto& constantRegister : m_linkTimeConstantRegisters)
193 constantRegister = nullptr;
194
81345200
A
195 if (m_isBuiltinFunction)
196 m_shouldEmitDebugHooks = false;
ed1e77d3 197
93a37866 198 m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
81345200 199 Vector<Identifier> boundParameterProperties;
ed1e77d3 200 FunctionParameters& parameters = *functionNode->parameters();
81345200
A
201 for (size_t i = 0; i < parameters.size(); i++) {
202 auto pattern = parameters.at(i);
203 if (pattern->isBindingNode())
204 continue;
205 pattern->collectBoundIdentifiers(boundParameterProperties);
206 continue;
207 }
93a37866 208
ed1e77d3
A
209 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain();
210 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
211 bool needsArguments = functionNode->usesArguments() || codeBlock->usesEval();
212
213 auto captures = [&] (UniquedStringImpl* uid) -> bool {
214 if (shouldCaptureAllOfTheThings)
215 return true;
216 if (!shouldCaptureSomeOfTheThings)
217 return false;
218 if (needsArguments && uid == propertyNames().arguments.impl()) {
219 // Actually, we only need to capture the arguments object when we "need full activation"
220 // because of name scopes. But historically we did it this way, so for now we just preserve
221 // the old behavior.
222 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=143072
223 return true;
224 }
225 return functionNode->captures(uid);
226 };
227 auto varKind = [&] (UniquedStringImpl* uid) -> VarKind {
228 return captures(uid) ? VarKind::Scope : VarKind::Stack;
229 };
14957cd0 230
ed1e77d3 231 emitOpcode(op_enter);
9dae56ea 232
ed1e77d3
A
233 allocateAndEmitScope();
234
235 m_calleeRegister.setIndex(JSStack::Callee);
236
237 if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
238 && functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())) {
239 // When we do this, we should make our local scope stack know about the function name symbol
240 // table. Currently this works because bytecode linking creates a phony name scope.
241 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141885
242 // Also, we could create the scope once per JSFunction instance that needs it. That wouldn't
243 // be any more correct, but it would be more performant.
244 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141887
245 emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &m_calleeRegister, ReadOnly | DontDelete);
ba379fdc 246 }
9dae56ea 247
ed1e77d3
A
248 if (shouldCaptureSomeOfTheThings) {
249 m_lexicalEnvironmentRegister = addVar();
250 m_codeBlock->setActivationRegister(m_lexicalEnvironmentRegister->virtualRegister());
251 emitOpcode(op_create_lexical_environment);
252 instructions().append(m_lexicalEnvironmentRegister->index());
253 instructions().append(scopeRegister()->index());
254 emitOpcode(op_mov);
255 instructions().append(scopeRegister()->index());
256 instructions().append(m_lexicalEnvironmentRegister->index());
257 }
258
259 // Make sure the code block knows about all of our parameters, and make sure that parameters
260 // needing destructuring are noted.
261 m_parameters.grow(parameters.size() + 1); // reserve space for "this"
262 m_thisRegister.setIndex(initializeNextParameter()->index()); // this
263 for (unsigned i = 0; i < parameters.size(); ++i) {
264 auto pattern = parameters.at(i);
265 RegisterID* reg = initializeNextParameter();
266 if (!pattern->isBindingNode())
267 m_destructuringParameters.append(std::make_pair(reg, pattern));
268 }
269
270 // Figure out some interesting facts about our arguments.
93a37866 271 bool capturesAnyArgumentByName = false;
ed1e77d3
A
272 if (functionNode->hasCapturedVariables()) {
273 FunctionParameters& parameters = *functionNode->parameters();
93a37866 274 for (size_t i = 0; i < parameters.size(); ++i) {
81345200
A
275 auto pattern = parameters.at(i);
276 if (!pattern->isBindingNode())
277 continue;
278 const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
ed1e77d3 279 capturesAnyArgumentByName |= captures(ident.impl());
93a37866
A
280 }
281 }
282
ed1e77d3
A
283 if (capturesAnyArgumentByName)
284 ASSERT(m_lexicalEnvironmentRegister);
285
286 // Need to know what our functions are called. Parameters have some goofy behaviors when it
287 // comes to functions of the same name.
288 for (FunctionBodyNode* function : functionNode->functionStack())
289 m_functions.add(function->ident().impl());
290
291 if (needsArguments) {
292 // Create the arguments object now. We may put the arguments object into the activation if
293 // it is captured. Either way, we create two arguments object variables: one is our
294 // private variable that is immutable, and another that is the user-visible variable. The
295 // immutable one is only used here, or during formal parameter resolutions if we opt for
296 // DirectArguments.
297
298 m_argumentsRegister = addVar();
299 m_argumentsRegister->ref();
93a37866 300 }
ed1e77d3
A
301
302 if (needsArguments && !codeBlock->isStrictMode()) {
303 // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
304 // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
305 // activation.
306
307 if (capturesAnyArgumentByName) {
308 m_symbolTable->setArgumentsLength(vm, parameters.size());
309
310 // For each parameter, we have two possibilities:
311 // Either it's a binding node with no function overlap, in which case it gets a name
312 // in the symbol table - or it just gets space reserved in the symbol table. Either
313 // way we lift the value into the scope.
314 for (unsigned i = 0; i < parameters.size(); ++i) {
315 ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
316 m_symbolTable->setArgumentOffset(vm, i, offset);
317 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i))) {
318 VarOffset varOffset(offset);
319 SymbolTableEntry entry(varOffset);
320 // Stores to these variables via the ScopedArguments object will not do
321 // notifyWrite(), since that would be cumbersome. Also, watching formal
322 // parameters when "arguments" is in play is unlikely to be super profitable.
323 // So, we just disable it.
324 entry.disableWatching();
325 m_symbolTable->set(name, entry);
326 }
327 emitOpcode(op_put_to_scope);
328 instructions().append(m_lexicalEnvironmentRegister->index());
329 instructions().append(UINT_MAX);
330 instructions().append(virtualRegisterForArgument(1 + i).offset());
331 instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
332 instructions().append(0);
333 instructions().append(offset.offset());
14957cd0 334 }
ed1e77d3
A
335
336 // This creates a scoped arguments object and copies the overflow arguments into the
337 // scope. It's the equivalent of calling ScopedArguments::createByCopying().
338 emitOpcode(op_create_scoped_arguments);
339 instructions().append(m_argumentsRegister->index());
340 instructions().append(m_lexicalEnvironmentRegister->index());
341 } else {
342 // We're going to put all parameters into the DirectArguments object. First ensure
343 // that the symbol table knows that this is happening.
344 for (unsigned i = 0; i < parameters.size(); ++i) {
345 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i)))
346 m_symbolTable->set(name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
347 }
348
349 emitOpcode(op_create_direct_arguments);
350 instructions().append(m_argumentsRegister->index());
14957cd0 351 }
ed1e77d3
A
352 } else {
353 // Create the formal parameters the normal way. Any of them could be captured, or not. If
354 // captured, lift them into the scope.
355 for (unsigned i = 0; i < parameters.size(); ++i) {
356 UniquedStringImpl* name = visibleNameForParameter(parameters.at(i));
357 if (!name)
358 continue;
359
360 if (!captures(name)) {
361 // This is the easy case - just tell the symbol table about the argument. It will
362 // be accessed directly.
363 m_symbolTable->set(name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
364 continue;
365 }
366
367 ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
368 const Identifier& ident =
369 static_cast<const BindingNode*>(parameters.at(i))->boundProperty();
370 m_symbolTable->set(name, SymbolTableEntry(VarOffset(offset)));
371
372 emitOpcode(op_put_to_scope);
373 instructions().append(m_lexicalEnvironmentRegister->index());
374 instructions().append(addConstant(ident));
375 instructions().append(virtualRegisterForArgument(1 + i).offset());
376 instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
377 instructions().append(0);
378 instructions().append(offset.offset());
14957cd0
A
379 }
380 }
ed1e77d3
A
381
382 if (needsArguments && codeBlock->isStrictMode()) {
383 // Allocate an out-of-bands arguments object.
384 emitOpcode(op_create_out_of_band_arguments);
385 instructions().append(m_argumentsRegister->index());
386 }
387
388 // Now declare all variables.
389 for (const Identifier& ident : boundParameterProperties)
390 createVariable(ident, varKind(ident.impl()), IsVariable);
391 for (FunctionBodyNode* function : functionNode->functionStack()) {
f9bf01c6 392 const Identifier& ident = function->ident();
ed1e77d3
A
393 createVariable(ident, varKind(ident.impl()), IsVariable);
394 m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
9dae56ea 395 }
ed1e77d3
A
396 for (auto& entry : functionNode->varStack()) {
397 ConstantMode constantMode = modeForIsConstant(entry.second & DeclarationStacks::IsConstant);
398 // Variables named "arguments" are never const.
399 if (entry.first == propertyNames().arguments)
400 constantMode = IsVariable;
401 createVariable(entry.first, varKind(entry.first.impl()), constantMode, IgnoreExisting);
81345200 402 }
ed1e77d3
A
403
404 // There are some variables that need to be preinitialized to something other than Undefined:
405 //
406 // - "arguments": unless it's used as a function or parameter, this should refer to the
407 // arguments object.
408 //
409 // - callee: unless it's used as a var, function, or parameter, this should refer to the
410 // callee (i.e. our function).
411 //
412 // - functions: these always override everything else.
413 //
414 // The most logical way to do all of this is to initialize none of the variables until now,
415 // and then initialize them in BytecodeGenerator::generate() in such an order that the rules
416 // for how these things override each other end up holding. We would initialize the callee
417 // first, then "arguments", then all arguments, then the functions.
418 //
419 // But some arguments are already initialized by default, since if they aren't captured and we
420 // don't have "arguments" then we just point the symbol table at the stack slot of those
421 // arguments. We end up initializing the rest of the arguments that have an uncomplicated
422 // binding (i.e. don't involve destructuring) above when figuring out how to lay them out,
423 // because that's just the simplest thing. This means that when we initialize them, we have to
424 // watch out for the things that override arguments (namely, functions).
425 //
426 // We also initialize callee here as well, just because it's so weird. We know whether we want
427 // to do this because we can just check if it's in the symbol table.
428 if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
429 && !functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())
430 && m_symbolTable->get(functionNode->ident().impl()).isNull()) {
431 if (captures(functionNode->ident().impl())) {
432 ScopeOffset offset;
433 {
434 ConcurrentJITLocker locker(m_symbolTable->m_lock);
435 offset = m_symbolTable->takeNextScopeOffset(locker);
436 m_symbolTable->add(
437 locker, functionNode->ident().impl(),
438 SymbolTableEntry(VarOffset(offset), ReadOnly));
439 }
440
441 emitOpcode(op_put_to_scope);
442 instructions().append(m_lexicalEnvironmentRegister->index());
443 instructions().append(addConstant(functionNode->ident()));
444 instructions().append(m_calleeRegister.index());
445 instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
446 instructions().append(0);
447 instructions().append(offset.offset());
448 } else {
449 m_symbolTable->add(
450 functionNode->ident().impl(),
451 SymbolTableEntry(VarOffset(m_calleeRegister.virtualRegister()), ReadOnly));
452 }
14957cd0 453 }
81345200 454
ed1e77d3
A
455 // This is our final act of weirdness. "arguments" is overridden by everything except the
456 // callee. We add it to the symbol table if it's not already there and it's not an argument.
457 if (needsArguments) {
458 // If "arguments" is overridden by a function or destructuring parameter name, then it's
459 // OK for us to call createVariable() because it won't change anything. It's also OK for
460 // us to them tell BytecodeGenerator::generate() to write to it because it will do so
461 // before it initializes functions and destructuring parameters. But if "arguments" is
462 // overridden by a "simple" function parameter, then we have to bail: createVariable()
463 // would assert and BytecodeGenerator::generate() would write the "arguments" after the
464 // argument value had already been properly initialized.
465
466 bool haveParameterNamedArguments = false;
467 for (unsigned i = 0; i < parameters.size(); ++i) {
468 UniquedStringImpl* name = visibleNameForParameter(parameters.at(i));
469 if (name == propertyNames().arguments.impl()) {
470 haveParameterNamedArguments = true;
471 break;
472 }
81345200 473 }
ed1e77d3
A
474
475 if (!haveParameterNamedArguments) {
476 createVariable(
477 propertyNames().arguments, varKind(propertyNames().arguments.impl()), IsVariable);
478 m_needToInitializeArguments = true;
93a37866 479 }
93a37866 480 }
ed1e77d3 481
93a37866 482 if (isConstructor()) {
ed1e77d3
A
483 if (constructorKind() == ConstructorKind::Derived) {
484 m_newTargetRegister = addVar();
485 emitMove(m_newTargetRegister, &m_thisRegister);
486 emitMoveEmptyValue(&m_thisRegister);
487 } else
488 emitCreateThis(&m_thisRegister);
489 } else if (constructorKind() != ConstructorKind::None) {
490 emitThrowTypeError("Cannot call a class constructor");
491 } else if (functionNode->usesThis() || codeBlock->usesEval()) {
81345200
A
492 m_codeBlock->addPropertyAccessInstruction(instructions().size());
493 emitOpcode(op_to_this);
93a37866 494 instructions().append(kill(&m_thisRegister));
81345200 495 instructions().append(0);
ed1e77d3 496 instructions().append(0);
14957cd0 497 }
9dae56ea
A
498}
499
81345200
A
500BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
501 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
502 , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
93a37866 503 , m_symbolTable(codeBlock->symbolTable())
9dae56ea 504 , m_scopeNode(evalNode)
93a37866 505 , m_codeBlock(vm, codeBlock)
6fe7ccc8 506 , m_thisRegister(CallFrame::thisArgumentOffset())
9dae56ea 507 , m_codeType(EvalCode)
93a37866 508 , m_vm(&vm)
9dae56ea 509{
ed1e77d3
A
510 for (auto& constantRegister : m_linkTimeConstantRegisters)
511 constantRegister = nullptr;
512
93a37866 513 m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
6fe7ccc8 514 m_codeBlock->setNumParameters(1);
9dae56ea 515
93a37866
A
516 emitOpcode(op_enter);
517
ed1e77d3
A
518 allocateAndEmitScope();
519
f9bf01c6
A
520 const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
521 for (size_t i = 0; i < functionStack.size(); ++i)
93a37866 522 m_codeBlock->addFunctionDecl(makeFunction(functionStack[i]));
f9bf01c6
A
523
524 const DeclarationStacks::VarStack& varStack = evalNode->varStack();
525 unsigned numVariables = varStack.size();
93a37866 526 Vector<Identifier, 0, UnsafeVectorOverflow> variables;
f9bf01c6 527 variables.reserveCapacity(numVariables);
81345200 528 for (size_t i = 0; i < numVariables; ++i) {
ed1e77d3 529 ASSERT(varStack[i].first.impl()->isAtomic() || varStack[i].first.impl()->isSymbol());
81345200
A
530 variables.append(varStack[i].first);
531 }
f9bf01c6 532 codeBlock->adoptVariables(variables);
9dae56ea
A
533}
534
6fe7ccc8
A
535BytecodeGenerator::~BytecodeGenerator()
536{
6fe7ccc8
A
537}
538
ed1e77d3 539RegisterID* BytecodeGenerator::initializeNextParameter()
93a37866 540{
ed1e77d3
A
541 VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
542 RegisterID& parameter = registerFor(reg);
543 parameter.setIndex(reg.offset());
93a37866 544 m_codeBlock->addParameter();
ed1e77d3 545 return &parameter;
6fe7ccc8
A
546}
547
ed1e77d3 548UniquedStringImpl* BytecodeGenerator::visibleNameForParameter(DestructuringPatternNode* pattern)
14957cd0 549{
ed1e77d3
A
550 if (pattern->isBindingNode()) {
551 const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
552 if (!m_functions.contains(ident.impl()))
553 return ident.impl();
554 }
555 return nullptr;
14957cd0
A
556}
557
9dae56ea
A
558RegisterID* BytecodeGenerator::newRegister()
559{
81345200
A
560 m_calleeRegisters.append(virtualRegisterForLocal(m_calleeRegisters.size()));
561 int numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size());
562 numCalleeRegisters = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numCalleeRegisters);
563 m_codeBlock->m_numCalleeRegisters = numCalleeRegisters;
9dae56ea
A
564 return &m_calleeRegisters.last();
565}
566
567RegisterID* BytecodeGenerator::newTemporary()
568{
569 // Reclaim free register IDs.
570 while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount())
571 m_calleeRegisters.removeLast();
572
573 RegisterID* result = newRegister();
574 result->setTemporary();
575 return result;
576}
577
93a37866 578LabelScopePtr BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
9dae56ea
A
579{
580 // Reclaim free label scopes.
581 while (m_labelScopes.size() && !m_labelScopes.last().refCount())
582 m_labelScopes.removeLast();
583
584 // Allocate new label scope.
f9bf01c6 585 LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
9dae56ea 586 m_labelScopes.append(scope);
81345200 587 return LabelScopePtr(m_labelScopes, m_labelScopes.size() - 1);
9dae56ea
A
588}
589
590PassRefPtr<Label> BytecodeGenerator::newLabel()
591{
592 // Reclaim free label IDs.
593 while (m_labels.size() && !m_labels.last().refCount())
594 m_labels.removeLast();
595
596 // Allocate new label ID.
ed1e77d3 597 m_labels.append(*this);
9dae56ea
A
598 return &m_labels.last();
599}
600
601PassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0)
602{
603 unsigned newLabelIndex = instructions().size();
604 l0->setLocation(newLabelIndex);
605
606 if (m_codeBlock->numberOfJumpTargets()) {
607 unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
608 ASSERT(lastLabelIndex <= newLabelIndex);
609 if (newLabelIndex == lastLabelIndex) {
610 // Peephole optimizations have already been disabled by emitting the last label
611 return l0;
612 }
613 }
614
615 m_codeBlock->addJumpTarget(newLabelIndex);
616
617 // This disables peephole optimizations when an instruction is a jump target
618 m_lastOpcodeID = op_end;
619 return l0;
620}
621
622void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
623{
14957cd0
A
624#ifndef NDEBUG
625 size_t opcodePosition = instructions().size();
626 ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
627 m_lastOpcodePosition = opcodePosition;
628#endif
93a37866 629 instructions().append(opcodeID);
9dae56ea
A
630 m_lastOpcodeID = opcodeID;
631}
632
93a37866 633UnlinkedArrayProfile BytecodeGenerator::newArrayProfile()
6fe7ccc8 634{
93a37866 635 return m_codeBlock->addArrayProfile();
93a37866
A
636}
637
638UnlinkedArrayAllocationProfile BytecodeGenerator::newArrayAllocationProfile()
639{
93a37866 640 return m_codeBlock->addArrayAllocationProfile();
93a37866
A
641}
642
643UnlinkedObjectAllocationProfile BytecodeGenerator::newObjectAllocationProfile()
644{
645 return m_codeBlock->addObjectAllocationProfile();
646}
647
648UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
649{
93a37866 650 UnlinkedValueProfile result = m_codeBlock->addValueProfile();
6fe7ccc8
A
651 emitOpcode(opcodeID);
652 return result;
653}
654
655void BytecodeGenerator::emitLoopHint()
656{
6fe7ccc8 657 emitOpcode(op_loop_hint);
6fe7ccc8
A
658}
659
9dae56ea
A
660void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
661{
662 ASSERT(instructions().size() >= 4);
663 size_t size = instructions().size();
664 dstIndex = instructions().at(size - 3).u.operand;
665 src1Index = instructions().at(size - 2).u.operand;
666 src2Index = instructions().at(size - 1).u.operand;
667}
668
669void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
670{
671 ASSERT(instructions().size() >= 3);
672 size_t size = instructions().size();
673 dstIndex = instructions().at(size - 2).u.operand;
674 srcIndex = instructions().at(size - 1).u.operand;
675}
676
677void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
678{
679 ASSERT(instructions().size() >= 4);
680 instructions().shrink(instructions().size() - 4);
14957cd0 681 m_lastOpcodeID = op_end;
9dae56ea
A
682}
683
684void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
685{
686 ASSERT(instructions().size() >= 3);
687 instructions().shrink(instructions().size() - 3);
14957cd0 688 m_lastOpcodeID = op_end;
9dae56ea
A
689}
690
691PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
692{
f9bf01c6 693 size_t begin = instructions().size();
93a37866 694 emitOpcode(op_jmp);
f9bf01c6 695 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
696 return target;
697}
698
699PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
700{
f9bf01c6 701 if (m_lastOpcodeID == op_less) {
9dae56ea
A
702 int dstIndex;
703 int src1Index;
704 int src2Index;
705
706 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
707
708 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
709 rewindBinaryOp();
f9bf01c6
A
710
711 size_t begin = instructions().size();
93a37866 712 emitOpcode(op_jless);
9dae56ea
A
713 instructions().append(src1Index);
714 instructions().append(src2Index);
f9bf01c6 715 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
716 return target;
717 }
4e4e5a6f 718 } else if (m_lastOpcodeID == op_lesseq) {
9dae56ea
A
719 int dstIndex;
720 int src1Index;
721 int src2Index;
722
723 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
724
725 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
726 rewindBinaryOp();
f9bf01c6
A
727
728 size_t begin = instructions().size();
93a37866 729 emitOpcode(op_jlesseq);
9dae56ea
A
730 instructions().append(src1Index);
731 instructions().append(src2Index);
f9bf01c6 732 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
733 return target;
734 }
6fe7ccc8
A
735 } else if (m_lastOpcodeID == op_greater) {
736 int dstIndex;
737 int src1Index;
738 int src2Index;
739
740 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
741
742 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
743 rewindBinaryOp();
744
745 size_t begin = instructions().size();
93a37866 746 emitOpcode(op_jgreater);
6fe7ccc8
A
747 instructions().append(src1Index);
748 instructions().append(src2Index);
749 instructions().append(target->bind(begin, instructions().size()));
750 return target;
751 }
752 } else if (m_lastOpcodeID == op_greatereq) {
753 int dstIndex;
754 int src1Index;
755 int src2Index;
756
757 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
758
759 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
760 rewindBinaryOp();
761
762 size_t begin = instructions().size();
93a37866 763 emitOpcode(op_jgreatereq);
6fe7ccc8
A
764 instructions().append(src1Index);
765 instructions().append(src2Index);
766 instructions().append(target->bind(begin, instructions().size()));
767 return target;
768 }
9dae56ea
A
769 } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
770 int dstIndex;
771 int srcIndex;
772
773 retrieveLastUnaryOp(dstIndex, srcIndex);
774
775 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
776 rewindUnaryOp();
f9bf01c6
A
777
778 size_t begin = instructions().size();
9dae56ea
A
779 emitOpcode(op_jeq_null);
780 instructions().append(srcIndex);
f9bf01c6 781 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
782 return target;
783 }
784 } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
785 int dstIndex;
786 int srcIndex;
787
788 retrieveLastUnaryOp(dstIndex, srcIndex);
789
790 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
791 rewindUnaryOp();
f9bf01c6
A
792
793 size_t begin = instructions().size();
9dae56ea
A
794 emitOpcode(op_jneq_null);
795 instructions().append(srcIndex);
f9bf01c6 796 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
797 return target;
798 }
799 }
800
f9bf01c6
A
801 size_t begin = instructions().size();
802
93a37866 803 emitOpcode(op_jtrue);
9dae56ea 804 instructions().append(cond->index());
f9bf01c6 805 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
806 return target;
807}
808
809PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
810{
f9bf01c6 811 if (m_lastOpcodeID == op_less && target->isForward()) {
9dae56ea
A
812 int dstIndex;
813 int src1Index;
814 int src2Index;
815
816 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
817
818 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
819 rewindBinaryOp();
f9bf01c6
A
820
821 size_t begin = instructions().size();
9dae56ea
A
822 emitOpcode(op_jnless);
823 instructions().append(src1Index);
824 instructions().append(src2Index);
f9bf01c6 825 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
826 return target;
827 }
f9bf01c6 828 } else if (m_lastOpcodeID == op_lesseq && target->isForward()) {
ba379fdc
A
829 int dstIndex;
830 int src1Index;
831 int src2Index;
832
833 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
834
835 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
836 rewindBinaryOp();
f9bf01c6
A
837
838 size_t begin = instructions().size();
ba379fdc
A
839 emitOpcode(op_jnlesseq);
840 instructions().append(src1Index);
841 instructions().append(src2Index);
f9bf01c6 842 instructions().append(target->bind(begin, instructions().size()));
ba379fdc
A
843 return target;
844 }
6fe7ccc8
A
845 } else if (m_lastOpcodeID == op_greater && target->isForward()) {
846 int dstIndex;
847 int src1Index;
848 int src2Index;
849
850 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
851
852 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
853 rewindBinaryOp();
854
855 size_t begin = instructions().size();
856 emitOpcode(op_jngreater);
857 instructions().append(src1Index);
858 instructions().append(src2Index);
859 instructions().append(target->bind(begin, instructions().size()));
860 return target;
861 }
862 } else if (m_lastOpcodeID == op_greatereq && target->isForward()) {
863 int dstIndex;
864 int src1Index;
865 int src2Index;
866
867 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
868
869 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
870 rewindBinaryOp();
871
872 size_t begin = instructions().size();
873 emitOpcode(op_jngreatereq);
874 instructions().append(src1Index);
875 instructions().append(src2Index);
876 instructions().append(target->bind(begin, instructions().size()));
877 return target;
878 }
9dae56ea
A
879 } else if (m_lastOpcodeID == op_not) {
880 int dstIndex;
881 int srcIndex;
882
883 retrieveLastUnaryOp(dstIndex, srcIndex);
884
885 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
886 rewindUnaryOp();
f9bf01c6
A
887
888 size_t begin = instructions().size();
93a37866 889 emitOpcode(op_jtrue);
9dae56ea 890 instructions().append(srcIndex);
f9bf01c6 891 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
892 return target;
893 }
f9bf01c6 894 } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
9dae56ea
A
895 int dstIndex;
896 int srcIndex;
897
898 retrieveLastUnaryOp(dstIndex, srcIndex);
899
900 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
901 rewindUnaryOp();
f9bf01c6
A
902
903 size_t begin = instructions().size();
9dae56ea
A
904 emitOpcode(op_jneq_null);
905 instructions().append(srcIndex);
f9bf01c6 906 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
907 return target;
908 }
f9bf01c6 909 } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
9dae56ea
A
910 int dstIndex;
911 int srcIndex;
912
913 retrieveLastUnaryOp(dstIndex, srcIndex);
914
915 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
916 rewindUnaryOp();
f9bf01c6
A
917
918 size_t begin = instructions().size();
9dae56ea
A
919 emitOpcode(op_jeq_null);
920 instructions().append(srcIndex);
f9bf01c6 921 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
922 return target;
923 }
924 }
925
f9bf01c6 926 size_t begin = instructions().size();
93a37866 927 emitOpcode(op_jfalse);
9dae56ea 928 instructions().append(cond->index());
f9bf01c6 929 instructions().append(target->bind(begin, instructions().size()));
9dae56ea
A
930 return target;
931}
932
ba379fdc
A
933PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
934{
f9bf01c6
A
935 size_t begin = instructions().size();
936
ba379fdc
A
937 emitOpcode(op_jneq_ptr);
938 instructions().append(cond->index());
93a37866 939 instructions().append(Special::CallFunction);
f9bf01c6 940 instructions().append(target->bind(begin, instructions().size()));
ba379fdc
A
941 return target;
942}
943
944PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
945{
f9bf01c6
A
946 size_t begin = instructions().size();
947
ba379fdc
A
948 emitOpcode(op_jneq_ptr);
949 instructions().append(cond->index());
93a37866 950 instructions().append(Special::ApplyFunction);
f9bf01c6 951 instructions().append(target->bind(begin, instructions().size()));
ba379fdc
A
952 return target;
953}
954
ed1e77d3
A
955bool BytecodeGenerator::hasConstant(const Identifier& ident) const
956{
957 UniquedStringImpl* rep = ident.impl();
958 return m_identifierMap.contains(rep);
959}
960
9dae56ea
A
961unsigned BytecodeGenerator::addConstant(const Identifier& ident)
962{
ed1e77d3 963 UniquedStringImpl* rep = ident.impl();
6fe7ccc8
A
964 IdentifierMap::AddResult result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
965 if (result.isNewEntry)
81345200 966 m_codeBlock->addIdentifier(ident);
93a37866
A
967
968 return result.iterator->value;
969}
970
971// We can't hash JSValue(), so we use a dedicated data member to cache it.
972RegisterID* BytecodeGenerator::addConstantEmptyValue()
973{
974 if (!m_emptyValueRegister) {
975 int index = m_nextConstantOffset;
976 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
977 ++m_nextConstantOffset;
978 m_codeBlock->addConstant(JSValue());
979 m_emptyValueRegister = &m_constantPoolRegisters[index];
980 }
9dae56ea 981
93a37866 982 return m_emptyValueRegister;
9dae56ea
A
983}
984
ed1e77d3 985RegisterID* BytecodeGenerator::addConstantValue(JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
9dae56ea 986{
93a37866
A
987 if (!v)
988 return addConstantEmptyValue();
9dae56ea 989
93a37866 990 int index = m_nextConstantOffset;
ed1e77d3
A
991
992 EncodedJSValueWithRepresentation valueMapKey { JSValue::encode(v), sourceCodeRepresentation };
993 JSValueMap::AddResult result = m_jsValueMap.add(valueMapKey, m_nextConstantOffset);
6fe7ccc8 994 if (result.isNewEntry) {
ba379fdc
A
995 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
996 ++m_nextConstantOffset;
ed1e77d3 997 m_codeBlock->addConstant(v, sourceCodeRepresentation);
ba379fdc 998 } else
93a37866 999 index = result.iterator->value;
ba379fdc 1000 return &m_constantPoolRegisters[index];
9dae56ea
A
1001}
1002
ed1e77d3
A
1003RegisterID* BytecodeGenerator::emitMoveLinkTimeConstant(RegisterID* dst, LinkTimeConstant type)
1004{
1005 unsigned constantIndex = static_cast<unsigned>(type);
1006 if (!m_linkTimeConstantRegisters[constantIndex]) {
1007 int index = m_nextConstantOffset;
1008 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1009 ++m_nextConstantOffset;
1010 m_codeBlock->addConstant(type);
1011 m_linkTimeConstantRegisters[constantIndex] = &m_constantPoolRegisters[index];
1012 }
1013
1014 emitOpcode(op_mov);
1015 instructions().append(dst->index());
1016 instructions().append(m_linkTimeConstantRegisters[constantIndex]->index());
1017
1018 return dst;
1019}
1020
9dae56ea
A
1021unsigned BytecodeGenerator::addRegExp(RegExp* r)
1022{
1023 return m_codeBlock->addRegExp(r);
1024}
1025
ed1e77d3 1026RegisterID* BytecodeGenerator::emitMoveEmptyValue(RegisterID* dst)
9dae56ea 1027{
ed1e77d3 1028 RefPtr<RegisterID> emptyValue = addConstantEmptyValue();
93a37866 1029
ed1e77d3 1030 emitOpcode(op_mov);
9dae56ea 1031 instructions().append(dst->index());
ed1e77d3 1032 instructions().append(emptyValue->index());
9dae56ea
A
1033 return dst;
1034}
1035
81345200
A
1036RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
1037{
ed1e77d3
A
1038 ASSERT(src != m_emptyValueRegister);
1039
1040 m_staticPropertyAnalyzer.mov(dst->index(), src->index());
1041 emitOpcode(op_mov);
1042 instructions().append(dst->index());
1043 instructions().append(src->index());
1044
1045 if (!dst->isTemporary() && vm()->typeProfiler())
1046 emitProfileType(dst, ProfileTypeBytecodeHasGlobalID, nullptr);
1047
1048 return dst;
81345200
A
1049}
1050
9dae56ea
A
1051RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1052{
1053 emitOpcode(opcodeID);
1054 instructions().append(dst->index());
1055 instructions().append(src->index());
1056 return dst;
1057}
1058
93a37866 1059RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
9dae56ea 1060{
93a37866 1061 emitOpcode(op_inc);
9dae56ea
A
1062 instructions().append(srcDst->index());
1063 return srcDst;
1064}
1065
93a37866 1066RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
9dae56ea 1067{
93a37866 1068 emitOpcode(op_dec);
9dae56ea
A
1069 instructions().append(srcDst->index());
1070 return srcDst;
1071}
1072
9dae56ea
A
1073RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
1074{
1075 emitOpcode(opcodeID);
1076 instructions().append(dst->index());
1077 instructions().append(src1->index());
1078 instructions().append(src2->index());
1079
1080 if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
ba379fdc 1081 opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
9dae56ea 1082 instructions().append(types.toInt());
9dae56ea
A
1083
1084 return dst;
1085}
1086
1087RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
1088{
1089 if (m_lastOpcodeID == op_typeof) {
1090 int dstIndex;
1091 int srcIndex;
1092
1093 retrieveLastUnaryOp(dstIndex, srcIndex);
1094
1095 if (src1->index() == dstIndex
1096 && src1->isTemporary()
1097 && m_codeBlock->isConstantRegisterIndex(src2->index())
14957cd0 1098 && m_codeBlock->constantRegister(src2->index()).get().isString()) {
93a37866 1099 const String& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
9dae56ea
A
1100 if (value == "undefined") {
1101 rewindUnaryOp();
1102 emitOpcode(op_is_undefined);
1103 instructions().append(dst->index());
1104 instructions().append(srcIndex);
1105 return dst;
1106 }
1107 if (value == "boolean") {
1108 rewindUnaryOp();
1109 emitOpcode(op_is_boolean);
1110 instructions().append(dst->index());
1111 instructions().append(srcIndex);
1112 return dst;
1113 }
1114 if (value == "number") {
1115 rewindUnaryOp();
1116 emitOpcode(op_is_number);
1117 instructions().append(dst->index());
1118 instructions().append(srcIndex);
1119 return dst;
1120 }
1121 if (value == "string") {
1122 rewindUnaryOp();
1123 emitOpcode(op_is_string);
1124 instructions().append(dst->index());
1125 instructions().append(srcIndex);
1126 return dst;
1127 }
1128 if (value == "object") {
1129 rewindUnaryOp();
ed1e77d3 1130 emitOpcode(op_is_object_or_null);
9dae56ea
A
1131 instructions().append(dst->index());
1132 instructions().append(srcIndex);
1133 return dst;
1134 }
1135 if (value == "function") {
1136 rewindUnaryOp();
1137 emitOpcode(op_is_function);
1138 instructions().append(dst->index());
1139 instructions().append(srcIndex);
1140 return dst;
1141 }
1142 }
1143 }
1144
1145 emitOpcode(opcodeID);
1146 instructions().append(dst->index());
1147 instructions().append(src1->index());
1148 instructions().append(src2->index());
1149 return dst;
1150}
1151
ed1e77d3 1152void BytecodeGenerator::emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot)
9dae56ea 1153{
ed1e77d3
A
1154 unsigned start = startDivot.offset; // Ranges are inclusive of their endpoints, AND 0 indexed.
1155 unsigned end = endDivot.offset - 1; // End Ranges already go one past the inclusive range, so subtract 1.
1156 unsigned instructionOffset = instructions().size() - 1;
1157 m_codeBlock->addTypeProfilerExpressionInfo(instructionOffset, start, end);
1158}
1159
1160void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag, const Identifier* identifier)
1161{
1162 if (flag == ProfileTypeBytecodeGetFromScope || flag == ProfileTypeBytecodePutToScope)
1163 RELEASE_ASSERT(identifier);
1164
1165 // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1166 emitOpcode(op_profile_type);
1167 instructions().append(registerToProfile->index());
1168 instructions().append(0);
1169 instructions().append(flag);
1170 instructions().append(identifier ? addConstant(*identifier) : 0);
1171 instructions().append(resolveType());
9dae56ea
A
1172}
1173
ed1e77d3 1174void BytecodeGenerator::emitProfileControlFlow(int textOffset)
9dae56ea 1175{
ed1e77d3
A
1176 if (vm()->controlFlowProfiler()) {
1177 RELEASE_ASSERT(textOffset >= 0);
1178 size_t bytecodeOffset = instructions().size();
1179 m_codeBlock->addOpProfileControlFlowBytecodeOffset(bytecodeOffset);
1180
1181 emitOpcode(op_profile_control_flow);
1182 instructions().append(textOffset);
1183 }
1184}
1185
1186RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
1187{
1188 return emitLoad(dst, jsBoolean(b));
9dae56ea
A
1189}
1190
1191RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
1192{
81345200 1193 JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
9dae56ea 1194 if (!stringInMap)
93a37866 1195 stringInMap = jsOwnedString(vm(), identifier.string());
ba379fdc 1196 return emitLoad(dst, JSValue(stringInMap));
9dae56ea
A
1197}
1198
ed1e77d3 1199RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
9dae56ea 1200{
ed1e77d3 1201 RegisterID* constantID = addConstantValue(v, sourceCodeRepresentation);
9dae56ea
A
1202 if (dst)
1203 return emitMove(dst, constantID);
1204 return constantID;
1205}
1206
93a37866 1207RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst)
9dae56ea 1208{
93a37866
A
1209 if (!m_globalObjectRegister) {
1210 int index = m_nextConstantOffset;
1211 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1212 ++m_nextConstantOffset;
1213 m_codeBlock->addConstant(JSValue());
1214 m_globalObjectRegister = &m_constantPoolRegisters[index];
81345200 1215 m_codeBlock->setGlobalObjectRegister(VirtualRegister(index));
93a37866
A
1216 }
1217 if (dst)
1218 emitMove(dst, m_globalObjectRegister);
1219 return m_globalObjectRegister;
1220}
1221
ed1e77d3 1222Variable BytecodeGenerator::variable(const Identifier& property)
81345200 1223{
ed1e77d3
A
1224 if (property == propertyNames().thisIdentifier) {
1225 return Variable(
1226 property, VarOffset(thisRegister()->virtualRegister()), thisRegister(),
1227 ReadOnly, Variable::SpecialVariable);
1228 }
81345200 1229
81345200 1230 if (!shouldOptimizeLocals())
ed1e77d3
A
1231 return Variable(property);
1232
1233 SymbolTableEntry entry = symbolTable().get(property.impl());
1234 if (entry.isNull())
1235 return Variable(property);
1236
1237 if (entry.varOffset().isScope() && m_localScopeDepth) {
1238 // FIXME: We should be able to statically resolve through our local scopes.
1239 // https://bugs.webkit.org/show_bug.cgi?id=141885
1240 return Variable(property);
1241 }
1242
1243 return variableForLocalEntry(property, entry);
1244}
93a37866 1245
ed1e77d3
A
1246Variable BytecodeGenerator::variablePerSymbolTable(const Identifier& property)
1247{
81345200
A
1248 SymbolTableEntry entry = symbolTable().get(property.impl());
1249 if (entry.isNull())
ed1e77d3
A
1250 return Variable(property);
1251
1252 return variableForLocalEntry(property, entry);
1253}
81345200 1254
ed1e77d3
A
1255Variable BytecodeGenerator::variableForLocalEntry(
1256 const Identifier& property, const SymbolTableEntry& entry)
1257{
1258 VarOffset offset = entry.varOffset();
1259
1260 RegisterID* local;
1261 if (offset.isStack())
1262 local = &registerFor(offset.stackOffset());
1263 else
1264 local = nullptr;
1265
1266 return Variable(property, offset, local, entry.getAttributes(), Variable::NormalVariable);
9dae56ea
A
1267}
1268
ed1e77d3
A
1269void BytecodeGenerator::createVariable(
1270 const Identifier& property, VarKind varKind, ConstantMode constantMode,
1271 ExistingVariableMode existingVariableMode)
93a37866 1272{
ed1e77d3
A
1273 ASSERT(property != propertyNames().thisIdentifier);
1274
1275 ConcurrentJITLocker locker(symbolTable().m_lock);
1276 SymbolTableEntry entry = symbolTable().get(locker, property.impl());
1277
1278 if (!entry.isNull()) {
1279 if (existingVariableMode == IgnoreExisting)
1280 return;
1281
1282 // Do some checks to ensure that the variable we're being asked to create is sufficiently
1283 // compatible with the one we have already created.
81345200 1284
ed1e77d3
A
1285 VarOffset offset = entry.varOffset();
1286
1287 // We can't change our minds about whether it's captured.
1288 if (offset.kind() != varKind || constantMode != entry.constantMode()) {
1289 dataLog(
1290 "Trying to add variable called ", property, " as ", varKind, "/", constantMode,
1291 " but it was already added as ", offset, "/", entry.constantMode(), ".\n");
1292 RELEASE_ASSERT_NOT_REACHED();
1293 }
93a37866 1294
ed1e77d3
A
1295 return;
1296 }
1297
1298 VarOffset varOffset;
1299 if (varKind == VarKind::Scope)
1300 varOffset = VarOffset(symbolTable().takeNextScopeOffset(locker));
1301 else {
1302 ASSERT(varKind == VarKind::Stack);
1303 varOffset = VarOffset(virtualRegisterForLocal(m_calleeRegisters.size()));
1304 }
1305 SymbolTableEntry newEntry(varOffset, constantMode == IsConstant ? ReadOnly : 0);
1306 symbolTable().add(locker, property.impl(), newEntry);
1307
1308 if (varKind == VarKind::Stack) {
1309 RegisterID* local = addVar();
1310 RELEASE_ASSERT(local->index() == varOffset.stackOffset().offset());
1311 }
93a37866
A
1312}
1313
1314void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target)
1315{
1316 size_t begin = instructions().size();
14957cd0 1317 emitOpcode(op_check_has_instance);
93a37866
A
1318 instructions().append(dst->index());
1319 instructions().append(value->index());
14957cd0 1320 instructions().append(base->index());
93a37866 1321 instructions().append(target->bind(begin, instructions().size()));
14957cd0
A
1322}
1323
81345200
A
1324// Indicates the least upper bound of resolve type based on local scope. The bytecode linker
1325// will start with this ResolveType and compute the least upper bound including intercepting scopes.
1326ResolveType BytecodeGenerator::resolveType()
14957cd0 1327{
81345200
A
1328 if (m_localScopeDepth)
1329 return Dynamic;
1330 if (m_symbolTable && m_symbolTable->usesNonStrictEval())
1331 return GlobalPropertyWithVarInjectionChecks;
1332 return GlobalProperty;
14957cd0
A
1333}
1334
ed1e77d3 1335RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& variable)
9dae56ea 1336{
ed1e77d3
A
1337 switch (variable.offset().kind()) {
1338 case VarKind::Stack:
1339 return nullptr;
1340
1341 case VarKind::DirectArgument:
1342 return argumentsRegister();
1343
1344 case VarKind::Scope:
1345 // This always refers to the activation that *we* allocated, and not the current scope that code
1346 // lives in. Note that this will change once we have proper support for block scoping. Once that
1347 // changes, it will be correct for this code to return scopeRegister(). The only reason why we
1348 // don't do that already is that m_lexicalEnvironment is required by ConstDeclNode. ConstDeclNode
1349 // requires weird things because it is a shameful pile of nonsense, but block scoping would make
1350 // that code sensible and obviate the need for us to do bad things.
1351 return m_lexicalEnvironmentRegister;
1352
1353 case VarKind::Invalid:
1354 // Indicates non-local resolution.
1355
1356 ASSERT(!m_symbolTable || !m_symbolTable->contains(variable.ident().impl()) || resolveType() == Dynamic);
1357
1358 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1359
1360 // resolve_scope dst, id, ResolveType, depth
1361 emitOpcode(op_resolve_scope);
1362 dst = tempDestination(dst);
1363 instructions().append(kill(dst));
1364 instructions().append(scopeRegister()->index());
1365 instructions().append(addConstant(variable.ident()));
1366 instructions().append(resolveType());
1367 instructions().append(0);
1368 instructions().append(0);
1369 return dst;
1370 }
1371
1372 RELEASE_ASSERT_NOT_REACHED();
1373 return nullptr;
9dae56ea
A
1374}
1375
ed1e77d3 1376RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable& variable, ResolveMode resolveMode)
9dae56ea 1377{
ed1e77d3
A
1378 switch (variable.offset().kind()) {
1379 case VarKind::Stack:
1380 return emitMove(dst, variable.local());
1381
1382 case VarKind::DirectArgument: {
1383 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_arguments);
1384 instructions().append(kill(dst));
1385 instructions().append(scope->index());
1386 instructions().append(variable.offset().capturedArgumentsOffset().offset());
1387 instructions().append(profile);
1388 return dst;
1389 }
1390
1391 case VarKind::Scope:
1392 case VarKind::Invalid: {
1393 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1394
1395 // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
1396 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
1397 instructions().append(kill(dst));
1398 instructions().append(scope->index());
1399 instructions().append(addConstant(variable.ident()));
1400 instructions().append(ResolveModeAndType(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType()).operand());
1401 instructions().append(0);
1402 instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
1403 instructions().append(profile);
1404 return dst;
1405 } }
1406
1407 RELEASE_ASSERT_NOT_REACHED();
1408}
9dae56ea 1409
ed1e77d3
A
1410RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode)
1411{
1412 switch (variable.offset().kind()) {
1413 case VarKind::Stack:
1414 emitMove(variable.local(), value);
1415 return value;
1416
1417 case VarKind::DirectArgument:
1418 emitOpcode(op_put_to_arguments);
1419 instructions().append(scope->index());
1420 instructions().append(variable.offset().capturedArgumentsOffset().offset());
1421 instructions().append(value->index());
1422 return value;
1423
1424 case VarKind::Scope:
1425 case VarKind::Invalid: {
1426 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1427
1428 // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
1429 emitOpcode(op_put_to_scope);
1430 instructions().append(scope->index());
1431 instructions().append(addConstant(variable.ident()));
1432 instructions().append(value->index());
1433 ScopeOffset offset;
1434 if (variable.offset().isScope()) {
1435 offset = variable.offset().scopeOffset();
1436 instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
1437 } else {
1438 ASSERT(resolveType() != LocalClosureVar);
1439 instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
1440 }
1441 instructions().append(0);
1442 instructions().append(!!offset ? offset.offset() : 0);
1443 return value;
1444 } }
1445
1446 RELEASE_ASSERT_NOT_REACHED();
9dae56ea
A
1447}
1448
ed1e77d3 1449RegisterID* BytecodeGenerator::initializeVariable(const Variable& variable, RegisterID* value)
9dae56ea 1450{
ed1e77d3
A
1451 RegisterID* scope;
1452 switch (variable.offset().kind()) {
1453 case VarKind::Stack:
1454 scope = nullptr;
1455 break;
1456
1457 case VarKind::DirectArgument:
1458 scope = argumentsRegister();
1459 break;
1460
1461 case VarKind::Scope:
1462 scope = scopeRegister();
1463 break;
1464
1465 default:
1466 scope = nullptr;
1467 RELEASE_ASSERT_NOT_REACHED();
1468 break;
1469 }
9dae56ea 1470
ed1e77d3 1471 return emitPutToScope(scope, variable, value, ThrowIfNotFound);
14957cd0
A
1472}
1473
81345200 1474RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
ed1e77d3 1475{
81345200
A
1476 emitOpcode(op_instanceof);
1477 instructions().append(dst->index());
1478 instructions().append(value->index());
1479 instructions().append(basePrototype->index());
1480 return dst;
93a37866
A
1481}
1482
1483RegisterID* BytecodeGenerator::emitInitGlobalConst(const Identifier& identifier, RegisterID* value)
1484{
1485 ASSERT(m_codeType == GlobalCode);
1486 emitOpcode(op_init_global_const_nop);
ba379fdc 1487 instructions().append(0);
93a37866 1488 instructions().append(value->index());
ba379fdc 1489 instructions().append(0);
93a37866
A
1490 instructions().append(addConstant(identifier));
1491 return value;
9dae56ea
A
1492}
1493
9dae56ea
A
1494RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1495{
9dae56ea 1496 m_codeBlock->addPropertyAccessInstruction(instructions().size());
9dae56ea 1497
93a37866
A
1498 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id);
1499 instructions().append(kill(dst));
9dae56ea
A
1500 instructions().append(base->index());
1501 instructions().append(addConstant(property));
1502 instructions().append(0);
1503 instructions().append(0);
1504 instructions().append(0);
1505 instructions().append(0);
6fe7ccc8 1506 instructions().append(profile);
9dae56ea
A
1507 return dst;
1508}
1509
1510RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1511{
93a37866
A
1512 unsigned propertyIndex = addConstant(property);
1513
1514 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
1515
9dae56ea 1516 m_codeBlock->addPropertyAccessInstruction(instructions().size());
9dae56ea
A
1517
1518 emitOpcode(op_put_by_id);
1519 instructions().append(base->index());
93a37866 1520 instructions().append(propertyIndex);
9dae56ea
A
1521 instructions().append(value->index());
1522 instructions().append(0);
1523 instructions().append(0);
1524 instructions().append(0);
1525 instructions().append(0);
4e4e5a6f 1526 instructions().append(0);
ed1e77d3 1527
4e4e5a6f
A
1528 return value;
1529}
1530
ed1e77d3 1531RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType putType)
4e4e5a6f 1532{
ed1e77d3 1533 ASSERT(!parseIndex(property));
93a37866
A
1534 unsigned propertyIndex = addConstant(property);
1535
1536 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
1537
4e4e5a6f 1538 m_codeBlock->addPropertyAccessInstruction(instructions().size());
4e4e5a6f
A
1539
1540 emitOpcode(op_put_by_id);
1541 instructions().append(base->index());
93a37866 1542 instructions().append(propertyIndex);
4e4e5a6f
A
1543 instructions().append(value->index());
1544 instructions().append(0);
1545 instructions().append(0);
1546 instructions().append(0);
1547 instructions().append(0);
ed1e77d3 1548 instructions().append(putType == PropertyNode::KnownDirect || property != m_vm->propertyNames->underscoreProto);
9dae56ea
A
1549 return value;
1550}
1551
ed1e77d3
A
1552void BytecodeGenerator::emitPutGetterById(RegisterID* base, const Identifier& property, RegisterID* getter)
1553{
1554 unsigned propertyIndex = addConstant(property);
1555 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
1556
1557 emitOpcode(op_put_getter_by_id);
1558 instructions().append(base->index());
1559 instructions().append(propertyIndex);
1560 instructions().append(getter->index());
1561}
1562
1563void BytecodeGenerator::emitPutSetterById(RegisterID* base, const Identifier& property, RegisterID* setter)
1564{
1565 unsigned propertyIndex = addConstant(property);
1566 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
1567
1568 emitOpcode(op_put_setter_by_id);
1569 instructions().append(base->index());
1570 instructions().append(propertyIndex);
1571 instructions().append(setter->index());
1572}
1573
6fe7ccc8 1574void BytecodeGenerator::emitPutGetterSetter(RegisterID* base, const Identifier& property, RegisterID* getter, RegisterID* setter)
9dae56ea 1575{
93a37866
A
1576 unsigned propertyIndex = addConstant(property);
1577
1578 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
1579
6fe7ccc8 1580 emitOpcode(op_put_getter_setter);
9dae56ea 1581 instructions().append(base->index());
93a37866 1582 instructions().append(propertyIndex);
6fe7ccc8
A
1583 instructions().append(getter->index());
1584 instructions().append(setter->index());
9dae56ea
A
1585}
1586
1587RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
1588{
1589 emitOpcode(op_del_by_id);
1590 instructions().append(dst->index());
1591 instructions().append(base->index());
1592 instructions().append(addConstant(property));
1593 return dst;
1594}
1595
1596RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1597{
f9bf01c6 1598 for (size_t i = m_forInContextStack.size(); i > 0; i--) {
ed1e77d3
A
1599 ForInContext* context = m_forInContextStack[i - 1].get();
1600 if (context->local() != property)
1601 continue;
1602
1603 if (!context->isValid())
1604 break;
1605
1606 if (context->type() == ForInContext::IndexedForInContextType) {
1607 property = static_cast<IndexedForInContext*>(context)->index();
1608 break;
f9bf01c6 1609 }
ed1e77d3
A
1610
1611 ASSERT(context->type() == ForInContext::StructureForInContextType);
1612 StructureForInContext* structureContext = static_cast<StructureForInContext*>(context);
1613 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_direct_pname);
1614 instructions().append(kill(dst));
1615 instructions().append(base->index());
1616 instructions().append(property->index());
1617 instructions().append(structureContext->index()->index());
1618 instructions().append(structureContext->enumerator()->index());
1619 instructions().append(profile);
1620 return dst;
f9bf01c6 1621 }
ed1e77d3 1622
93a37866
A
1623 UnlinkedArrayProfile arrayProfile = newArrayProfile();
1624 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val);
1625 instructions().append(kill(dst));
9dae56ea
A
1626 instructions().append(base->index());
1627 instructions().append(property->index());
93a37866 1628 instructions().append(arrayProfile);
6fe7ccc8 1629 instructions().append(profile);
9dae56ea
A
1630 return dst;
1631}
1632
1633RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
1634{
93a37866 1635 UnlinkedArrayProfile arrayProfile = newArrayProfile();
ed1e77d3 1636 emitOpcode(op_put_by_val);
81345200
A
1637 instructions().append(base->index());
1638 instructions().append(property->index());
1639 instructions().append(value->index());
1640 instructions().append(arrayProfile);
ed1e77d3 1641
81345200
A
1642 return value;
1643}
1644
1645RegisterID* BytecodeGenerator::emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
1646{
1647 UnlinkedArrayProfile arrayProfile = newArrayProfile();
1648 emitOpcode(op_put_by_val_direct);
9dae56ea
A
1649 instructions().append(base->index());
1650 instructions().append(property->index());
1651 instructions().append(value->index());
93a37866 1652 instructions().append(arrayProfile);
9dae56ea
A
1653 return value;
1654}
1655
1656RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1657{
1658 emitOpcode(op_del_by_val);
1659 instructions().append(dst->index());
1660 instructions().append(base->index());
1661 instructions().append(property->index());
1662 return dst;
1663}
1664
1665RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
1666{
1667 emitOpcode(op_put_by_index);
1668 instructions().append(base->index());
1669 instructions().append(index);
1670 instructions().append(value->index());
1671 return value;
1672}
1673
93a37866 1674RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
ed1e77d3 1675{
93a37866
A
1676 size_t begin = instructions().size();
1677 m_staticPropertyAnalyzer.createThis(m_thisRegister.index(), begin + 3);
1678
ed1e77d3 1679 m_codeBlock->addPropertyAccessInstruction(instructions().size());
93a37866
A
1680 emitOpcode(op_create_this);
1681 instructions().append(m_thisRegister.index());
ed1e77d3
A
1682 instructions().append(m_thisRegister.index());
1683 instructions().append(0);
93a37866
A
1684 instructions().append(0);
1685 return dst;
1686}
1687
ed1e77d3
A
1688void BytecodeGenerator::emitTDZCheck(RegisterID* target)
1689{
1690 emitOpcode(op_check_tdz);
1691 instructions().append(target->index());
1692}
1693
9dae56ea
A
1694RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
1695{
93a37866
A
1696 size_t begin = instructions().size();
1697 m_staticPropertyAnalyzer.newObject(dst->index(), begin + 2);
1698
9dae56ea
A
1699 emitOpcode(op_new_object);
1700 instructions().append(dst->index());
93a37866
A
1701 instructions().append(0);
1702 instructions().append(newObjectAllocationProfile());
9dae56ea
A
1703 return dst;
1704}
1705
14957cd0
A
1706unsigned BytecodeGenerator::addConstantBuffer(unsigned length)
1707{
1708 return m_codeBlock->addConstantBuffer(length);
1709}
1710
1711JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
1712{
81345200 1713 JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
14957cd0 1714 if (!stringInMap) {
93a37866 1715 stringInMap = jsString(vm(), identifier.string());
14957cd0
A
1716 addConstantValue(stringInMap);
1717 }
1718 return stringInMap;
1719}
1720
ed1e77d3
A
1721JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(const TemplateRegistryKey& templateRegistryKey)
1722{
1723 JSTemplateRegistryKey*& templateRegistryKeyInMap = m_templateRegistryKeyMap.add(templateRegistryKey, nullptr).iterator->value;
1724 if (!templateRegistryKeyInMap) {
1725 templateRegistryKeyInMap = JSTemplateRegistryKey::create(*vm(), templateRegistryKey);
1726 addConstantValue(templateRegistryKeyInMap);
1727 }
1728 return templateRegistryKeyInMap;
1729}
1730
14957cd0 1731RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
9dae56ea 1732{
14957cd0
A
1733#if !ASSERT_DISABLED
1734 unsigned checkLength = 0;
1735#endif
1736 bool hadVariableExpression = false;
1737 if (length) {
1738 for (ElementNode* n = elements; n; n = n->next()) {
93a37866 1739 if (!n->value()->isConstant()) {
14957cd0
A
1740 hadVariableExpression = true;
1741 break;
1742 }
1743 if (n->elision())
1744 break;
1745#if !ASSERT_DISABLED
1746 checkLength++;
1747#endif
1748 }
1749 if (!hadVariableExpression) {
1750 ASSERT(length == checkLength);
1751 unsigned constantBufferIndex = addConstantBuffer(length);
93a37866 1752 JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex).data();
14957cd0
A
1753 unsigned index = 0;
1754 for (ElementNode* n = elements; index < length; n = n->next()) {
93a37866
A
1755 ASSERT(n->value()->isConstant());
1756 constantBuffer[index++] = static_cast<ConstantNode*>(n->value())->jsValue(*this);
14957cd0
A
1757 }
1758 emitOpcode(op_new_array_buffer);
1759 instructions().append(dst->index());
1760 instructions().append(constantBufferIndex);
1761 instructions().append(length);
93a37866 1762 instructions().append(newArrayAllocationProfile());
14957cd0
A
1763 return dst;
1764 }
1765 }
1766
93a37866 1767 Vector<RefPtr<RegisterID>, 16, UnsafeVectorOverflow> argv;
9dae56ea 1768 for (ElementNode* n = elements; n; n = n->next()) {
81345200 1769 if (!length)
9dae56ea 1770 break;
81345200
A
1771 length--;
1772 ASSERT(!n->value()->isSpreadExpression());
9dae56ea
A
1773 argv.append(newTemporary());
1774 // op_new_array requires the initial values to be a sequential range of registers
81345200 1775 ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() - 1);
9dae56ea
A
1776 emitNode(argv.last().get(), n->value());
1777 }
81345200 1778 ASSERT(!length);
9dae56ea
A
1779 emitOpcode(op_new_array);
1780 instructions().append(dst->index());
1781 instructions().append(argv.size() ? argv[0]->index() : 0); // argv
1782 instructions().append(argv.size()); // argc
93a37866 1783 instructions().append(newArrayAllocationProfile());
9dae56ea
A
1784 return dst;
1785}
1786
ed1e77d3 1787RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
14957cd0 1788{
ed1e77d3 1789 return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)));
14957cd0 1790}
f9bf01c6 1791
ed1e77d3 1792RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index)
14957cd0 1793{
ed1e77d3 1794 emitOpcode(op_new_func);
9dae56ea 1795 instructions().append(dst->index());
ed1e77d3 1796 instructions().append(scopeRegister()->index());
f9bf01c6 1797 instructions().append(index);
9dae56ea
A
1798 return dst;
1799}
1800
1801RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
1802{
1803 emitOpcode(op_new_regexp);
1804 instructions().append(dst->index());
1805 instructions().append(addRegExp(regExp));
1806 return dst;
1807}
1808
9dae56ea
A
1809RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
1810{
f9bf01c6 1811 FunctionBodyNode* function = n->body();
93a37866 1812 unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function));
ed1e77d3 1813
9dae56ea
A
1814 emitOpcode(op_new_func_exp);
1815 instructions().append(r0->index());
ed1e77d3 1816 instructions().append(scopeRegister()->index());
f9bf01c6 1817 instructions().append(index);
9dae56ea
A
1818 return r0;
1819}
1820
ed1e77d3 1821RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier& name)
ba379fdc 1822{
ed1e77d3 1823 UnlinkedFunctionExecutable* executable = m_vm->builtinExecutables()->createDefaultConstructor(constructorKind, name);
14957cd0 1824
ed1e77d3 1825 unsigned index = m_codeBlock->addFunctionExpr(executable);
14957cd0 1826
ed1e77d3
A
1827 emitOpcode(op_new_func_exp);
1828 instructions().append(dst->index());
1829 instructions().append(scopeRegister()->index());
1830 instructions().append(index);
1831 return dst;
ba379fdc
A
1832}
1833
ed1e77d3 1834RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
9dae56ea 1835{
ed1e77d3 1836 return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
9dae56ea
A
1837}
1838
81345200 1839RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
93a37866 1840{
81345200 1841 return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, divotStart, divotEnd);
93a37866
A
1842}
1843
1844ExpectedFunction BytecodeGenerator::expectedFunctionForIdentifier(const Identifier& identifier)
1845{
ed1e77d3 1846 if (identifier == m_vm->propertyNames->Object || identifier == m_vm->propertyNames->ObjectPrivateName)
93a37866 1847 return ExpectObjectConstructor;
ed1e77d3 1848 if (identifier == m_vm->propertyNames->Array || identifier == m_vm->propertyNames->ArrayPrivateName)
93a37866
A
1849 return ExpectArrayConstructor;
1850 return NoExpectedFunction;
1851}
1852
1853ExpectedFunction BytecodeGenerator::emitExpectedFunctionSnippet(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, Label* done)
14957cd0 1854{
93a37866
A
1855 RefPtr<Label> realCall = newLabel();
1856 switch (expectedFunction) {
1857 case ExpectObjectConstructor: {
1858 // If the number of arguments is non-zero, then we can't do anything interesting.
1859 if (callArguments.argumentCountIncludingThis() >= 2)
1860 return NoExpectedFunction;
1861
1862 size_t begin = instructions().size();
1863 emitOpcode(op_jneq_ptr);
1864 instructions().append(func->index());
1865 instructions().append(Special::ObjectConstructor);
1866 instructions().append(realCall->bind(begin, instructions().size()));
1867
1868 if (dst != ignoredResult())
1869 emitNewObject(dst);
1870 break;
1871 }
1872
1873 case ExpectArrayConstructor: {
1874 // If you're doing anything other than "new Array()" or "new Array(foo)" then we
1875 // don't do inline it, for now. The only reason is that call arguments are in
1876 // the opposite order of what op_new_array expects, so we'd either need to change
1877 // how op_new_array works or we'd need an op_new_array_reverse. Neither of these
1878 // things sounds like it's worth it.
1879 if (callArguments.argumentCountIncludingThis() > 2)
1880 return NoExpectedFunction;
1881
1882 size_t begin = instructions().size();
1883 emitOpcode(op_jneq_ptr);
1884 instructions().append(func->index());
1885 instructions().append(Special::ArrayConstructor);
1886 instructions().append(realCall->bind(begin, instructions().size()));
1887
1888 if (dst != ignoredResult()) {
1889 if (callArguments.argumentCountIncludingThis() == 2) {
1890 emitOpcode(op_new_array_with_size);
1891 instructions().append(dst->index());
1892 instructions().append(callArguments.argumentRegister(0)->index());
1893 instructions().append(newArrayAllocationProfile());
1894 } else {
1895 ASSERT(callArguments.argumentCountIncludingThis() == 1);
1896 emitOpcode(op_new_array);
1897 instructions().append(dst->index());
1898 instructions().append(0);
1899 instructions().append(0);
1900 instructions().append(newArrayAllocationProfile());
1901 }
1902 }
1903 break;
1904 }
1905
1906 default:
1907 ASSERT(expectedFunction == NoExpectedFunction);
1908 return NoExpectedFunction;
1909 }
1910
1911 size_t begin = instructions().size();
1912 emitOpcode(op_jmp);
1913 instructions().append(done->bind(begin, instructions().size()));
1914 emitLabel(realCall.get());
1915
1916 return expectedFunction;
14957cd0
A
1917}
1918
81345200 1919RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
9dae56ea
A
1920{
1921 ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
1922 ASSERT(func->refCount());
9dae56ea 1923
14957cd0
A
1924 if (m_shouldEmitProfileHooks)
1925 emitMove(callArguments.profileHookRegister(), func);
9dae56ea
A
1926
1927 // Generate code for arguments.
6fe7ccc8 1928 unsigned argument = 0;
81345200
A
1929 if (callArguments.argumentsNode()) {
1930 ArgumentListNode* n = callArguments.argumentsNode()->m_listNode;
1931 if (n && n->m_expr->isSpreadExpression()) {
1932 RELEASE_ASSERT(!n->m_next);
1933 auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
1934 RefPtr<RegisterID> argumentRegister;
ed1e77d3 1935 argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
81345200
A
1936 RefPtr<RegisterID> thisRegister = emitMove(newTemporary(), callArguments.thisRegister());
1937 return emitCallVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
1938 }
1939 for (; n; n = n->m_next)
1940 emitNode(callArguments.argumentRegister(argument++), n);
1941 }
1942
9dae56ea 1943 // Reserve space for call frame.
93a37866
A
1944 Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize, UnsafeVectorOverflow> callFrame;
1945 for (int i = 0; i < JSStack::CallFrameHeaderSize; ++i)
9dae56ea
A
1946 callFrame.append(newTemporary());
1947
1948 if (m_shouldEmitProfileHooks) {
1949 emitOpcode(op_profile_will_call);
14957cd0 1950 instructions().append(callArguments.profileHookRegister()->index());
9dae56ea
A
1951 }
1952
81345200 1953 emitExpressionInfo(divot, divotStart, divotEnd);
9dae56ea 1954
93a37866
A
1955 RefPtr<Label> done = newLabel();
1956 expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
1957
9dae56ea 1958 // Emit call.
93a37866 1959 UnlinkedArrayProfile arrayProfile = newArrayProfile();
81345200
A
1960 UnlinkedValueProfile profile = emitProfiledOpcode(opcodeID);
1961 ASSERT(dst);
1962 ASSERT(dst != ignoredResult());
1963 instructions().append(dst->index());
1964 instructions().append(func->index());
1965 instructions().append(callArguments.argumentCountIncludingThis());
1966 instructions().append(callArguments.stackOffset());
6fe7ccc8 1967 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
6fe7ccc8 1968 instructions().append(0);
93a37866 1969 instructions().append(arrayProfile);
81345200 1970 instructions().append(profile);
93a37866
A
1971
1972 if (expectedFunction != NoExpectedFunction)
1973 emitLabel(done.get());
9dae56ea
A
1974
1975 if (m_shouldEmitProfileHooks) {
1976 emitOpcode(op_profile_did_call);
14957cd0 1977 instructions().append(callArguments.profileHookRegister()->index());
9dae56ea
A
1978 }
1979
1980 return dst;
1981}
1982
81345200
A
1983RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
1984{
1985 return emitCallVarargs(op_call_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
1986}
1987
ed1e77d3 1988RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
81345200 1989{
ed1e77d3 1990 return emitCallVarargs(op_construct_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
81345200
A
1991}
1992
1993RegisterID* BytecodeGenerator::emitCallVarargs(OpcodeID opcode, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
ba379fdc 1994{
ba379fdc 1995 if (m_shouldEmitProfileHooks) {
6fe7ccc8 1996 emitMove(profileHookRegister, func);
ba379fdc 1997 emitOpcode(op_profile_will_call);
6fe7ccc8 1998 instructions().append(profileHookRegister->index());
ba379fdc
A
1999 }
2000
81345200 2001 emitExpressionInfo(divot, divotStart, divotEnd);
6fe7ccc8 2002
ba379fdc 2003 // Emit call.
81345200
A
2004 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2005 UnlinkedValueProfile profile = emitProfiledOpcode(opcode);
2006 ASSERT(dst != ignoredResult());
2007 instructions().append(dst->index());
6fe7ccc8 2008 instructions().append(func->index());
81345200 2009 instructions().append(thisRegister ? thisRegister->index() : 0);
6fe7ccc8
A
2010 instructions().append(arguments->index());
2011 instructions().append(firstFreeRegister->index());
81345200
A
2012 instructions().append(firstVarArgOffset);
2013 instructions().append(arrayProfile);
2014 instructions().append(profile);
ba379fdc
A
2015 if (m_shouldEmitProfileHooks) {
2016 emitOpcode(op_profile_did_call);
6fe7ccc8 2017 instructions().append(profileHookRegister->index());
ba379fdc
A
2018 }
2019 return dst;
2020}
2021
ed1e77d3
A
2022void BytecodeGenerator::emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
2023 RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition& position)
9dae56ea 2024{
ed1e77d3 2025 RefPtr<RegisterID> descriptorRegister = emitNewObject(newTemporary());
93a37866 2026
ed1e77d3
A
2027 RefPtr<RegisterID> trueRegister = emitLoad(newTemporary(), true);
2028 if (options & PropertyConfigurable)
2029 emitDirectPutById(descriptorRegister.get(), propertyNames().configurable, trueRegister.get(), PropertyNode::Unknown);
2030 if (options & PropertyWritable)
2031 emitDirectPutById(descriptorRegister.get(), propertyNames().writable, trueRegister.get(), PropertyNode::Unknown);
2032 else if (valueRegister) {
2033 RefPtr<RegisterID> falseRegister = emitLoad(newTemporary(), false);
2034 emitDirectPutById(descriptorRegister.get(), propertyNames().writable, falseRegister.get(), PropertyNode::Unknown);
14957cd0 2035 }
ed1e77d3
A
2036 if (options & PropertyEnumerable)
2037 emitDirectPutById(descriptorRegister.get(), propertyNames().enumerable, trueRegister.get(), PropertyNode::Unknown);
2038
2039 if (valueRegister)
2040 emitDirectPutById(descriptorRegister.get(), propertyNames().value, valueRegister, PropertyNode::Unknown);
2041 if (getterRegister)
2042 emitDirectPutById(descriptorRegister.get(), propertyNames().get, getterRegister, PropertyNode::Unknown);
2043 if (setterRegister)
2044 emitDirectPutById(descriptorRegister.get(), propertyNames().set, setterRegister, PropertyNode::Unknown);
2045
2046 RefPtr<RegisterID> definePropertyRegister = emitMoveLinkTimeConstant(newTemporary(), LinkTimeConstant::DefinePropertyFunction);
2047
2048 CallArguments callArguments(*this, nullptr, 3);
2049 emitLoad(callArguments.thisRegister(), jsUndefined());
2050 emitMove(callArguments.argumentRegister(0), newObj);
2051 emitMove(callArguments.argumentRegister(1), propertyNameRegister);
2052 emitMove(callArguments.argumentRegister(2), descriptorRegister.get());
2053
2054 emitCall(newTemporary(), definePropertyRegister.get(), NoExpectedFunction, callArguments, position, position, position);
2055}
2056
2057RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
2058{
2059 if (isConstructor()) {
2060 bool derived = constructorKind() == ConstructorKind::Derived;
2061 if (derived && src->index() == m_thisRegister.index())
2062 emitTDZCheck(src);
2063
2064 RefPtr<Label> isObjectLabel = newLabel();
2065 emitJumpIfTrue(emitIsObject(newTemporary(), src), isObjectLabel.get());
2066
2067 if (derived) {
2068 RefPtr<Label> isUndefinedLabel = newLabel();
2069 emitJumpIfTrue(emitIsUndefined(newTemporary(), src), isUndefinedLabel.get());
2070 emitThrowTypeError("Cannot return a non-object type in the constructor of a derived class.");
2071 emitLabel(isUndefinedLabel.get());
2072 if (constructorKind() == ConstructorKind::Derived)
2073 emitTDZCheck(&m_thisRegister);
2074 }
9dae56ea 2075
ed1e77d3
A
2076 emitUnaryNoDstOp(op_ret, &m_thisRegister);
2077
2078 emitLabel(isObjectLabel.get());
14957cd0 2079 }
ed1e77d3 2080
9dae56ea
A
2081 return emitUnaryNoDstOp(op_ret, src);
2082}
2083
2084RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src)
2085{
2086 emitOpcode(opcodeID);
2087 instructions().append(src->index());
2088 return src;
2089}
2090
81345200 2091RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
9dae56ea
A
2092{
2093 ASSERT(func->refCount());
2094
14957cd0
A
2095 if (m_shouldEmitProfileHooks)
2096 emitMove(callArguments.profileHookRegister(), func);
9dae56ea
A
2097
2098 // Generate code for arguments.
6fe7ccc8 2099 unsigned argument = 0;
14957cd0 2100 if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) {
81345200
A
2101
2102 ArgumentListNode* n = callArguments.argumentsNode()->m_listNode;
2103 if (n && n->m_expr->isSpreadExpression()) {
2104 RELEASE_ASSERT(!n->m_next);
2105 auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
2106 RefPtr<RegisterID> argumentRegister;
ed1e77d3
A
2107 argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
2108 return emitConstructVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
81345200
A
2109 }
2110
14957cd0 2111 for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next)
6fe7ccc8 2112 emitNode(callArguments.argumentRegister(argument++), n);
9dae56ea
A
2113 }
2114
2115 if (m_shouldEmitProfileHooks) {
2116 emitOpcode(op_profile_will_call);
14957cd0 2117 instructions().append(callArguments.profileHookRegister()->index());
9dae56ea
A
2118 }
2119
9dae56ea 2120 // Reserve space for call frame.
93a37866
A
2121 Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize, UnsafeVectorOverflow> callFrame;
2122 for (int i = 0; i < JSStack::CallFrameHeaderSize; ++i)
9dae56ea
A
2123 callFrame.append(newTemporary());
2124
81345200 2125 emitExpressionInfo(divot, divotStart, divotEnd);
93a37866
A
2126
2127 RefPtr<Label> done = newLabel();
2128 expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
9dae56ea 2129
81345200
A
2130 UnlinkedValueProfile profile = emitProfiledOpcode(op_construct);
2131 ASSERT(dst != ignoredResult());
2132 instructions().append(dst->index());
2133 instructions().append(func->index());
2134 instructions().append(callArguments.argumentCountIncludingThis());
2135 instructions().append(callArguments.stackOffset());
6fe7ccc8 2136 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
6fe7ccc8 2137 instructions().append(0);
6fe7ccc8 2138 instructions().append(0);
81345200 2139 instructions().append(profile);
9dae56ea 2140
93a37866
A
2141 if (expectedFunction != NoExpectedFunction)
2142 emitLabel(done.get());
2143
9dae56ea
A
2144 if (m_shouldEmitProfileHooks) {
2145 emitOpcode(op_profile_did_call);
14957cd0 2146 instructions().append(callArguments.profileHookRegister()->index());
9dae56ea
A
2147 }
2148
2149 return dst;
2150}
2151
ba379fdc
A
2152RegisterID* BytecodeGenerator::emitStrcat(RegisterID* dst, RegisterID* src, int count)
2153{
2154 emitOpcode(op_strcat);
2155 instructions().append(dst->index());
2156 instructions().append(src->index());
2157 instructions().append(count);
2158
2159 return dst;
2160}
2161
2162void BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src)
2163{
2164 emitOpcode(op_to_primitive);
2165 instructions().append(dst->index());
2166 instructions().append(src->index());
2167}
2168
ed1e77d3
A
2169void BytecodeGenerator::emitGetScope()
2170{
2171 emitOpcode(op_get_scope);
2172 instructions().append(scopeRegister()->index());
2173}
2174
2175RegisterID* BytecodeGenerator::emitPushWithScope(RegisterID* dst, RegisterID* scope)
9dae56ea 2176{
9dae56ea
A
2177 ControlFlowContext context;
2178 context.isFinallyBlock = false;
2179 m_scopeContextStack.append(context);
81345200 2180 m_localScopeDepth++;
9dae56ea 2181
ed1e77d3 2182 return emitUnaryOp(op_push_with_scope, dst, scope);
9dae56ea
A
2183}
2184
ed1e77d3 2185void BytecodeGenerator::emitPopScope(RegisterID* srcDst)
9dae56ea
A
2186{
2187 ASSERT(m_scopeContextStack.size());
2188 ASSERT(!m_scopeContextStack.last().isFinallyBlock);
2189
2190 emitOpcode(op_pop_scope);
ed1e77d3 2191 instructions().append(srcDst->index());
9dae56ea
A
2192
2193 m_scopeContextStack.removeLast();
81345200 2194 m_localScopeDepth--;
9dae56ea
A
2195}
2196
81345200 2197void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, unsigned line, unsigned charOffset, unsigned lineStart)
9dae56ea 2198{
4e4e5a6f
A
2199#if ENABLE(DEBUG_WITH_BREAKPOINT)
2200 if (debugHookID != DidReachBreakpoint)
2201 return;
2202#else
9dae56ea
A
2203 if (!m_shouldEmitDebugHooks)
2204 return;
4e4e5a6f 2205#endif
81345200
A
2206 JSTextPosition divot(line, charOffset, lineStart);
2207 emitExpressionInfo(divot, divot, divot);
9dae56ea
A
2208 emitOpcode(op_debug);
2209 instructions().append(debugHookID);
81345200 2210 instructions().append(false);
9dae56ea
A
2211}
2212
6fe7ccc8 2213void BytecodeGenerator::pushFinallyContext(StatementNode* finallyBlock)
9dae56ea 2214{
81345200
A
2215 // Reclaim free label scopes.
2216 while (m_labelScopes.size() && !m_labelScopes.last().refCount())
2217 m_labelScopes.removeLast();
2218
9dae56ea
A
2219 ControlFlowContext scope;
2220 scope.isFinallyBlock = true;
6fe7ccc8
A
2221 FinallyContext context = {
2222 finallyBlock,
ed1e77d3
A
2223 nullptr,
2224 nullptr,
2225 static_cast<unsigned>(m_scopeContextStack.size()),
2226 static_cast<unsigned>(m_switchContextStack.size()),
2227 static_cast<unsigned>(m_forInContextStack.size()),
2228 static_cast<unsigned>(m_tryContextStack.size()),
2229 static_cast<unsigned>(m_labelScopes.size()),
2230 m_finallyDepth,
2231 m_localScopeDepth
2232 };
2233 scope.finallyContext = context;
2234 m_scopeContextStack.append(scope);
2235 m_finallyDepth++;
2236}
2237
2238void BytecodeGenerator::pushIteratorCloseContext(RegisterID* iterator, ThrowableExpressionData* node)
2239{
2240 // Reclaim free label scopes.
2241 while (m_labelScopes.size() && !m_labelScopes.last().refCount())
2242 m_labelScopes.removeLast();
2243
2244 ControlFlowContext scope;
2245 scope.isFinallyBlock = true;
2246 FinallyContext context = {
2247 nullptr,
2248 iterator,
2249 node,
93a37866
A
2250 static_cast<unsigned>(m_scopeContextStack.size()),
2251 static_cast<unsigned>(m_switchContextStack.size()),
2252 static_cast<unsigned>(m_forInContextStack.size()),
2253 static_cast<unsigned>(m_tryContextStack.size()),
2254 static_cast<unsigned>(m_labelScopes.size()),
6fe7ccc8 2255 m_finallyDepth,
81345200 2256 m_localScopeDepth
6fe7ccc8 2257 };
9dae56ea
A
2258 scope.finallyContext = context;
2259 m_scopeContextStack.append(scope);
2260 m_finallyDepth++;
2261}
2262
2263void BytecodeGenerator::popFinallyContext()
2264{
2265 ASSERT(m_scopeContextStack.size());
2266 ASSERT(m_scopeContextStack.last().isFinallyBlock);
ed1e77d3
A
2267 ASSERT(m_scopeContextStack.last().finallyContext.finallyBlock);
2268 ASSERT(!m_scopeContextStack.last().finallyContext.iterator);
2269 ASSERT(!m_scopeContextStack.last().finallyContext.enumerationNode);
2270 ASSERT(m_finallyDepth > 0);
2271 m_scopeContextStack.removeLast();
2272 m_finallyDepth--;
2273}
2274
2275void BytecodeGenerator::popIteratorCloseContext()
2276{
2277 ASSERT(m_scopeContextStack.size());
2278 ASSERT(m_scopeContextStack.last().isFinallyBlock);
2279 ASSERT(!m_scopeContextStack.last().finallyContext.finallyBlock);
2280 ASSERT(m_scopeContextStack.last().finallyContext.iterator);
2281 ASSERT(m_scopeContextStack.last().finallyContext.enumerationNode);
9dae56ea
A
2282 ASSERT(m_finallyDepth > 0);
2283 m_scopeContextStack.removeLast();
2284 m_finallyDepth--;
2285}
2286
81345200 2287LabelScopePtr BytecodeGenerator::breakTarget(const Identifier& name)
9dae56ea
A
2288{
2289 // Reclaim free label scopes.
ba379fdc
A
2290 //
2291 // The condition was previously coded as 'm_labelScopes.size() && !m_labelScopes.last().refCount()',
2292 // however sometimes this appears to lead to GCC going a little haywire and entering the loop with
2293 // size 0, leading to segfaulty badness. We are yet to identify a valid cause within our code to
2294 // cause the GCC codegen to misbehave in this fashion, and as such the following refactoring of the
2295 // loop condition is a workaround.
2296 while (m_labelScopes.size()) {
2297 if (m_labelScopes.last().refCount())
2298 break;
9dae56ea 2299 m_labelScopes.removeLast();
ba379fdc 2300 }
9dae56ea
A
2301
2302 if (!m_labelScopes.size())
81345200 2303 return LabelScopePtr::null();
9dae56ea
A
2304
2305 // We special-case the following, which is a syntax error in Firefox:
2306 // label:
2307 // break;
2308 if (name.isEmpty()) {
2309 for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2310 LabelScope* scope = &m_labelScopes[i];
2311 if (scope->type() != LabelScope::NamedLabel) {
2312 ASSERT(scope->breakTarget());
81345200 2313 return LabelScopePtr(m_labelScopes, i);
9dae56ea
A
2314 }
2315 }
81345200 2316 return LabelScopePtr::null();
9dae56ea
A
2317 }
2318
2319 for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2320 LabelScope* scope = &m_labelScopes[i];
2321 if (scope->name() && *scope->name() == name) {
2322 ASSERT(scope->breakTarget());
81345200 2323 return LabelScopePtr(m_labelScopes, i);
9dae56ea
A
2324 }
2325 }
81345200 2326 return LabelScopePtr::null();
9dae56ea
A
2327}
2328
81345200 2329LabelScopePtr BytecodeGenerator::continueTarget(const Identifier& name)
9dae56ea
A
2330{
2331 // Reclaim free label scopes.
2332 while (m_labelScopes.size() && !m_labelScopes.last().refCount())
2333 m_labelScopes.removeLast();
2334
2335 if (!m_labelScopes.size())
81345200 2336 return LabelScopePtr::null();
9dae56ea
A
2337
2338 if (name.isEmpty()) {
2339 for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2340 LabelScope* scope = &m_labelScopes[i];
2341 if (scope->type() == LabelScope::Loop) {
2342 ASSERT(scope->continueTarget());
81345200 2343 return LabelScopePtr(m_labelScopes, i);
9dae56ea
A
2344 }
2345 }
81345200 2346 return LabelScopePtr::null();
9dae56ea
A
2347 }
2348
2349 // Continue to the loop nested nearest to the label scope that matches
2350 // 'name'.
81345200 2351 LabelScopePtr result = LabelScopePtr::null();
9dae56ea
A
2352 for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2353 LabelScope* scope = &m_labelScopes[i];
2354 if (scope->type() == LabelScope::Loop) {
2355 ASSERT(scope->continueTarget());
81345200 2356 result = LabelScopePtr(m_labelScopes, i);
9dae56ea
A
2357 }
2358 if (scope->name() && *scope->name() == name)
81345200 2359 return result; // may be null.
9dae56ea 2360 }
81345200 2361 return LabelScopePtr::null();
9dae56ea
A
2362}
2363
ed1e77d3
A
2364void BytecodeGenerator::allocateAndEmitScope()
2365{
2366 m_scopeRegister = addVar();
2367 m_scopeRegister->ref();
2368 m_codeBlock->setScopeRegister(scopeRegister()->virtualRegister());
2369 emitGetScope();
2370}
2371
2372void BytecodeGenerator::emitComplexPopScopes(RegisterID* scope, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
9dae56ea
A
2373{
2374 while (topScope > bottomScope) {
2375 // First we count the number of dynamic scopes we need to remove to get
2376 // to a finally block.
2377 int nNormalScopes = 0;
2378 while (topScope > bottomScope) {
2379 if (topScope->isFinallyBlock)
2380 break;
2381 ++nNormalScopes;
2382 --topScope;
2383 }
2384
2385 if (nNormalScopes) {
2386 // We need to remove a number of dynamic scopes to get to the next
2387 // finally block
ed1e77d3 2388 while (nNormalScopes--) {
93a37866 2389 emitOpcode(op_pop_scope);
ed1e77d3
A
2390 instructions().append(scope->index());
2391 }
9dae56ea 2392
93a37866
A
2393 // If topScope == bottomScope then there isn't a finally block left to emit.
2394 if (topScope == bottomScope)
2395 return;
9dae56ea 2396 }
6fe7ccc8
A
2397
2398 Vector<ControlFlowContext> savedScopeContextStack;
2399 Vector<SwitchInfo> savedSwitchContextStack;
ed1e77d3 2400 Vector<std::unique_ptr<ForInContext>> savedForInContextStack;
93a37866
A
2401 Vector<TryContext> poppedTryContexts;
2402 LabelScopeStore savedLabelScopes;
ba379fdc 2403 while (topScope > bottomScope && topScope->isFinallyBlock) {
93a37866
A
2404 RefPtr<Label> beforeFinally = emitLabel(newLabel().get());
2405
6fe7ccc8
A
2406 // Save the current state of the world while instating the state of the world
2407 // for the finally block.
2408 FinallyContext finallyContext = topScope->finallyContext;
2409 bool flipScopes = finallyContext.scopeContextStackSize != m_scopeContextStack.size();
2410 bool flipSwitches = finallyContext.switchContextStackSize != m_switchContextStack.size();
2411 bool flipForIns = finallyContext.forInContextStackSize != m_forInContextStack.size();
93a37866 2412 bool flipTries = finallyContext.tryContextStackSize != m_tryContextStack.size();
6fe7ccc8
A
2413 bool flipLabelScopes = finallyContext.labelScopesSize != m_labelScopes.size();
2414 int topScopeIndex = -1;
2415 int bottomScopeIndex = -1;
2416 if (flipScopes) {
2417 topScopeIndex = topScope - m_scopeContextStack.begin();
2418 bottomScopeIndex = bottomScope - m_scopeContextStack.begin();
2419 savedScopeContextStack = m_scopeContextStack;
2420 m_scopeContextStack.shrink(finallyContext.scopeContextStackSize);
2421 }
2422 if (flipSwitches) {
2423 savedSwitchContextStack = m_switchContextStack;
2424 m_switchContextStack.shrink(finallyContext.switchContextStackSize);
2425 }
2426 if (flipForIns) {
ed1e77d3 2427 savedForInContextStack.swap(m_forInContextStack);
6fe7ccc8
A
2428 m_forInContextStack.shrink(finallyContext.forInContextStackSize);
2429 }
93a37866
A
2430 if (flipTries) {
2431 while (m_tryContextStack.size() != finallyContext.tryContextStackSize) {
2432 ASSERT(m_tryContextStack.size() > finallyContext.tryContextStackSize);
2433 TryContext context = m_tryContextStack.last();
2434 m_tryContextStack.removeLast();
2435 TryRange range;
2436 range.start = context.start;
2437 range.end = beforeFinally;
2438 range.tryData = context.tryData;
2439 m_tryRanges.append(range);
2440 poppedTryContexts.append(context);
2441 }
2442 }
6fe7ccc8
A
2443 if (flipLabelScopes) {
2444 savedLabelScopes = m_labelScopes;
2445 while (m_labelScopes.size() > finallyContext.labelScopesSize)
2446 m_labelScopes.removeLast();
2447 }
2448 int savedFinallyDepth = m_finallyDepth;
2449 m_finallyDepth = finallyContext.finallyDepth;
81345200
A
2450 int savedDynamicScopeDepth = m_localScopeDepth;
2451 m_localScopeDepth = finallyContext.dynamicScopeDepth;
6fe7ccc8 2452
ed1e77d3
A
2453 if (finallyContext.finallyBlock) {
2454 // Emit the finally block.
2455 emitNode(finallyContext.finallyBlock);
2456 } else {
2457 // Emit the IteratorClose block.
2458 ASSERT(finallyContext.iterator);
2459 emitIteratorClose(finallyContext.iterator, finallyContext.enumerationNode);
2460 }
2461
93a37866
A
2462 RefPtr<Label> afterFinally = emitLabel(newLabel().get());
2463
6fe7ccc8
A
2464 // Restore the state of the world.
2465 if (flipScopes) {
2466 m_scopeContextStack = savedScopeContextStack;
2467 topScope = &m_scopeContextStack[topScopeIndex]; // assert it's within bounds
2468 bottomScope = m_scopeContextStack.begin() + bottomScopeIndex; // don't assert, since it the index might be -1.
2469 }
2470 if (flipSwitches)
2471 m_switchContextStack = savedSwitchContextStack;
2472 if (flipForIns)
ed1e77d3 2473 m_forInContextStack.swap(savedForInContextStack);
93a37866
A
2474 if (flipTries) {
2475 ASSERT(m_tryContextStack.size() == finallyContext.tryContextStackSize);
2476 for (unsigned i = poppedTryContexts.size(); i--;) {
2477 TryContext context = poppedTryContexts[i];
2478 context.start = afterFinally;
2479 m_tryContextStack.append(context);
2480 }
2481 poppedTryContexts.clear();
2482 }
6fe7ccc8
A
2483 if (flipLabelScopes)
2484 m_labelScopes = savedLabelScopes;
2485 m_finallyDepth = savedFinallyDepth;
81345200 2486 m_localScopeDepth = savedDynamicScopeDepth;
6fe7ccc8 2487
9dae56ea 2488 --topScope;
ba379fdc 2489 }
9dae56ea 2490 }
9dae56ea
A
2491}
2492
ed1e77d3 2493void BytecodeGenerator::emitPopScopes(RegisterID* scope, int targetScopeDepth)
9dae56ea
A
2494{
2495 ASSERT(scopeDepth() - targetScopeDepth >= 0);
9dae56ea
A
2496
2497 size_t scopeDelta = scopeDepth() - targetScopeDepth;
2498 ASSERT(scopeDelta <= m_scopeContextStack.size());
2499 if (!scopeDelta)
93a37866 2500 return;
9dae56ea 2501
93a37866 2502 if (!m_finallyDepth) {
ed1e77d3 2503 while (scopeDelta--) {
93a37866 2504 emitOpcode(op_pop_scope);
ed1e77d3
A
2505 instructions().append(scope->index());
2506 }
93a37866
A
2507 return;
2508 }
f9bf01c6 2509
ed1e77d3 2510 emitComplexPopScopes(scope, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
9dae56ea
A
2511}
2512
93a37866
A
2513TryData* BytecodeGenerator::pushTry(Label* start)
2514{
2515 TryData tryData;
2516 tryData.target = newLabel();
2517 tryData.targetScopeDepth = UINT_MAX;
ed1e77d3 2518 tryData.handlerType = HandlerType::Illegal;
93a37866
A
2519 m_tryData.append(tryData);
2520 TryData* result = &m_tryData.last();
2521
2522 TryContext tryContext;
2523 tryContext.start = start;
2524 tryContext.tryData = result;
2525
2526 m_tryContextStack.append(tryContext);
2527
2528 return result;
2529}
2530
ed1e77d3 2531void BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID* exceptionRegister, RegisterID* thrownValueRegister, Label* end, HandlerType handlerType)
9dae56ea 2532{
14957cd0 2533 m_usesExceptions = true;
93a37866
A
2534
2535 ASSERT_UNUSED(tryData, m_tryContextStack.last().tryData == tryData);
2536
2537 TryRange tryRange;
2538 tryRange.start = m_tryContextStack.last().start;
2539 tryRange.end = end;
2540 tryRange.tryData = m_tryContextStack.last().tryData;
2541 m_tryRanges.append(tryRange);
2542 m_tryContextStack.removeLast();
2543
2544 emitLabel(tryRange.tryData->target.get());
81345200 2545 tryRange.tryData->targetScopeDepth = m_localScopeDepth;
ed1e77d3 2546 tryRange.tryData->handlerType = handlerType;
9dae56ea 2547
9dae56ea 2548 emitOpcode(op_catch);
ed1e77d3
A
2549 instructions().append(exceptionRegister->index());
2550 instructions().append(thrownValueRegister->index());
9dae56ea
A
2551}
2552
93a37866 2553void BytecodeGenerator::emitThrowReferenceError(const String& message)
9dae56ea 2554{
93a37866 2555 emitOpcode(op_throw_static_error);
ed1e77d3 2556 instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, message)))->index());
93a37866 2557 instructions().append(true);
9dae56ea
A
2558}
2559
ed1e77d3
A
2560void BytecodeGenerator::emitThrowTypeError(const String& message)
2561{
2562 emitOpcode(op_throw_static_error);
2563 instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, message)))->index());
2564 instructions().append(false);
2565}
2566
2567void BytecodeGenerator::emitPushFunctionNameScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes)
81345200
A
2568{
2569 emitOpcode(op_push_name_scope);
ed1e77d3 2570 instructions().append(dst->index());
81345200 2571 instructions().append(value->index());
ed1e77d3
A
2572 instructions().append(addConstantValue(SymbolTable::createNameScopeTable(*vm(), property, attributes))->index());
2573 instructions().append(JSNameScope::FunctionNameScope);
81345200
A
2574}
2575
ed1e77d3 2576void BytecodeGenerator::emitPushCatchScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes)
9dae56ea
A
2577{
2578 ControlFlowContext context;
2579 context.isFinallyBlock = false;
2580 m_scopeContextStack.append(context);
81345200 2581 m_localScopeDepth++;
ba379fdc 2582
93a37866 2583 emitOpcode(op_push_name_scope);
ed1e77d3 2584 instructions().append(dst->index());
9dae56ea 2585 instructions().append(value->index());
ed1e77d3
A
2586 instructions().append(addConstantValue(SymbolTable::createNameScopeTable(*vm(), property, attributes))->index());
2587 instructions().append(JSNameScope::CatchScope);
9dae56ea
A
2588}
2589
2590void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
2591{
93a37866 2592 SwitchInfo info = { static_cast<uint32_t>(instructions().size()), type };
9dae56ea
A
2593 switch (type) {
2594 case SwitchInfo::SwitchImmediate:
2595 emitOpcode(op_switch_imm);
2596 break;
2597 case SwitchInfo::SwitchCharacter:
2598 emitOpcode(op_switch_char);
2599 break;
2600 case SwitchInfo::SwitchString:
2601 emitOpcode(op_switch_string);
2602 break;
2603 default:
93a37866 2604 RELEASE_ASSERT_NOT_REACHED();
9dae56ea
A
2605 }
2606
2607 instructions().append(0); // place holder for table index
2608 instructions().append(0); // place holder for default target
2609 instructions().append(scrutineeRegister->index());
2610 m_switchContextStack.append(info);
2611}
2612
2613static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max)
2614{
2615 UNUSED_PARAM(max);
2616 ASSERT(node->isNumber());
2617 double value = static_cast<NumberNode*>(node)->value();
2618 int32_t key = static_cast<int32_t>(value);
9dae56ea
A
2619 ASSERT(key == value);
2620 ASSERT(key >= min);
2621 ASSERT(key <= max);
2622 return key - min;
2623}
2624
9dae56ea
A
2625static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max)
2626{
2627 UNUSED_PARAM(max);
2628 ASSERT(node->isString());
14957cd0 2629 StringImpl* clause = static_cast<StringNode*>(node)->value().impl();
4e4e5a6f 2630 ASSERT(clause->length() == 1);
9dae56ea 2631
6fe7ccc8 2632 int32_t key = (*clause)[0];
9dae56ea
A
2633 ASSERT(key >= min);
2634 ASSERT(key <= max);
2635 return key - min;
2636}
2637
81345200
A
2638static void prepareJumpTableForSwitch(
2639 UnlinkedSimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount,
2640 RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max,
2641 int32_t (*keyGetter)(ExpressionNode*, int32_t min, int32_t max))
9dae56ea
A
2642{
2643 jumpTable.min = min;
2644 jumpTable.branchOffsets.resize(max - min + 1);
2645 jumpTable.branchOffsets.fill(0);
2646 for (uint32_t i = 0; i < clauseCount; ++i) {
2647 // We're emitting this after the clause labels should have been fixed, so
2648 // the labels should not be "forward" references
2649 ASSERT(!labels[i]->isForward());
81345200 2650 jumpTable.add(keyGetter(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
9dae56ea
A
2651 }
2652}
2653
93a37866 2654static void prepareJumpTableForStringSwitch(UnlinkedStringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
9dae56ea
A
2655{
2656 for (uint32_t i = 0; i < clauseCount; ++i) {
2657 // We're emitting this after the clause labels should have been fixed, so
2658 // the labels should not be "forward" references
2659 ASSERT(!labels[i]->isForward());
2660
2661 ASSERT(nodes[i]->isString());
14957cd0 2662 StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl();
93a37866 2663 jumpTable.offsetTable.add(clause, labels[i]->bind(switchAddress, switchAddress + 3));
9dae56ea
A
2664 }
2665}
2666
2667void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max)
2668{
2669 SwitchInfo switchInfo = m_switchContextStack.last();
2670 m_switchContextStack.removeLast();
81345200
A
2671
2672 switch (switchInfo.switchType) {
2673 case SwitchInfo::SwitchImmediate:
2674 case SwitchInfo::SwitchCharacter: {
2675 instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfSwitchJumpTables();
f9bf01c6 2676 instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
9dae56ea 2677
81345200
A
2678 UnlinkedSimpleJumpTable& jumpTable = m_codeBlock->addSwitchJumpTable();
2679 prepareJumpTableForSwitch(
2680 jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max,
2681 switchInfo.switchType == SwitchInfo::SwitchImmediate
2682 ? keyForImmediateSwitch
2683 : keyForCharacterSwitch);
2684 break;
2685 }
9dae56ea 2686
81345200 2687 case SwitchInfo::SwitchString: {
9dae56ea 2688 instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
f9bf01c6 2689 instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
9dae56ea 2690
93a37866 2691 UnlinkedStringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
f9bf01c6 2692 prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
81345200
A
2693 break;
2694 }
2695
2696 default:
2697 RELEASE_ASSERT_NOT_REACHED();
2698 break;
9dae56ea
A
2699 }
2700}
2701
2702RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
2703{
2704 // It would be nice to do an even better job of identifying exactly where the expression is.
2705 // And we could make the caller pass the node pointer in, if there was some way of getting
2706 // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
2707 // is still good enough to get us an accurate line number.
14957cd0
A
2708 m_expressionTooDeep = true;
2709 return newTemporary();
2710}
2711
6fe7ccc8 2712bool BytecodeGenerator::isArgumentNumber(const Identifier& ident, int argumentNumber)
14957cd0 2713{
ed1e77d3
A
2714 RegisterID* registerID = variable(ident).local();
2715 if (!registerID)
2716 return false;
6fe7ccc8 2717 return registerID->index() == CallFrame::argumentOffset(argumentNumber);
9dae56ea
A
2718}
2719
93a37866
A
2720void BytecodeGenerator::emitReadOnlyExceptionIfNeeded()
2721{
2722 if (!isStrictMode())
2723 return;
2724 emitOpcode(op_throw_static_error);
ed1e77d3 2725 instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, StrictModeReadonlyPropertyWriteError)))->index());
93a37866
A
2726 instructions().append(false);
2727}
81345200
A
2728
2729void BytecodeGenerator::emitEnumeration(ThrowableExpressionData* node, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack)
2730{
ed1e77d3
A
2731 RefPtr<RegisterID> subject = newTemporary();
2732 emitNode(subject.get(), subjectNode);
2733 RefPtr<RegisterID> iterator = emitGetById(newTemporary(), subject.get(), propertyNames().iteratorSymbol);
2734 {
2735 CallArguments args(*this, nullptr);
2736 emitMove(args.thisRegister(), subject.get());
2737 emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, node->divot(), node->divotStart(), node->divotEnd());
2738 }
81345200 2739
ed1e77d3
A
2740 RefPtr<Label> loopDone = newLabel();
2741 // RefPtr<Register> iterator's lifetime must be longer than IteratorCloseContext.
2742 pushIteratorCloseContext(iterator.get(), node);
2743 {
81345200 2744 LabelScopePtr scope = newLabelScope(LabelScope::Loop);
ed1e77d3
A
2745 RefPtr<RegisterID> value = newTemporary();
2746 emitLoad(value.get(), jsUndefined());
2747
2748 emitJump(scope->continueTarget());
2749
81345200 2750 RefPtr<Label> loopStart = newLabel();
81345200
A
2751 emitLabel(loopStart.get());
2752 emitLoopHint();
ed1e77d3
A
2753
2754 RefPtr<Label> tryStartLabel = newLabel();
2755 emitLabel(tryStartLabel.get());
2756 TryData* tryData = pushTry(tryStartLabel.get());
81345200 2757 callBack(*this, value.get());
ed1e77d3
A
2758 emitJump(scope->continueTarget());
2759
2760 // IteratorClose sequence for throw-ed control flow.
2761 {
2762 RefPtr<Label> catchHere = emitLabel(newLabel().get());
2763 RefPtr<RegisterID> exceptionRegister = newTemporary();
2764 RefPtr<RegisterID> thrownValueRegister = newTemporary();
2765 popTryAndEmitCatch(tryData, exceptionRegister.get(),
2766 thrownValueRegister.get(), catchHere.get(), HandlerType::SynthesizedFinally);
2767
2768 RefPtr<Label> catchDone = newLabel();
2769
2770 RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword);
2771 emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), catchDone.get());
2772
2773 RefPtr<Label> returnCallTryStart = newLabel();
2774 emitLabel(returnCallTryStart.get());
2775 TryData* returnCallTryData = pushTry(returnCallTryStart.get());
2776
2777 CallArguments returnArguments(*this, nullptr);
2778 emitMove(returnArguments.thisRegister(), iterator.get());
2779 emitCall(value.get(), returnMethod.get(), NoExpectedFunction, returnArguments, node->divot(), node->divotStart(), node->divotEnd());
2780
2781 emitLabel(catchDone.get());
2782 emitThrow(exceptionRegister.get());
2783
2784 // Absorb exception.
2785 popTryAndEmitCatch(returnCallTryData, newTemporary(),
2786 newTemporary(), catchDone.get(), HandlerType::SynthesizedFinally);
2787 emitThrow(exceptionRegister.get());
2788 }
2789
81345200 2790 emitLabel(scope->continueTarget());
ed1e77d3
A
2791 {
2792 emitIteratorNext(value.get(), iterator.get(), node);
2793 emitJumpIfTrue(emitGetById(newTemporary(), value.get(), propertyNames().done), loopDone.get());
2794 emitGetById(value.get(), value.get(), propertyNames().value);
2795 emitJump(loopStart.get());
2796 }
2797
81345200 2798 emitLabel(scope->breakTarget());
81345200
A
2799 }
2800
ed1e77d3
A
2801 // IteratorClose sequence for break-ed control flow.
2802 popIteratorCloseContext();
2803 emitIteratorClose(iterator.get(), node);
2804 emitLabel(loopDone.get());
2805}
2806
2807#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
2808RegisterID* BytecodeGenerator::emitGetTemplateObject(RegisterID* dst, TaggedTemplateNode* taggedTemplate)
2809{
2810 TemplateRegistryKey::StringVector rawStrings;
2811 TemplateRegistryKey::StringVector cookedStrings;
2812
2813 TemplateStringListNode* templateString = taggedTemplate->templateLiteral()->templateStrings();
2814 for (; templateString; templateString = templateString->next()) {
2815 rawStrings.append(templateString->value()->raw().impl());
2816 cookedStrings.append(templateString->value()->cooked().impl());
2817 }
2818
2819 RefPtr<RegisterID> getTemplateObject = nullptr;
2820 Variable var = variable(propertyNames().getTemplateObjectPrivateName);
2821 if (RegisterID* local = var.local())
2822 getTemplateObject = emitMove(newTemporary(), local);
2823 else {
2824 getTemplateObject = newTemporary();
2825 RefPtr<RegisterID> scope = newTemporary();
2826 moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), var));
2827 emitGetFromScope(getTemplateObject.get(), scope.get(), var, ThrowIfNotFound);
2828 }
2829
2830 CallArguments arguments(*this, nullptr);
2831 emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(TemplateRegistryKey(rawStrings, cookedStrings))));
2832 return emitCall(dst, getTemplateObject.get(), NoExpectedFunction, arguments, taggedTemplate->divot(), taggedTemplate->divotStart(), taggedTemplate->divotEnd());
2833}
2834#endif
2835
2836RegisterID* BytecodeGenerator::emitGetEnumerableLength(RegisterID* dst, RegisterID* base)
2837{
2838 emitOpcode(op_get_enumerable_length);
2839 instructions().append(dst->index());
2840 instructions().append(base->index());
2841 return dst;
2842}
2843
2844RegisterID* BytecodeGenerator::emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName)
2845{
2846 emitOpcode(op_has_generic_property);
2847 instructions().append(dst->index());
2848 instructions().append(base->index());
2849 instructions().append(propertyName->index());
2850 return dst;
2851}
2852
2853RegisterID* BytecodeGenerator::emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName)
2854{
2855 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2856 emitOpcode(op_has_indexed_property);
2857 instructions().append(dst->index());
2858 instructions().append(base->index());
2859 instructions().append(propertyName->index());
2860 instructions().append(arrayProfile);
2861 return dst;
2862}
2863
2864RegisterID* BytecodeGenerator::emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator)
2865{
2866 emitOpcode(op_has_structure_property);
2867 instructions().append(dst->index());
2868 instructions().append(base->index());
2869 instructions().append(propertyName->index());
2870 instructions().append(enumerator->index());
2871 return dst;
2872}
2873
2874RegisterID* BytecodeGenerator::emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base)
2875{
2876 emitOpcode(op_get_property_enumerator);
2877 instructions().append(dst->index());
2878 instructions().append(base->index());
2879 return dst;
2880}
2881
2882RegisterID* BytecodeGenerator::emitEnumeratorStructurePropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index)
2883{
2884 emitOpcode(op_enumerator_structure_pname);
2885 instructions().append(dst->index());
2886 instructions().append(enumerator->index());
2887 instructions().append(index->index());
2888 return dst;
2889}
2890
2891RegisterID* BytecodeGenerator::emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index)
2892{
2893 emitOpcode(op_enumerator_generic_pname);
2894 instructions().append(dst->index());
2895 instructions().append(enumerator->index());
2896 instructions().append(index->index());
2897 return dst;
2898}
2899
2900RegisterID* BytecodeGenerator::emitToIndexString(RegisterID* dst, RegisterID* index)
2901{
2902 emitOpcode(op_to_index_string);
2903 instructions().append(dst->index());
2904 instructions().append(index->index());
2905 return dst;
2906}
2907
2908
2909RegisterID* BytecodeGenerator::emitIsObject(RegisterID* dst, RegisterID* src)
2910{
2911 emitOpcode(op_is_object);
2912 instructions().append(dst->index());
2913 instructions().append(src->index());
2914 return dst;
2915}
2916
2917RegisterID* BytecodeGenerator::emitIsUndefined(RegisterID* dst, RegisterID* src)
2918{
2919 emitOpcode(op_is_undefined);
2920 instructions().append(dst->index());
2921 instructions().append(src->index());
2922 return dst;
2923}
2924
2925RegisterID* BytecodeGenerator::emitIteratorNext(RegisterID* dst, RegisterID* iterator, const ThrowableExpressionData* node)
2926{
81345200 2927 {
ed1e77d3
A
2928 RefPtr<RegisterID> next = emitGetById(newTemporary(), iterator, propertyNames().next);
2929 CallArguments nextArguments(*this, nullptr);
2930 emitMove(nextArguments.thisRegister(), iterator);
2931 emitCall(dst, next.get(), NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd());
2932 }
2933 {
2934 RefPtr<Label> typeIsObject = newLabel();
2935 emitJumpIfTrue(emitIsObject(newTemporary(), dst), typeIsObject.get());
2936 emitThrowTypeError(ASCIILiteral("Iterator result interface is not an object."));
2937 emitLabel(typeIsObject.get());
81345200 2938 }
ed1e77d3
A
2939 return dst;
2940}
2941
2942void BytecodeGenerator::emitIteratorClose(RegisterID* iterator, const ThrowableExpressionData* node)
2943{
2944 RefPtr<Label> done = newLabel();
2945 RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator, propertyNames().returnKeyword);
2946 emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), done.get());
2947
81345200 2948 RefPtr<RegisterID> value = newTemporary();
ed1e77d3
A
2949 CallArguments returnArguments(*this, nullptr);
2950 emitMove(returnArguments.thisRegister(), iterator);
2951 emitCall(value.get(), returnMethod.get(), NoExpectedFunction, returnArguments, node->divot(), node->divotStart(), node->divotEnd());
2952 emitJumpIfTrue(emitIsObject(newTemporary(), value.get()), done.get());
2953 emitThrowTypeError(ASCIILiteral("Iterator result interface is not an object."));
2954 emitLabel(done.get());
2955}
2956
2957void BytecodeGenerator::pushIndexedForInScope(RegisterID* localRegister, RegisterID* indexRegister)
2958{
2959 if (!localRegister)
2960 return;
2961 m_forInContextStack.append(std::make_unique<IndexedForInContext>(localRegister, indexRegister));
2962}
2963
2964void BytecodeGenerator::popIndexedForInScope(RegisterID* localRegister)
2965{
2966 if (!localRegister)
2967 return;
2968 m_forInContextStack.removeLast();
2969}
2970
2971void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
2972{
2973 if (!localRegister)
2974 return;
2975 m_forInContextStack.append(std::make_unique<StructureForInContext>(localRegister, indexRegister, propertyRegister, enumeratorRegister));
2976}
2977
2978void BytecodeGenerator::popStructureForInScope(RegisterID* localRegister)
2979{
2980 if (!localRegister)
2981 return;
2982 m_forInContextStack.removeLast();
2983}
2984
2985void BytecodeGenerator::invalidateForInContextForLocal(RegisterID* localRegister)
2986{
2987 // Lexically invalidating ForInContexts is kind of weak sauce, but it only occurs if
2988 // either of the following conditions is true:
2989 //
2990 // (1) The loop iteration variable is re-assigned within the body of the loop.
2991 // (2) The loop iteration variable is captured in the lexical scope of the function.
2992 //
2993 // These two situations occur sufficiently rarely that it's okay to use this style of
2994 // "analysis" to make iteration faster. If we didn't want to do this, we would either have
2995 // to perform some flow-sensitive analysis to see if/when the loop iteration variable was
2996 // reassigned, or we'd have to resort to runtime checks to see if the variable had been
2997 // reassigned from its original value.
2998 for (size_t i = m_forInContextStack.size(); i > 0; i--) {
2999 ForInContext* context = m_forInContextStack[i - 1].get();
3000 if (context->local() != localRegister)
3001 continue;
3002 context->invalidate();
3003 break;
3004 }
81345200 3005}
93a37866 3006
9dae56ea 3007} // namespace JSC