2 * Copyright (C) 2008-2009, 2012-2016 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4 * Copyright (C) 2012 Igalia, S.L.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
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.
32 #include "BytecodeGenerator.h"
34 #include "ArithProfile.h"
35 #include "BuiltinExecutables.h"
36 #include "BytecodeLivenessAnalysis.h"
37 #include "Interpreter.h"
38 #include "JSFunction.h"
39 #include "JSGeneratorFunction.h"
40 #include "JSLexicalEnvironment.h"
41 #include "JSTemplateRegistryKey.h"
42 #include "LowLevelInterpreter.h"
43 #include "JSCInlines.h"
45 #include "StackAlignment.h"
46 #include "StrongInlines.h"
47 #include "UnlinkedCodeBlock.h"
48 #include "UnlinkedInstructionStream.h"
49 #include <wtf/CommaPrinter.h>
50 #include <wtf/SmallPtrSet.h>
51 #include <wtf/StdLibExtras.h>
52 #include <wtf/text/WTFString.h>
58 void Label::setLocation(unsigned location)
60 m_location = location;
62 unsigned size = m_unresolvedJumps.size();
63 for (unsigned i = 0; i < size; ++i)
64 m_generator.instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
67 void Variable::dump(PrintStream& out) const
71 ", offset = ", m_offset,
72 ", local = ", RawPointer(m_local),
73 ", attributes = ", m_attributes,
75 ", symbolTableConstantIndex = ", m_symbolTableConstantIndex,
76 ", isLexicallyScoped = ", m_isLexicallyScoped, "}");
79 ParserError BytecodeGenerator::generate()
81 m_codeBlock->setThisRegister(m_thisRegister.virtualRegister());
83 emitLogShadowChickenPrologueIfNecessary();
85 // If we have declared a variable named "arguments" and we are using arguments then we should
86 // perform that assignment now.
87 if (m_needToInitializeArguments)
88 initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
91 m_restParameter->emit(*this);
94 RefPtr<RegisterID> temp = newTemporary();
95 RefPtr<RegisterID> globalScope;
96 for (auto functionPair : m_functionsToInitialize) {
97 FunctionMetadataNode* metadata = functionPair.first;
98 FunctionVariableType functionType = functionPair.second;
99 emitNewFunction(temp.get(), metadata);
100 if (functionType == NormalFunctionVariable)
101 initializeVariable(variable(metadata->ident()), temp.get());
102 else if (functionType == GlobalFunctionVariable) {
104 // We know this will resolve to the global object because our parser/global initialization code
105 // doesn't allow let/const/class variables to have the same names as functions.
106 RefPtr<RegisterID> globalObjectScope = emitResolveScope(nullptr, Variable(metadata->ident()));
107 globalScope = newBlockScopeVariable();
108 emitMove(globalScope.get(), globalObjectScope.get());
110 emitPutToScope(globalScope.get(), Variable(metadata->ident()), temp.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
112 RELEASE_ASSERT_NOT_REACHED();
116 bool callingClassConstructor = constructorKind() != ConstructorKind::None && !isConstructor();
117 if (!callingClassConstructor)
118 m_scopeNode->emitBytecode(*this);
120 m_staticPropertyAnalyzer.kill();
122 for (unsigned i = 0; i < m_tryRanges.size(); ++i) {
123 TryRange& range = m_tryRanges[i];
124 int start = range.start->bind();
125 int end = range.end->bind();
127 // This will happen for empty try blocks and for some cases of finally blocks:
139 // The return will pop scopes to execute the outer finally block. But this includes
140 // popping the try context for the inner try. The try context is live in the fall-through
141 // part of the finally block not because we will emit a handler that overlaps the finally,
142 // but because we haven't yet had a chance to plant the catch target. Then when we finish
143 // emitting code for the outer finally block, we repush the try contex, this time with a
144 // new start index. But that means that the start index for the try range corresponding
145 // to the inner-finally-following-the-return (marked as "*HERE*" above) will be greater
146 // than the end index of the try block. This is harmless since end < start handlers will
147 // never get matched in our logic, but we do the runtime a favor and choose to not emit
148 // such handlers at all.
152 ASSERT(range.tryData->handlerType != HandlerType::Illegal);
153 UnlinkedHandlerInfo info(static_cast<uint32_t>(start), static_cast<uint32_t>(end),
154 static_cast<uint32_t>(range.tryData->target->bind()), range.tryData->handlerType);
155 m_codeBlock->addExceptionHandler(info);
158 m_codeBlock->setInstructions(std::make_unique<UnlinkedInstructionStream>(m_instructions));
160 m_codeBlock->shrinkToFit();
162 if (m_expressionTooDeep)
163 return ParserError(ParserError::OutOfMemory);
164 return ParserError(ParserError::ErrorNone);
167 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
168 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
169 , m_scopeNode(programNode)
170 , m_codeBlock(vm, codeBlock)
171 , m_thisRegister(CallFrame::thisArgumentOffset())
172 , m_codeType(GlobalCode)
174 , m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval())
176 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
178 for (auto& constantRegister : m_linkTimeConstantRegisters)
179 constantRegister = nullptr;
181 allocateCalleeSaveSpace();
183 m_codeBlock->setNumParameters(1); // Allocate space for "this"
187 allocateAndEmitScope();
189 const FunctionStack& functionStack = programNode->functionStack();
191 for (size_t i = 0; i < functionStack.size(); ++i) {
192 FunctionMetadataNode* function = functionStack[i];
193 m_functionsToInitialize.append(std::make_pair(function, GlobalFunctionVariable));
195 if (Options::validateBytecode()) {
196 for (auto& entry : programNode->varDeclarations())
197 RELEASE_ASSERT(entry.value.isVar());
199 codeBlock->setVariableDeclarations(programNode->varDeclarations());
200 codeBlock->setLexicalDeclarations(programNode->lexicalVariables());
201 // Even though this program may have lexical variables that go under TDZ, when linking the get_from_scope/put_to_scope
202 // operations we emit we will have ResolveTypes that implictly do TDZ checks. Therefore, we don't need
203 // additional TDZ checks on top of those. This is why we can omit pushing programNode->lexicalVariables()
206 if (needsToUpdateArrowFunctionContext()) {
207 initializeArrowFunctionContextScopeIfNeeded();
208 emitPutThisToArrowFunctionContextScope();
212 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
213 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
214 , m_scopeNode(functionNode)
215 , m_codeBlock(vm, codeBlock)
216 , m_codeType(FunctionCode)
218 , m_isBuiltinFunction(codeBlock->isBuiltinFunction())
219 , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
220 // FIXME: We should be able to have tail call elimination with the profiler
221 // enabled. This is currently not possible because the profiler expects
222 // op_will_call / op_did_call pairs before and after a call, which are not
223 // compatible with tail calls (we have no way of emitting op_did_call).
224 // https://bugs.webkit.org/show_bug.cgi?id=148819
225 , m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && isStrictMode())
226 , m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval())
227 , m_derivedContextType(codeBlock->derivedContextType())
229 for (auto& constantRegister : m_linkTimeConstantRegisters)
230 constantRegister = nullptr;
232 if (m_isBuiltinFunction)
233 m_shouldEmitDebugHooks = false;
235 allocateCalleeSaveSpace();
237 SymbolTable* functionSymbolTable = SymbolTable::create(*m_vm);
238 functionSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval);
239 int symbolTableConstantIndex = 0;
241 FunctionParameters& parameters = *functionNode->parameters();
242 // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
243 // This implements IsSimpleParameterList in the Ecma 2015 spec.
244 // If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
245 // IsSimpleParameterList is false if the argument list contains any default parameter values,
246 // a rest parameter, or any destructuring patterns.
247 bool isSimpleParameterList = true;
248 // If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope.
249 for (size_t i = 0; i < parameters.size(); i++) {
250 std::pair<DestructuringPatternNode*, ExpressionNode*> parameter = parameters.at(i);
251 bool hasDefaultParameterValue = !!parameter.second;
252 auto pattern = parameter.first;
253 bool isSimpleParameter = !hasDefaultParameterValue && pattern->isBindingNode();
254 isSimpleParameterList &= isSimpleParameter;
257 SourceParseMode parseMode = codeBlock->parseMode();
259 bool containsArrowOrEvalButNotInArrowBlock = ((functionNode->usesArrowFunction() && functionNode->doAnyInnerArrowFunctionsUseAnyFeature()) || functionNode->usesEval()) && !m_codeBlock->isArrowFunction();
260 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || functionNode->needsActivation() || containsArrowOrEvalButNotInArrowBlock;
262 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
263 bool needsArguments = (functionNode->usesArguments() || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction()));
265 // Generator never provides "arguments". "arguments" reference will be resolved in an upper generator function scope.
266 if (parseMode == SourceParseMode::GeneratorBodyMode)
267 needsArguments = false;
269 if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode && needsArguments) {
270 // Generator does not provide "arguments". Instead, wrapping GeneratorFunction provides "arguments".
271 // This is because arguments of a generator should be evaluated before starting it.
272 // To workaround it, we evaluate these arguments as arguments of a wrapping generator function, and reference it from a generator.
274 // function *gen(a, b = hello())
277 // @generatorNext: function (@generator, @generatorState, @generatorValue, @generatorResumeMode)
279 // arguments; // This `arguments` should reference to the gen's arguments.
284 shouldCaptureSomeOfTheThings = true;
287 if (shouldCaptureAllOfTheThings)
288 functionNode->varDeclarations().markAllVariablesAsCaptured();
290 auto captures = [&] (UniquedStringImpl* uid) -> bool {
291 if (!shouldCaptureSomeOfTheThings)
293 if (needsArguments && uid == propertyNames().arguments.impl()) {
294 // Actually, we only need to capture the arguments object when we "need full activation"
295 // because of name scopes. But historically we did it this way, so for now we just preserve
297 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=143072
300 return functionNode->captures(uid);
302 auto varKind = [&] (UniquedStringImpl* uid) -> VarKind {
303 return captures(uid) ? VarKind::Scope : VarKind::Stack;
308 allocateAndEmitScope();
310 m_calleeRegister.setIndex(CallFrameSlot::callee);
312 initializeParameters(parameters);
313 ASSERT(!(isSimpleParameterList && m_restParameter));
315 // Before emitting a scope creation, emit a generator prologue that contains jump based on a generator's state.
316 if (parseMode == SourceParseMode::GeneratorBodyMode) {
317 m_generatorRegister = &m_parameters[1];
319 // Jump with switch_imm based on @generatorState. We don't take the coroutine styled generator implementation.
320 // When calling `next()`, we would like to enter the same prologue instead of jumping based on the saved instruction pointer.
321 // It's suitale for inlining, because it just inlines one `next` function implementation.
323 beginGenerator(generatorStateRegister());
326 emitGeneratorStateLabel();
329 if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())) {
330 ASSERT(parseMode != SourceParseMode::GeneratorBodyMode);
331 bool isDynamicScope = functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode());
332 bool isFunctionNameCaptured = captures(functionNode->ident().impl());
333 bool markAsCaptured = isDynamicScope || isFunctionNameCaptured;
334 emitPushFunctionNameScope(functionNode->ident(), &m_calleeRegister, markAsCaptured);
337 if (shouldCaptureSomeOfTheThings)
338 m_lexicalEnvironmentRegister = addVar();
340 if (shouldCaptureSomeOfTheThings || vm.typeProfiler())
341 symbolTableConstantIndex = addConstantValue(functionSymbolTable)->index();
343 // We can allocate the "var" environment if we don't have default parameter expressions. If we have
344 // default parameter expressions, we have to hold off on allocating the "var" environment because
345 // the parent scope of the "var" environment is the parameter environment.
346 if (isSimpleParameterList)
347 initializeVarLexicalEnvironment(symbolTableConstantIndex, functionSymbolTable, shouldCaptureSomeOfTheThings);
349 // Figure out some interesting facts about our arguments.
350 bool capturesAnyArgumentByName = false;
351 if (functionNode->hasCapturedVariables()) {
352 FunctionParameters& parameters = *functionNode->parameters();
353 for (size_t i = 0; i < parameters.size(); ++i) {
354 auto pattern = parameters.at(i).first;
355 if (!pattern->isBindingNode())
357 const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
358 capturesAnyArgumentByName |= captures(ident.impl());
362 if (capturesAnyArgumentByName)
363 ASSERT(m_lexicalEnvironmentRegister);
365 // Need to know what our functions are called. Parameters have some goofy behaviors when it
366 // comes to functions of the same name.
367 for (FunctionMetadataNode* function : functionNode->functionStack())
368 m_functions.add(function->ident().impl());
370 if (needsArguments) {
371 // Create the arguments object now. We may put the arguments object into the activation if
372 // it is captured. Either way, we create two arguments object variables: one is our
373 // private variable that is immutable, and another that is the user-visible variable. The
374 // immutable one is only used here, or during formal parameter resolutions if we opt for
377 m_argumentsRegister = addVar();
378 m_argumentsRegister->ref();
381 if (needsArguments && !codeBlock->isStrictMode() && isSimpleParameterList) {
382 // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
383 // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
386 if (capturesAnyArgumentByName) {
387 functionSymbolTable->setArgumentsLength(vm, parameters.size());
389 // For each parameter, we have two possibilities:
390 // Either it's a binding node with no function overlap, in which case it gets a name
391 // in the symbol table - or it just gets space reserved in the symbol table. Either
392 // way we lift the value into the scope.
393 for (unsigned i = 0; i < parameters.size(); ++i) {
394 ScopeOffset offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
395 functionSymbolTable->setArgumentOffset(vm, i, offset);
396 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first)) {
397 VarOffset varOffset(offset);
398 SymbolTableEntry entry(varOffset);
399 // Stores to these variables via the ScopedArguments object will not do
400 // notifyWrite(), since that would be cumbersome. Also, watching formal
401 // parameters when "arguments" is in play is unlikely to be super profitable.
402 // So, we just disable it.
403 entry.disableWatching(*m_vm);
404 functionSymbolTable->set(NoLockingNecessary, name, entry);
406 emitOpcode(op_put_to_scope);
407 instructions().append(m_lexicalEnvironmentRegister->index());
408 instructions().append(UINT_MAX);
409 instructions().append(virtualRegisterForArgument(1 + i).offset());
410 instructions().append(GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization).operand());
411 instructions().append(symbolTableConstantIndex);
412 instructions().append(offset.offset());
415 // This creates a scoped arguments object and copies the overflow arguments into the
416 // scope. It's the equivalent of calling ScopedArguments::createByCopying().
417 emitOpcode(op_create_scoped_arguments);
418 instructions().append(m_argumentsRegister->index());
419 instructions().append(m_lexicalEnvironmentRegister->index());
421 // We're going to put all parameters into the DirectArguments object. First ensure
422 // that the symbol table knows that this is happening.
423 for (unsigned i = 0; i < parameters.size(); ++i) {
424 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first))
425 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
428 emitOpcode(op_create_direct_arguments);
429 instructions().append(m_argumentsRegister->index());
431 } else if (isSimpleParameterList) {
432 // Create the formal parameters the normal way. Any of them could be captured, or not. If
433 // captured, lift them into the scope. We cannot do this if we have default parameter expressions
434 // because when default parameter expressions exist, they belong in their own lexical environment
435 // separate from the "var" lexical environment.
436 for (unsigned i = 0; i < parameters.size(); ++i) {
437 UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first);
441 if (!captures(name)) {
442 // This is the easy case - just tell the symbol table about the argument. It will
443 // be accessed directly.
444 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
448 ScopeOffset offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
449 const Identifier& ident =
450 static_cast<const BindingNode*>(parameters.at(i).first)->boundProperty();
451 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(offset)));
453 emitOpcode(op_put_to_scope);
454 instructions().append(m_lexicalEnvironmentRegister->index());
455 instructions().append(addConstant(ident));
456 instructions().append(virtualRegisterForArgument(1 + i).offset());
457 instructions().append(GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization).operand());
458 instructions().append(symbolTableConstantIndex);
459 instructions().append(offset.offset());
463 if (needsArguments && (codeBlock->isStrictMode() || !isSimpleParameterList)) {
464 // Allocate a cloned arguments object.
465 emitOpcode(op_create_cloned_arguments);
466 instructions().append(m_argumentsRegister->index());
469 // There are some variables that need to be preinitialized to something other than Undefined:
471 // - "arguments": unless it's used as a function or parameter, this should refer to the
474 // - functions: these always override everything else.
476 // The most logical way to do all of this is to initialize none of the variables until now,
477 // and then initialize them in BytecodeGenerator::generate() in such an order that the rules
478 // for how these things override each other end up holding. We would initialize "arguments" first,
479 // then all arguments, then the functions.
481 // But some arguments are already initialized by default, since if they aren't captured and we
482 // don't have "arguments" then we just point the symbol table at the stack slot of those
483 // arguments. We end up initializing the rest of the arguments that have an uncomplicated
484 // binding (i.e. don't involve destructuring) above when figuring out how to lay them out,
485 // because that's just the simplest thing. This means that when we initialize them, we have to
486 // watch out for the things that override arguments (namely, functions).
488 // This is our final act of weirdness. "arguments" is overridden by everything except the
489 // callee. We add it to the symbol table if it's not already there and it's not an argument.
490 bool shouldCreateArgumentsVariableInParameterScope = false;
491 if (needsArguments) {
492 // If "arguments" is overridden by a function or destructuring parameter name, then it's
493 // OK for us to call createVariable() because it won't change anything. It's also OK for
494 // us to them tell BytecodeGenerator::generate() to write to it because it will do so
495 // before it initializes functions and destructuring parameters. But if "arguments" is
496 // overridden by a "simple" function parameter, then we have to bail: createVariable()
497 // would assert and BytecodeGenerator::generate() would write the "arguments" after the
498 // argument value had already been properly initialized.
500 bool haveParameterNamedArguments = false;
501 for (unsigned i = 0; i < parameters.size(); ++i) {
502 UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first);
503 if (name == propertyNames().arguments.impl()) {
504 haveParameterNamedArguments = true;
509 bool shouldCreateArgumensVariable = !haveParameterNamedArguments && !m_codeBlock->isArrowFunction();
510 shouldCreateArgumentsVariableInParameterScope = shouldCreateArgumensVariable && !isSimpleParameterList;
511 // Do not create arguments variable in case of Arrow function. Value will be loaded from parent scope
512 if (shouldCreateArgumensVariable && !shouldCreateArgumentsVariableInParameterScope) {
514 propertyNames().arguments, varKind(propertyNames().arguments.impl()), functionSymbolTable);
516 m_needToInitializeArguments = true;
520 for (FunctionMetadataNode* function : functionNode->functionStack()) {
521 const Identifier& ident = function->ident();
522 createVariable(ident, varKind(ident.impl()), functionSymbolTable);
523 m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
525 for (auto& entry : functionNode->varDeclarations()) {
526 ASSERT(!entry.value.isLet() && !entry.value.isConst());
527 if (!entry.value.isVar()) // This is either a parameter or callee.
529 if (shouldCreateArgumentsVariableInParameterScope && entry.key.get() == propertyNames().arguments.impl())
531 createVariable(Identifier::fromUid(m_vm, entry.key.get()), varKind(entry.key.get()), functionSymbolTable, IgnoreExisting);
535 m_newTargetRegister = addVar();
537 case SourceParseMode::GeneratorWrapperFunctionMode: {
538 m_generatorRegister = addVar();
540 // FIXME: Emit to_this only when Generator uses it.
541 // https://bugs.webkit.org/show_bug.cgi?id=151586
542 m_codeBlock->addPropertyAccessInstruction(instructions().size());
543 emitOpcode(op_to_this);
544 instructions().append(kill(&m_thisRegister));
545 instructions().append(0);
546 instructions().append(0);
548 emitMove(m_generatorRegister, &m_calleeRegister);
549 emitCreateThis(m_generatorRegister);
553 case SourceParseMode::GeneratorBodyMode: {
554 // |this| is already filled correctly before here.
555 emitLoad(m_newTargetRegister, jsUndefined());
560 if (SourceParseMode::ArrowFunctionMode != parseMode) {
561 if (isConstructor()) {
562 emitMove(m_newTargetRegister, &m_thisRegister);
563 if (constructorKind() == ConstructorKind::Extends) {
564 RefPtr<Label> isDerived = newLabel();
565 RefPtr<Label> done = newLabel();
566 m_isDerivedConstuctor = addVar();
567 emitGetById(m_isDerivedConstuctor, &m_calleeRegister, propertyNames().builtinNames().isDerivedConstructorPrivateName());
568 emitJumpIfTrue(m_isDerivedConstuctor, isDerived.get());
569 emitCreateThis(&m_thisRegister);
570 emitJump(done.get());
571 emitLabel(isDerived.get());
572 emitMoveEmptyValue(&m_thisRegister);
573 emitLabel(done.get());
575 emitCreateThis(&m_thisRegister);
576 } else if (constructorKind() != ConstructorKind::None)
577 emitThrowTypeError("Cannot call a class constructor without |new|");
579 bool shouldEmitToThis = false;
580 if (functionNode->usesThis() || codeBlock->usesEval() || m_scopeNode->doAnyInnerArrowFunctionsUseThis() || m_scopeNode->doAnyInnerArrowFunctionsUseEval())
581 shouldEmitToThis = true;
582 else if ((functionNode->usesSuperProperty() || m_scopeNode->doAnyInnerArrowFunctionsUseSuperProperty()) && !codeBlock->isStrictMode()) {
583 // We must emit to_this when we're not in strict mode because we
584 // will convert |this| to an object, and that object may be passed
585 // to a strict function as |this|. This is observable because that
586 // strict function's to_this will just return the object.
588 // We don't need to emit this for strict-mode code because
589 // strict-mode code may call another strict function, which will
590 // to_this if it directly uses this; this is OK, because we defer
591 // to_this until |this| is used directly. Strict-mode code might
592 // also call a sloppy mode function, and that will to_this, which
593 // will defer the conversion, again, until necessary.
594 shouldEmitToThis = true;
597 if (shouldEmitToThis) {
598 m_codeBlock->addPropertyAccessInstruction(instructions().size());
599 emitOpcode(op_to_this);
600 instructions().append(kill(&m_thisRegister));
601 instructions().append(0);
602 instructions().append(0);
610 // We need load |super| & |this| for arrow function before initializeDefaultParameterValuesAndSetupFunctionScopeStack
611 // if we have default parameter expression. Because |super| & |this| values can be used there
612 if (SourceParseMode::ArrowFunctionMode == parseMode && !isSimpleParameterList) {
613 if (functionNode->usesThis() || functionNode->usesSuperProperty())
614 emitLoadThisFromArrowFunctionLexicalEnvironment();
616 if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
617 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
620 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) {
621 bool canReuseLexicalEnvironment = isSimpleParameterList;
622 initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable, canReuseLexicalEnvironment);
623 emitPutThisToArrowFunctionContextScope();
624 emitPutNewTargetToArrowFunctionContextScope();
625 emitPutDerivedConstructorToArrowFunctionContextScope();
628 // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called
629 // because a function's default parameter ExpressionNodes will use temporary registers.
630 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ);
631 initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, isSimpleParameterList, functionNode, functionSymbolTable, symbolTableConstantIndex, captures, shouldCreateArgumentsVariableInParameterScope);
633 // If we don't have default parameter expression, then loading |this| inside an arrow function must be done
634 // after initializeDefaultParameterValuesAndSetupFunctionScopeStack() because that function sets up the
635 // SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment() consults the SymbolTable stack
636 if (SourceParseMode::ArrowFunctionMode == parseMode && isSimpleParameterList) {
637 if (functionNode->usesThis() || functionNode->usesSuperProperty())
638 emitLoadThisFromArrowFunctionLexicalEnvironment();
640 if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
641 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
644 bool shouldInitializeBlockScopedFunctions = false; // We generate top-level function declarations in ::generate().
645 pushLexicalScope(m_scopeNode, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions);
648 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
649 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
650 , m_scopeNode(evalNode)
651 , m_codeBlock(vm, codeBlock)
652 , m_thisRegister(CallFrame::thisArgumentOffset())
653 , m_codeType(EvalCode)
655 , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
656 , m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval())
657 , m_derivedContextType(codeBlock->derivedContextType())
659 for (auto& constantRegister : m_linkTimeConstantRegisters)
660 constantRegister = nullptr;
662 allocateCalleeSaveSpace();
664 m_codeBlock->setNumParameters(1);
666 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ);
670 allocateAndEmitScope();
672 const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
673 for (size_t i = 0; i < functionStack.size(); ++i)
674 m_codeBlock->addFunctionDecl(makeFunction(functionStack[i]));
676 const VariableEnvironment& varDeclarations = evalNode->varDeclarations();
677 unsigned numVariables = varDeclarations.size();
678 Vector<Identifier, 0, UnsafeVectorOverflow> variables;
679 variables.reserveCapacity(numVariables);
680 for (auto& entry : varDeclarations) {
681 ASSERT(entry.value.isVar());
682 ASSERT(entry.key->isAtomic() || entry.key->isSymbol());
683 variables.append(Identifier::fromUid(m_vm, entry.key.get()));
685 codeBlock->adoptVariables(variables);
687 if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
688 m_newTargetRegister = addVar();
690 if (codeBlock->isArrowFunctionContext() && (evalNode->usesThis() || evalNode->usesSuperProperty()))
691 emitLoadThisFromArrowFunctionLexicalEnvironment();
693 if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
694 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
696 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunctionContext() && !isDerivedConstructorContext()) {
697 initializeArrowFunctionContextScopeIfNeeded();
698 emitPutThisToArrowFunctionContextScope();
701 bool shouldInitializeBlockScopedFunctions = false; // We generate top-level function declarations in ::generate().
702 pushLexicalScope(m_scopeNode, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions);
705 BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
706 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
707 , m_scopeNode(moduleProgramNode)
708 , m_codeBlock(vm, codeBlock)
709 , m_thisRegister(CallFrame::thisArgumentOffset())
710 , m_codeType(ModuleCode)
712 , m_usesNonStrictEval(false)
713 , m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval())
715 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
717 for (auto& constantRegister : m_linkTimeConstantRegisters)
718 constantRegister = nullptr;
720 if (m_isBuiltinFunction)
721 m_shouldEmitDebugHooks = false;
723 allocateCalleeSaveSpace();
725 SymbolTable* moduleEnvironmentSymbolTable = SymbolTable::create(*m_vm);
726 moduleEnvironmentSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval);
727 moduleEnvironmentSymbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope);
729 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
730 if (shouldCaptureAllOfTheThings)
731 moduleProgramNode->varDeclarations().markAllVariablesAsCaptured();
733 auto captures = [&] (UniquedStringImpl* uid) -> bool {
734 return moduleProgramNode->captures(uid);
736 auto lookUpVarKind = [&] (UniquedStringImpl* uid, const VariableEnvironmentEntry& entry) -> VarKind {
737 // Allocate the exported variables in the module environment.
738 if (entry.isExported())
739 return VarKind::Scope;
741 // Allocate the namespace variables in the module environment to instantiate
742 // it from the outside of the module code.
743 if (entry.isImportedNamespace())
744 return VarKind::Scope;
746 if (entry.isCaptured())
747 return VarKind::Scope;
748 return captures(uid) ? VarKind::Scope : VarKind::Stack;
753 allocateAndEmitScope();
755 m_calleeRegister.setIndex(CallFrameSlot::callee);
757 m_codeBlock->setNumParameters(1); // Allocate space for "this"
759 // Now declare all variables.
761 for (auto& entry : moduleProgramNode->varDeclarations()) {
762 ASSERT(!entry.value.isLet() && !entry.value.isConst());
763 if (!entry.value.isVar()) // This is either a parameter or callee.
765 // Imported bindings are not allocated in the module environment as usual variables' way.
766 // These references remain the "Dynamic" in the unlinked code block. Later, when linking
767 // the code block, we resolve the reference to the "ModuleVar".
768 if (entry.value.isImported() && !entry.value.isImportedNamespace())
770 createVariable(Identifier::fromUid(m_vm, entry.key.get()), lookUpVarKind(entry.key.get(), entry.value), moduleEnvironmentSymbolTable, IgnoreExisting);
773 VariableEnvironment& lexicalVariables = moduleProgramNode->lexicalVariables();
774 instantiateLexicalVariables(lexicalVariables, moduleEnvironmentSymbolTable, ScopeRegisterType::Block, lookUpVarKind);
776 // We keep the symbol table in the constant pool.
777 RegisterID* constantSymbolTable = nullptr;
778 if (vm.typeProfiler())
779 constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable);
781 constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable->cloneScopePart(*m_vm));
783 pushTDZVariables(lexicalVariables, TDZCheckOptimization::Optimize, TDZRequirement::UnderTDZ);
784 bool isWithScope = false;
785 m_symbolTableStack.append(SymbolTableStackEntry { moduleEnvironmentSymbolTable, m_topMostScope, isWithScope, constantSymbolTable->index() });
786 emitPrefillStackTDZVariables(lexicalVariables, moduleEnvironmentSymbolTable);
788 // makeFunction assumes that there's correct TDZ stack entries.
789 // So it should be called after putting our lexical environment to the TDZ stack correctly.
791 for (FunctionMetadataNode* function : moduleProgramNode->functionStack()) {
792 const auto& iterator = moduleProgramNode->varDeclarations().find(function->ident().impl());
793 RELEASE_ASSERT(iterator != moduleProgramNode->varDeclarations().end());
794 RELEASE_ASSERT(!iterator->value.isImported());
796 VarKind varKind = lookUpVarKind(iterator->key.get(), iterator->value);
797 if (varKind == VarKind::Scope) {
798 // http://www.ecma-international.org/ecma-262/6.0/#sec-moduledeclarationinstantiation
799 // Section 15.2.1.16.4, step 16-a-iv-1.
800 // All heap allocated function declarations should be instantiated when the module environment
801 // is created. They include the exported function declarations and not-exported-but-heap-allocated
802 // function declarations. This is required because exported function should be instantiated before
803 // executing the any module in the dependency graph. This enables the modules to link the imported
804 // bindings before executing the any module code.
806 // And since function declarations are instantiated before executing the module body code, the spec
807 // allows the functions inside the module to be executed before its module body is executed under
808 // the circular dependencies. The following is the example.
810 // Module A (executed first):
811 // import { b } from "B";
812 // // Here, the module "B" is not executed yet, but the function declaration is already instantiated.
813 // // So we can call the function exported from "B".
816 // export function a() {
819 // Module B (executed second):
820 // import { a } from "A";
822 // export function b() {
826 // // c is not exported, but since it is referenced from the b, we should instantiate it before
827 // // executing the "B" module code.
832 // Module EntryPoint (executed last):
836 m_codeBlock->addFunctionDecl(makeFunction(function));
838 // Stack allocated functions can be allocated when executing the module's body.
839 m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
843 // Remember the constant register offset to the top-most symbol table. This symbol table will be
844 // cloned in the code block linking. After that, to create the module environment, we retrieve
845 // the cloned symbol table from the linked code block by using this offset.
846 codeBlock->setModuleEnvironmentSymbolTableConstantRegisterOffset(constantSymbolTable->index());
849 BytecodeGenerator::~BytecodeGenerator()
853 void BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack(
854 FunctionParameters& parameters, bool isSimpleParameterList, FunctionNode* functionNode, SymbolTable* functionSymbolTable,
855 int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures, bool shouldCreateArgumentsVariableInParameterScope)
857 Vector<std::pair<Identifier, RefPtr<RegisterID>>> valuesToMoveIntoVars;
858 ASSERT(!(isSimpleParameterList && shouldCreateArgumentsVariableInParameterScope));
859 if (!isSimpleParameterList) {
860 // Refer to the ES6 spec section 9.2.12: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
861 // This implements step 21.
862 VariableEnvironment environment;
863 Vector<Identifier> allParameterNames;
864 for (unsigned i = 0; i < parameters.size(); i++)
865 parameters.at(i).first->collectBoundIdentifiers(allParameterNames);
866 if (shouldCreateArgumentsVariableInParameterScope)
867 allParameterNames.append(propertyNames().arguments);
868 IdentifierSet parameterSet;
869 for (auto& ident : allParameterNames) {
870 parameterSet.add(ident.impl());
871 auto addResult = environment.add(ident);
872 addResult.iterator->value.setIsLet(); // When we have default parameter expressions, parameters act like "let" variables.
873 if (captures(ident.impl()))
874 addResult.iterator->value.setIsCaptured();
876 // This implements step 25 of section 9.2.12.
877 pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
879 if (shouldCreateArgumentsVariableInParameterScope) {
880 Variable argumentsVariable = variable(propertyNames().arguments);
881 initializeVariable(argumentsVariable, m_argumentsRegister);
882 liftTDZCheckIfPossible(argumentsVariable);
885 RefPtr<RegisterID> temp = newTemporary();
886 for (unsigned i = 0; i < parameters.size(); i++) {
887 std::pair<DestructuringPatternNode*, ExpressionNode*> parameter = parameters.at(i);
888 if (parameter.first->isRestParameter())
890 RefPtr<RegisterID> parameterValue = ®isterFor(virtualRegisterForArgument(1 + i));
891 emitMove(temp.get(), parameterValue.get());
892 if (parameter.second) {
893 RefPtr<RegisterID> condition = emitIsUndefined(newTemporary(), parameterValue.get());
894 RefPtr<Label> skipDefaultParameterBecauseNotUndefined = newLabel();
895 emitJumpIfFalse(condition.get(), skipDefaultParameterBecauseNotUndefined.get());
896 emitNode(temp.get(), parameter.second);
897 emitLabel(skipDefaultParameterBecauseNotUndefined.get());
900 parameter.first->bindValue(*this, temp.get());
903 // Final act of weirdness for default parameters. If a "var" also
904 // has the same name as a parameter, it should start out as the
905 // value of that parameter. Note, though, that they will be distinct
907 // This is step 28 of section 9.2.12.
908 for (auto& entry : functionNode->varDeclarations()) {
909 if (!entry.value.isVar()) // This is either a parameter or callee.
912 if (parameterSet.contains(entry.key)) {
913 Identifier ident = Identifier::fromUid(m_vm, entry.key.get());
914 Variable var = variable(ident);
915 RegisterID* scope = emitResolveScope(nullptr, var);
916 RefPtr<RegisterID> value = emitGetFromScope(newTemporary(), scope, var, DoNotThrowIfNotFound);
917 valuesToMoveIntoVars.append(std::make_pair(ident, value));
921 // Functions with default parameter expressions must have a separate environment
922 // record for parameters and "var"s. The "var" environment record must have the
923 // parameter environment record as its parent.
924 // See step 28 of section 9.2.12.
925 bool hasCapturedVariables = !!m_lexicalEnvironmentRegister;
926 initializeVarLexicalEnvironment(symbolTableConstantIndex, functionSymbolTable, hasCapturedVariables);
929 // This completes step 28 of section 9.2.12.
930 for (unsigned i = 0; i < valuesToMoveIntoVars.size(); i++) {
931 ASSERT(!isSimpleParameterList);
932 Variable var = variable(valuesToMoveIntoVars[i].first);
933 RegisterID* scope = emitResolveScope(nullptr, var);
934 emitPutToScope(scope, var, valuesToMoveIntoVars[i].second.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
938 void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable, bool canReuseLexicalEnvironment)
940 ASSERT(!m_arrowFunctionContextLexicalEnvironmentRegister);
942 if (canReuseLexicalEnvironment && m_lexicalEnvironmentRegister) {
943 RELEASE_ASSERT(!m_codeBlock->isArrowFunction());
944 RELEASE_ASSERT(functionSymbolTable);
946 m_arrowFunctionContextLexicalEnvironmentRegister = m_lexicalEnvironmentRegister;
950 if (isThisUsedInInnerArrowFunction()) {
951 offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
952 functionSymbolTable->set(NoLockingNecessary, propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset)));
955 if (m_codeType == FunctionCode && isNewTargetUsedInInnerArrowFunction()) {
956 offset = functionSymbolTable->takeNextScopeOffset();
957 functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().newTargetLocalPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
960 if (isConstructor() && constructorKind() == ConstructorKind::Extends && isSuperUsedInInnerArrowFunction()) {
961 offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
962 functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().derivedConstructorPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
968 VariableEnvironment environment;
970 if (isThisUsedInInnerArrowFunction()) {
971 auto addResult = environment.add(propertyNames().thisIdentifier);
972 addResult.iterator->value.setIsCaptured();
973 addResult.iterator->value.setIsLet();
976 if (m_codeType == FunctionCode && isNewTargetUsedInInnerArrowFunction()) {
977 auto addTarget = environment.add(propertyNames().builtinNames().newTargetLocalPrivateName());
978 addTarget.iterator->value.setIsCaptured();
979 addTarget.iterator->value.setIsLet();
982 if (isConstructor() && constructorKind() == ConstructorKind::Extends && isSuperUsedInInnerArrowFunction()) {
983 auto derivedConstructor = environment.add(propertyNames().builtinNames().derivedConstructorPrivateName());
984 derivedConstructor.iterator->value.setIsCaptured();
985 derivedConstructor.iterator->value.setIsLet();
988 if (environment.size() > 0) {
989 size_t size = m_symbolTableStack.size();
990 pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
992 ASSERT_UNUSED(size, m_symbolTableStack.size() == size + 1);
994 m_arrowFunctionContextLexicalEnvironmentRegister = m_symbolTableStack.last().m_scope;
998 RegisterID* BytecodeGenerator::initializeNextParameter()
1000 VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
1001 RegisterID& parameter = registerFor(reg);
1002 parameter.setIndex(reg.offset());
1003 m_codeBlock->addParameter();
1007 void BytecodeGenerator::initializeParameters(FunctionParameters& parameters)
1009 // Make sure the code block knows about all of our parameters, and make sure that parameters
1010 // needing destructuring are noted.
1011 m_parameters.grow(parameters.size() + 1); // reserve space for "this"
1012 m_thisRegister.setIndex(initializeNextParameter()->index()); // this
1013 for (unsigned i = 0; i < parameters.size(); ++i) {
1014 auto pattern = parameters.at(i).first;
1015 if (pattern->isRestParameter()) {
1016 RELEASE_ASSERT(!m_restParameter);
1017 m_restParameter = static_cast<RestParameterNode*>(pattern);
1019 initializeNextParameter();
1023 void BytecodeGenerator::initializeVarLexicalEnvironment(int symbolTableConstantIndex, SymbolTable* functionSymbolTable, bool hasCapturedVariables)
1025 if (hasCapturedVariables) {
1026 RELEASE_ASSERT(m_lexicalEnvironmentRegister);
1027 emitOpcode(op_create_lexical_environment);
1028 instructions().append(m_lexicalEnvironmentRegister->index());
1029 instructions().append(scopeRegister()->index());
1030 instructions().append(symbolTableConstantIndex);
1031 instructions().append(addConstantValue(jsUndefined())->index());
1034 instructions().append(scopeRegister()->index());
1035 instructions().append(m_lexicalEnvironmentRegister->index());
1037 pushScopedControlFlowContext();
1039 bool isWithScope = false;
1040 m_symbolTableStack.append(SymbolTableStackEntry{ functionSymbolTable, m_lexicalEnvironmentRegister, isWithScope, symbolTableConstantIndex });
1041 m_varScopeSymbolTableIndex = m_symbolTableStack.size() - 1;
1044 UniquedStringImpl* BytecodeGenerator::visibleNameForParameter(DestructuringPatternNode* pattern)
1046 if (pattern->isBindingNode()) {
1047 const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
1048 if (!m_functions.contains(ident.impl()))
1049 return ident.impl();
1054 RegisterID* BytecodeGenerator::newRegister()
1056 m_calleeLocals.append(virtualRegisterForLocal(m_calleeLocals.size()));
1057 int numCalleeLocals = max<int>(m_codeBlock->m_numCalleeLocals, m_calleeLocals.size());
1058 numCalleeLocals = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numCalleeLocals);
1059 m_codeBlock->m_numCalleeLocals = numCalleeLocals;
1060 return &m_calleeLocals.last();
1063 void BytecodeGenerator::reclaimFreeRegisters()
1065 while (m_calleeLocals.size() && !m_calleeLocals.last().refCount())
1066 m_calleeLocals.removeLast();
1069 RegisterID* BytecodeGenerator::newBlockScopeVariable()
1071 reclaimFreeRegisters();
1073 return newRegister();
1076 RegisterID* BytecodeGenerator::newTemporary()
1078 reclaimFreeRegisters();
1080 RegisterID* result = newRegister();
1081 result->setTemporary();
1085 LabelScopePtr BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
1087 // Reclaim free label scopes.
1088 while (m_labelScopes.size() && !m_labelScopes.last().refCount())
1089 m_labelScopes.removeLast();
1091 // Allocate new label scope.
1092 LabelScope scope(type, name, labelScopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
1093 m_labelScopes.append(scope);
1094 return LabelScopePtr(m_labelScopes, m_labelScopes.size() - 1);
1097 PassRefPtr<Label> BytecodeGenerator::newLabel()
1099 // Reclaim free label IDs.
1100 while (m_labels.size() && !m_labels.last().refCount())
1101 m_labels.removeLast();
1103 // Allocate new label ID.
1104 m_labels.append(*this);
1105 return &m_labels.last();
1108 PassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0)
1110 unsigned newLabelIndex = instructions().size();
1111 l0->setLocation(newLabelIndex);
1113 if (m_codeBlock->numberOfJumpTargets()) {
1114 unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
1115 ASSERT(lastLabelIndex <= newLabelIndex);
1116 if (newLabelIndex == lastLabelIndex) {
1117 // Peephole optimizations have already been disabled by emitting the last label
1122 m_codeBlock->addJumpTarget(newLabelIndex);
1124 // This disables peephole optimizations when an instruction is a jump target
1125 m_lastOpcodeID = op_end;
1129 void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
1132 size_t opcodePosition = instructions().size();
1133 ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
1134 m_lastOpcodePosition = opcodePosition;
1136 instructions().append(opcodeID);
1137 m_lastOpcodeID = opcodeID;
1140 UnlinkedArrayProfile BytecodeGenerator::newArrayProfile()
1142 return m_codeBlock->addArrayProfile();
1145 UnlinkedArrayAllocationProfile BytecodeGenerator::newArrayAllocationProfile()
1147 return m_codeBlock->addArrayAllocationProfile();
1150 UnlinkedObjectAllocationProfile BytecodeGenerator::newObjectAllocationProfile()
1152 return m_codeBlock->addObjectAllocationProfile();
1155 UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
1157 UnlinkedValueProfile result = m_codeBlock->addValueProfile();
1158 emitOpcode(opcodeID);
1162 void BytecodeGenerator::emitEnter()
1164 emitOpcode(op_enter);
1168 void BytecodeGenerator::emitLoopHint()
1170 emitOpcode(op_loop_hint);
1174 void BytecodeGenerator::emitWatchdog()
1176 if (vm()->watchdog())
1177 emitOpcode(op_watchdog);
1180 void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
1182 ASSERT(instructions().size() >= 4);
1183 size_t size = instructions().size();
1184 dstIndex = instructions().at(size - 3).u.operand;
1185 src1Index = instructions().at(size - 2).u.operand;
1186 src2Index = instructions().at(size - 1).u.operand;
1189 void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
1191 ASSERT(instructions().size() >= 3);
1192 size_t size = instructions().size();
1193 dstIndex = instructions().at(size - 2).u.operand;
1194 srcIndex = instructions().at(size - 1).u.operand;
1197 void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
1199 ASSERT(instructions().size() >= 4);
1200 instructions().shrink(instructions().size() - 4);
1201 m_lastOpcodeID = op_end;
1204 void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
1206 ASSERT(instructions().size() >= 3);
1207 instructions().shrink(instructions().size() - 3);
1208 m_lastOpcodeID = op_end;
1211 PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
1213 size_t begin = instructions().size();
1215 instructions().append(target->bind(begin, instructions().size()));
1219 PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
1221 if (m_lastOpcodeID == op_less) {
1226 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1228 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1231 size_t begin = instructions().size();
1232 emitOpcode(op_jless);
1233 instructions().append(src1Index);
1234 instructions().append(src2Index);
1235 instructions().append(target->bind(begin, instructions().size()));
1238 } else if (m_lastOpcodeID == op_lesseq) {
1243 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1245 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1248 size_t begin = instructions().size();
1249 emitOpcode(op_jlesseq);
1250 instructions().append(src1Index);
1251 instructions().append(src2Index);
1252 instructions().append(target->bind(begin, instructions().size()));
1255 } else if (m_lastOpcodeID == op_greater) {
1260 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1262 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1265 size_t begin = instructions().size();
1266 emitOpcode(op_jgreater);
1267 instructions().append(src1Index);
1268 instructions().append(src2Index);
1269 instructions().append(target->bind(begin, instructions().size()));
1272 } else if (m_lastOpcodeID == op_greatereq) {
1277 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1279 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1282 size_t begin = instructions().size();
1283 emitOpcode(op_jgreatereq);
1284 instructions().append(src1Index);
1285 instructions().append(src2Index);
1286 instructions().append(target->bind(begin, instructions().size()));
1289 } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
1293 retrieveLastUnaryOp(dstIndex, srcIndex);
1295 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1298 size_t begin = instructions().size();
1299 emitOpcode(op_jeq_null);
1300 instructions().append(srcIndex);
1301 instructions().append(target->bind(begin, instructions().size()));
1304 } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
1308 retrieveLastUnaryOp(dstIndex, srcIndex);
1310 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1313 size_t begin = instructions().size();
1314 emitOpcode(op_jneq_null);
1315 instructions().append(srcIndex);
1316 instructions().append(target->bind(begin, instructions().size()));
1321 size_t begin = instructions().size();
1323 emitOpcode(op_jtrue);
1324 instructions().append(cond->index());
1325 instructions().append(target->bind(begin, instructions().size()));
1329 PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
1331 if (m_lastOpcodeID == op_less && target->isForward()) {
1336 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1338 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1341 size_t begin = instructions().size();
1342 emitOpcode(op_jnless);
1343 instructions().append(src1Index);
1344 instructions().append(src2Index);
1345 instructions().append(target->bind(begin, instructions().size()));
1348 } else if (m_lastOpcodeID == op_lesseq && target->isForward()) {
1353 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1355 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1358 size_t begin = instructions().size();
1359 emitOpcode(op_jnlesseq);
1360 instructions().append(src1Index);
1361 instructions().append(src2Index);
1362 instructions().append(target->bind(begin, instructions().size()));
1365 } else if (m_lastOpcodeID == op_greater && target->isForward()) {
1370 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1372 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1375 size_t begin = instructions().size();
1376 emitOpcode(op_jngreater);
1377 instructions().append(src1Index);
1378 instructions().append(src2Index);
1379 instructions().append(target->bind(begin, instructions().size()));
1382 } else if (m_lastOpcodeID == op_greatereq && target->isForward()) {
1387 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1389 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1392 size_t begin = instructions().size();
1393 emitOpcode(op_jngreatereq);
1394 instructions().append(src1Index);
1395 instructions().append(src2Index);
1396 instructions().append(target->bind(begin, instructions().size()));
1399 } else if (m_lastOpcodeID == op_not) {
1403 retrieveLastUnaryOp(dstIndex, srcIndex);
1405 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1408 size_t begin = instructions().size();
1409 emitOpcode(op_jtrue);
1410 instructions().append(srcIndex);
1411 instructions().append(target->bind(begin, instructions().size()));
1414 } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
1418 retrieveLastUnaryOp(dstIndex, srcIndex);
1420 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1423 size_t begin = instructions().size();
1424 emitOpcode(op_jneq_null);
1425 instructions().append(srcIndex);
1426 instructions().append(target->bind(begin, instructions().size()));
1429 } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
1433 retrieveLastUnaryOp(dstIndex, srcIndex);
1435 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1438 size_t begin = instructions().size();
1439 emitOpcode(op_jeq_null);
1440 instructions().append(srcIndex);
1441 instructions().append(target->bind(begin, instructions().size()));
1446 size_t begin = instructions().size();
1447 emitOpcode(op_jfalse);
1448 instructions().append(cond->index());
1449 instructions().append(target->bind(begin, instructions().size()));
1453 PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
1455 size_t begin = instructions().size();
1457 emitOpcode(op_jneq_ptr);
1458 instructions().append(cond->index());
1459 instructions().append(Special::CallFunction);
1460 instructions().append(target->bind(begin, instructions().size()));
1461 instructions().append(0);
1465 PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
1467 size_t begin = instructions().size();
1469 emitOpcode(op_jneq_ptr);
1470 instructions().append(cond->index());
1471 instructions().append(Special::ApplyFunction);
1472 instructions().append(target->bind(begin, instructions().size()));
1473 instructions().append(0);
1477 bool BytecodeGenerator::hasConstant(const Identifier& ident) const
1479 UniquedStringImpl* rep = ident.impl();
1480 return m_identifierMap.contains(rep);
1483 unsigned BytecodeGenerator::addConstant(const Identifier& ident)
1485 UniquedStringImpl* rep = ident.impl();
1486 IdentifierMap::AddResult result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
1487 if (result.isNewEntry)
1488 m_codeBlock->addIdentifier(ident);
1490 return result.iterator->value;
1493 // We can't hash JSValue(), so we use a dedicated data member to cache it.
1494 RegisterID* BytecodeGenerator::addConstantEmptyValue()
1496 if (!m_emptyValueRegister) {
1497 int index = m_nextConstantOffset;
1498 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1499 ++m_nextConstantOffset;
1500 m_codeBlock->addConstant(JSValue());
1501 m_emptyValueRegister = &m_constantPoolRegisters[index];
1504 return m_emptyValueRegister;
1507 RegisterID* BytecodeGenerator::addConstantValue(JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
1510 return addConstantEmptyValue();
1512 int index = m_nextConstantOffset;
1514 if (sourceCodeRepresentation == SourceCodeRepresentation::Double && v.isInt32())
1515 v = jsDoubleNumber(v.asNumber());
1516 EncodedJSValueWithRepresentation valueMapKey { JSValue::encode(v), sourceCodeRepresentation };
1517 JSValueMap::AddResult result = m_jsValueMap.add(valueMapKey, m_nextConstantOffset);
1518 if (result.isNewEntry) {
1519 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1520 ++m_nextConstantOffset;
1521 m_codeBlock->addConstant(v, sourceCodeRepresentation);
1523 index = result.iterator->value;
1524 return &m_constantPoolRegisters[index];
1527 RegisterID* BytecodeGenerator::emitMoveLinkTimeConstant(RegisterID* dst, LinkTimeConstant type)
1529 unsigned constantIndex = static_cast<unsigned>(type);
1530 if (!m_linkTimeConstantRegisters[constantIndex]) {
1531 int index = m_nextConstantOffset;
1532 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1533 ++m_nextConstantOffset;
1534 m_codeBlock->addConstant(type);
1535 m_linkTimeConstantRegisters[constantIndex] = &m_constantPoolRegisters[index];
1539 instructions().append(dst->index());
1540 instructions().append(m_linkTimeConstantRegisters[constantIndex]->index());
1545 unsigned BytecodeGenerator::addRegExp(RegExp* r)
1547 return m_codeBlock->addRegExp(r);
1550 RegisterID* BytecodeGenerator::emitMoveEmptyValue(RegisterID* dst)
1552 RefPtr<RegisterID> emptyValue = addConstantEmptyValue();
1555 instructions().append(dst->index());
1556 instructions().append(emptyValue->index());
1560 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
1562 ASSERT(src != m_emptyValueRegister);
1564 m_staticPropertyAnalyzer.mov(dst->index(), src->index());
1566 instructions().append(dst->index());
1567 instructions().append(src->index());
1572 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1574 ASSERT_WITH_MESSAGE(op_to_number != opcodeID, "op_to_number is profiled.");
1575 emitOpcode(opcodeID);
1576 instructions().append(dst->index());
1577 instructions().append(src->index());
1581 RegisterID* BytecodeGenerator::emitUnaryOpProfiled(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1583 UnlinkedValueProfile profile = emitProfiledOpcode(opcodeID);
1584 instructions().append(dst->index());
1585 instructions().append(src->index());
1586 instructions().append(profile);
1590 RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
1593 instructions().append(srcDst->index());
1597 RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
1600 instructions().append(srcDst->index());
1604 RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
1606 emitOpcode(opcodeID);
1607 instructions().append(dst->index());
1608 instructions().append(src1->index());
1609 instructions().append(src2->index());
1611 if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
1612 opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
1613 instructions().append(ArithProfile(types.first(), types.second()).bits());
1618 RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
1620 if (m_lastOpcodeID == op_typeof) {
1624 retrieveLastUnaryOp(dstIndex, srcIndex);
1626 if (src1->index() == dstIndex
1627 && src1->isTemporary()
1628 && m_codeBlock->isConstantRegisterIndex(src2->index())
1629 && m_codeBlock->constantRegister(src2->index()).get().isString()) {
1630 const String& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
1631 if (value == "undefined") {
1633 emitOpcode(op_is_undefined);
1634 instructions().append(dst->index());
1635 instructions().append(srcIndex);
1638 if (value == "boolean") {
1640 emitOpcode(op_is_boolean);
1641 instructions().append(dst->index());
1642 instructions().append(srcIndex);
1645 if (value == "number") {
1647 emitOpcode(op_is_number);
1648 instructions().append(dst->index());
1649 instructions().append(srcIndex);
1652 if (value == "string") {
1654 emitOpcode(op_is_string);
1655 instructions().append(dst->index());
1656 instructions().append(srcIndex);
1659 if (value == "object") {
1661 emitOpcode(op_is_object_or_null);
1662 instructions().append(dst->index());
1663 instructions().append(srcIndex);
1666 if (value == "function") {
1668 emitOpcode(op_is_function);
1669 instructions().append(dst->index());
1670 instructions().append(srcIndex);
1676 emitOpcode(opcodeID);
1677 instructions().append(dst->index());
1678 instructions().append(src1->index());
1679 instructions().append(src2->index());
1683 void BytecodeGenerator::emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1685 ASSERT(vm()->typeProfiler());
1687 unsigned start = startDivot.offset; // Ranges are inclusive of their endpoints, AND 0 indexed.
1688 unsigned end = endDivot.offset - 1; // End Ranges already go one past the inclusive range, so subtract 1.
1689 unsigned instructionOffset = instructions().size() - 1;
1690 m_codeBlock->addTypeProfilerExpressionInfo(instructionOffset, start, end);
1693 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag)
1695 if (!vm()->typeProfiler())
1698 if (!registerToProfile)
1701 emitOpcode(op_profile_type);
1702 instructions().append(registerToProfile->index());
1703 instructions().append(0);
1704 instructions().append(flag);
1705 instructions().append(0);
1706 instructions().append(resolveType());
1708 // Don't emit expression info for this version of profile type. This generally means
1709 // we're profiling information for something that isn't in the actual text of a JavaScript
1710 // program. For example, implicit return undefined from a function call.
1713 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1715 emitProfileType(registerToProfile, ProfileTypeBytecodeDoesNotHaveGlobalID, startDivot, endDivot);
1718 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1720 if (!vm()->typeProfiler())
1723 if (!registerToProfile)
1726 // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1727 emitOpcode(op_profile_type);
1728 instructions().append(registerToProfile->index());
1729 instructions().append(0);
1730 instructions().append(flag);
1731 instructions().append(0);
1732 instructions().append(resolveType());
1734 emitTypeProfilerExpressionInfo(startDivot, endDivot);
1737 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const Variable& var, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1739 if (!vm()->typeProfiler())
1742 if (!registerToProfile)
1745 ProfileTypeBytecodeFlag flag;
1746 int symbolTableOrScopeDepth;
1747 if (var.local() || var.offset().isScope()) {
1748 flag = ProfileTypeBytecodeLocallyResolved;
1749 ASSERT(var.symbolTableConstantIndex());
1750 symbolTableOrScopeDepth = var.symbolTableConstantIndex();
1752 flag = ProfileTypeBytecodeClosureVar;
1753 symbolTableOrScopeDepth = localScopeDepth();
1756 // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1757 emitOpcode(op_profile_type);
1758 instructions().append(registerToProfile->index());
1759 instructions().append(symbolTableOrScopeDepth);
1760 instructions().append(flag);
1761 instructions().append(addConstant(var.ident()));
1762 instructions().append(resolveType());
1764 emitTypeProfilerExpressionInfo(startDivot, endDivot);
1767 void BytecodeGenerator::emitProfileControlFlow(int textOffset)
1769 if (vm()->controlFlowProfiler()) {
1770 RELEASE_ASSERT(textOffset >= 0);
1771 size_t bytecodeOffset = instructions().size();
1772 m_codeBlock->addOpProfileControlFlowBytecodeOffset(bytecodeOffset);
1774 emitOpcode(op_profile_control_flow);
1775 instructions().append(textOffset);
1779 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
1781 return emitLoad(dst, jsBoolean(b));
1784 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
1786 ASSERT(!identifier.isSymbol());
1787 JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
1789 stringInMap = jsOwnedString(vm(), identifier.string());
1791 return emitLoad(dst, JSValue(stringInMap));
1794 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
1796 RegisterID* constantID = addConstantValue(v, sourceCodeRepresentation);
1798 return emitMove(dst, constantID);
1802 RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst)
1804 if (!m_globalObjectRegister) {
1805 int index = m_nextConstantOffset;
1806 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1807 ++m_nextConstantOffset;
1808 m_codeBlock->addConstant(JSValue());
1809 m_globalObjectRegister = &m_constantPoolRegisters[index];
1810 m_codeBlock->setGlobalObjectRegister(VirtualRegister(index));
1813 emitMove(dst, m_globalObjectRegister);
1814 return m_globalObjectRegister;
1817 template<typename LookUpVarKindFunctor>
1818 bool BytecodeGenerator::instantiateLexicalVariables(const VariableEnvironment& lexicalVariables, SymbolTable* symbolTable, ScopeRegisterType scopeRegisterType, LookUpVarKindFunctor lookUpVarKind)
1820 bool hasCapturedVariables = false;
1822 for (auto& entry : lexicalVariables) {
1823 ASSERT(entry.value.isLet() || entry.value.isConst() || entry.value.isFunction());
1824 ASSERT(!entry.value.isVar());
1825 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
1826 ASSERT(symbolTableEntry.isNull());
1828 // Imported bindings which are not the namespace bindings are not allocated
1829 // in the module environment as usual variables' way.
1830 // And since these types of the variables only seen in the module environment,
1831 // other lexical environment need not to take care this.
1832 if (entry.value.isImported() && !entry.value.isImportedNamespace())
1835 VarKind varKind = lookUpVarKind(entry.key.get(), entry.value);
1836 VarOffset varOffset;
1837 if (varKind == VarKind::Scope) {
1838 varOffset = VarOffset(symbolTable->takeNextScopeOffset(NoLockingNecessary));
1839 hasCapturedVariables = true;
1841 ASSERT(varKind == VarKind::Stack);
1843 if (scopeRegisterType == ScopeRegisterType::Block) {
1844 local = newBlockScopeVariable();
1848 varOffset = VarOffset(local->virtualRegister());
1851 SymbolTableEntry newEntry(varOffset, entry.value.isConst() ? ReadOnly : 0);
1852 symbolTable->add(NoLockingNecessary, entry.key.get(), newEntry);
1855 return hasCapturedVariables;
1858 void BytecodeGenerator::emitPrefillStackTDZVariables(const VariableEnvironment& lexicalVariables, SymbolTable* symbolTable)
1860 // Prefill stack variables with the TDZ empty value.
1861 // Scope variables will be initialized to the TDZ empty value when JSLexicalEnvironment is allocated.
1862 for (auto& entry : lexicalVariables) {
1863 // Imported bindings which are not the namespace bindings are not allocated
1864 // in the module environment as usual variables' way.
1865 // And since these types of the variables only seen in the module environment,
1866 // other lexical environment need not to take care this.
1867 if (entry.value.isImported() && !entry.value.isImportedNamespace())
1870 if (entry.value.isFunction())
1873 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
1874 ASSERT(!symbolTableEntry.isNull());
1875 VarOffset offset = symbolTableEntry.varOffset();
1876 if (offset.isScope())
1879 ASSERT(offset.isStack());
1880 emitMoveEmptyValue(®isterFor(offset.stackOffset()));
1884 void BytecodeGenerator::pushLexicalScope(VariableEnvironmentNode* node, TDZCheckOptimization tdzCheckOptimization, NestedScopeType nestedScopeType, RegisterID** constantSymbolTableResult, bool shouldInitializeBlockScopedFunctions)
1886 VariableEnvironment& environment = node->lexicalVariables();
1887 RegisterID* constantSymbolTableResultTemp = nullptr;
1888 pushLexicalScopeInternal(environment, tdzCheckOptimization, nestedScopeType, &constantSymbolTableResultTemp, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
1890 if (shouldInitializeBlockScopedFunctions)
1891 initializeBlockScopedFunctions(environment, node->functionStack(), constantSymbolTableResultTemp);
1893 if (constantSymbolTableResult && constantSymbolTableResultTemp)
1894 *constantSymbolTableResult = constantSymbolTableResultTemp;
1897 void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environment, TDZCheckOptimization tdzCheckOptimization, NestedScopeType nestedScopeType,
1898 RegisterID** constantSymbolTableResult, TDZRequirement tdzRequirement, ScopeType scopeType, ScopeRegisterType scopeRegisterType)
1900 if (!environment.size())
1903 if (m_shouldEmitDebugHooks)
1904 environment.markAllVariablesAsCaptured();
1906 SymbolTable* symbolTable = SymbolTable::create(*m_vm);
1907 switch (scopeType) {
1908 case ScopeType::CatchScope:
1909 symbolTable->setScopeType(SymbolTable::ScopeType::CatchScope);
1911 case ScopeType::LetConstScope:
1912 symbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope);
1914 case ScopeType::FunctionNameScope:
1915 symbolTable->setScopeType(SymbolTable::ScopeType::FunctionNameScope);
1919 if (nestedScopeType == NestedScopeType::IsNested)
1920 symbolTable->markIsNestedLexicalScope();
1922 auto lookUpVarKind = [] (UniquedStringImpl*, const VariableEnvironmentEntry& entry) -> VarKind {
1923 return entry.isCaptured() ? VarKind::Scope : VarKind::Stack;
1926 bool hasCapturedVariables = instantiateLexicalVariables(environment, symbolTable, scopeRegisterType, lookUpVarKind);
1928 RegisterID* newScope = nullptr;
1929 RegisterID* constantSymbolTable = nullptr;
1930 int symbolTableConstantIndex = 0;
1931 if (vm()->typeProfiler()) {
1932 constantSymbolTable = addConstantValue(symbolTable);
1933 symbolTableConstantIndex = constantSymbolTable->index();
1935 if (hasCapturedVariables) {
1936 if (scopeRegisterType == ScopeRegisterType::Block) {
1937 newScope = newBlockScopeVariable();
1940 newScope = addVar();
1941 if (!constantSymbolTable) {
1942 ASSERT(!vm()->typeProfiler());
1943 constantSymbolTable = addConstantValue(symbolTable->cloneScopePart(*m_vm));
1944 symbolTableConstantIndex = constantSymbolTable->index();
1946 if (constantSymbolTableResult)
1947 *constantSymbolTableResult = constantSymbolTable;
1949 emitOpcode(op_create_lexical_environment);
1950 instructions().append(newScope->index());
1951 instructions().append(scopeRegister()->index());
1952 instructions().append(constantSymbolTable->index());
1953 instructions().append(addConstantValue(tdzRequirement == TDZRequirement::UnderTDZ ? jsTDZValue() : jsUndefined())->index());
1955 emitMove(scopeRegister(), newScope);
1957 pushScopedControlFlowContext();
1960 bool isWithScope = false;
1961 m_symbolTableStack.append(SymbolTableStackEntry{ symbolTable, newScope, isWithScope, symbolTableConstantIndex });
1962 pushTDZVariables(environment, tdzCheckOptimization, tdzRequirement);
1964 if (tdzRequirement == TDZRequirement::UnderTDZ)
1965 emitPrefillStackTDZVariables(environment, symbolTable);
1968 void BytecodeGenerator::initializeBlockScopedFunctions(VariableEnvironment& environment, FunctionStack& functionStack, RegisterID* constantSymbolTable)
1971 * We must transform block scoped function declarations in strict mode like so:
1975 * function foo() { ... }
1978 * function baz() { ... }
1986 * let foo = function foo() { ... }
1987 * let baz = function baz() { ... }
1993 * But without the TDZ checks.
1996 if (!environment.size()) {
1997 RELEASE_ASSERT(!functionStack.size());
2001 if (!functionStack.size())
2004 SymbolTable* symbolTable = m_symbolTableStack.last().m_symbolTable;
2005 RegisterID* scope = m_symbolTableStack.last().m_scope;
2006 RefPtr<RegisterID> temp = newTemporary();
2007 int symbolTableIndex = constantSymbolTable ? constantSymbolTable->index() : 0;
2008 for (FunctionMetadataNode* function : functionStack) {
2009 const Identifier& name = function->ident();
2010 auto iter = environment.find(name.impl());
2011 RELEASE_ASSERT(iter != environment.end());
2012 RELEASE_ASSERT(iter->value.isFunction());
2013 // We purposefully don't hold the symbol table lock around this loop because emitNewFunctionExpressionCommon may GC.
2014 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, name.impl());
2015 RELEASE_ASSERT(!entry.isNull());
2016 emitNewFunctionExpressionCommon(temp.get(), function);
2017 bool isLexicallyScoped = true;
2018 emitPutToScope(scope, variableForLocalEntry(name, entry, symbolTableIndex, isLexicallyScoped), temp.get(), DoNotThrowIfNotFound, InitializationMode::Initialization);
2022 void BytecodeGenerator::hoistSloppyModeFunctionIfNecessary(const Identifier& functionName)
2024 if (m_scopeNode->hasSloppyModeHoistedFunction(functionName.impl())) {
2025 Variable currentFunctionVariable = variable(functionName);
2026 RefPtr<RegisterID> currentValue;
2027 if (RegisterID* local = currentFunctionVariable.local())
2028 currentValue = local;
2030 RefPtr<RegisterID> scope = emitResolveScope(nullptr, currentFunctionVariable);
2031 currentValue = emitGetFromScope(newTemporary(), scope.get(), currentFunctionVariable, DoNotThrowIfNotFound);
2034 ASSERT(m_varScopeSymbolTableIndex);
2035 ASSERT(*m_varScopeSymbolTableIndex < m_symbolTableStack.size());
2036 SymbolTableStackEntry& varScope = m_symbolTableStack[*m_varScopeSymbolTableIndex];
2037 SymbolTable* varSymbolTable = varScope.m_symbolTable;
2038 ASSERT(varSymbolTable->scopeType() == SymbolTable::ScopeType::VarScope);
2039 SymbolTableEntry entry = varSymbolTable->get(NoLockingNecessary, functionName.impl());
2040 ASSERT(!entry.isNull());
2041 bool isLexicallyScoped = false;
2042 emitPutToScope(varScope.m_scope, variableForLocalEntry(functionName, entry, varScope.m_symbolTableConstantIndex, isLexicallyScoped), currentValue.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2046 void BytecodeGenerator::popLexicalScope(VariableEnvironmentNode* node)
2048 VariableEnvironment& environment = node->lexicalVariables();
2049 popLexicalScopeInternal(environment);
2052 void BytecodeGenerator::popLexicalScopeInternal(VariableEnvironment& environment)
2054 // NOTE: This function only makes sense for scopes that aren't ScopeRegisterType::Var (only function name scope right now is ScopeRegisterType::Var).
2055 // This doesn't make sense for ScopeRegisterType::Var because we deref RegisterIDs here.
2056 if (!environment.size())
2059 if (m_shouldEmitDebugHooks)
2060 environment.markAllVariablesAsCaptured();
2062 SymbolTableStackEntry stackEntry = m_symbolTableStack.takeLast();
2063 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2064 bool hasCapturedVariables = false;
2065 for (auto& entry : environment) {
2066 if (entry.value.isCaptured()) {
2067 hasCapturedVariables = true;
2070 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
2071 ASSERT(!symbolTableEntry.isNull());
2072 VarOffset offset = symbolTableEntry.varOffset();
2073 ASSERT(offset.isStack());
2074 RegisterID* local = ®isterFor(offset.stackOffset());
2078 if (hasCapturedVariables) {
2079 RELEASE_ASSERT(stackEntry.m_scope);
2080 emitPopScope(scopeRegister(), stackEntry.m_scope);
2081 popScopedControlFlowContext();
2082 stackEntry.m_scope->deref();
2085 m_TDZStack.removeLast();
2088 void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode* node, RegisterID* loopSymbolTable)
2090 VariableEnvironment& environment = node->lexicalVariables();
2091 if (!environment.size())
2093 if (m_shouldEmitDebugHooks)
2094 environment.markAllVariablesAsCaptured();
2095 if (!environment.hasCapturedVariables())
2098 RELEASE_ASSERT(loopSymbolTable);
2100 // This function needs to do setup for a for loop's activation if any of
2101 // the for loop's lexically declared variables are captured (that is, variables
2102 // declared in the loop header, not the loop body). This function needs to
2103 // make a copy of the current activation and copy the values from the previous
2104 // activation into the new activation because each iteration of a for loop
2105 // gets a new activation.
2107 SymbolTableStackEntry stackEntry = m_symbolTableStack.last();
2108 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2109 RegisterID* loopScope = stackEntry.m_scope;
2110 ASSERT(symbolTable->scopeSize());
2112 Vector<std::pair<RegisterID*, Identifier>> activationValuesToCopyOver;
2115 activationValuesToCopyOver.reserveInitialCapacity(symbolTable->scopeSize());
2117 for (auto end = symbolTable->end(NoLockingNecessary), ptr = symbolTable->begin(NoLockingNecessary); ptr != end; ++ptr) {
2118 if (!ptr->value.varOffset().isScope())
2121 RefPtr<UniquedStringImpl> ident = ptr->key;
2122 Identifier identifier = Identifier::fromUid(m_vm, ident.get());
2124 RegisterID* transitionValue = newBlockScopeVariable();
2125 transitionValue->ref();
2126 emitGetFromScope(transitionValue, loopScope, variableForLocalEntry(identifier, ptr->value, loopSymbolTable->index(), true), DoNotThrowIfNotFound);
2127 activationValuesToCopyOver.uncheckedAppend(std::make_pair(transitionValue, identifier));
2131 // We need this dynamic behavior of the executing code to ensure
2132 // each loop iteration has a new activation object. (It's pretty ugly).
2133 // Also, this new activation needs to be assigned to the same register
2134 // as the previous scope because the loop body is compiled under
2135 // the assumption that the scope's register index is constant even
2136 // though the value in that register will change on each loop iteration.
2137 RefPtr<RegisterID> parentScope = emitGetParentScope(newTemporary(), loopScope);
2138 emitMove(scopeRegister(), parentScope.get());
2140 emitOpcode(op_create_lexical_environment);
2141 instructions().append(loopScope->index());
2142 instructions().append(scopeRegister()->index());
2143 instructions().append(loopSymbolTable->index());
2144 instructions().append(addConstantValue(jsTDZValue())->index());
2146 emitMove(scopeRegister(), loopScope);
2149 for (auto pair : activationValuesToCopyOver) {
2150 const Identifier& identifier = pair.second;
2151 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, identifier.impl());
2152 RELEASE_ASSERT(!entry.isNull());
2153 RegisterID* transitionValue = pair.first;
2154 emitPutToScope(loopScope, variableForLocalEntry(identifier, entry, loopSymbolTable->index(), true), transitionValue, DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2155 transitionValue->deref();
2160 Variable BytecodeGenerator::variable(const Identifier& property, ThisResolutionType thisResolutionType)
2162 if (property == propertyNames().thisIdentifier && thisResolutionType == ThisResolutionType::Local) {
2163 return Variable(property, VarOffset(thisRegister()->virtualRegister()), thisRegister(),
2164 ReadOnly, Variable::SpecialVariable, 0, false);
2167 // We can optimize lookups if the lexical variable is found before a "with" or "catch"
2168 // scope because we're guaranteed static resolution. If we have to pass through
2169 // a "with" or "catch" scope we loose this guarantee.
2170 // We can't optimize cases like this:
2174 // doSomethingWith(x);
2177 // Because we can't gaurantee static resolution on x.
2178 // But, in this case, we are guaranteed static resolution:
2183 // doSomethingWith(x);
2186 for (unsigned i = m_symbolTableStack.size(); i--; ) {
2187 SymbolTableStackEntry& stackEntry = m_symbolTableStack[i];
2188 if (stackEntry.m_isWithScope)
2189 return Variable(property);
2190 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2191 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, property.impl());
2192 if (symbolTableEntry.isNull())
2194 bool resultIsCallee = false;
2195 if (symbolTable->scopeType() == SymbolTable::ScopeType::FunctionNameScope) {
2196 if (m_usesNonStrictEval) {
2197 // We don't know if an eval has introduced a "var" named the same thing as the function name scope variable name.
2198 // We resort to dynamic lookup to answer this question.
2199 Variable result = Variable(property);
2202 resultIsCallee = true;
2204 Variable result = variableForLocalEntry(property, symbolTableEntry, stackEntry.m_symbolTableConstantIndex, symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope);
2206 result.setIsReadOnly();
2210 return Variable(property);
2213 Variable BytecodeGenerator::variableForLocalEntry(
2214 const Identifier& property, const SymbolTableEntry& entry, int symbolTableConstantIndex, bool isLexicallyScoped)
2216 VarOffset offset = entry.varOffset();
2219 if (offset.isStack())
2220 local = ®isterFor(offset.stackOffset());
2224 return Variable(property, offset, local, entry.getAttributes(), Variable::NormalVariable, symbolTableConstantIndex, isLexicallyScoped);
2227 void BytecodeGenerator::createVariable(
2228 const Identifier& property, VarKind varKind, SymbolTable* symbolTable, ExistingVariableMode existingVariableMode)
2230 ASSERT(property != propertyNames().thisIdentifier);
2231 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, property.impl());
2233 if (!entry.isNull()) {
2234 if (existingVariableMode == IgnoreExisting)
2237 // Do some checks to ensure that the variable we're being asked to create is sufficiently
2238 // compatible with the one we have already created.
2240 VarOffset offset = entry.varOffset();
2242 // We can't change our minds about whether it's captured.
2243 if (offset.kind() != varKind) {
2245 "Trying to add variable called ", property, " as ", varKind,
2246 " but it was already added as ", offset, ".\n");
2247 RELEASE_ASSERT_NOT_REACHED();
2253 VarOffset varOffset;
2254 if (varKind == VarKind::Scope)
2255 varOffset = VarOffset(symbolTable->takeNextScopeOffset(NoLockingNecessary));
2257 ASSERT(varKind == VarKind::Stack);
2258 varOffset = VarOffset(virtualRegisterForLocal(m_calleeLocals.size()));
2260 SymbolTableEntry newEntry(varOffset, 0);
2261 symbolTable->add(NoLockingNecessary, property.impl(), newEntry);
2263 if (varKind == VarKind::Stack) {
2264 RegisterID* local = addVar();
2265 RELEASE_ASSERT(local->index() == varOffset.stackOffset().offset());
2269 RegisterID* BytecodeGenerator::emitOverridesHasInstance(RegisterID* dst, RegisterID* constructor, RegisterID* hasInstanceValue)
2271 emitOpcode(op_overrides_has_instance);
2272 instructions().append(dst->index());
2273 instructions().append(constructor->index());
2274 instructions().append(hasInstanceValue->index());
2278 // Indicates the least upper bound of resolve type based on local scope. The bytecode linker
2279 // will start with this ResolveType and compute the least upper bound including intercepting scopes.
2280 ResolveType BytecodeGenerator::resolveType()
2282 for (unsigned i = m_symbolTableStack.size(); i--; ) {
2283 if (m_symbolTableStack[i].m_isWithScope)
2285 if (m_usesNonStrictEval && m_symbolTableStack[i].m_symbolTable->scopeType() == SymbolTable::ScopeType::FunctionNameScope) {
2286 // We never want to assign to a FunctionNameScope. Returning Dynamic here achieves this goal.
2287 // If we aren't in non-strict eval mode, then NodesCodeGen needs to take care not to emit
2288 // a put_to_scope with the destination being the function name scope variable.
2293 if (m_usesNonStrictEval)
2294 return GlobalPropertyWithVarInjectionChecks;
2295 return GlobalProperty;
2298 RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& variable)
2300 switch (variable.offset().kind()) {
2301 case VarKind::Stack:
2304 case VarKind::DirectArgument:
2305 return argumentsRegister();
2307 case VarKind::Scope: {
2308 // This always refers to the activation that *we* allocated, and not the current scope that code
2309 // lives in. Note that this will change once we have proper support for block scoping. Once that
2310 // changes, it will be correct for this code to return scopeRegister(). The only reason why we
2311 // don't do that already is that m_lexicalEnvironment is required by ConstDeclNode. ConstDeclNode
2312 // requires weird things because it is a shameful pile of nonsense, but block scoping would make
2313 // that code sensible and obviate the need for us to do bad things.
2314 for (unsigned i = m_symbolTableStack.size(); i--; ) {
2315 SymbolTableStackEntry& stackEntry = m_symbolTableStack[i];
2316 // We should not resolve a variable to VarKind::Scope if a "with" scope lies in between the current
2317 // scope and the resolved scope.
2318 RELEASE_ASSERT(!stackEntry.m_isWithScope);
2320 if (stackEntry.m_symbolTable->get(NoLockingNecessary, variable.ident().impl()).isNull())
2323 RegisterID* scope = stackEntry.m_scope;
2324 RELEASE_ASSERT(scope);
2328 RELEASE_ASSERT_NOT_REACHED();
2332 case VarKind::Invalid:
2333 // Indicates non-local resolution.
2335 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2337 // resolve_scope dst, id, ResolveType, depth
2338 dst = tempDestination(dst);
2339 emitOpcode(op_resolve_scope);
2340 instructions().append(kill(dst));
2341 instructions().append(scopeRegister()->index());
2342 instructions().append(addConstant(variable.ident()));
2343 instructions().append(resolveType());
2344 instructions().append(localScopeDepth());
2345 instructions().append(0);
2349 RELEASE_ASSERT_NOT_REACHED();
2353 RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable& variable, ResolveMode resolveMode)
2355 switch (variable.offset().kind()) {
2356 case VarKind::Stack:
2357 return emitMove(dst, variable.local());
2359 case VarKind::DirectArgument: {
2360 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_arguments);
2361 instructions().append(kill(dst));
2362 instructions().append(scope->index());
2363 instructions().append(variable.offset().capturedArgumentsOffset().offset());
2364 instructions().append(profile);
2368 case VarKind::Scope:
2369 case VarKind::Invalid: {
2370 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2372 // get_from_scope dst, scope, id, GetPutInfo, Structure, Operand
2373 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
2374 instructions().append(kill(dst));
2375 instructions().append(scope->index());
2376 instructions().append(addConstant(variable.ident()));
2377 instructions().append(GetPutInfo(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType(), InitializationMode::NotInitialization).operand());
2378 instructions().append(localScopeDepth());
2379 instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
2380 instructions().append(profile);
2384 RELEASE_ASSERT_NOT_REACHED();
2387 RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode, InitializationMode initializationMode)
2389 switch (variable.offset().kind()) {
2390 case VarKind::Stack:
2391 emitMove(variable.local(), value);
2394 case VarKind::DirectArgument:
2395 emitOpcode(op_put_to_arguments);
2396 instructions().append(scope->index());
2397 instructions().append(variable.offset().capturedArgumentsOffset().offset());
2398 instructions().append(value->index());
2401 case VarKind::Scope:
2402 case VarKind::Invalid: {
2403 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2405 // put_to_scope scope, id, value, GetPutInfo, Structure, Operand
2406 emitOpcode(op_put_to_scope);
2407 instructions().append(scope->index());
2408 instructions().append(addConstant(variable.ident()));
2409 instructions().append(value->index());
2411 if (variable.offset().isScope()) {
2412 offset = variable.offset().scopeOffset();
2413 instructions().append(GetPutInfo(resolveMode, LocalClosureVar, initializationMode).operand());
2414 instructions().append(variable.symbolTableConstantIndex());
2416 ASSERT(resolveType() != LocalClosureVar);
2417 instructions().append(GetPutInfo(resolveMode, resolveType(), initializationMode).operand());
2418 instructions().append(localScopeDepth());
2420 instructions().append(!!offset ? offset.offset() : 0);
2424 RELEASE_ASSERT_NOT_REACHED();
2427 RegisterID* BytecodeGenerator::initializeVariable(const Variable& variable, RegisterID* value)
2429 RELEASE_ASSERT(variable.offset().kind() != VarKind::Invalid);
2430 RegisterID* scope = emitResolveScope(nullptr, variable);
2431 return emitPutToScope(scope, variable, value, ThrowIfNotFound, InitializationMode::NotInitialization);
2434 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
2436 emitOpcode(op_instanceof);
2437 instructions().append(dst->index());
2438 instructions().append(value->index());
2439 instructions().append(basePrototype->index());
2443 RegisterID* BytecodeGenerator::emitInstanceOfCustom(RegisterID* dst, RegisterID* value, RegisterID* constructor, RegisterID* hasInstanceValue)
2445 emitOpcode(op_instanceof_custom);
2446 instructions().append(dst->index());
2447 instructions().append(value->index());
2448 instructions().append(constructor->index());
2449 instructions().append(hasInstanceValue->index());
2453 RegisterID* BytecodeGenerator::emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
2455 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties are not supported with tryGetById.");
2457 emitOpcode(op_try_get_by_id);
2458 instructions().append(kill(dst));
2459 instructions().append(base->index());
2460 instructions().append(addConstant(property));
2464 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
2466 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
2468 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2470 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id);
2471 instructions().append(kill(dst));
2472 instructions().append(base->index());
2473 instructions().append(addConstant(property));
2474 instructions().append(0);
2475 instructions().append(0);
2476 instructions().append(0);
2477 instructions().append(Options::prototypeHitCountForLLIntCaching());
2478 instructions().append(profile);
2482 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, RegisterID* thisVal, const Identifier& property)
2484 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
2486 emitOpcode(op_get_by_id_with_this);
2487 instructions().append(kill(dst));
2488 instructions().append(base->index());
2489 instructions().append(thisVal->index());
2490 instructions().append(addConstant(property));
2494 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
2496 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val.");
2498 unsigned propertyIndex = addConstant(property);
2500 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2502 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2504 emitOpcode(op_put_by_id);
2505 instructions().append(base->index());
2506 instructions().append(propertyIndex);
2507 instructions().append(value->index());
2508 instructions().append(0); // old structure
2509 instructions().append(0); // offset
2510 instructions().append(0); // new structure
2511 instructions().append(0); // structure chain
2512 instructions().append(static_cast<int>(PutByIdNone)); // is not direct
2517 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, RegisterID* thisValue, const Identifier& property, RegisterID* value)
2519 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val.");
2521 unsigned propertyIndex = addConstant(property);
2523 emitOpcode(op_put_by_id_with_this);
2524 instructions().append(base->index());
2525 instructions().append(thisValue->index());
2526 instructions().append(propertyIndex);
2527 instructions().append(value->index());
2532 RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType putType)
2534 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val(direct).");
2536 unsigned propertyIndex = addConstant(property);
2538 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2540 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2542 emitOpcode(op_put_by_id);
2543 instructions().append(base->index());
2544 instructions().append(propertyIndex);
2545 instructions().append(value->index());
2546 instructions().append(0); // old structure
2547 instructions().append(0); // offset
2548 instructions().append(0); // new structure
2549 instructions().append(0); // structure chain (unused if direct)
2550 instructions().append(static_cast<int>((putType == PropertyNode::KnownDirect || property != m_vm->propertyNames->underscoreProto) ? PutByIdIsDirect : PutByIdNone));
2554 void BytecodeGenerator::emitPutGetterById(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter)
2556 unsigned propertyIndex = addConstant(property);
2557 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2559 emitOpcode(op_put_getter_by_id);
2560 instructions().append(base->index());
2561 instructions().append(propertyIndex);
2562 instructions().append(attributes);
2563 instructions().append(getter->index());
2566 void BytecodeGenerator::emitPutSetterById(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* setter)
2568 unsigned propertyIndex = addConstant(property);
2569 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2571 emitOpcode(op_put_setter_by_id);
2572 instructions().append(base->index());
2573 instructions().append(propertyIndex);
2574 instructions().append(attributes);
2575 instructions().append(setter->index());
2578 void BytecodeGenerator::emitPutGetterSetter(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter, RegisterID* setter)
2580 unsigned propertyIndex = addConstant(property);
2582 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2584 emitOpcode(op_put_getter_setter_by_id);
2585 instructions().append(base->index());
2586 instructions().append(propertyIndex);
2587 instructions().append(attributes);
2588 instructions().append(getter->index());
2589 instructions().append(setter->index());
2592 void BytecodeGenerator::emitPutGetterByVal(RegisterID* base, RegisterID* property, unsigned attributes, RegisterID* getter)
2594 emitOpcode(op_put_getter_by_val);
2595 instructions().append(base->index());
2596 instructions().append(property->index());
2597 instructions().append(attributes);
2598 instructions().append(getter->index());
2601 void BytecodeGenerator::emitPutSetterByVal(RegisterID* base, RegisterID* property, unsigned attributes, RegisterID* setter)
2603 emitOpcode(op_put_setter_by_val);
2604 instructions().append(base->index());
2605 instructions().append(property->index());
2606 instructions().append(attributes);
2607 instructions().append(setter->index());
2610 RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
2612 emitOpcode(op_del_by_id);
2613 instructions().append(dst->index());
2614 instructions().append(base->index());
2615 instructions().append(addConstant(property));
2619 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
2621 for (size_t i = m_forInContextStack.size(); i > 0; i--) {
2622 ForInContext* context = m_forInContextStack[i - 1].get();
2623 if (context->local() != property)
2626 if (!context->isValid())
2629 if (context->type() == ForInContext::IndexedForInContextType) {
2630 property = static_cast<IndexedForInContext*>(context)->index();
2634 ASSERT(context->type() == ForInContext::StructureForInContextType);
2635 StructureForInContext* structureContext = static_cast<StructureForInContext*>(context);
2636 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_direct_pname);
2637 instructions().append(kill(dst));
2638 instructions().append(base->index());
2639 instructions().append(property->index());
2640 instructions().append(structureContext->index()->index());
2641 instructions().append(structureContext->enumerator()->index());
2642 instructions().append(profile);
2646 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2647 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val);
2648 instructions().append(kill(dst));
2649 instructions().append(base->index());
2650 instructions().append(property->index());
2651 instructions().append(arrayProfile);
2652 instructions().append(profile);
2656 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property)
2658 emitOpcode(op_get_by_val_with_this);
2659 instructions().append(kill(dst));
2660 instructions().append(base->index());
2661 instructions().append(thisValue->index());
2662 instructions().append(property->index());
2666 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
2668 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2669 emitOpcode(op_put_by_val);
2670 instructions().append(base->index());
2671 instructions().append(property->index());
2672 instructions().append(value->index());
2673 instructions().append(arrayProfile);
2678 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value)
2680 emitOpcode(op_put_by_val_with_this);
2681 instructions().append(base->index());
2682 instructions().append(thisValue->index());
2683 instructions().append(property->index());
2684 instructions().append(value->index());
2689 RegisterID* BytecodeGenerator::emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
2691 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2692 emitOpcode(op_put_by_val_direct);
2693 instructions().append(base->index());
2694 instructions().append(property->index());
2695 instructions().append(value->index());
2696 instructions().append(arrayProfile);
2700 RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
2702 emitOpcode(op_del_by_val);
2703 instructions().append(dst->index());
2704 instructions().append(base->index());
2705 instructions().append(property->index());
2709 RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
2711 emitOpcode(op_put_by_index);
2712 instructions().append(base->index());
2713 instructions().append(index);
2714 instructions().append(value->index());
2718 RegisterID* BytecodeGenerator::emitAssert(RegisterID* condition, int line)
2720 emitOpcode(op_assert);
2721 instructions().append(condition->index());
2722 instructions().append(line);
2726 RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
2728 size_t begin = instructions().size();
2729 m_staticPropertyAnalyzer.createThis(dst->index(), begin + 3);
2731 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2732 emitOpcode(op_create_this);
2733 instructions().append(dst->index());
2734 instructions().append(dst->index());
2735 instructions().append(0);
2736 instructions().append(0);
2740 void BytecodeGenerator::emitTDZCheck(RegisterID* target)
2742 emitOpcode(op_check_tdz);
2743 instructions().append(target->index());
2746 bool BytecodeGenerator::needsTDZCheck(const Variable& variable)
2748 for (unsigned i = m_TDZStack.size(); i--;) {
2749 auto iter = m_TDZStack[i].find(variable.ident().impl());
2750 if (iter == m_TDZStack[i].end())
2752 return iter->value != TDZNecessityLevel::NotNeeded;
2758 void BytecodeGenerator::emitTDZCheckIfNecessary(const Variable& variable, RegisterID* target, RegisterID* scope)
2760 if (needsTDZCheck(variable)) {
2762 emitTDZCheck(target);
2764 RELEASE_ASSERT(!variable.isLocal() && scope);
2765 RefPtr<RegisterID> result = emitGetFromScope(newTemporary(), scope, variable, DoNotThrowIfNotFound);
2766 emitTDZCheck(result.get());
2771 void BytecodeGenerator::liftTDZCheckIfPossible(const Variable& variable)
2773 RefPtr<UniquedStringImpl> identifier(variable.ident().impl());
2774 for (unsigned i = m_TDZStack.size(); i--;) {
2775 auto iter = m_TDZStack[i].find(identifier);
2776 if (iter != m_TDZStack[i].end()) {
2777 if (iter->value == TDZNecessityLevel::Optimize)
2778 iter->value = TDZNecessityLevel::NotNeeded;
2784 void BytecodeGenerator::pushTDZVariables(const VariableEnvironment& environment, TDZCheckOptimization optimization, TDZRequirement requirement)
2786 if (!environment.size())
2789 TDZNecessityLevel level;
2790 if (requirement == TDZRequirement::UnderTDZ) {
2791 if (optimization == TDZCheckOptimization::Optimize)
2792 level = TDZNecessityLevel::Optimize;
2794 level = TDZNecessityLevel::DoNotOptimize;
2796 level = TDZNecessityLevel::NotNeeded;
2799 for (const auto& entry : environment)
2800 map.add(entry.key, entry.value.isFunction() ? TDZNecessityLevel::NotNeeded : level);
2802 m_TDZStack.append(WTFMove(map));
2805 void BytecodeGenerator::getVariablesUnderTDZ(VariableEnvironment& result)
2807 // We keep track of variablesThatDontNeedTDZ in this algorithm to prevent
2808 // reporting that "x" is under TDZ if this function is called at "...".
2818 SmallPtrSet<UniquedStringImpl*, 16> variablesThatDontNeedTDZ;
2819 for (unsigned i = m_TDZStack.size(); i--; ) {
2820 auto& map = m_TDZStack[i];
2821 for (auto& entry : map) {
2822 if (entry.value != TDZNecessityLevel::NotNeeded) {
2823 if (!variablesThatDontNeedTDZ.contains(entry.key.get()))
2824 result.add(entry.key.get());
2826 variablesThatDontNeedTDZ.add(entry.key.get());
2831 RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
2833 size_t begin = instructions().size();
2834 m_staticPropertyAnalyzer.newObject(dst->index(), begin + 2);
2836 emitOpcode(op_new_object);
2837 instructions().append(dst->index());
2838 instructions().append(0);
2839 instructions().append(newObjectAllocationProfile());
2843 unsigned BytecodeGenerator::addConstantBuffer(unsigned length)
2845 return m_codeBlock->addConstantBuffer(length);
2848 JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
2850 JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
2852 stringInMap = jsString(vm(), identifier.string());
2853 addConstantValue(stringInMap);
2858 JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(const TemplateRegistryKey& templateRegistryKey)
2860 JSTemplateRegistryKey*& templateRegistryKeyInMap = m_templateRegistryKeyMap.add(templateRegistryKey, nullptr).iterator->value;
2861 if (!templateRegistryKeyInMap) {
2862 templateRegistryKeyInMap = JSTemplateRegistryKey::create(*vm(), templateRegistryKey);
2863 addConstantValue(templateRegistryKeyInMap);
2865 return templateRegistryKeyInMap;
2868 RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
2870 #if !ASSERT_DISABLED
2871 unsigned checkLength = 0;
2873 bool hadVariableExpression = false;
2875 for (ElementNode* n = elements; n; n = n->next()) {
2876 if (!n->value()->isConstant()) {
2877 hadVariableExpression = true;
2882 #if !ASSERT_DISABLED
2886 if (!hadVariableExpression) {
2887 ASSERT(length == checkLength);
2888 unsigned constantBufferIndex = addConstantBuffer(length);
2889 JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex).data();
2891 for (ElementNode* n = elements; index < length; n = n->next()) {
2892 ASSERT(n->value()->isConstant());
2893 constantBuffer[index++] = static_cast<ConstantNode*>(n->value())->jsValue(*this);
2895 emitOpcode(op_new_array_buffer);
2896 instructions().append(dst->index());
2897 instructions().append(constantBufferIndex);
2898 instructions().append(length);
2899 instructions().append(newArrayAllocationProfile());
2904 Vector<RefPtr<RegisterID>, 16, UnsafeVectorOverflow> argv;
2905 for (ElementNode* n = elements; n; n = n->next()) {
2909 ASSERT(!n->value()->isSpreadExpression());
2910 argv.append(newTemporary());
2911 // op_new_array requires the initial values to be a sequential range of registers
2912 ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() - 1);
2913 emitNode(argv.last().get(), n->value());
2916 emitOpcode(op_new_array);
2917 instructions().append(dst->index());
2918 instructions().append(argv.size() ? argv[0]->index() : 0); // argv
2919 instructions().append(argv.size()); // argc
2920 instructions().append(newArrayAllocationProfile());
2924 RegisterID* BytecodeGenerator::emitNewArrayWithSize(RegisterID* dst, RegisterID* length)
2926 emitOpcode(op_new_array_with_size);
2927 instructions().append(dst->index());
2928 instructions().append(length->index());
2929 instructions().append(newArrayAllocationProfile());
2934 RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
2936 emitOpcode(op_new_regexp);
2937 instructions().append(dst->index());
2938 instructions().append(addRegExp(regExp));
2942 void BytecodeGenerator::emitNewFunctionExpressionCommon(RegisterID* dst, FunctionMetadataNode* function)
2944 unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function));
2946 OpcodeID opcodeID = op_new_func_exp;
2947 switch (function->parseMode()) {
2948 case SourceParseMode::GeneratorWrapperFunctionMode:
2949 opcodeID = op_new_generator_func_exp;
2955 emitOpcode(opcodeID);
2956 instructions().append(dst->index());
2957 instructions().append(scopeRegister()->index());
2958 instructions().append(index);
2961 RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func)
2963 emitNewFunctionExpressionCommon(dst, func->metadata());
2967 RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func)
2969 ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode);
2970 emitNewFunctionExpressionCommon(dst, func->metadata());
2974 RegisterID* BytecodeGenerator::emitNewMethodDefinition(RegisterID* dst, MethodDefinitionNode* func)
2976 ASSERT(func->metadata()->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode
2977 || func->metadata()->parseMode() == SourceParseMode::GetterMode
2978 || func->metadata()->parseMode() == SourceParseMode::SetterMode
2979 || func->metadata()->parseMode() == SourceParseMode::MethodMode);
2980 emitNewFunctionExpressionCommon(dst, func->metadata());
2984 RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier& name,
2985 const Identifier& ecmaName, const SourceCode& classSource)
2987 UnlinkedFunctionExecutable* executable = m_vm->builtinExecutables()->createDefaultConstructor(constructorKind, name);
2988 executable->setInvalidTypeProfilingOffsets();
2989 executable->setEcmaName(ecmaName);
2990 executable->setClassSource(classSource);
2992 unsigned index = m_codeBlock->addFunctionExpr(executable);
2994 emitOpcode(op_new_func_exp);
2995 instructions().append(dst->index());
2996 instructions().append(scopeRegister()->index());
2997 instructions().append(index);
3001 RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionMetadataNode* function)
3003 unsigned index = m_codeBlock->addFunctionDecl(makeFunction(function));
3004 if (function->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode)
3005 emitOpcode(op_new_generator_func);
3007 emitOpcode(op_new_func);
3008 instructions().append(dst->index());
3009 instructions().append(scopeRegister()->index());
3010 instructions().append(index);
3014 void BytecodeGenerator::emitSetFunctionNameIfNeeded(ExpressionNode* valueNode, RegisterID* value, RegisterID* name)
3016 if (valueNode->isFuncExprNode()) {
3017 FunctionMetadataNode* metadata = static_cast<FuncExprNode*>(valueNode)->metadata();
3018 if (!metadata->ecmaName().isNull())
3020 } else if (valueNode->isClassExprNode()) {
3021 ClassExprNode* classExprNode = static_cast<ClassExprNode*>(valueNode);
3022 if (!classExprNode->ecmaName().isNull())
3024 if (classExprNode->hasStaticProperty(m_vm->propertyNames->name))
3029 // FIXME: We should use an op_call to an internal function here instead.
3030 // https://bugs.webkit.org/show_bug.cgi?id=155547
3031 emitOpcode(op_set_function_name);
3032 instructions().append(value->index());
3033 instructions().append(name->index());
3036 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
3038 return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
3041 RegisterID* BytecodeGenerator::emitCallInTailPosition(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
3043 return emitCall(m_inTailPosition ? op_tail_call : op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
3046 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
3048 return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, divotStart, divotEnd);
3051 ExpectedFunction BytecodeGenerator::expectedFunctionForIdentifier(const Identifier& identifier)
3053 if (identifier == propertyNames().Object || identifier == propertyNames().builtinNames().ObjectPrivateName())
3054 return ExpectObjectConstructor;
3055 if (identifier == propertyNames().Array || identifier == propertyNames().builtinNames().ArrayPrivateName())
3056 return ExpectArrayConstructor;
3057 return NoExpectedFunction;
3060 ExpectedFunction BytecodeGenerator::emitExpectedFunctionSnippet(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, Label* done)
3062 RefPtr<Label> realCall = newLabel();
3063 switch (expectedFunction) {
3064 case ExpectObjectConstructor: {
3065 // If the number of arguments is non-zero, then we can't do anything interesting.
3066 if (callArguments.argumentCountIncludingThis() >= 2)
3067 return NoExpectedFunction;
3069 size_t begin = instructions().size();
3070 emitOpcode(op_jneq_ptr);
3071 instructions().append(func->index());
3072 instructions().append(Special::ObjectConstructor);
3073 instructions().append(realCall->bind(begin, instructions().size()));
3074 instructions().append(0);
3076 if (dst != ignoredResult())
3081 case ExpectArrayConstructor: {
3082 // If you're doing anything other than "new Array()" or "new Array(foo)" then we
3083 // don't do inline it, for now. The only reason is that call arguments are in
3084 // the opposite order of what op_new_array expects, so we'd either need to change
3085 // how op_new_array works or we'd need an op_new_array_reverse. Neither of these
3086 // things sounds like it's worth it.
3087 if (callArguments.argumentCountIncludingThis() > 2)
3088 return NoExpectedFunction;
3090 size_t begin = instructions().size();
3091 emitOpcode(op_jneq_ptr);
3092 instructions().append(func->index());
3093 instructions().append(Special::ArrayConstructor);
3094 instructions().append(realCall->bind(begin, instructions().size()));
3095 instructions().append(0);
3097 if (dst != ignoredResult()) {
3098 if (callArguments.argumentCountIncludingThis() == 2)
3099 emitNewArrayWithSize(dst, callArguments.argumentRegister(0));
3101 ASSERT(callArguments.argumentCountIncludingThis() == 1);
3102 emitOpcode(op_new_array);
3103 instructions().append(dst->index());
3104 instructions().append(0);
3105 instructions().append(0);
3106 instructions().append(newArrayAllocationProfile());
3113 ASSERT(expectedFunction == NoExpectedFunction);
3114 return NoExpectedFunction;
3117 size_t begin = instructions().size();
3119 instructions().append(done->bind(begin, instructions().size()));
3120 emitLabel(realCall.get());
3122 return expectedFunction;
3125 RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
3127 ASSERT(opcodeID == op_call || opcodeID == op_call_eval || opcodeID == op_tail_call);
3128 ASSERT(func->refCount());
3130 // Generate code for arguments.
3131 unsigned argument = 0;
3132 if (callArguments.argumentsNode()) {
3133 ArgumentListNode* n = callArguments.argumentsNode()->m_listNode;
3134 if (n && n->m_expr->isSpreadExpression()) {
3135 RELEASE_ASSERT(!n->m_next);
3136 auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
3137 RefPtr<RegisterID> argumentRegister;
3138 argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
3139 RefPtr<RegisterID> thisRegister = emitMove(newTemporary(), callArguments.thisRegister());
3140 return emitCallVarargs(opcodeID == op_tail_call ? op_tail_call_varargs : op_call_varargs, dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, divot, divotStart, divotEnd);
3142 for (; n; n = n->m_next)
3143 emitNode(callArguments.argumentRegister(argument++), n);
3146 // Reserve space for call frame.
3147 Vector<RefPtr<RegisterID>, CallFrame::headerSizeInRegisters, UnsafeVectorOverflow> callFrame;
3148 for (int i = 0; i < CallFrame::headerSizeInRegisters; ++i)
3149 callFrame.append(newTemporary());
3151 emitExpressionInfo(divot, divotStart, divotEnd);
3153 RefPtr<Label> done = newLabel();
3154 expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
3156 if (opcodeID == op_tail_call)
3157 emitLogShadowChickenTailIfNecessary();
3160 UnlinkedArrayProfile arrayProfile = newArrayProfile();
3161 UnlinkedValueProfile profile = emitProfiledOpcode(opcodeID);
3163 ASSERT(dst != ignoredResult());
3164 instructions().append(dst->index());
3165 instructions().append(func->index());