2 * Copyright (C) 2008-2017 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 "BuiltinNames.h"
37 #include "BytecodeGeneratorification.h"
38 #include "BytecodeLivenessAnalysis.h"
39 #include "DefinePropertyAttributes.h"
40 #include "Interpreter.h"
41 #include "JSAsyncGeneratorFunction.h"
42 #include "JSCInlines.h"
43 #include "JSFunction.h"
44 #include "JSGeneratorFunction.h"
45 #include "JSLexicalEnvironment.h"
46 #include "JSTemplateRegistryKey.h"
47 #include "LowLevelInterpreter.h"
49 #include "StackAlignment.h"
50 #include "StrongInlines.h"
51 #include "SuperSamplerBytecodeScope.h"
52 #include "UnlinkedCodeBlock.h"
53 #include "UnlinkedEvalCodeBlock.h"
54 #include "UnlinkedFunctionCodeBlock.h"
55 #include "UnlinkedInstructionStream.h"
56 #include "UnlinkedModuleProgramCodeBlock.h"
57 #include "UnlinkedProgramCodeBlock.h"
58 #include <wtf/BitVector.h>
59 #include <wtf/CommaPrinter.h>
60 #include <wtf/SmallPtrSet.h>
61 #include <wtf/StdLibExtras.h>
62 #include <wtf/text/WTFString.h>
69 static inline void shrinkToFit(T& segmentedVector)
71 while (segmentedVector.size() && !segmentedVector.last().refCount())
72 segmentedVector.removeLast();
75 void Label::setLocation(BytecodeGenerator& generator, unsigned location)
77 m_location = location;
79 unsigned size = m_unresolvedJumps.size();
80 for (unsigned i = 0; i < size; ++i)
81 generator.instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
84 void Variable::dump(PrintStream& out) const
88 ", offset = ", m_offset,
89 ", local = ", RawPointer(m_local),
90 ", attributes = ", m_attributes,
92 ", symbolTableConstantIndex = ", m_symbolTableConstantIndex,
93 ", isLexicallyScoped = ", m_isLexicallyScoped, "}");
96 ParserError BytecodeGenerator::generate()
98 m_codeBlock->setThisRegister(m_thisRegister.virtualRegister());
100 emitLogShadowChickenPrologueIfNecessary();
102 // If we have declared a variable named "arguments" and we are using arguments then we should
103 // perform that assignment now.
104 if (m_needToInitializeArguments)
105 initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
108 m_restParameter->emit(*this);
111 RefPtr<RegisterID> temp = newTemporary();
112 RefPtr<RegisterID> tolLevelScope;
113 for (auto functionPair : m_functionsToInitialize) {
114 FunctionMetadataNode* metadata = functionPair.first;
115 FunctionVariableType functionType = functionPair.second;
116 emitNewFunction(temp.get(), metadata);
117 if (functionType == NormalFunctionVariable)
118 initializeVariable(variable(metadata->ident()), temp.get());
119 else if (functionType == TopLevelFunctionVariable) {
120 if (!tolLevelScope) {
121 // We know this will resolve to the top level scope or global object because our parser/global initialization code
122 // doesn't allow let/const/class variables to have the same names as functions.
123 // This is a top level function, and it's an error to ever create a top level function
124 // name that would resolve to a lexical variable. E.g:
130 // //// error thrown here
131 // eval("function x(){}");
136 // Therefore, we're guaranteed to have this resolve to a top level variable.
137 RefPtr<RegisterID> tolLevelObjectScope = emitResolveScope(nullptr, Variable(metadata->ident()));
138 tolLevelScope = newBlockScopeVariable();
139 emitMove(tolLevelScope.get(), tolLevelObjectScope.get());
141 emitPutToScope(tolLevelScope.get(), Variable(metadata->ident()), temp.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
143 RELEASE_ASSERT_NOT_REACHED();
147 bool callingClassConstructor = constructorKind() != ConstructorKind::None && !isConstructor();
148 if (!callingClassConstructor)
149 m_scopeNode->emitBytecode(*this);
151 // At this point we would have emitted an unconditional throw followed by some nonsense that's
152 // just an artifact of how this generator is structured. That code never runs, but it confuses
153 // bytecode analyses because it constitutes an unterminated basic block. So, we terminate the
154 // basic block the strongest way possible.
158 for (auto& tuple : m_catchesToEmit) {
159 Ref<Label> realCatchTarget = newEmittedLabel();
160 emitOpcode(op_catch);
161 instructions().append(std::get<1>(tuple));
162 instructions().append(std::get<2>(tuple));
163 instructions().append(0);
165 TryData* tryData = std::get<0>(tuple);
166 emitJump(tryData->target.get());
167 tryData->target = WTFMove(realCatchTarget);
170 m_staticPropertyAnalyzer.kill();
172 for (auto& range : m_tryRanges) {
173 int start = range.start->bind();
174 int end = range.end->bind();
176 // This will happen for empty try blocks and for some cases of finally blocks:
188 // The return will pop scopes to execute the outer finally block. But this includes
189 // popping the try context for the inner try. The try context is live in the fall-through
190 // part of the finally block not because we will emit a handler that overlaps the finally,
191 // but because we haven't yet had a chance to plant the catch target. Then when we finish
192 // emitting code for the outer finally block, we repush the try contex, this time with a
193 // new start index. But that means that the start index for the try range corresponding
194 // to the inner-finally-following-the-return (marked as "*HERE*" above) will be greater
195 // than the end index of the try block. This is harmless since end < start handlers will
196 // never get matched in our logic, but we do the runtime a favor and choose to not emit
197 // such handlers at all.
201 UnlinkedHandlerInfo info(static_cast<uint32_t>(start), static_cast<uint32_t>(end),
202 static_cast<uint32_t>(range.tryData->target->bind()), range.tryData->handlerType);
203 m_codeBlock->addExceptionHandler(info);
207 if (isGeneratorOrAsyncFunctionBodyParseMode(m_codeBlock->parseMode()))
208 performGeneratorification(m_codeBlock.get(), m_instructions, m_generatorFrameSymbolTable.get(), m_generatorFrameSymbolTableIndex);
210 RELEASE_ASSERT(static_cast<unsigned>(m_codeBlock->numCalleeLocals()) < static_cast<unsigned>(FirstConstantRegisterIndex));
211 m_codeBlock->setInstructions(std::make_unique<UnlinkedInstructionStream>(m_instructions));
213 m_codeBlock->shrinkToFit();
215 if (m_expressionTooDeep)
216 return ParserError(ParserError::OutOfMemory);
217 return ParserError(ParserError::ErrorNone);
220 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
221 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
222 , m_scopeNode(programNode)
223 , m_codeBlock(vm, codeBlock)
224 , m_thisRegister(CallFrame::thisArgumentOffset())
225 , m_codeType(GlobalCode)
227 , m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval())
229 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
231 for (auto& constantRegister : m_linkTimeConstantRegisters)
232 constantRegister = nullptr;
234 allocateCalleeSaveSpace();
236 m_codeBlock->setNumParameters(1); // Allocate space for "this"
240 allocateAndEmitScope();
244 const FunctionStack& functionStack = programNode->functionStack();
246 for (auto* function : functionStack)
247 m_functionsToInitialize.append(std::make_pair(function, TopLevelFunctionVariable));
249 if (Options::validateBytecode()) {
250 for (auto& entry : programNode->varDeclarations())
251 RELEASE_ASSERT(entry.value.isVar());
253 codeBlock->setVariableDeclarations(programNode->varDeclarations());
254 codeBlock->setLexicalDeclarations(programNode->lexicalVariables());
255 // Even though this program may have lexical variables that go under TDZ, when linking the get_from_scope/put_to_scope
256 // operations we emit we will have ResolveTypes that implictly do TDZ checks. Therefore, we don't need
257 // additional TDZ checks on top of those. This is why we can omit pushing programNode->lexicalVariables()
260 if (needsToUpdateArrowFunctionContext()) {
261 initializeArrowFunctionContextScopeIfNeeded();
262 emitPutThisToArrowFunctionContextScope();
266 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
267 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
268 , m_scopeNode(functionNode)
269 , m_codeBlock(vm, codeBlock)
270 , m_codeType(FunctionCode)
272 , m_isBuiltinFunction(codeBlock->isBuiltinFunction())
273 , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
274 // FIXME: We should be able to have tail call elimination with the profiler
275 // enabled. This is currently not possible because the profiler expects
276 // op_will_call / op_did_call pairs before and after a call, which are not
277 // compatible with tail calls (we have no way of emitting op_did_call).
278 // https://bugs.webkit.org/show_bug.cgi?id=148819
279 , m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && isStrictMode())
280 , m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval())
281 , m_derivedContextType(codeBlock->derivedContextType())
283 for (auto& constantRegister : m_linkTimeConstantRegisters)
284 constantRegister = nullptr;
286 if (m_isBuiltinFunction)
287 m_shouldEmitDebugHooks = false;
289 allocateCalleeSaveSpace();
291 SymbolTable* functionSymbolTable = SymbolTable::create(*m_vm);
292 functionSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval);
293 int symbolTableConstantIndex = 0;
295 FunctionParameters& parameters = *functionNode->parameters();
296 // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
297 // This implements IsSimpleParameterList in the Ecma 2015 spec.
298 // If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
299 // IsSimpleParameterList is false if the argument list contains any default parameter values,
300 // a rest parameter, or any destructuring patterns.
301 // If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope.
302 bool isSimpleParameterList = parameters.isSimpleParameterList();
304 SourceParseMode parseMode = codeBlock->parseMode();
306 bool containsArrowOrEvalButNotInArrowBlock = ((functionNode->usesArrowFunction() && functionNode->doAnyInnerArrowFunctionsUseAnyFeature()) || functionNode->usesEval()) && !m_codeBlock->isArrowFunction();
307 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || functionNode->needsActivation() || containsArrowOrEvalButNotInArrowBlock;
309 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
310 bool needsArguments = ((functionNode->usesArguments() && !codeBlock->isArrowFunction()) || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction()));
312 if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode)) {
313 // Generator and AsyncFunction never provides "arguments". "arguments" reference will be resolved in an upper generator function scope.
314 needsArguments = false;
316 // Generator and AsyncFunction uses the var scope to save and resume its variables. So the lexical scope is always instantiated.
317 shouldCaptureSomeOfTheThings = true;
320 if (isGeneratorOrAsyncFunctionWrapperParseMode(parseMode) && needsArguments) {
321 // Generator does not provide "arguments". Instead, wrapping GeneratorFunction provides "arguments".
322 // This is because arguments of a generator should be evaluated before starting it.
323 // To workaround it, we evaluate these arguments as arguments of a wrapping generator function, and reference it from a generator.
325 // function *gen(a, b = hello())
328 // @generatorNext: function (@generator, @generatorState, @generatorValue, @generatorResumeMode, @generatorFrame)
330 // arguments; // This `arguments` should reference to the gen's arguments.
335 shouldCaptureSomeOfTheThings = true;
338 if (shouldCaptureAllOfTheThings)
339 functionNode->varDeclarations().markAllVariablesAsCaptured();
341 auto captures = [&] (UniquedStringImpl* uid) -> bool {
342 if (!shouldCaptureSomeOfTheThings)
344 if (needsArguments && uid == propertyNames().arguments.impl()) {
345 // Actually, we only need to capture the arguments object when we "need full activation"
346 // because of name scopes. But historically we did it this way, so for now we just preserve
348 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=143072
351 return functionNode->captures(uid);
353 auto varKind = [&] (UniquedStringImpl* uid) -> VarKind {
354 return captures(uid) ? VarKind::Scope : VarKind::Stack;
357 m_calleeRegister.setIndex(CallFrameSlot::callee);
359 initializeParameters(parameters);
360 ASSERT(!(isSimpleParameterList && m_restParameter));
364 if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode))
365 m_generatorRegister = &m_parameters[1];
367 allocateAndEmitScope();
371 if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())) {
372 ASSERT(parseMode != SourceParseMode::GeneratorBodyMode);
373 ASSERT(!isAsyncFunctionBodyParseMode(parseMode));
374 bool isDynamicScope = functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode());
375 bool isFunctionNameCaptured = captures(functionNode->ident().impl());
376 bool markAsCaptured = isDynamicScope || isFunctionNameCaptured;
377 emitPushFunctionNameScope(functionNode->ident(), &m_calleeRegister, markAsCaptured);
380 if (shouldCaptureSomeOfTheThings)
381 m_lexicalEnvironmentRegister = addVar();
383 if (shouldCaptureSomeOfTheThings || vm.typeProfiler())
384 symbolTableConstantIndex = addConstantValue(functionSymbolTable)->index();
386 // We can allocate the "var" environment if we don't have default parameter expressions. If we have
387 // default parameter expressions, we have to hold off on allocating the "var" environment because
388 // the parent scope of the "var" environment is the parameter environment.
389 if (isSimpleParameterList)
390 initializeVarLexicalEnvironment(symbolTableConstantIndex, functionSymbolTable, shouldCaptureSomeOfTheThings);
392 // Figure out some interesting facts about our arguments.
393 bool capturesAnyArgumentByName = false;
394 if (functionNode->hasCapturedVariables()) {
395 FunctionParameters& parameters = *functionNode->parameters();
396 for (size_t i = 0; i < parameters.size(); ++i) {
397 auto pattern = parameters.at(i).first;
398 if (!pattern->isBindingNode())
400 const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
401 capturesAnyArgumentByName |= captures(ident.impl());
405 if (capturesAnyArgumentByName)
406 ASSERT(m_lexicalEnvironmentRegister);
408 // Need to know what our functions are called. Parameters have some goofy behaviors when it
409 // comes to functions of the same name.
410 for (FunctionMetadataNode* function : functionNode->functionStack())
411 m_functions.add(function->ident().impl());
413 if (needsArguments) {
414 // Create the arguments object now. We may put the arguments object into the activation if
415 // it is captured. Either way, we create two arguments object variables: one is our
416 // private variable that is immutable, and another that is the user-visible variable. The
417 // immutable one is only used here, or during formal parameter resolutions if we opt for
420 m_argumentsRegister = addVar();
421 m_argumentsRegister->ref();
424 if (needsArguments && !codeBlock->isStrictMode() && isSimpleParameterList) {
425 // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
426 // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
429 if (capturesAnyArgumentByName) {
430 functionSymbolTable->setArgumentsLength(vm, parameters.size());
432 // For each parameter, we have two possibilities:
433 // Either it's a binding node with no function overlap, in which case it gets a name
434 // in the symbol table - or it just gets space reserved in the symbol table. Either
435 // way we lift the value into the scope.
436 for (unsigned i = 0; i < parameters.size(); ++i) {
437 ScopeOffset offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
438 functionSymbolTable->setArgumentOffset(vm, i, offset);
439 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first)) {
440 VarOffset varOffset(offset);
441 SymbolTableEntry entry(varOffset);
442 // Stores to these variables via the ScopedArguments object will not do
443 // notifyWrite(), since that would be cumbersome. Also, watching formal
444 // parameters when "arguments" is in play is unlikely to be super profitable.
445 // So, we just disable it.
446 entry.disableWatching(*m_vm);
447 functionSymbolTable->set(NoLockingNecessary, name, entry);
449 emitOpcode(op_put_to_scope);
450 instructions().append(m_lexicalEnvironmentRegister->index());
451 instructions().append(UINT_MAX);
452 instructions().append(virtualRegisterForArgument(1 + i).offset());
453 instructions().append(GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization).operand());
454 instructions().append(symbolTableConstantIndex);
455 instructions().append(offset.offset());
458 // This creates a scoped arguments object and copies the overflow arguments into the
459 // scope. It's the equivalent of calling ScopedArguments::createByCopying().
460 emitOpcode(op_create_scoped_arguments);
461 instructions().append(m_argumentsRegister->index());
462 instructions().append(m_lexicalEnvironmentRegister->index());
464 // We're going to put all parameters into the DirectArguments object. First ensure
465 // that the symbol table knows that this is happening.
466 for (unsigned i = 0; i < parameters.size(); ++i) {
467 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first))
468 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
471 emitOpcode(op_create_direct_arguments);
472 instructions().append(m_argumentsRegister->index());
474 } else if (isSimpleParameterList) {
475 // Create the formal parameters the normal way. Any of them could be captured, or not. If
476 // captured, lift them into the scope. We cannot do this if we have default parameter expressions
477 // because when default parameter expressions exist, they belong in their own lexical environment
478 // separate from the "var" lexical environment.
479 for (unsigned i = 0; i < parameters.size(); ++i) {
480 UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first);
484 if (!captures(name)) {
485 // This is the easy case - just tell the symbol table about the argument. It will
486 // be accessed directly.
487 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
491 ScopeOffset offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
492 const Identifier& ident =
493 static_cast<const BindingNode*>(parameters.at(i).first)->boundProperty();
494 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(offset)));
496 emitOpcode(op_put_to_scope);
497 instructions().append(m_lexicalEnvironmentRegister->index());
498 instructions().append(addConstant(ident));
499 instructions().append(virtualRegisterForArgument(1 + i).offset());
500 instructions().append(GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization).operand());
501 instructions().append(symbolTableConstantIndex);
502 instructions().append(offset.offset());
506 if (needsArguments && (codeBlock->isStrictMode() || !isSimpleParameterList)) {
507 // Allocate a cloned arguments object.
508 emitOpcode(op_create_cloned_arguments);
509 instructions().append(m_argumentsRegister->index());
512 // There are some variables that need to be preinitialized to something other than Undefined:
514 // - "arguments": unless it's used as a function or parameter, this should refer to the
517 // - functions: these always override everything else.
519 // The most logical way to do all of this is to initialize none of the variables until now,
520 // and then initialize them in BytecodeGenerator::generate() in such an order that the rules
521 // for how these things override each other end up holding. We would initialize "arguments" first,
522 // then all arguments, then the functions.
524 // But some arguments are already initialized by default, since if they aren't captured and we
525 // don't have "arguments" then we just point the symbol table at the stack slot of those
526 // arguments. We end up initializing the rest of the arguments that have an uncomplicated
527 // binding (i.e. don't involve destructuring) above when figuring out how to lay them out,
528 // because that's just the simplest thing. This means that when we initialize them, we have to
529 // watch out for the things that override arguments (namely, functions).
531 // This is our final act of weirdness. "arguments" is overridden by everything except the
532 // callee. We add it to the symbol table if it's not already there and it's not an argument.
533 bool shouldCreateArgumentsVariableInParameterScope = false;
534 if (needsArguments) {
535 // If "arguments" is overridden by a function or destructuring parameter name, then it's
536 // OK for us to call createVariable() because it won't change anything. It's also OK for
537 // us to them tell BytecodeGenerator::generate() to write to it because it will do so
538 // before it initializes functions and destructuring parameters. But if "arguments" is
539 // overridden by a "simple" function parameter, then we have to bail: createVariable()
540 // would assert and BytecodeGenerator::generate() would write the "arguments" after the
541 // argument value had already been properly initialized.
543 bool haveParameterNamedArguments = false;
544 for (unsigned i = 0; i < parameters.size(); ++i) {
545 UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first);
546 if (name == propertyNames().arguments.impl()) {
547 haveParameterNamedArguments = true;
552 bool shouldCreateArgumensVariable = !haveParameterNamedArguments
553 && !SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(m_codeBlock->parseMode());
554 shouldCreateArgumentsVariableInParameterScope = shouldCreateArgumensVariable && !isSimpleParameterList;
555 // Do not create arguments variable in case of Arrow function. Value will be loaded from parent scope
556 if (shouldCreateArgumensVariable && !shouldCreateArgumentsVariableInParameterScope) {
558 propertyNames().arguments, varKind(propertyNames().arguments.impl()), functionSymbolTable);
560 m_needToInitializeArguments = true;
564 for (FunctionMetadataNode* function : functionNode->functionStack()) {
565 const Identifier& ident = function->ident();
566 createVariable(ident, varKind(ident.impl()), functionSymbolTable);
567 m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
569 for (auto& entry : functionNode->varDeclarations()) {
570 ASSERT(!entry.value.isLet() && !entry.value.isConst());
571 if (!entry.value.isVar()) // This is either a parameter or callee.
573 if (shouldCreateArgumentsVariableInParameterScope && entry.key.get() == propertyNames().arguments.impl())
575 createVariable(Identifier::fromUid(m_vm, entry.key.get()), varKind(entry.key.get()), functionSymbolTable, IgnoreExisting);
579 m_newTargetRegister = addVar();
581 case SourceParseMode::GeneratorWrapperFunctionMode:
582 case SourceParseMode::GeneratorWrapperMethodMode:
583 case SourceParseMode::AsyncGeneratorWrapperMethodMode:
584 case SourceParseMode::AsyncGeneratorWrapperFunctionMode: {
585 m_generatorRegister = addVar();
587 // FIXME: Emit to_this only when Generator uses it.
588 // https://bugs.webkit.org/show_bug.cgi?id=151586
589 m_codeBlock->addPropertyAccessInstruction(instructions().size());
590 emitOpcode(op_to_this);
591 instructions().append(kill(&m_thisRegister));
592 instructions().append(0);
593 instructions().append(0);
595 emitMove(m_generatorRegister, &m_calleeRegister);
596 emitCreateThis(m_generatorRegister);
600 case SourceParseMode::AsyncArrowFunctionMode:
601 case SourceParseMode::AsyncMethodMode:
602 case SourceParseMode::AsyncFunctionMode: {
603 ASSERT(!isConstructor());
604 ASSERT(constructorKind() == ConstructorKind::None);
605 m_generatorRegister = addVar();
606 m_promiseCapabilityRegister = addVar();
608 if (parseMode != SourceParseMode::AsyncArrowFunctionMode) {
609 // FIXME: Emit to_this only when AsyncFunctionBody uses it.
610 // https://bugs.webkit.org/show_bug.cgi?id=151586
611 m_codeBlock->addPropertyAccessInstruction(instructions().size());
612 emitOpcode(op_to_this);
613 instructions().append(kill(&m_thisRegister));
614 instructions().append(0);
615 instructions().append(0);
618 emitNewObject(m_generatorRegister);
620 // let promiseCapability be @newPromiseCapability(@Promise)
621 auto varNewPromiseCapability = variable(propertyNames().builtinNames().newPromiseCapabilityPrivateName());
622 RefPtr<RegisterID> scope = newTemporary();
623 moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), varNewPromiseCapability));
624 RefPtr<RegisterID> newPromiseCapability = emitGetFromScope(newTemporary(), scope.get(), varNewPromiseCapability, ThrowIfNotFound);
626 CallArguments args(*this, nullptr, 1);
627 emitLoad(args.thisRegister(), jsUndefined());
629 auto varPromiseConstructor = variable(propertyNames().builtinNames().PromisePrivateName());
630 moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), varPromiseConstructor));
631 emitGetFromScope(args.argumentRegister(0), scope.get(), varPromiseConstructor, ThrowIfNotFound);
633 // JSTextPosition(int _line, int _offset, int _lineStartOffset)
634 JSTextPosition divot(m_scopeNode->firstLine(), m_scopeNode->startOffset(), m_scopeNode->lineStartOffset());
635 emitCall(promiseCapabilityRegister(), newPromiseCapability.get(), NoExpectedFunction, args, divot, divot, divot, DebuggableCall::No);
639 case SourceParseMode::AsyncGeneratorBodyMode:
640 case SourceParseMode::AsyncFunctionBodyMode:
641 case SourceParseMode::AsyncArrowFunctionBodyMode:
642 case SourceParseMode::GeneratorBodyMode: {
643 // |this| is already filled correctly before here.
644 emitLoad(m_newTargetRegister, jsUndefined());
649 if (SourceParseMode::ArrowFunctionMode != parseMode) {
650 if (isConstructor()) {
651 emitMove(m_newTargetRegister, &m_thisRegister);
652 if (constructorKind() == ConstructorKind::Extends) {
653 emitMoveEmptyValue(&m_thisRegister);
655 emitCreateThis(&m_thisRegister);
656 } else if (constructorKind() != ConstructorKind::None)
657 emitThrowTypeError("Cannot call a class constructor without |new|");
659 bool shouldEmitToThis = false;
660 if (functionNode->usesThis() || codeBlock->usesEval() || m_scopeNode->doAnyInnerArrowFunctionsUseThis() || m_scopeNode->doAnyInnerArrowFunctionsUseEval())
661 shouldEmitToThis = true;
662 else if ((functionNode->usesSuperProperty() || m_scopeNode->doAnyInnerArrowFunctionsUseSuperProperty()) && !codeBlock->isStrictMode()) {
663 // We must emit to_this when we're not in strict mode because we
664 // will convert |this| to an object, and that object may be passed
665 // to a strict function as |this|. This is observable because that
666 // strict function's to_this will just return the object.
668 // We don't need to emit this for strict-mode code because
669 // strict-mode code may call another strict function, which will
670 // to_this if it directly uses this; this is OK, because we defer
671 // to_this until |this| is used directly. Strict-mode code might
672 // also call a sloppy mode function, and that will to_this, which
673 // will defer the conversion, again, until necessary.
674 shouldEmitToThis = true;
677 if (shouldEmitToThis) {
678 m_codeBlock->addPropertyAccessInstruction(instructions().size());
679 emitOpcode(op_to_this);
680 instructions().append(kill(&m_thisRegister));
681 instructions().append(0);
682 instructions().append(0);
690 // We need load |super| & |this| for arrow function before initializeDefaultParameterValuesAndSetupFunctionScopeStack
691 // if we have default parameter expression. Because |super| & |this| values can be used there
692 if ((SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(parseMode) && !isSimpleParameterList) || parseMode == SourceParseMode::AsyncArrowFunctionBodyMode) {
693 if (functionNode->usesThis() || functionNode->usesSuperProperty())
694 emitLoadThisFromArrowFunctionLexicalEnvironment();
696 if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
697 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
700 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) {
701 bool canReuseLexicalEnvironment = isSimpleParameterList;
702 initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable, canReuseLexicalEnvironment);
703 emitPutThisToArrowFunctionContextScope();
704 emitPutNewTargetToArrowFunctionContextScope();
705 emitPutDerivedConstructorToArrowFunctionContextScope();
708 // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called
709 // because a function's default parameter ExpressionNodes will use temporary registers.
710 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ);
712 Ref<Label> catchLabel = newLabel();
713 TryData* tryFormalParametersData = nullptr;
714 bool needTryCatch = isAsyncFunctionWrapperParseMode(parseMode) && !isSimpleParameterList;
716 Ref<Label> tryFormalParametersStart = newEmittedLabel();
717 tryFormalParametersData = pushTry(tryFormalParametersStart.get(), catchLabel.get(), HandlerType::SynthesizedCatch);
720 initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, isSimpleParameterList, functionNode, functionSymbolTable, symbolTableConstantIndex, captures, shouldCreateArgumentsVariableInParameterScope);
723 Ref<Label> didNotThrow = newLabel();
724 emitJump(didNotThrow.get());
725 emitLabel(catchLabel.get());
726 popTry(tryFormalParametersData, catchLabel.get());
728 RefPtr<RegisterID> thrownValue = newTemporary();
729 RegisterID* unused = newTemporary();
730 emitCatch(unused, thrownValue.get(), tryFormalParametersData);
732 // return promiseCapability.@reject(thrownValue)
733 RefPtr<RegisterID> reject = emitGetById(newTemporary(), promiseCapabilityRegister(), m_vm->propertyNames->builtinNames().rejectPrivateName());
735 CallArguments args(*this, nullptr, 1);
736 emitLoad(args.thisRegister(), jsUndefined());
737 emitMove(args.argumentRegister(0), thrownValue.get());
739 JSTextPosition divot(functionNode->firstLine(), functionNode->startOffset(), functionNode->lineStartOffset());
741 RefPtr<RegisterID> result = emitCall(newTemporary(), reject.get(), NoExpectedFunction, args, divot, divot, divot, DebuggableCall::No);
742 emitReturn(emitGetById(newTemporary(), promiseCapabilityRegister(), m_vm->propertyNames->builtinNames().promisePrivateName()));
744 emitLabel(didNotThrow.get());
747 // If we don't have default parameter expression, then loading |this| inside an arrow function must be done
748 // after initializeDefaultParameterValuesAndSetupFunctionScopeStack() because that function sets up the
749 // SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment() consults the SymbolTable stack
750 if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(parseMode) && isSimpleParameterList) {
751 if (functionNode->usesThis() || functionNode->usesSuperProperty())
752 emitLoadThisFromArrowFunctionLexicalEnvironment();
754 if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
755 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
758 // Set up the lexical environment scope as the generator frame. We store the saved and resumed generator registers into this scope with the symbol keys.
759 // Since they are symbol keyed, these variables cannot be reached from the usual code.
760 if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode)) {
761 ASSERT(m_lexicalEnvironmentRegister);
762 m_generatorFrameSymbolTable.set(*m_vm, functionSymbolTable);
763 m_generatorFrameSymbolTableIndex = symbolTableConstantIndex;
764 emitMove(generatorFrameRegister(), m_lexicalEnvironmentRegister);
765 emitPutById(generatorRegister(), propertyNames().builtinNames().generatorFramePrivateName(), generatorFrameRegister());
768 bool shouldInitializeBlockScopedFunctions = false; // We generate top-level function declarations in ::generate().
769 pushLexicalScope(m_scopeNode, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions);
772 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
773 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
774 , m_scopeNode(evalNode)
775 , m_codeBlock(vm, codeBlock)
776 , m_thisRegister(CallFrame::thisArgumentOffset())
777 , m_codeType(EvalCode)
779 , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
780 , m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval())
781 , m_derivedContextType(codeBlock->derivedContextType())
783 for (auto& constantRegister : m_linkTimeConstantRegisters)
784 constantRegister = nullptr;
786 allocateCalleeSaveSpace();
788 m_codeBlock->setNumParameters(1);
790 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ);
794 allocateAndEmitScope();
798 for (FunctionMetadataNode* function : evalNode->functionStack()) {
799 m_codeBlock->addFunctionDecl(makeFunction(function));
800 m_functionsToInitialize.append(std::make_pair(function, TopLevelFunctionVariable));
803 const VariableEnvironment& varDeclarations = evalNode->varDeclarations();
804 Vector<Identifier, 0, UnsafeVectorOverflow> variables;
805 Vector<Identifier, 0, UnsafeVectorOverflow> hoistedFunctions;
806 for (auto& entry : varDeclarations) {
807 ASSERT(entry.value.isVar());
808 ASSERT(entry.key->isAtomic() || entry.key->isSymbol());
809 if (entry.value.isSloppyModeHoistingCandidate())
810 hoistedFunctions.append(Identifier::fromUid(m_vm, entry.key.get()));
812 variables.append(Identifier::fromUid(m_vm, entry.key.get()));
814 codeBlock->adoptVariables(variables);
815 codeBlock->adoptFunctionHoistingCandidates(WTFMove(hoistedFunctions));
817 if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
818 m_newTargetRegister = addVar();
820 if (codeBlock->isArrowFunctionContext() && (evalNode->usesThis() || evalNode->usesSuperProperty()))
821 emitLoadThisFromArrowFunctionLexicalEnvironment();
823 if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
824 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
826 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunctionContext() && !isDerivedConstructorContext()) {
827 initializeArrowFunctionContextScopeIfNeeded();
828 emitPutThisToArrowFunctionContextScope();
831 bool shouldInitializeBlockScopedFunctions = false; // We generate top-level function declarations in ::generate().
832 pushLexicalScope(m_scopeNode, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions);
835 BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
836 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
837 , m_scopeNode(moduleProgramNode)
838 , m_codeBlock(vm, codeBlock)
839 , m_thisRegister(CallFrame::thisArgumentOffset())
840 , m_codeType(ModuleCode)
842 , m_usesNonStrictEval(false)
843 , m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval())
845 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
847 for (auto& constantRegister : m_linkTimeConstantRegisters)
848 constantRegister = nullptr;
850 if (m_isBuiltinFunction)
851 m_shouldEmitDebugHooks = false;
853 allocateCalleeSaveSpace();
855 SymbolTable* moduleEnvironmentSymbolTable = SymbolTable::create(*m_vm);
856 moduleEnvironmentSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval);
857 moduleEnvironmentSymbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope);
859 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
860 if (shouldCaptureAllOfTheThings)
861 moduleProgramNode->varDeclarations().markAllVariablesAsCaptured();
863 auto captures = [&] (UniquedStringImpl* uid) -> bool {
864 return moduleProgramNode->captures(uid);
866 auto lookUpVarKind = [&] (UniquedStringImpl* uid, const VariableEnvironmentEntry& entry) -> VarKind {
867 // Allocate the exported variables in the module environment.
868 if (entry.isExported())
869 return VarKind::Scope;
871 // Allocate the namespace variables in the module environment to instantiate
872 // it from the outside of the module code.
873 if (entry.isImportedNamespace())
874 return VarKind::Scope;
876 if (entry.isCaptured())
877 return VarKind::Scope;
878 return captures(uid) ? VarKind::Scope : VarKind::Stack;
883 allocateAndEmitScope();
887 m_calleeRegister.setIndex(CallFrameSlot::callee);
889 m_codeBlock->setNumParameters(1); // Allocate space for "this"
891 // Now declare all variables.
893 createVariable(m_vm->propertyNames->builtinNames().metaPrivateName(), VarKind::Scope, moduleEnvironmentSymbolTable, VerifyExisting);
895 for (auto& entry : moduleProgramNode->varDeclarations()) {
896 ASSERT(!entry.value.isLet() && !entry.value.isConst());
897 if (!entry.value.isVar()) // This is either a parameter or callee.
899 // Imported bindings are not allocated in the module environment as usual variables' way.
900 // These references remain the "Dynamic" in the unlinked code block. Later, when linking
901 // the code block, we resolve the reference to the "ModuleVar".
902 if (entry.value.isImported() && !entry.value.isImportedNamespace())
904 createVariable(Identifier::fromUid(m_vm, entry.key.get()), lookUpVarKind(entry.key.get(), entry.value), moduleEnvironmentSymbolTable, IgnoreExisting);
907 VariableEnvironment& lexicalVariables = moduleProgramNode->lexicalVariables();
908 instantiateLexicalVariables(lexicalVariables, moduleEnvironmentSymbolTable, ScopeRegisterType::Block, lookUpVarKind);
910 // We keep the symbol table in the constant pool.
911 RegisterID* constantSymbolTable = nullptr;
912 if (vm.typeProfiler())
913 constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable);
915 constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable->cloneScopePart(*m_vm));
917 pushTDZVariables(lexicalVariables, TDZCheckOptimization::Optimize, TDZRequirement::UnderTDZ);
918 bool isWithScope = false;
919 m_lexicalScopeStack.append({ moduleEnvironmentSymbolTable, m_topMostScope, isWithScope, constantSymbolTable->index() });
920 emitPrefillStackTDZVariables(lexicalVariables, moduleEnvironmentSymbolTable);
922 // makeFunction assumes that there's correct TDZ stack entries.
923 // So it should be called after putting our lexical environment to the TDZ stack correctly.
925 for (FunctionMetadataNode* function : moduleProgramNode->functionStack()) {
926 const auto& iterator = moduleProgramNode->varDeclarations().find(function->ident().impl());
927 RELEASE_ASSERT(iterator != moduleProgramNode->varDeclarations().end());
928 RELEASE_ASSERT(!iterator->value.isImported());
930 VarKind varKind = lookUpVarKind(iterator->key.get(), iterator->value);
931 if (varKind == VarKind::Scope) {
932 // http://www.ecma-international.org/ecma-262/6.0/#sec-moduledeclarationinstantiation
933 // Section 15.2.1.16.4, step 16-a-iv-1.
934 // All heap allocated function declarations should be instantiated when the module environment
935 // is created. They include the exported function declarations and not-exported-but-heap-allocated
936 // function declarations. This is required because exported function should be instantiated before
937 // executing the any module in the dependency graph. This enables the modules to link the imported
938 // bindings before executing the any module code.
940 // And since function declarations are instantiated before executing the module body code, the spec
941 // allows the functions inside the module to be executed before its module body is executed under
942 // the circular dependencies. The following is the example.
944 // Module A (executed first):
945 // import { b } from "B";
946 // // Here, the module "B" is not executed yet, but the function declaration is already instantiated.
947 // // So we can call the function exported from "B".
950 // export function a() {
953 // Module B (executed second):
954 // import { a } from "A";
956 // export function b() {
960 // // c is not exported, but since it is referenced from the b, we should instantiate it before
961 // // executing the "B" module code.
966 // Module EntryPoint (executed last):
970 m_codeBlock->addFunctionDecl(makeFunction(function));
972 // Stack allocated functions can be allocated when executing the module's body.
973 m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
977 // Remember the constant register offset to the top-most symbol table. This symbol table will be
978 // cloned in the code block linking. After that, to create the module environment, we retrieve
979 // the cloned symbol table from the linked code block by using this offset.
980 codeBlock->setModuleEnvironmentSymbolTableConstantRegisterOffset(constantSymbolTable->index());
983 BytecodeGenerator::~BytecodeGenerator()
987 void BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack(
988 FunctionParameters& parameters, bool isSimpleParameterList, FunctionNode* functionNode, SymbolTable* functionSymbolTable,
989 int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures, bool shouldCreateArgumentsVariableInParameterScope)
991 Vector<std::pair<Identifier, RefPtr<RegisterID>>> valuesToMoveIntoVars;
992 ASSERT(!(isSimpleParameterList && shouldCreateArgumentsVariableInParameterScope));
993 if (!isSimpleParameterList) {
994 // Refer to the ES6 spec section 9.2.12: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
995 // This implements step 21.
996 VariableEnvironment environment;
997 Vector<Identifier> allParameterNames;
998 for (unsigned i = 0; i < parameters.size(); i++)
999 parameters.at(i).first->collectBoundIdentifiers(allParameterNames);
1000 if (shouldCreateArgumentsVariableInParameterScope)
1001 allParameterNames.append(propertyNames().arguments);
1002 IdentifierSet parameterSet;
1003 for (auto& ident : allParameterNames) {
1004 parameterSet.add(ident.impl());
1005 auto addResult = environment.add(ident);
1006 addResult.iterator->value.setIsLet(); // When we have default parameter expressions, parameters act like "let" variables.
1007 if (captures(ident.impl()))
1008 addResult.iterator->value.setIsCaptured();
1010 // This implements step 25 of section 9.2.12.
1011 pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
1013 if (shouldCreateArgumentsVariableInParameterScope) {
1014 Variable argumentsVariable = variable(propertyNames().arguments);
1015 initializeVariable(argumentsVariable, m_argumentsRegister);
1016 liftTDZCheckIfPossible(argumentsVariable);
1019 RefPtr<RegisterID> temp = newTemporary();
1020 for (unsigned i = 0; i < parameters.size(); i++) {
1021 std::pair<DestructuringPatternNode*, ExpressionNode*> parameter = parameters.at(i);
1022 if (parameter.first->isRestParameter())
1024 if ((i + 1) < m_parameters.size())
1025 emitMove(temp.get(), &m_parameters[i + 1]);
1027 emitGetArgument(temp.get(), i);
1028 if (parameter.second) {
1029 RefPtr<RegisterID> condition = emitIsUndefined(newTemporary(), temp.get());
1030 Ref<Label> skipDefaultParameterBecauseNotUndefined = newLabel();
1031 emitJumpIfFalse(condition.get(), skipDefaultParameterBecauseNotUndefined.get());
1032 emitNode(temp.get(), parameter.second);
1033 emitLabel(skipDefaultParameterBecauseNotUndefined.get());
1036 parameter.first->bindValue(*this, temp.get());
1039 // Final act of weirdness for default parameters. If a "var" also
1040 // has the same name as a parameter, it should start out as the
1041 // value of that parameter. Note, though, that they will be distinct
1043 // This is step 28 of section 9.2.12.
1044 for (auto& entry : functionNode->varDeclarations()) {
1045 if (!entry.value.isVar()) // This is either a parameter or callee.
1048 if (parameterSet.contains(entry.key)) {
1049 Identifier ident = Identifier::fromUid(m_vm, entry.key.get());
1050 Variable var = variable(ident);
1051 RegisterID* scope = emitResolveScope(nullptr, var);
1052 RefPtr<RegisterID> value = emitGetFromScope(newTemporary(), scope, var, DoNotThrowIfNotFound);
1053 valuesToMoveIntoVars.append(std::make_pair(ident, value));
1057 // Functions with default parameter expressions must have a separate environment
1058 // record for parameters and "var"s. The "var" environment record must have the
1059 // parameter environment record as its parent.
1060 // See step 28 of section 9.2.12.
1061 bool hasCapturedVariables = !!m_lexicalEnvironmentRegister;
1062 initializeVarLexicalEnvironment(symbolTableConstantIndex, functionSymbolTable, hasCapturedVariables);
1065 // This completes step 28 of section 9.2.12.
1066 for (unsigned i = 0; i < valuesToMoveIntoVars.size(); i++) {
1067 ASSERT(!isSimpleParameterList);
1068 Variable var = variable(valuesToMoveIntoVars[i].first);
1069 RegisterID* scope = emitResolveScope(nullptr, var);
1070 emitPutToScope(scope, var, valuesToMoveIntoVars[i].second.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
1074 bool BytecodeGenerator::needsDerivedConstructorInArrowFunctionLexicalEnvironment()
1076 ASSERT(m_codeBlock->isClassContext() || !(isConstructor() && constructorKind() == ConstructorKind::Extends));
1077 return m_codeBlock->isClassContext() && isSuperUsedInInnerArrowFunction();
1080 void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable, bool canReuseLexicalEnvironment)
1082 ASSERT(!m_arrowFunctionContextLexicalEnvironmentRegister);
1084 if (canReuseLexicalEnvironment && m_lexicalEnvironmentRegister) {
1085 RELEASE_ASSERT(!m_codeBlock->isArrowFunction());
1086 RELEASE_ASSERT(functionSymbolTable);
1088 m_arrowFunctionContextLexicalEnvironmentRegister = m_lexicalEnvironmentRegister;
1092 if (isThisUsedInInnerArrowFunction()) {
1093 offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
1094 functionSymbolTable->set(NoLockingNecessary, propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset)));
1097 if (m_codeType == FunctionCode && isNewTargetUsedInInnerArrowFunction()) {
1098 offset = functionSymbolTable->takeNextScopeOffset();
1099 functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().newTargetLocalPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
1102 if (needsDerivedConstructorInArrowFunctionLexicalEnvironment()) {
1103 offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
1104 functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().derivedConstructorPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
1110 VariableEnvironment environment;
1112 if (isThisUsedInInnerArrowFunction()) {
1113 auto addResult = environment.add(propertyNames().thisIdentifier);
1114 addResult.iterator->value.setIsCaptured();
1115 addResult.iterator->value.setIsLet();
1118 if (m_codeType == FunctionCode && isNewTargetUsedInInnerArrowFunction()) {
1119 auto addTarget = environment.add(propertyNames().builtinNames().newTargetLocalPrivateName());
1120 addTarget.iterator->value.setIsCaptured();
1121 addTarget.iterator->value.setIsLet();
1124 if (needsDerivedConstructorInArrowFunctionLexicalEnvironment()) {
1125 auto derivedConstructor = environment.add(propertyNames().builtinNames().derivedConstructorPrivateName());
1126 derivedConstructor.iterator->value.setIsCaptured();
1127 derivedConstructor.iterator->value.setIsLet();
1130 if (environment.size() > 0) {
1131 size_t size = m_lexicalScopeStack.size();
1132 pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
1134 ASSERT_UNUSED(size, m_lexicalScopeStack.size() == size + 1);
1136 m_arrowFunctionContextLexicalEnvironmentRegister = m_lexicalScopeStack.last().m_scope;
1140 RegisterID* BytecodeGenerator::initializeNextParameter()
1142 VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
1143 m_parameters.grow(m_parameters.size() + 1);
1144 auto& parameter = registerFor(reg);
1145 parameter.setIndex(reg.offset());
1146 m_codeBlock->addParameter();
1150 void BytecodeGenerator::initializeParameters(FunctionParameters& parameters)
1152 // Make sure the code block knows about all of our parameters, and make sure that parameters
1153 // needing destructuring are noted.
1154 m_thisRegister.setIndex(initializeNextParameter()->index()); // this
1156 bool nonSimpleArguments = false;
1157 for (unsigned i = 0; i < parameters.size(); ++i) {
1158 auto parameter = parameters.at(i);
1159 auto pattern = parameter.first;
1160 if (pattern->isRestParameter()) {
1161 RELEASE_ASSERT(!m_restParameter);
1162 m_restParameter = static_cast<RestParameterNode*>(pattern);
1163 nonSimpleArguments = true;
1166 if (parameter.second) {
1167 nonSimpleArguments = true;
1170 if (!nonSimpleArguments)
1171 initializeNextParameter();
1175 void BytecodeGenerator::initializeVarLexicalEnvironment(int symbolTableConstantIndex, SymbolTable* functionSymbolTable, bool hasCapturedVariables)
1177 if (hasCapturedVariables) {
1178 RELEASE_ASSERT(m_lexicalEnvironmentRegister);
1179 emitOpcode(op_create_lexical_environment);
1180 instructions().append(m_lexicalEnvironmentRegister->index());
1181 instructions().append(scopeRegister()->index());
1182 instructions().append(symbolTableConstantIndex);
1183 instructions().append(addConstantValue(jsUndefined())->index());
1186 instructions().append(scopeRegister()->index());
1187 instructions().append(m_lexicalEnvironmentRegister->index());
1189 pushLocalControlFlowScope();
1191 bool isWithScope = false;
1192 m_lexicalScopeStack.append({ functionSymbolTable, m_lexicalEnvironmentRegister, isWithScope, symbolTableConstantIndex });
1193 m_varScopeLexicalScopeStackIndex = m_lexicalScopeStack.size() - 1;
1196 UniquedStringImpl* BytecodeGenerator::visibleNameForParameter(DestructuringPatternNode* pattern)
1198 if (pattern->isBindingNode()) {
1199 const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
1200 if (!m_functions.contains(ident.impl()))
1201 return ident.impl();
1206 RegisterID* BytecodeGenerator::newRegister()
1208 m_calleeLocals.append(virtualRegisterForLocal(m_calleeLocals.size()));
1209 int numCalleeLocals = max<int>(m_codeBlock->m_numCalleeLocals, m_calleeLocals.size());
1210 numCalleeLocals = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numCalleeLocals);
1211 m_codeBlock->m_numCalleeLocals = numCalleeLocals;
1212 return &m_calleeLocals.last();
1215 void BytecodeGenerator::reclaimFreeRegisters()
1217 shrinkToFit(m_calleeLocals);
1220 RegisterID* BytecodeGenerator::newBlockScopeVariable()
1222 reclaimFreeRegisters();
1224 return newRegister();
1227 RegisterID* BytecodeGenerator::newTemporary()
1229 reclaimFreeRegisters();
1231 RegisterID* result = newRegister();
1232 result->setTemporary();
1236 Ref<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
1238 shrinkToFit(m_labelScopes);
1240 // Allocate new label scope.
1241 m_labelScopes.append(type, name, labelScopeDepth(), newLabel(), type == LabelScope::Loop ? RefPtr<Label>(newLabel()) : RefPtr<Label>()); // Only loops have continue targets.
1242 return m_labelScopes.last();
1245 Ref<Label> BytecodeGenerator::newLabel()
1247 shrinkToFit(m_labels);
1249 // Allocate new label ID.
1251 return m_labels.last();
1254 Ref<Label> BytecodeGenerator::newEmittedLabel()
1256 Ref<Label> label = newLabel();
1257 emitLabel(label.get());
1261 void BytecodeGenerator::emitLabel(Label& l0)
1263 unsigned newLabelIndex = instructions().size();
1264 l0.setLocation(*this, newLabelIndex);
1266 if (m_codeBlock->numberOfJumpTargets()) {
1267 unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
1268 ASSERT(lastLabelIndex <= newLabelIndex);
1269 if (newLabelIndex == lastLabelIndex) {
1270 // Peephole optimizations have already been disabled by emitting the last label
1275 m_codeBlock->addJumpTarget(newLabelIndex);
1277 // This disables peephole optimizations when an instruction is a jump target
1278 m_lastOpcodeID = op_end;
1281 void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
1284 size_t opcodePosition = instructions().size();
1285 ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
1286 m_lastOpcodePosition = opcodePosition;
1288 instructions().append(opcodeID);
1289 m_lastOpcodeID = opcodeID;
1292 UnlinkedArrayProfile BytecodeGenerator::newArrayProfile()
1294 return m_codeBlock->addArrayProfile();
1297 UnlinkedArrayAllocationProfile BytecodeGenerator::newArrayAllocationProfile()
1299 return m_codeBlock->addArrayAllocationProfile();
1302 UnlinkedObjectAllocationProfile BytecodeGenerator::newObjectAllocationProfile()
1304 return m_codeBlock->addObjectAllocationProfile();
1307 UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
1309 UnlinkedValueProfile result = m_codeBlock->addValueProfile();
1310 emitOpcode(opcodeID);
1314 void BytecodeGenerator::emitEnter()
1316 emitOpcode(op_enter);
1318 // We must add the end of op_enter as a potential jump target, because the bytecode parser may decide to split its basic block
1319 // to have somewhere to jump to if there is a recursive tail-call that points to this function.
1320 m_codeBlock->addJumpTarget(instructions().size());
1321 // This disables peephole optimizations when an instruction is a jump target
1322 m_lastOpcodeID = op_end;
1325 void BytecodeGenerator::emitLoopHint()
1327 emitOpcode(op_loop_hint);
1331 void BytecodeGenerator::emitCheckTraps()
1333 emitOpcode(op_check_traps);
1336 void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
1338 ASSERT(instructions().size() >= 4);
1339 size_t size = instructions().size();
1340 dstIndex = instructions().at(size - 3).u.operand;
1341 src1Index = instructions().at(size - 2).u.operand;
1342 src2Index = instructions().at(size - 1).u.operand;
1345 void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
1347 ASSERT(instructions().size() >= 3);
1348 size_t size = instructions().size();
1349 dstIndex = instructions().at(size - 2).u.operand;
1350 srcIndex = instructions().at(size - 1).u.operand;
1353 void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
1355 ASSERT(instructions().size() >= 4);
1356 instructions().shrink(instructions().size() - 4);
1357 m_lastOpcodeID = op_end;
1360 void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
1362 ASSERT(instructions().size() >= 3);
1363 instructions().shrink(instructions().size() - 3);
1364 m_lastOpcodeID = op_end;
1367 void BytecodeGenerator::emitJump(Label& target)
1369 size_t begin = instructions().size();
1371 instructions().append(target.bind(begin, instructions().size()));
1374 void BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label& target)
1376 auto fuseCompareAndJump = [&] (OpcodeID jumpID) {
1381 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1383 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1386 size_t begin = instructions().size();
1388 instructions().append(src1Index);
1389 instructions().append(src2Index);
1390 instructions().append(target.bind(begin, instructions().size()));
1396 if (m_lastOpcodeID == op_less) {
1397 if (fuseCompareAndJump(op_jless))
1399 } else if (m_lastOpcodeID == op_lesseq) {
1400 if (fuseCompareAndJump(op_jlesseq))
1402 } else if (m_lastOpcodeID == op_greater) {
1403 if (fuseCompareAndJump(op_jgreater))
1405 } else if (m_lastOpcodeID == op_greatereq) {
1406 if (fuseCompareAndJump(op_jgreatereq))
1408 } else if (m_lastOpcodeID == op_below) {
1409 if (fuseCompareAndJump(op_jbelow))
1411 } else if (m_lastOpcodeID == op_beloweq) {
1412 if (fuseCompareAndJump(op_jbeloweq))
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_jeq_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_jneq_null);
1440 instructions().append(srcIndex);
1441 instructions().append(target.bind(begin, instructions().size()));
1446 size_t begin = instructions().size();
1448 emitOpcode(op_jtrue);
1449 instructions().append(cond->index());
1450 instructions().append(target.bind(begin, instructions().size()));
1453 void BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label& target)
1455 auto fuseCompareAndJump = [&] (OpcodeID jumpID, bool replaceOperands) {
1460 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1462 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1465 size_t begin = instructions().size();
1467 // Since op_below and op_beloweq only accepts Int32, replacing operands is not observable to users.
1468 if (replaceOperands)
1469 std::swap(src1Index, src2Index);
1470 instructions().append(src1Index);
1471 instructions().append(src2Index);
1472 instructions().append(target.bind(begin, instructions().size()));
1478 if (m_lastOpcodeID == op_less && target.isForward()) {
1479 if (fuseCompareAndJump(op_jnless, false))
1481 } else if (m_lastOpcodeID == op_lesseq && target.isForward()) {
1482 if (fuseCompareAndJump(op_jnlesseq, false))
1484 } else if (m_lastOpcodeID == op_greater && target.isForward()) {
1485 if (fuseCompareAndJump(op_jngreater, false))
1487 } else if (m_lastOpcodeID == op_greatereq && target.isForward()) {
1488 if (fuseCompareAndJump(op_jngreatereq, false))
1490 } else if (m_lastOpcodeID == op_below && target.isForward()) {
1491 if (fuseCompareAndJump(op_jbeloweq, true))
1493 } else if (m_lastOpcodeID == op_beloweq && target.isForward()) {
1494 if (fuseCompareAndJump(op_jbelow, true))
1496 } else if (m_lastOpcodeID == op_not) {
1500 retrieveLastUnaryOp(dstIndex, srcIndex);
1502 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1505 size_t begin = instructions().size();
1506 emitOpcode(op_jtrue);
1507 instructions().append(srcIndex);
1508 instructions().append(target.bind(begin, instructions().size()));
1511 } else if (m_lastOpcodeID == op_eq_null && target.isForward()) {
1515 retrieveLastUnaryOp(dstIndex, srcIndex);
1517 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1520 size_t begin = instructions().size();
1521 emitOpcode(op_jneq_null);
1522 instructions().append(srcIndex);
1523 instructions().append(target.bind(begin, instructions().size()));
1526 } else if (m_lastOpcodeID == op_neq_null && target.isForward()) {
1530 retrieveLastUnaryOp(dstIndex, srcIndex);
1532 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1535 size_t begin = instructions().size();
1536 emitOpcode(op_jeq_null);
1537 instructions().append(srcIndex);
1538 instructions().append(target.bind(begin, instructions().size()));
1543 size_t begin = instructions().size();
1544 emitOpcode(op_jfalse);
1545 instructions().append(cond->index());
1546 instructions().append(target.bind(begin, instructions().size()));
1549 void BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label& target)
1551 size_t begin = instructions().size();
1553 emitOpcode(op_jneq_ptr);
1554 instructions().append(cond->index());
1555 instructions().append(Special::CallFunction);
1556 instructions().append(target.bind(begin, instructions().size()));
1557 instructions().append(0);
1560 void BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label& target)
1562 size_t begin = instructions().size();
1564 emitOpcode(op_jneq_ptr);
1565 instructions().append(cond->index());
1566 instructions().append(Special::ApplyFunction);
1567 instructions().append(target.bind(begin, instructions().size()));
1568 instructions().append(0);
1571 bool BytecodeGenerator::hasConstant(const Identifier& ident) const
1573 UniquedStringImpl* rep = ident.impl();
1574 return m_identifierMap.contains(rep);
1577 unsigned BytecodeGenerator::addConstant(const Identifier& ident)
1579 UniquedStringImpl* rep = ident.impl();
1580 IdentifierMap::AddResult result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
1581 if (result.isNewEntry)
1582 m_codeBlock->addIdentifier(ident);
1584 return result.iterator->value;
1587 // We can't hash JSValue(), so we use a dedicated data member to cache it.
1588 RegisterID* BytecodeGenerator::addConstantEmptyValue()
1590 if (!m_emptyValueRegister) {
1591 int index = addConstantIndex();
1592 m_codeBlock->addConstant(JSValue());
1593 m_emptyValueRegister = &m_constantPoolRegisters[index];
1596 return m_emptyValueRegister;
1599 RegisterID* BytecodeGenerator::addConstantValue(JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
1602 return addConstantEmptyValue();
1604 int index = m_nextConstantOffset;
1606 if (sourceCodeRepresentation == SourceCodeRepresentation::Double && v.isInt32())
1607 v = jsDoubleNumber(v.asNumber());
1608 EncodedJSValueWithRepresentation valueMapKey { JSValue::encode(v), sourceCodeRepresentation };
1609 JSValueMap::AddResult result = m_jsValueMap.add(valueMapKey, m_nextConstantOffset);
1610 if (result.isNewEntry) {
1612 m_codeBlock->addConstant(v, sourceCodeRepresentation);
1614 index = result.iterator->value;
1615 return &m_constantPoolRegisters[index];
1618 RegisterID* BytecodeGenerator::emitMoveLinkTimeConstant(RegisterID* dst, LinkTimeConstant type)
1620 unsigned constantIndex = static_cast<unsigned>(type);
1621 if (!m_linkTimeConstantRegisters[constantIndex]) {
1622 int index = addConstantIndex();
1623 m_codeBlock->addConstant(type);
1624 m_linkTimeConstantRegisters[constantIndex] = &m_constantPoolRegisters[index];
1628 return m_linkTimeConstantRegisters[constantIndex];
1631 instructions().append(dst->index());
1632 instructions().append(m_linkTimeConstantRegisters[constantIndex]->index());
1637 unsigned BytecodeGenerator::addRegExp(RegExp* r)
1639 return m_codeBlock->addRegExp(r);
1642 RegisterID* BytecodeGenerator::emitMoveEmptyValue(RegisterID* dst)
1644 RefPtr<RegisterID> emptyValue = addConstantEmptyValue();
1647 instructions().append(dst->index());
1648 instructions().append(emptyValue->index());
1652 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
1654 ASSERT(src != m_emptyValueRegister);
1656 m_staticPropertyAnalyzer.mov(dst->index(), src->index());
1658 instructions().append(dst->index());
1659 instructions().append(src->index());
1664 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1666 ASSERT_WITH_MESSAGE(op_to_number != opcodeID, "op_to_number has a Value Profile.");
1667 ASSERT_WITH_MESSAGE(op_negate != opcodeID, "op_negate has an Arith Profile.");
1668 emitOpcode(opcodeID);
1669 instructions().append(dst->index());
1670 instructions().append(src->index());
1675 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, OperandTypes types)
1677 ASSERT_WITH_MESSAGE(op_to_number != opcodeID, "op_to_number has a Value Profile.");
1678 emitOpcode(opcodeID);
1679 instructions().append(dst->index());
1680 instructions().append(src->index());
1682 if (opcodeID == op_negate)
1683 instructions().append(ArithProfile(types.first()).bits());
1687 RegisterID* BytecodeGenerator::emitUnaryOpProfiled(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1689 UnlinkedValueProfile profile = emitProfiledOpcode(opcodeID);
1690 instructions().append(dst->index());
1691 instructions().append(src->index());
1692 instructions().append(profile);
1696 RegisterID* BytecodeGenerator::emitToObject(RegisterID* dst, RegisterID* src, const Identifier& message)
1698 UnlinkedValueProfile profile = emitProfiledOpcode(op_to_object);
1699 instructions().append(dst->index());
1700 instructions().append(src->index());
1701 instructions().append(addConstant(message));
1702 instructions().append(profile);
1706 RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
1709 instructions().append(srcDst->index());
1713 RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
1716 instructions().append(srcDst->index());
1720 RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
1722 emitOpcode(opcodeID);
1723 instructions().append(dst->index());
1724 instructions().append(src1->index());
1725 instructions().append(src2->index());
1727 if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
1728 opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
1729 instructions().append(ArithProfile(types.first(), types.second()).bits());
1734 RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
1736 if (m_lastOpcodeID == op_typeof) {
1740 retrieveLastUnaryOp(dstIndex, srcIndex);
1742 if (src1->index() == dstIndex
1743 && src1->isTemporary()
1744 && m_codeBlock->isConstantRegisterIndex(src2->index())
1745 && m_codeBlock->constantRegister(src2->index()).get().isString()) {
1746 const String& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
1747 if (value == "undefined") {
1749 emitOpcode(op_is_undefined);
1750 instructions().append(dst->index());
1751 instructions().append(srcIndex);
1754 if (value == "boolean") {
1756 emitOpcode(op_is_boolean);
1757 instructions().append(dst->index());
1758 instructions().append(srcIndex);
1761 if (value == "number") {
1763 emitOpcode(op_is_number);
1764 instructions().append(dst->index());
1765 instructions().append(srcIndex);
1768 if (value == "string") {
1770 emitOpcode(op_is_cell_with_type);
1771 instructions().append(dst->index());
1772 instructions().append(srcIndex);
1773 instructions().append(StringType);
1776 if (value == "symbol") {
1778 emitOpcode(op_is_cell_with_type);
1779 instructions().append(dst->index());
1780 instructions().append(srcIndex);
1781 instructions().append(SymbolType);
1784 if (value == "object") {
1786 emitOpcode(op_is_object_or_null);
1787 instructions().append(dst->index());
1788 instructions().append(srcIndex);
1791 if (value == "function") {
1793 emitOpcode(op_is_function);
1794 instructions().append(dst->index());
1795 instructions().append(srcIndex);
1801 emitOpcode(opcodeID);
1802 instructions().append(dst->index());
1803 instructions().append(src1->index());
1804 instructions().append(src2->index());
1808 void BytecodeGenerator::emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1810 ASSERT(vm()->typeProfiler());
1812 unsigned start = startDivot.offset; // Ranges are inclusive of their endpoints, AND 0 indexed.
1813 unsigned end = endDivot.offset - 1; // End Ranges already go one past the inclusive range, so subtract 1.
1814 unsigned instructionOffset = instructions().size() - 1;
1815 m_codeBlock->addTypeProfilerExpressionInfo(instructionOffset, start, end);
1818 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag)
1820 if (!vm()->typeProfiler())
1823 if (!registerToProfile)
1826 emitOpcode(op_profile_type);
1827 instructions().append(registerToProfile->index());
1828 instructions().append(0);
1829 instructions().append(flag);
1830 instructions().append(0);
1831 instructions().append(resolveType());
1833 // Don't emit expression info for this version of profile type. This generally means
1834 // we're profiling information for something that isn't in the actual text of a JavaScript
1835 // program. For example, implicit return undefined from a function call.
1838 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1840 emitProfileType(registerToProfile, ProfileTypeBytecodeDoesNotHaveGlobalID, startDivot, endDivot);
1843 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1845 if (!vm()->typeProfiler())
1848 if (!registerToProfile)
1851 // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1852 emitOpcode(op_profile_type);
1853 instructions().append(registerToProfile->index());
1854 instructions().append(0);
1855 instructions().append(flag);
1856 instructions().append(0);
1857 instructions().append(resolveType());
1859 emitTypeProfilerExpressionInfo(startDivot, endDivot);
1862 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const Variable& var, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1864 if (!vm()->typeProfiler())
1867 if (!registerToProfile)
1870 ProfileTypeBytecodeFlag flag;
1871 int symbolTableOrScopeDepth;
1872 if (var.local() || var.offset().isScope()) {
1873 flag = ProfileTypeBytecodeLocallyResolved;
1874 ASSERT(var.symbolTableConstantIndex());
1875 symbolTableOrScopeDepth = var.symbolTableConstantIndex();
1877 flag = ProfileTypeBytecodeClosureVar;
1878 symbolTableOrScopeDepth = localScopeDepth();
1881 // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1882 emitOpcode(op_profile_type);
1883 instructions().append(registerToProfile->index());
1884 instructions().append(symbolTableOrScopeDepth);
1885 instructions().append(flag);
1886 instructions().append(addConstant(var.ident()));
1887 instructions().append(resolveType());
1889 emitTypeProfilerExpressionInfo(startDivot, endDivot);
1892 void BytecodeGenerator::emitProfileControlFlow(int textOffset)
1894 if (vm()->controlFlowProfiler()) {
1895 RELEASE_ASSERT(textOffset >= 0);
1896 size_t bytecodeOffset = instructions().size();
1897 m_codeBlock->addOpProfileControlFlowBytecodeOffset(bytecodeOffset);
1899 emitOpcode(op_profile_control_flow);
1900 instructions().append(textOffset);
1904 unsigned BytecodeGenerator::addConstantIndex()
1906 unsigned index = m_nextConstantOffset;
1907 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1908 ++m_nextConstantOffset;
1912 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
1914 return emitLoad(dst, jsBoolean(b));
1917 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
1919 ASSERT(!identifier.isSymbol());
1920 JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
1922 stringInMap = jsOwnedString(vm(), identifier.string());
1924 return emitLoad(dst, JSValue(stringInMap));
1927 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
1929 RegisterID* constantID = addConstantValue(v, sourceCodeRepresentation);
1931 return emitMove(dst, constantID);
1935 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, IdentifierSet& set)
1937 for (const auto& entry : m_codeBlock->constantIdentifierSets()) {
1938 if (entry.first != set)
1941 return &m_constantPoolRegisters[entry.second];
1944 unsigned index = addConstantIndex();
1945 m_codeBlock->addSetConstant(set);
1946 RegisterID* m_setRegister = &m_constantPoolRegisters[index];
1949 return emitMove(dst, m_setRegister);
1951 return m_setRegister;
1954 RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst)
1956 if (!m_globalObjectRegister) {
1957 int index = addConstantIndex();
1958 m_codeBlock->addConstant(JSValue());
1959 m_globalObjectRegister = &m_constantPoolRegisters[index];
1960 m_codeBlock->setGlobalObjectRegister(VirtualRegister(index));
1963 emitMove(dst, m_globalObjectRegister);
1964 return m_globalObjectRegister;
1967 template<typename LookUpVarKindFunctor>
1968 bool BytecodeGenerator::instantiateLexicalVariables(const VariableEnvironment& lexicalVariables, SymbolTable* symbolTable, ScopeRegisterType scopeRegisterType, LookUpVarKindFunctor lookUpVarKind)
1970 bool hasCapturedVariables = false;
1972 for (auto& entry : lexicalVariables) {
1973 ASSERT(entry.value.isLet() || entry.value.isConst() || entry.value.isFunction());
1974 ASSERT(!entry.value.isVar());
1975 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
1976 ASSERT(symbolTableEntry.isNull());
1978 // Imported bindings which are not the namespace bindings are not allocated
1979 // in the module environment as usual variables' way.
1980 // And since these types of the variables only seen in the module environment,
1981 // other lexical environment need not to take care this.
1982 if (entry.value.isImported() && !entry.value.isImportedNamespace())
1985 VarKind varKind = lookUpVarKind(entry.key.get(), entry.value);
1986 VarOffset varOffset;
1987 if (varKind == VarKind::Scope) {
1988 varOffset = VarOffset(symbolTable->takeNextScopeOffset(NoLockingNecessary));
1989 hasCapturedVariables = true;
1991 ASSERT(varKind == VarKind::Stack);
1993 if (scopeRegisterType == ScopeRegisterType::Block) {
1994 local = newBlockScopeVariable();
1998 varOffset = VarOffset(local->virtualRegister());
2001 SymbolTableEntry newEntry(varOffset, static_cast<unsigned>(entry.value.isConst() ? PropertyAttribute::ReadOnly : PropertyAttribute::None));
2002 symbolTable->add(NoLockingNecessary, entry.key.get(), newEntry);
2005 return hasCapturedVariables;
2008 void BytecodeGenerator::emitPrefillStackTDZVariables(const VariableEnvironment& lexicalVariables, SymbolTable* symbolTable)
2010 // Prefill stack variables with the TDZ empty value.
2011 // Scope variables will be initialized to the TDZ empty value when JSLexicalEnvironment is allocated.
2012 for (auto& entry : lexicalVariables) {
2013 // Imported bindings which are not the namespace bindings are not allocated
2014 // in the module environment as usual variables' way.
2015 // And since these types of the variables only seen in the module environment,
2016 // other lexical environment need not to take care this.
2017 if (entry.value.isImported() && !entry.value.isImportedNamespace())
2020 if (entry.value.isFunction())
2023 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
2024 ASSERT(!symbolTableEntry.isNull());
2025 VarOffset offset = symbolTableEntry.varOffset();
2026 if (offset.isScope())
2029 ASSERT(offset.isStack());
2030 emitMoveEmptyValue(®isterFor(offset.stackOffset()));
2034 void BytecodeGenerator::pushLexicalScope(VariableEnvironmentNode* node, TDZCheckOptimization tdzCheckOptimization, NestedScopeType nestedScopeType, RegisterID** constantSymbolTableResult, bool shouldInitializeBlockScopedFunctions)
2036 VariableEnvironment& environment = node->lexicalVariables();
2037 RegisterID* constantSymbolTableResultTemp = nullptr;
2038 pushLexicalScopeInternal(environment, tdzCheckOptimization, nestedScopeType, &constantSymbolTableResultTemp, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
2040 if (shouldInitializeBlockScopedFunctions)
2041 initializeBlockScopedFunctions(environment, node->functionStack(), constantSymbolTableResultTemp);
2043 if (constantSymbolTableResult && constantSymbolTableResultTemp)
2044 *constantSymbolTableResult = constantSymbolTableResultTemp;
2047 void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environment, TDZCheckOptimization tdzCheckOptimization, NestedScopeType nestedScopeType,
2048 RegisterID** constantSymbolTableResult, TDZRequirement tdzRequirement, ScopeType scopeType, ScopeRegisterType scopeRegisterType)
2050 if (!environment.size())
2053 if (m_shouldEmitDebugHooks)
2054 environment.markAllVariablesAsCaptured();
2056 SymbolTable* symbolTable = SymbolTable::create(*m_vm);
2057 switch (scopeType) {
2058 case ScopeType::CatchScope:
2059 symbolTable->setScopeType(SymbolTable::ScopeType::CatchScope);
2061 case ScopeType::LetConstScope:
2062 symbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope);
2064 case ScopeType::FunctionNameScope:
2065 symbolTable->setScopeType(SymbolTable::ScopeType::FunctionNameScope);
2069 if (nestedScopeType == NestedScopeType::IsNested)
2070 symbolTable->markIsNestedLexicalScope();
2072 auto lookUpVarKind = [] (UniquedStringImpl*, const VariableEnvironmentEntry& entry) -> VarKind {
2073 return entry.isCaptured() ? VarKind::Scope : VarKind::Stack;
2076 bool hasCapturedVariables = instantiateLexicalVariables(environment, symbolTable, scopeRegisterType, lookUpVarKind);
2078 RegisterID* newScope = nullptr;
2079 RegisterID* constantSymbolTable = nullptr;
2080 int symbolTableConstantIndex = 0;
2081 if (vm()->typeProfiler()) {
2082 constantSymbolTable = addConstantValue(symbolTable);
2083 symbolTableConstantIndex = constantSymbolTable->index();
2085 if (hasCapturedVariables) {
2086 if (scopeRegisterType == ScopeRegisterType::Block) {
2087 newScope = newBlockScopeVariable();
2090 newScope = addVar();
2091 if (!constantSymbolTable) {
2092 ASSERT(!vm()->typeProfiler());
2093 constantSymbolTable = addConstantValue(symbolTable->cloneScopePart(*m_vm));
2094 symbolTableConstantIndex = constantSymbolTable->index();
2096 if (constantSymbolTableResult)
2097 *constantSymbolTableResult = constantSymbolTable;
2099 emitOpcode(op_create_lexical_environment);
2100 instructions().append(newScope->index());
2101 instructions().append(scopeRegister()->index());
2102 instructions().append(constantSymbolTable->index());
2103 instructions().append(addConstantValue(tdzRequirement == TDZRequirement::UnderTDZ ? jsTDZValue() : jsUndefined())->index());
2105 emitMove(scopeRegister(), newScope);
2107 pushLocalControlFlowScope();
2110 bool isWithScope = false;
2111 m_lexicalScopeStack.append({ symbolTable, newScope, isWithScope, symbolTableConstantIndex });
2112 pushTDZVariables(environment, tdzCheckOptimization, tdzRequirement);
2114 if (tdzRequirement == TDZRequirement::UnderTDZ)
2115 emitPrefillStackTDZVariables(environment, symbolTable);
2118 void BytecodeGenerator::initializeBlockScopedFunctions(VariableEnvironment& environment, FunctionStack& functionStack, RegisterID* constantSymbolTable)
2121 * We must transform block scoped function declarations in strict mode like so:
2125 * function foo() { ... }
2128 * function baz() { ... }
2136 * let foo = function foo() { ... }
2137 * let baz = function baz() { ... }
2143 * But without the TDZ checks.
2146 if (!environment.size()) {
2147 RELEASE_ASSERT(!functionStack.size());
2151 if (!functionStack.size())
2154 SymbolTable* symbolTable = m_lexicalScopeStack.last().m_symbolTable;
2155 RegisterID* scope = m_lexicalScopeStack.last().m_scope;
2156 RefPtr<RegisterID> temp = newTemporary();
2157 int symbolTableIndex = constantSymbolTable ? constantSymbolTable->index() : 0;
2158 for (FunctionMetadataNode* function : functionStack) {
2159 const Identifier& name = function->ident();
2160 auto iter = environment.find(name.impl());
2161 RELEASE_ASSERT(iter != environment.end());
2162 RELEASE_ASSERT(iter->value.isFunction());
2163 // We purposefully don't hold the symbol table lock around this loop because emitNewFunctionExpressionCommon may GC.
2164 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, name.impl());
2165 RELEASE_ASSERT(!entry.isNull());
2166 emitNewFunctionExpressionCommon(temp.get(), function);
2167 bool isLexicallyScoped = true;
2168 emitPutToScope(scope, variableForLocalEntry(name, entry, symbolTableIndex, isLexicallyScoped), temp.get(), DoNotThrowIfNotFound, InitializationMode::Initialization);
2172 void BytecodeGenerator::hoistSloppyModeFunctionIfNecessary(const Identifier& functionName)
2174 if (m_scopeNode->hasSloppyModeHoistedFunction(functionName.impl())) {
2175 if (codeType() != EvalCode) {
2176 Variable currentFunctionVariable = variable(functionName);
2177 RefPtr<RegisterID> currentValue;
2178 if (RegisterID* local = currentFunctionVariable.local())
2179 currentValue = local;
2181 RefPtr<RegisterID> scope = emitResolveScope(nullptr, currentFunctionVariable);
2182 currentValue = emitGetFromScope(newTemporary(), scope.get(), currentFunctionVariable, DoNotThrowIfNotFound);
2185 ASSERT(m_varScopeLexicalScopeStackIndex);
2186 ASSERT(*m_varScopeLexicalScopeStackIndex < m_lexicalScopeStack.size());
2187 LexicalScopeStackEntry varScope = m_lexicalScopeStack[*m_varScopeLexicalScopeStackIndex];
2188 SymbolTable* varSymbolTable = varScope.m_symbolTable;
2189 ASSERT(varSymbolTable->scopeType() == SymbolTable::ScopeType::VarScope);
2190 SymbolTableEntry entry = varSymbolTable->get(NoLockingNecessary, functionName.impl());
2191 if (functionName == propertyNames().arguments && entry.isNull()) {
2192 // "arguments" might be put in the parameter scope when we have a non-simple
2193 // parameter list since "arguments" is visible to expressions inside the
2194 // parameter evaluation list.
2196 // function foo(x = arguments) { { function arguments() { } } }
2197 RELEASE_ASSERT(*m_varScopeLexicalScopeStackIndex > 0);
2198 varScope = m_lexicalScopeStack[*m_varScopeLexicalScopeStackIndex - 1];
2199 SymbolTable* parameterSymbolTable = varScope.m_symbolTable;
2200 entry = parameterSymbolTable->get(NoLockingNecessary, functionName.impl());
2202 RELEASE_ASSERT(!entry.isNull());
2203 bool isLexicallyScoped = false;
2204 emitPutToScope(varScope.m_scope, variableForLocalEntry(functionName, entry, varScope.m_symbolTableConstantIndex, isLexicallyScoped), currentValue.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2206 Variable currentFunctionVariable = variable(functionName);
2207 RefPtr<RegisterID> currentValue;
2208 if (RegisterID* local = currentFunctionVariable.local())
2209 currentValue = local;
2211 RefPtr<RegisterID> scope = emitResolveScope(nullptr, currentFunctionVariable);
2212 currentValue = emitGetFromScope(newTemporary(), scope.get(), currentFunctionVariable, DoNotThrowIfNotFound);
2215 RefPtr<RegisterID> scopeId = emitResolveScopeForHoistingFuncDeclInEval(nullptr, functionName);
2216 RefPtr<RegisterID> checkResult = emitIsUndefined(newTemporary(), scopeId.get());
2218 Ref<Label> isNotVarScopeLabel = newLabel();
2219 emitJumpIfTrue(checkResult.get(), isNotVarScopeLabel.get());
2221 // Put to outer scope
2222 emitPutToScope(scopeId.get(), functionName, currentValue.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2223 emitLabel(isNotVarScopeLabel.get());
2229 RegisterID* BytecodeGenerator::emitResolveScopeForHoistingFuncDeclInEval(RegisterID* dst, const Identifier& property)
2231 ASSERT(m_codeType == EvalCode);
2233 dst = finalDestination(dst);
2234 emitOpcode(op_resolve_scope_for_hoisting_func_decl_in_eval);
2235 instructions().append(kill(dst));
2236 instructions().append(m_topMostScope->index());
2237 instructions().append(addConstant(property));
2241 void BytecodeGenerator::popLexicalScope(VariableEnvironmentNode* node)
2243 VariableEnvironment& environment = node->lexicalVariables();
2244 popLexicalScopeInternal(environment);
2247 void BytecodeGenerator::popLexicalScopeInternal(VariableEnvironment& environment)
2249 // NOTE: This function only makes sense for scopes that aren't ScopeRegisterType::Var (only function name scope right now is ScopeRegisterType::Var).
2250 // This doesn't make sense for ScopeRegisterType::Var because we deref RegisterIDs here.
2251 if (!environment.size())
2254 if (m_shouldEmitDebugHooks)
2255 environment.markAllVariablesAsCaptured();
2257 auto stackEntry = m_lexicalScopeStack.takeLast();
2258 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2259 bool hasCapturedVariables = false;
2260 for (auto& entry : environment) {
2261 if (entry.value.isCaptured()) {
2262 hasCapturedVariables = true;
2265 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
2266 ASSERT(!symbolTableEntry.isNull());
2267 VarOffset offset = symbolTableEntry.varOffset();
2268 ASSERT(offset.isStack());
2269 RegisterID* local = ®isterFor(offset.stackOffset());
2273 if (hasCapturedVariables) {
2274 RELEASE_ASSERT(stackEntry.m_scope);
2275 emitPopScope(scopeRegister(), stackEntry.m_scope);
2276 popLocalControlFlowScope();
2277 stackEntry.m_scope->deref();
2280 m_TDZStack.removeLast();
2283 void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode* node, RegisterID* loopSymbolTable)
2285 VariableEnvironment& environment = node->lexicalVariables();
2286 if (!environment.size())
2288 if (m_shouldEmitDebugHooks)
2289 environment.markAllVariablesAsCaptured();
2290 if (!environment.hasCapturedVariables())
2293 RELEASE_ASSERT(loopSymbolTable);
2295 // This function needs to do setup for a for loop's activation if any of
2296 // the for loop's lexically declared variables are captured (that is, variables
2297 // declared in the loop header, not the loop body). This function needs to
2298 // make a copy of the current activation and copy the values from the previous
2299 // activation into the new activation because each iteration of a for loop
2300 // gets a new activation.
2302 auto stackEntry = m_lexicalScopeStack.last();
2303 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2304 RegisterID* loopScope = stackEntry.m_scope;
2305 ASSERT(symbolTable->scopeSize());
2307 Vector<std::pair<RegisterID*, Identifier>> activationValuesToCopyOver;
2310 activationValuesToCopyOver.reserveInitialCapacity(symbolTable->scopeSize());
2312 for (auto end = symbolTable->end(NoLockingNecessary), ptr = symbolTable->begin(NoLockingNecessary); ptr != end; ++ptr) {
2313 if (!ptr->value.varOffset().isScope())
2316 RefPtr<UniquedStringImpl> ident = ptr->key;
2317 Identifier identifier = Identifier::fromUid(m_vm, ident.get());
2319 RegisterID* transitionValue = newBlockScopeVariable();
2320 transitionValue->ref();
2321 emitGetFromScope(transitionValue, loopScope, variableForLocalEntry(identifier, ptr->value, loopSymbolTable->index(), true), DoNotThrowIfNotFound);
2322 activationValuesToCopyOver.uncheckedAppend(std::make_pair(transitionValue, identifier));
2326 // We need this dynamic behavior of the executing code to ensure
2327 // each loop iteration has a new activation object. (It's pretty ugly).
2328 // Also, this new activation needs to be assigned to the same register
2329 // as the previous scope because the loop body is compiled under
2330 // the assumption that the scope's register index is constant even
2331 // though the value in that register will change on each loop iteration.
2332 RefPtr<RegisterID> parentScope = emitGetParentScope(newTemporary(), loopScope);
2333 emitMove(scopeRegister(), parentScope.get());
2335 emitOpcode(op_create_lexical_environment);
2336 instructions().append(loopScope->index());
2337 instructions().append(scopeRegister()->index());
2338 instructions().append(loopSymbolTable->index());
2339 instructions().append(addConstantValue(jsTDZValue())->index());
2341 emitMove(scopeRegister(), loopScope);
2344 for (auto pair : activationValuesToCopyOver) {
2345 const Identifier& identifier = pair.second;
2346 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, identifier.impl());
2347 RELEASE_ASSERT(!entry.isNull());
2348 RegisterID* transitionValue = pair.first;
2349 emitPutToScope(loopScope, variableForLocalEntry(identifier, entry, loopSymbolTable->index(), true), transitionValue, DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2350 transitionValue->deref();
2355 Variable BytecodeGenerator::variable(const Identifier& property, ThisResolutionType thisResolutionType)
2357 if (property == propertyNames().thisIdentifier && thisResolutionType == ThisResolutionType::Local)
2358 return Variable(property, VarOffset(thisRegister()->virtualRegister()), thisRegister(), static_cast<unsigned>(PropertyAttribute::ReadOnly), Variable::SpecialVariable, 0, false);
2360 // We can optimize lookups if the lexical variable is found before a "with" or "catch"
2361 // scope because we're guaranteed static resolution. If we have to pass through
2362 // a "with" or "catch" scope we loose this guarantee.
2363 // We can't optimize cases like this:
2367 // doSomethingWith(x);
2370 // Because we can't gaurantee static resolution on x.
2371 // But, in this case, we are guaranteed static resolution:
2376 // doSomethingWith(x);
2379 for (unsigned i = m_lexicalScopeStack.size(); i--; ) {
2380 auto& stackEntry = m_lexicalScopeStack[i];
2381 if (stackEntry.m_isWithScope)
2382 return Variable(property);
2383 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2384 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, property.impl());
2385 if (symbolTableEntry.isNull())
2387 bool resultIsCallee = false;
2388 if (symbolTable->scopeType() == SymbolTable::ScopeType::FunctionNameScope) {
2389 if (m_usesNonStrictEval) {
2390 // We don't know if an eval has introduced a "var" named the same thing as the function name scope variable name.
2391 // We resort to dynamic lookup to answer this question.
2392 Variable result = Variable(property);
2395 resultIsCallee = true;
2397 Variable result = variableForLocalEntry(property, symbolTableEntry, stackEntry.m_symbolTableConstantIndex, symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope);
2399 result.setIsReadOnly();
2403 return Variable(property);
2406 Variable BytecodeGenerator::variableForLocalEntry(
2407 const Identifier& property, const SymbolTableEntry& entry, int symbolTableConstantIndex, bool isLexicallyScoped)
2409 VarOffset offset = entry.varOffset();
2412 if (offset.isStack())
2413 local = ®isterFor(offset.stackOffset());
2417 return Variable(property, offset, local, entry.getAttributes(), Variable::NormalVariable, symbolTableConstantIndex, isLexicallyScoped);
2420 void BytecodeGenerator::createVariable(
2421 const Identifier& property, VarKind varKind, SymbolTable* symbolTable, ExistingVariableMode existingVariableMode)
2423 ASSERT(property != propertyNames().thisIdentifier);
2424 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, property.impl());
2426 if (!entry.isNull()) {
2427 if (existingVariableMode == IgnoreExisting)
2430 // Do some checks to ensure that the variable we're being asked to create is sufficiently
2431 // compatible with the one we have already created.
2433 VarOffset offset = entry.varOffset();
2435 // We can't change our minds about whether it's captured.
2436 if (offset.kind() != varKind) {
2438 "Trying to add variable called ", property, " as ", varKind,
2439 " but it was already added as ", offset, ".\n");
2440 RELEASE_ASSERT_NOT_REACHED();
2446 VarOffset varOffset;
2447 if (varKind == VarKind::Scope)
2448 varOffset = VarOffset(symbolTable->takeNextScopeOffset(NoLockingNecessary));
2450 ASSERT(varKind == VarKind::Stack);
2451 varOffset = VarOffset(virtualRegisterForLocal(m_calleeLocals.size()));
2453 SymbolTableEntry newEntry(varOffset, 0);
2454 symbolTable->add(NoLockingNecessary, property.impl(), newEntry);
2456 if (varKind == VarKind::Stack) {
2457 RegisterID* local = addVar();
2458 RELEASE_ASSERT(local->index() == varOffset.stackOffset().offset());
2462 RegisterID* BytecodeGenerator::emitOverridesHasInstance(RegisterID* dst, RegisterID* constructor, RegisterID* hasInstanceValue)
2464 emitOpcode(op_overrides_has_instance);
2465 instructions().append(dst->index());
2466 instructions().append(constructor->index());
2467 instructions().append(hasInstanceValue->index());
2471 // Indicates the least upper bound of resolve type based on local scope. The bytecode linker
2472 // will start with this ResolveType and compute the least upper bound including intercepting scopes.
2473 ResolveType BytecodeGenerator::resolveType()
2475 for (unsigned i = m_lexicalScopeStack.size(); i--; ) {
2476 if (m_lexicalScopeStack[i].m_isWithScope)
2478 if (m_usesNonStrictEval && m_lexicalScopeStack[i].m_symbolTable->scopeType() == SymbolTable::ScopeType::FunctionNameScope) {
2479 // We never want to assign to a FunctionNameScope. Returning Dynamic here achieves this goal.
2480 // If we aren't in non-strict eval mode, then NodesCodeGen needs to take care not to emit
2481 // a put_to_scope with the destination being the function name scope variable.
2486 if (m_usesNonStrictEval)
2487 return GlobalPropertyWithVarInjectionChecks;
2488 return GlobalProperty;
2491 RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& variable)
2493 switch (variable.offset().kind()) {
2494 case VarKind::Stack:
2497 case VarKind::DirectArgument:
2498 return argumentsRegister();
2500 case VarKind::Scope: {
2501 // This always refers to the activation that *we* allocated, and not the current scope that code
2502 // lives in. Note that this will change once we have proper support for block scoping. Once that
2503 // changes, it will be correct for this code to return scopeRegister(). The only reason why we
2504 // don't do that already is that m_lexicalEnvironment is required by ConstDeclNode. ConstDeclNode
2505 // requires weird things because it is a shameful pile of nonsense, but block scoping would make
2506 // that code sensible and obviate the need for us to do bad things.
2507 for (unsigned i = m_lexicalScopeStack.size(); i--; ) {
2508 auto& stackEntry = m_lexicalScopeStack[i];
2509 // We should not resolve a variable to VarKind::Scope if a "with" scope lies in between the current
2510 // scope and the resolved scope.
2511 RELEASE_ASSERT(!stackEntry.m_isWithScope);
2513 if (stackEntry.m_symbolTable->get(NoLockingNecessary, variable.ident().impl()).isNull())
2516 RegisterID* scope = stackEntry.m_scope;
2517 RELEASE_ASSERT(scope);
2521 RELEASE_ASSERT_NOT_REACHED();
2525 case VarKind::Invalid:
2526 // Indicates non-local resolution.
2528 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2530 // resolve_scope dst, id, ResolveType, depth
2531 dst = tempDestination(dst);
2532 emitOpcode(op_resolve_scope);
2533 instructions().append(kill(dst));
2534 instructions().append(scopeRegister()->index());
2535 instructions().append(addConstant(variable.ident()));
2536 instructions().append(resolveType());
2537 instructions().append(localScopeDepth());
2538 instructions().append(0);
2542 RELEASE_ASSERT_NOT_REACHED();
2546 RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable& variable, ResolveMode resolveMode)
2548 switch (variable.offset().kind()) {
2549 case VarKind::Stack:
2550 return emitMove(dst, variable.local());
2552 case VarKind::DirectArgument: {
2553 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_arguments);
2554 instructions().append(kill(dst));
2555 instructions().append(scope->index());
2556 instructions().append(variable.offset().capturedArgumentsOffset().offset());
2557 instructions().append(profile);
2561 case VarKind::Scope:
2562 case VarKind::Invalid: {
2563 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2565 // get_from_scope dst, scope, id, GetPutInfo, Structure, Operand
2566 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
2567 instructions().append(kill(dst));
2568 instructions().append(scope->index());
2569 instructions().append(addConstant(variable.ident()));
2570 instructions().append(GetPutInfo(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType(), InitializationMode::NotInitialization).operand());
2571 instructions().append(localScopeDepth());
2572 instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
2573 instructions().append(profile);
2577 RELEASE_ASSERT_NOT_REACHED();
2580 RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode, InitializationMode initializationMode)
2582 switch (variable.offset().kind()) {
2583 case VarKind::Stack:
2584 emitMove(variable.local(), value);
2587 case VarKind::DirectArgument:
2588 emitOpcode(op_put_to_arguments);
2589 instructions().append(scope->index());
2590 instructions().append(variable.offset().capturedArgumentsOffset().offset());
2591 instructions().append(value->index());
2594 case VarKind::Scope:
2595 case VarKind::Invalid: {
2596 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2598 // put_to_scope scope, id, value, GetPutInfo, Structure, Operand
2599 emitOpcode(op_put_to_scope);
2600 instructions().append(scope->index());
2601 instructions().append(addConstant(variable.ident()));
2602 instructions().append(value->index());
2604 if (variable.offset().isScope()) {
2605 offset = variable.offset().scopeOffset();
2606 instructions().append(GetPutInfo(resolveMode, LocalClosureVar, initializationMode).operand());
2607 instructions().append(variable.symbolTableConstantIndex());
2609 ASSERT(resolveType() != LocalClosureVar);
2610 instructions().append(GetPutInfo(resolveMode, resolveType(), initializationMode).operand());
2611 instructions().append(localScopeDepth());
2613 instructions().append(!!offset ? offset.offset() : 0);
2617 RELEASE_ASSERT_NOT_REACHED();
2620 RegisterID* BytecodeGenerator::initializeVariable(const Variable& variable, RegisterID* value)
2622 RELEASE_ASSERT(variable.offset().kind() != VarKind::Invalid);
2623 RegisterID* scope = emitResolveScope(nullptr, variable);
2624 return emitPutToScope(scope, variable, value, ThrowIfNotFound, InitializationMode::NotInitialization);
2627 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
2629 emitOpcode(op_instanceof);
2630 instructions().append(dst->index());
2631 instructions().append(value->index());
2632 instructions().append(basePrototype->index());
2636 RegisterID* BytecodeGenerator::emitInstanceOfCustom(RegisterID* dst, RegisterID* value, RegisterID* constructor, RegisterID* hasInstanceValue)
2638 emitOpcode(op_instanceof_custom);
2639 instructions().append(dst->index());
2640 instructions().append(value->index());
2641 instructions().append(constructor->index());
2642 instructions().append(hasInstanceValue->index());
2646 RegisterID* BytecodeGenerator::emitIn(RegisterID* dst, RegisterID* property, RegisterID* base)
2648 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2650 instructions().append(dst->index());
2651 instructions().append(base->index());
2652 instructions().append(property->index());
2653 instructions().append(arrayProfile);
2657 RegisterID* BytecodeGenerator::emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
2659 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties are not supported with tryGetById.");
2661 UnlinkedValueProfile profile = emitProfiledOpcode(op_try_get_by_id);
2662 instructions().append(kill(dst));
2663 instructions().append(base->index());
2664 instructions().append(addConstant(property));
2665 instructions().append(profile);
2669 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
2671 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
2673 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2675 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id);
2676 instructions().append(kill(dst));
2677 instructions().append(base->index());
2678 instructions().append(addConstant(property));
2679 instructions().append(0);
2680 instructions().append(0);
2681 instructions().append(0);
2682 instructions().append(Options::prototypeHitCountForLLIntCaching());
2683 instructions().append(profile);
2687 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, RegisterID* thisVal, const Identifier& property)
2689 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
2691 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id_with_this);
2692 instructions().append(kill(dst));
2693 instructions().append(base->index());
2694 instructions().append(thisVal->index());
2695 instructions().append(addConstant(property));
2696 instructions().append(profile);
2700 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
2702 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val.");
2704 unsigned propertyIndex = addConstant(property);
2706 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2708 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2710 emitOpcode(op_put_by_id);
2711 instructions().append(base->index());
2712 instructions().append(propertyIndex);
2713 instructions().append(value->index());
2714 instructions().append(0); // old structure
2715 instructions().append(0); // offset
2716 instructions().append(0); // new structure
2717 instructions().append(0); // structure chain
2718 instructions().append(static_cast<int>(PutByIdNone)); // is not direct
2723 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, RegisterID* thisValue, const Identifier& property, RegisterID* value)
2725 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val.");
2727 unsigned propertyIndex = addConstant(property);
2729 emitOpcode(op_put_by_id_with_this);
2730 instructions().append(base->index());
2731 instructions().append(thisValue->index());
2732 instructions().append(propertyIndex);
2733 instructions().append(value->index());
2738 RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType putType)
2740 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val(direct).");
2742 unsigned propertyIndex = addConstant(property);
2744 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2746 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2748 emitOpcode(op_put_by_id);
2749 instructions().append(base->index());
2750 instructions().append(propertyIndex);
2751 instructions().append(value->index());
2752 instructions().append(0); // old structure
2753 instructions().append(0); // offset
2754 instructions().append(0); // new structure
2755 instructions().append(0); // structure chain (unused if direct)
2756 instructions().append(static_cast<int>((putType == PropertyNode::KnownDirect || property != m_vm->propertyNames->underscoreProto) ? PutByIdIsDirect : PutByIdNone));
2760 void BytecodeGenerator::emitPutGetterById(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter)
2762 unsigned propertyIndex = addConstant(property);
2763 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2765 emitOpcode(op_put_getter_by_id);
2766 instructions().append(base->index());
2767 instructions().append(propertyIndex);
2768 instructions().append(attributes);
2769 instructions().append(getter->index());
2772 void BytecodeGenerator::emitPutSetterById(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* setter)
2774 unsigned propertyIndex = addConstant(property);
2775 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2777 emitOpcode(op_put_setter_by_id);
2778 instructions().append(base->index());
2779 instructions().append(propertyIndex);
2780 instructions().append(attributes);
2781 instructions().append(setter->index());
2784 void BytecodeGenerator::emitPutGetterSetter(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter, RegisterID* setter)
2786 unsigned propertyIndex = addConstant(property);
2788 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2790 emitOpcode(op_put_getter_setter_by_id);
2791 instructions().append(base->index());
2792 instructions().append(propertyIndex);
2793 instructions().append(attributes);
2794 instructions().append(getter->index());
2795 instructions().append(setter->index());
2798 void BytecodeGenerator::emitPutGetterByVal(RegisterID* base, RegisterID* property, unsigned attributes, RegisterID* getter)
2800 emitOpcode(op_put_getter_by_val);
2801 instructions().append(base->index());
2802 instructions().append(property->index());
2803 instructions().append(attributes);
2804 instructions().append(getter->index());
2807 void BytecodeGenerator::emitPutSetterByVal(RegisterID* base, RegisterID* property, unsigned attributes, RegisterID* setter)
2809 emitOpcode(op_put_setter_by_val);
2810 instructions().append(base->index());
2811 instructions().append(property->index());
2812 instructions().append(attributes);
2813 instructions().append(setter->index());
2816 void BytecodeGenerator::emitPutGeneratorFields(RegisterID* nextFunction)
2818 // FIXME: Currently, we just create an object and store generator related fields as its properties for ease.
2819 // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties.
2820 // https://bugs.webkit.org/show_bug.cgi?id=151545
2822 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorNextPrivateName(), nextFunction, PropertyNode::KnownDirect);
2824 // We do not store 'this' in arrow function within constructor,
2825 // because it might be not initialized, if super is called later.
2826 if (!(isDerivedConstructorContext() && m_codeBlock->parseMode() == SourceParseMode::AsyncArrowFunctionMode))
2827 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorThisPrivateName(), &m_thisRegister, PropertyNode::KnownDirect);
2829 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorStatePrivateName(), emitLoad(nullptr, jsNumber(0)), PropertyNode::KnownDirect);
2831 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorFramePrivateName(), emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
2834 void BytecodeGenerator::emitPutAsyncGeneratorFields(RegisterID* nextFunction)
2836 ASSERT(isAsyncGeneratorFunctionParseMode(parseMode()));
2838 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorNextPrivateName(), nextFunction, PropertyNode::KnownDirect);
2840 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorThisPrivateName(), &m_thisRegister, PropertyNode::KnownDirect);
2842 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorStatePrivateName(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSAsyncGeneratorFunction::AsyncGeneratorState::SuspendedStart))), PropertyNode::KnownDirect);
2844 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorFramePrivateName(), emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
2846 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().asyncGeneratorSuspendReasonPrivateName(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason::None))), PropertyNode::KnownDirect);
2848 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().asyncGeneratorQueueFirstPrivateName(), emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
2849 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().asyncGeneratorQueueLastPrivateName(), emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
2852 RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
2854 emitOpcode(op_del_by_id);
2855 instructions().append(dst->index());
2856 instructions().append(base->index());
2857 instructions().append(addConstant(property));
2861 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
2863 for (size_t i = m_forInContextStack.size(); i--; ) {
2864 ForInContext& context = m_forInContextStack[i].get();
2865 if (context.local() != property)
2868 unsigned instIndex = instructions().size();
2870 if (context.type() == ForInContext::IndexedForInContextType) {
2871 static_cast<IndexedForInContext&>(context).addGetInst(instIndex, property->index());
2872 property = static_cast<IndexedForInContext&>(context).index();
2876 ASSERT(context.type() == ForInContext::StructureForInContextType);
2877 StructureForInContext& structureContext = static_cast<StructureForInContext&>(context);
2878 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_direct_pname);
2879 instructions().append(kill(dst));
2880 instructions().append(base->index());
2881 instructions().append(property->index());
2882 instructions().append(structureContext.index()->index());
2883 instructions().append(structureContext.enumerator()->index());
2884 instructions().append(profile);
2886 structureContext.addGetInst(instIndex, property->index(), profile);
2890 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2891 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val);
2892 instructions().append(kill(dst));
2893 instructions().append(base->index());
2894 instructions().append(property->index());
2895 instructions().append(arrayProfile);
2896 instructions().append(profile);
2900 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property)
2902 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val_with_this);
2903 instructions().append(kill(dst));
2904 instructions().append(base->index());
2905 instructions().append(thisValue->index());
2906 instructions().append(property->index());
2907 instructions().append(profile);
2911 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
2913 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2914 emitOpcode(op_put_by_val);
2915 instructions().append(base->index());
2916 instructions().append(property->index());
2917 instructions().append(value->index());
2918 instructions().append(arrayProfile);
2923 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value)
2925 emitOpcode(op_put_by_val_with_this);
2926 instructions().append(base->index());
2927 instructions().append(thisValue->index());
2928 instructions().append(property->index());
2929 instructions().append(value->index());
2934 RegisterID* BytecodeGenerator::emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
2936 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2937 emitOpcode(op_put_by_val_direct);
2938 instructions().append(base->index());
2939 instructions().append(property->index());
2940 instructions().append(value->index());
2941 instructions().append(arrayProfile);
2945 RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
2947 emitOpcode(op_del_by_val);
2948 instructions().append(dst->index());
2949 instructions().append(base->index());
2950 instructions().append(property->index());
2954 RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
2956 emitOpcode(op_put_by_index);
2957 instructions().append(base->index());
2958 instructions().append(index);
2959 instructions().append(value->index());
2963 RegisterID* BytecodeGenerator::emitAssert(RegisterID* condition, int line)
2965 emitOpcode(op_assert);
2966 instructions().append(condition->index());
2967 instructions().append(line);
2971 void BytecodeGenerator::emitSuperSamplerBegin()
2973 emitOpcode(op_super_sampler_begin);
2976 void BytecodeGenerator::emitSuperSamplerEnd()
2978 emitOpcode(op_super_sampler_end);
2981 RegisterID* BytecodeGenerator::emitIdWithProfile(RegisterID* src, SpeculatedType profile)
2983 emitOpcode(op_identity_with_profile);
2984 instructions().append(src->index());
2985 instructions().append(static_cast<uint32_t>(profile >> 32));
2986 instructions().append(static_cast<uint32_t>(profile));
2990 void BytecodeGenerator::emitUnreachable()
2992 emitOpcode(op_unreachable);
2995 RegisterID* BytecodeGenerator::emitGetArgument(RegisterID* dst, int32_t index)
2997 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument);
2998 instructions().append(dst->index());
2999 instructions().append(index + 1); // Including |this|.
3000 instructions().append(profile);
3004 RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
3006 size_t begin = instructions().size();
3007 m_staticPropertyAnalyzer.createThis(dst->index(), begin + 3);
3009 m_codeBlock->addPropertyAccessInstruction(instructions().size());
3010 emitOpcode(op_create_this);
3011 instructions().append(dst->index());
3012 instructions().append(dst->index());
3013 instructions().append(0);
3014 instructions().append(0);
3018 void BytecodeGenerator::emitTDZCheck(RegisterID* target)
3020 emitOpcode(op_check_tdz);
3021 instructions().append(target->index());
3024 bool BytecodeGenerator::needsTDZCheck(const Variable& variable)
3026 for (unsigned i = m_TDZStack.size(); i--;) {
3027 auto iter = m_TDZStack[i].find(variable.ident().impl());
3028 if (iter == m_TDZStack[i].end())
3030 return iter->value != TDZNecessityLevel::NotNeeded;
3036 void BytecodeGenerator::emitTDZCheckIfNecessary(const Variable& variable, RegisterID* target, RegisterID* scope)
3038 if (needsTDZCheck(variable)) {
3040 emitTDZCheck(target);
3042 RELEASE_ASSERT(!variable.isLocal() && scope);
3043 RefPtr<RegisterID> result = emitGetFromScope(newTemporary(), scope, variable, DoNotThrowIfNotFound);
3044 emitTDZCheck(result.get());
3049 void BytecodeGenerator::liftTDZCheckIfPossible(const Variable& variable)
3051 RefPtr<UniquedStringImpl> identifier(variable.ident().impl());
3052 for (unsigned i = m_TDZStack.size(); i--;) {
3053 auto iter = m_TDZStack[i].find(identifier);
3054 if (iter != m_TDZStack[i].end()) {
3055 if (iter->value == TDZNecessityLevel::Optimize)
3056 iter->value = TDZNecessityLevel::NotNeeded;
3062 void BytecodeGenerator::pushTDZVariables(const VariableEnvironment& environment, TDZCheckOptimization optimization, TDZRequirement requirement)
3064 if (!environment.size())
3067 TDZNecessityLevel level;
3068 if (requirement == TDZRequirement::UnderTDZ) {
3069 if (optimization == TDZCheckOptimization::Optimize)
3070 level = TDZNecessityLevel::Optimize;
3072 level = TDZNecessityLevel::DoNotOptimize;
3074 level = TDZNecessityLevel::NotNeeded;
3077 for (const auto& entry : environment)
3078 map.add(entry.key, entry.value.isFunction() ? TDZNecessityLevel::NotNeeded : level);
3080 m_TDZStack.append(WTFMove(map));
3083 void BytecodeGenerator::getVariablesUnderTDZ(VariableEnvironment& result)
3085 // We keep track of variablesThatDontNeedTDZ in this algorithm to prevent
3086 // reporting that "x" is under TDZ if this function is called at "...".
3096 SmallPtrSet<UniquedStringImpl*, 16> variablesThatDontNeedTDZ;
3097 for (unsigned i = m_TDZStack.size(); i--; ) {
3098 auto& map = m_TDZStack[i];
3099 for (auto& entry : map) {
3100 if (entry.value != TDZNecessityLevel::NotNeeded) {
3101 if (!variablesThatDontNeedTDZ.contains(entry.key.get()))
3102 result.add(entry.key.get());
3104 variablesThatDontNeedTDZ.add(entry.key.get());
3109 RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
3111 size_t begin = instructions().size();
3112 m_staticPropertyAnalyzer.newObject(dst->index(), begin + 2);
3114 emitOpcode(op_new_object);
3115 instructions().append(dst->index());
3116 instructions().append(0);
3117 instructions().append(newObjectAllocationProfile());
3121 unsigned BytecodeGenerator::addConstantBuffer(unsigned length)
3123 return m_codeBlock->addConstantBuffer(length);
3126 JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
3128 JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
3130 stringInMap = jsString(vm(), identifier.string());
3131 addConstantValue(stringInMap);
3136 RegisterID* BytecodeGenerator::addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&& templateRegistryKey)
3138 return m_templateRegistryKeyMap.ensure(templateRegistryKey.copyRef(), [&] {
3139 auto* result = JSTemplateRegistryKey::create(*vm(), WTFMove(templateRegistryKey));
3140 unsigned index = addConstantIndex();
3141 m_codeBlock->addConstant(result);
3142 return &m_constantPoolRegisters[index];
3146 RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
3148 #if !ASSERT_DISABLED
3149 unsigned checkLength = 0;
3151 bool hadVariableExpression = false;
3153 for (ElementNode* n = elements; n; n = n->next()) {
3154 if (!n->value()->isConstant()) {
3155 hadVariableExpression = true;
3160 #if !ASSERT_DISABLED
3164 if (!hadVariableExpression) {
3165 ASSERT(length == checkLength);
3166 unsigned constantBufferIndex = addConstantBuffer(length);
3167 JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex).data();
3169 for (ElementNode* n = elements; index < length; n = n->next()) {
3170 ASSERT(n->value()->isConstant());
3171 constantBuffer[index++] = static_cast<ConstantNode*>(n->value())->jsValue(*this);
3173 emitOpcode(op_new_array_buffer);
3174 instructions().append(dst->index());
3175 instructions().append(constantBufferIndex);
3176 instructions().append(length);
3177 instructions().append(newArrayAllocationProfile());
3182 Vector<RefPtr<RegisterID>, 16, UnsafeVectorOverflow> argv;
3183 for (ElementNode* n = elements; n; n = n->next()) {
3187 ASSERT(!n->value()->isSpreadExpression());
3188 argv.append(newTemporary());
3189 // op_new_array requires the initial values to be a sequential range of registers
3190 ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() - 1);
3191 emitNode(argv.last().get(), n->value());
3194 emitOpcode(op_new_array);
3195 instructions().append(dst->index());
3196 instructions().append(argv.size() ? argv[0]->index() : 0); // argv
3197 instructions().append(argv.size()); // argc
3198 instructions().append(newArrayAllocationProfile());
3202 RegisterID* BytecodeGenerator::emitNewArrayWithSpread(RegisterID* dst, ElementNode* elements)
3204 BitVector bitVector;
3205 Vector<RefPtr<RegisterID>, 16> argv;
3206 for (ElementNode* node = elements; node; node = node->next()) {
3207 bitVector.set(argv.size(), node->value()->isSpreadExpression());
3209 argv.append(newTemporary());
3210 // op_new_array_with_spread requires the initial values to be a sequential range of registers.
3211 RELEASE_ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() - 1);
3214 RELEASE_ASSERT(argv.size());
3218 for (ElementNode* node = elements; node; node = node->next()) {
3219 if (node->value()->isSpreadExpression()) {
3220 ExpressionNode* expression = static_cast<SpreadExpressionNode*>(node->value())->expression();
3221 RefPtr<RegisterID> tmp = newTemporary();
3222 emitNode(tmp.get(), expression);
3224 emitOpcode(op_spread);
3225 instructions().append(argv[i].get()->index());
3226 instructions().append(tmp.get()->index());
3228 ExpressionNode* expression = node->value();
3229 emitNode(argv[i].get(), expression);
3235 unsigned bitVectorIndex = m_codeBlock->addBitVector(WTFMove(bitVector));
3236 emitOpcode(op_new_array_with_spread);
3237 instructions().append(dst->index());
3238 instructions().append(argv[0]->index()); // argv
3239 instructions().append(argv.size()); // argc
3240 instructions().append(bitVectorIndex);
3245 RegisterID* BytecodeGenerator::emitNewArrayWithSize(RegisterID* dst, RegisterID* length)
3247 emitOpcode(op_new_array_with_size);
3248 instructions().append(dst->index());
3249 instructions().append(length->index());
3250 instructions().append(newArrayAllocationProfile());
3255 RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
3257 emitOpcode(op_new_regexp);
3258 instructions().append(dst->index());
3259 instructions().append(addRegExp(regExp));
3263 void BytecodeGenerator::emitNewFunctionExpressionCommon(RegisterID* dst, FunctionMetadataNode* function)
3265 unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function));
3267 OpcodeID opcodeID = op_new_func_exp;
3268 switch (function->parseMode()) {
3269 case SourceParseMode::GeneratorWrapperFunctionMode:
3270 case SourceParseMode::GeneratorWrapperMethodMode:
3271 opcodeID = op_new_generator_func_exp;
3273 case SourceParseMode::AsyncFunctionMode:
3274 case SourceParseMode::AsyncMethodMode:
3275 case SourceParseMode::AsyncArrowFunctionMode:
3276 opcodeID = op_new_async_func_exp;
3278 case SourceParseMode::AsyncGeneratorWrapperFunctionMode:
3279 case SourceParseMode::AsyncGeneratorWrapperMethodMode:
3280 ASSERT(Options::useAsyncIterator());
3281 opcodeID = op_new_async_generator_func_exp;
3287 emitOpcode(opcodeID);
3288 instructions().append(dst->index());
3289 instructions().append(scopeRegister()->index());
3290 instructions().append(index);
3293 RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func)
3295 emitNewFunctionExpressionCommon(dst, func->metadata());
3299 RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func)
3301 ASSERT(SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(func->metadata()->parseMode()));
3302 emitNewFunctionExpressionCommon(dst, func->metadata());
3306 RegisterID* BytecodeGenerator::emitNewMethodDefinition(RegisterID* dst, MethodDefinitionNode* func)
3308 ASSERT(isMethodParseMode(func->metadata()->parseMode()));
3309 emitNewFunctionExpressionCommon(dst, func->metadata());
3313 RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier& name,
3314 const Identifier& ecmaName, const SourceCode& classSource)
3316 UnlinkedFunctionExecutable* executable = m_vm->builtinExecutables()->createDefaultConstructor(constructorKind, name);
3317 executable->setInvalidTypeProfilingOffsets();
3318 executable->setEcmaName(ecmaName);
3319 executable->setClassSource(classSource);
3321 unsigned index = m_codeBlock->addFunctionExpr(executable);
3323 emitOpcode(op_new_func_exp);
3324 instructions().append(dst->index());
3325 instructions().append(scopeRegister()->index());
3326 instructions().append(index);
3330 RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionMetadataNode* function)
3332 unsigned index = m_codeBlock->addFunctionDecl(makeFunction(function));
3333 if (isGeneratorWrapperParseMode(function->parseMode()))
3334 emitOpcode(op_new_generator_func);
3335 else if (function->parseMode() == SourceParseMode::AsyncFunctionMode)
3336 emitOpcode(op_new_async_func);
3337 else if (function->parseMode() == SourceParseMode::AsyncGeneratorWrapperFunctionMode) {
3338 ASSERT(Options::useAsyncIterator());
3339 emitOpcode(op_new_async_generator_func);
3341 emitOpcode(op_new_func);
3342 instructions().append(dst->index());
3343 instructions().append(scopeRegister()->index());
3344 instructions().append(index);
3348 void BytecodeGenerator::emitSetFunctionNameIfNeeded(ExpressionNode* valueNode, RegisterID* value, RegisterID* name)
3350 if (valueNode->isBaseFuncExprNode()) {
3351 FunctionMetadataNode* metadata = static_cast<BaseFuncExprNode*>(valueNode)->metadata();
3352 if (!metadata->ecmaName().isNull())
3354 } else if (valueNode->isClassExprNode()) {
3355 ClassExprNode* classExprNode = static_cast<ClassExprNode*>(valueNode);
3356 if (!classExprNode->ecmaName().isNull())
3358 if (classExprNode->hasStaticProperty(m_vm->propertyNames->name))
3363 // FIXME: We should use an op_call to an internal function here instead.
3364 // https://bugs.webkit.org/show_bug.cgi?id=155547
3365 emitOpcode(op_set_function_name);
3366 instructions().append(value->index());
3367 instructions().append(name->index());
3370 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3372 return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd, debuggableCall);
3375 RegisterID* BytecodeGenerator::emitCallInTailPosition(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3377 if (m_inTailPosition) {
3378 m_codeBlock->setHasTailCalls();
3379 return emitCall(op_tail_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd, debuggableCall);
3381 return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd, debuggableCall);
3384 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3386 return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, divotStart, divotEnd, debuggableCall);
3389 ExpectedFunction BytecodeGenerator::expectedFunctionForIdentifier(const Identifier& identifier)
3391 if (identifier == propertyNames().Object || identifier == propertyNames().builtinNames().ObjectPrivateName())
3392 return ExpectObjectConstructor;
3393 if (identifier == propertyNames().Array || identifier == propertyNames().builtinNames().ArrayPrivateName())
3394 return ExpectArrayConstructor;
3395 return NoExpectedFunction;
3398 ExpectedFunction BytecodeGenerator::emitExpectedFunctionSnippet(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, Label& done)
3400 Ref<Label> realCall = newLabel();
3401 switch (expectedFunction) {
3402 case ExpectObjectConstructor: {
3403 // If the number of arguments is non-zero, then we can't do anything interesting.
3404 if (callArguments.argumentCountIncludingThis() >= 2)
3405 return NoExpectedFunction;
3407 size_t begin = instructions().size();
3408 emitOpcode(op_jneq_ptr);
3409 instructions().append(func->index());
3410 instructions().append(Special::ObjectConstructor);
3411 instructions().append(realCall->bind(begin, instructions().size()));
3412 instructions().append(0);
3414 if (dst != ignoredResult())
3419 case ExpectArrayConstructor: {
3420 // If you're doing anything other than "new Array()" or "new Array(foo)" then we
3421 // don't do inline it, for now. The only reason is that call arguments are in
3422 // the opposite order of what op_new_array expects, so we'd either need to change
3423 // how op_new_array works or we'd need an op_new_array_reverse. Neither of these
3424 // things sounds like it's worth it.
3425 if (callArguments.argumentCountIncludingThis() > 2)
3426 return NoExpectedFunction;
3428 size_t begin = instructions().size();
3429 emitOpcode(op_jneq_ptr);
3430 instructions().append(func->index());
3431 instructions().append(Special::ArrayConstructor);
3432 instructions().append(realCall->bind(begin, instructions().size()));
3433 instructions().append(0);
3435 if (dst != ignoredResult()) {
3436 if (callArguments.argumentCountIncludingThis() == 2)
3437 emitNewArrayWithSize(dst, callArguments.argumentRegister(0));
3439 ASSERT(callArguments.argumentCountIncludingThis() == 1);
3440 emitOpcode(op_new_array);
3441 instructions().append(dst->index());
3442 instructions().append(0);
3443 instructions().append(0);
3444 instructions().append(newArrayAllocationProfile());
3451 ASSERT(expectedFunction == NoExpectedFunction);
3452 return NoExpectedFunction;
3455 size_t begin = instructions().size();
3457 instructions().append(done.bind(begin, instructions().size()));
3458 emitLabel(realCall.get());
3460 return expectedFunction;
3463 RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3465 ASSERT(opcodeID == op_call || opcodeID == op_call_eval || opcodeID == op_tail_call);
3466 ASSERT(func->refCount());
3468 // Generate code for arguments.
3469 unsigned argument = 0;
3470 if (callArguments.argumentsNode()) {
3471 ArgumentListNode* n = callArguments.argumentsNode()->m_listNode;
3472 if (n && n->m_expr->isSpreadExpression()) {
3473 RELEASE_ASSERT(!n->m_next);
3474 auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
3475 if (expression->isArrayLiteral()) {
3476 auto* elements = static_cast<ArrayNode*>(expression)->elements();
3477 if (elements && !elements->next() && elements->value()->isSpreadExpression()) {
3478 ExpressionNode* expression = static_cast<SpreadExpressionNode*>(elements->value())->expression();
3479 RefPtr<RegisterID> argumentRegister = emitNode(callArguments.argumentRegister(0), expression);
3480 emitOpcode(op_spread);
3481 instructions().append(argumentRegister.get()->index());
3482 instructions().append(argumentRegister.get()->index());
3484 RefPtr<RegisterID> thisRegister = emitMove(newTemporary(), callArguments.thisRegister());
3485 return emitCallVarargs(opcodeID == op_tail_call ? op_tail_call_varargs : op_call_varargs, dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, divot, divotStart, divotEnd, debuggableCall);
3488 RefPtr<RegisterID> argumentRegister;
3489 argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
3490 RefPtr<RegisterID> thisRegister = emitMove(newTemporary(), callArguments.thisRegister());
3491 return emitCallVarargs(opcodeID == op_tail_call ? op_tail_call_varargs : op_call_varargs, dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, divot, divotStart, divotEnd, debuggableCall);
3493 for (; n; n = n->m_next)
3494 emitNode(callArguments.argumentRegister(argument++), n);
3497 // Reserve space for call frame.
3498 Vector<RefPtr<RegisterID>, CallFrame::headerSizeInRegisters, UnsafeVectorOverflow> callFrame;
3499 for (int i = 0; i < CallFrame::headerSizeInRegisters; ++i)
3500 callFrame.append(newTemporary());
3502 if (m_shouldEmitDebugHooks && debuggableCall == DebuggableCall::Yes)
3503 emitDebugHook(WillExecuteExpression, divotStart);
3505 emitExpressionInfo(divot, divotStart, divotEnd);
3507 Ref<Label> done = newLabel();
3508 expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
3510 if (opcodeID == op_tail_call)
3511 emitLogShadowChickenTailIfNecessary();
3514 UnlinkedArrayProfile arrayProfile = newArrayProfile();
3515 UnlinkedValueProfile profile = emitProfiledOpcode(opcodeID);
3517 ASSERT(dst != ignoredResult());
3518 instructions().append(dst->index());
3519 instructions().append(func->index());
3520 instructions().append(callArguments.argumentCountIncludingThis());
3521 instructions().append(callArguments.stackOffset());
3522 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
3523 instructions().append(0);
3524 instructions().append(arrayProfile);
3525 instructions().append(profile);
3527 if (expectedFunction != NoExpectedFunction)
3528 emitLabel(done.get());
3533 RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3535 return emitCallVarargs(op_call_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, divot, divotStart, divotEnd, debuggableCall);
3538 RegisterID* BytecodeGenerator::emitCallVarargsInTailPosition(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3540 return emitCallVarargs(m_inTailPosition ? op_tail_call_varargs : op_call_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, divot, divotStart, divotEnd, debuggableCall);
3543 RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3545 return emitCallVarargs(op_construct_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, divot, divotStart, divotEnd, debuggableCall);
3548 RegisterID* BytecodeGenerator::emitCallForwardArgumentsInTailPosition(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3550 ASSERT(m_inTailPosition);
3551 return emitCallVarargs(op_tail_call_forward_arguments, dst, func, thisRegister, nullptr, firstFreeRegister, firstVarArgOffset, divot, divotStart, divotEnd, debuggableCall);
3554 RegisterID* BytecodeGenerator::emitCallVarargs(OpcodeID opcode, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall)
3556 if (m_shouldEmitDebugHooks && debuggableCall == DebuggableCall::Yes)
3557 emitDebugHook(WillExecuteExpression, divotStart);
3559 emitExpressionInfo(divot, divotStart, divotEnd);
3561 if (opcode == op_tail_call_varargs)
3562 emitLogShadowChickenTailIfNecessary();
3565 UnlinkedArrayProfile arrayProfile = newArrayProfile();
3566 UnlinkedValueProfile profile = emitProfiledOpcode(opcode);
3567 ASSERT(dst != ignoredResult());
3568 instructions().append(dst->index());
3569 instructions().append(func->index());
3570 instructions().append(thisRegister ? thisRegister->index() : 0);
3571 instructions().append(arguments ? arguments->index() : 0);
3572 instructions().append(firstFreeRegister->index());
3573 instructions().append(firstVarArgOffset);
3574 instructions().append(arrayProfile);
3575 instructions().append(profile);
3579 void BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary()
3581 if (!m_shouldEmitDebugHooks && !Options::alwaysUseShadowChicken())
3583 emitOpcode(op_log_shadow_chicken_prologue);
3584 instructions().append(scopeRegister()->index());
3587 void BytecodeGenerator::emitLogShadowChickenTailIfNecessary()
3589 if (!m_shouldEmitDebugHooks && !Options::alwaysUseShadowChicken())
3591 emitOpcode(op_log_shadow_chicken_tail);
3592 instructions().append(thisRegister()->index());
3593 instructions().append(scopeRegister()->index());
3596 void BytecodeGenerator::emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
3597 RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition& position)
3599 DefinePropertyAttributes attributes;
3600 if (options & PropertyConfigurable)
3601 attributes.setConfigurable(true);
3603 if (options & PropertyWritable)
3604 attributes.setWritable(true);
3605 else if (valueRegister)
3606 attributes.setWritable(false);
3608 if (options & PropertyEnumerable)
3609 attributes.setEnumerable(true);
3612 attributes.setValue();
3614 attributes.setGet();
3616 attributes.setSet();
3618 ASSERT(!valueRegister || (!getterRegister && !setterRegister));
3620 emitExpressionInfo(position, position, position);
3622 if (attributes.hasGet() || attributes.hasSet()) {
3623 RefPtr<RegisterID> throwTypeErrorFunction;
3624 if (!attributes.hasGet() || !attributes.hasSet())
3625 throwTypeErrorFunction = emitMoveLinkTimeConstant(nullptr, LinkTimeConstant::ThrowTypeErrorFunction);
3627 RefPtr<RegisterID> getter;
3628 if (attributes.hasGet())
3629 getter = getterRegister;
3631 getter = throwTypeErrorFunction;
3633 RefPtr<RegisterID> setter;
3634 if (attributes.hasSet())
3635 setter = setterRegister;
3637 setter = throwTypeErrorFunction;
3639 emitOpcode(op_define_accessor_property);
3640 instructions().append(newObj->index());
3641 instructions().append(propertyNameRegister->index());
3642 instructions().append(getter->index());
3643 instructions().append(setter->index());
3644 instructions().append(emitLoad(nullptr, jsNumber(attributes.rawRepresentation()))->index());
3646 emitOpcode(op_define_data_property);
3647 instructions().append(newObj->index());
3648 instructions().append(propertyNameRegister->index());
3649 instructions().append(valueRegister->index());
3650 instructions().append(emitLoad(nullptr, jsNumber(attributes.rawRepresentation()))->index());