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 "BytecodeGeneratorification.h"
37 #include "BytecodeLivenessAnalysis.h"
38 #include "DefinePropertyAttributes.h"
39 #include "Interpreter.h"
40 #include "JSCInlines.h"
41 #include "JSFunction.h"
42 #include "JSGeneratorFunction.h"
43 #include "JSLexicalEnvironment.h"
44 #include "JSTemplateRegistryKey.h"
45 #include "LowLevelInterpreter.h"
47 #include "StackAlignment.h"
48 #include "StrongInlines.h"
49 #include "UnlinkedCodeBlock.h"
50 #include "UnlinkedEvalCodeBlock.h"
51 #include "UnlinkedFunctionCodeBlock.h"
52 #include "UnlinkedInstructionStream.h"
53 #include "UnlinkedModuleProgramCodeBlock.h"
54 #include "UnlinkedProgramCodeBlock.h"
55 #include <wtf/BitVector.h>
56 #include <wtf/CommaPrinter.h>
57 #include <wtf/SmallPtrSet.h>
58 #include <wtf/StdLibExtras.h>
59 #include <wtf/text/WTFString.h>
65 void Label::setLocation(unsigned location)
67 m_location = location;
69 unsigned size = m_unresolvedJumps.size();
70 for (unsigned i = 0; i < size; ++i)
71 m_generator.instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
74 void Variable::dump(PrintStream& out) const
78 ", offset = ", m_offset,
79 ", local = ", RawPointer(m_local),
80 ", attributes = ", m_attributes,
82 ", symbolTableConstantIndex = ", m_symbolTableConstantIndex,
83 ", isLexicallyScoped = ", m_isLexicallyScoped, "}");
86 ParserError BytecodeGenerator::generate()
88 m_codeBlock->setThisRegister(m_thisRegister.virtualRegister());
90 emitLogShadowChickenPrologueIfNecessary();
92 // If we have declared a variable named "arguments" and we are using arguments then we should
93 // perform that assignment now.
94 if (m_needToInitializeArguments)
95 initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
98 m_restParameter->emit(*this);
101 RefPtr<RegisterID> temp = newTemporary();
102 RefPtr<RegisterID> globalScope;
103 for (auto functionPair : m_functionsToInitialize) {
104 FunctionMetadataNode* metadata = functionPair.first;
105 FunctionVariableType functionType = functionPair.second;
106 emitNewFunction(temp.get(), metadata);
107 if (functionType == NormalFunctionVariable)
108 initializeVariable(variable(metadata->ident()), temp.get());
109 else if (functionType == GlobalFunctionVariable) {
111 // We know this will resolve to the global object because our parser/global initialization code
112 // doesn't allow let/const/class variables to have the same names as functions.
113 RefPtr<RegisterID> globalObjectScope = emitResolveScope(nullptr, Variable(metadata->ident()));
114 globalScope = newBlockScopeVariable();
115 emitMove(globalScope.get(), globalObjectScope.get());
117 emitPutToScope(globalScope.get(), Variable(metadata->ident()), temp.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
119 RELEASE_ASSERT_NOT_REACHED();
123 bool callingClassConstructor = constructorKind() != ConstructorKind::None && !isConstructor();
124 if (!callingClassConstructor)
125 m_scopeNode->emitBytecode(*this);
127 m_staticPropertyAnalyzer.kill();
129 for (auto& range : m_tryRanges) {
130 int start = range.start->bind();
131 int end = range.end->bind();
133 // This will happen for empty try blocks and for some cases of finally blocks:
145 // The return will pop scopes to execute the outer finally block. But this includes
146 // popping the try context for the inner try. The try context is live in the fall-through
147 // part of the finally block not because we will emit a handler that overlaps the finally,
148 // but because we haven't yet had a chance to plant the catch target. Then when we finish
149 // emitting code for the outer finally block, we repush the try contex, this time with a
150 // new start index. But that means that the start index for the try range corresponding
151 // to the inner-finally-following-the-return (marked as "*HERE*" above) will be greater
152 // than the end index of the try block. This is harmless since end < start handlers will
153 // never get matched in our logic, but we do the runtime a favor and choose to not emit
154 // such handlers at all.
158 UnlinkedHandlerInfo info(static_cast<uint32_t>(start), static_cast<uint32_t>(end),
159 static_cast<uint32_t>(range.tryData->target->bind()), range.tryData->handlerType);
160 m_codeBlock->addExceptionHandler(info);
164 if (isGeneratorOrAsyncFunctionBodyParseMode(m_codeBlock->parseMode()))
165 performGeneratorification(m_codeBlock.get(), m_instructions, m_generatorFrameSymbolTable.get(), m_generatorFrameSymbolTableIndex);
167 m_codeBlock->setInstructions(std::make_unique<UnlinkedInstructionStream>(m_instructions));
169 m_codeBlock->shrinkToFit();
171 if (m_expressionTooDeep)
172 return ParserError(ParserError::OutOfMemory);
173 return ParserError(ParserError::ErrorNone);
176 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
177 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
178 , m_scopeNode(programNode)
179 , m_codeBlock(vm, codeBlock)
180 , m_thisRegister(CallFrame::thisArgumentOffset())
181 , m_codeType(GlobalCode)
183 , m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval())
185 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
187 for (auto& constantRegister : m_linkTimeConstantRegisters)
188 constantRegister = nullptr;
190 allocateCalleeSaveSpace();
192 m_codeBlock->setNumParameters(1); // Allocate space for "this"
196 allocateAndEmitScope();
200 const FunctionStack& functionStack = programNode->functionStack();
202 for (auto* function : functionStack)
203 m_functionsToInitialize.append(std::make_pair(function, GlobalFunctionVariable));
205 if (Options::validateBytecode()) {
206 for (auto& entry : programNode->varDeclarations())
207 RELEASE_ASSERT(entry.value.isVar());
209 codeBlock->setVariableDeclarations(programNode->varDeclarations());
210 codeBlock->setLexicalDeclarations(programNode->lexicalVariables());
211 // Even though this program may have lexical variables that go under TDZ, when linking the get_from_scope/put_to_scope
212 // operations we emit we will have ResolveTypes that implictly do TDZ checks. Therefore, we don't need
213 // additional TDZ checks on top of those. This is why we can omit pushing programNode->lexicalVariables()
216 if (needsToUpdateArrowFunctionContext()) {
217 initializeArrowFunctionContextScopeIfNeeded();
218 emitPutThisToArrowFunctionContextScope();
222 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
223 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
224 , m_scopeNode(functionNode)
225 , m_codeBlock(vm, codeBlock)
226 , m_codeType(FunctionCode)
228 , m_isBuiltinFunction(codeBlock->isBuiltinFunction())
229 , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
230 // FIXME: We should be able to have tail call elimination with the profiler
231 // enabled. This is currently not possible because the profiler expects
232 // op_will_call / op_did_call pairs before and after a call, which are not
233 // compatible with tail calls (we have no way of emitting op_did_call).
234 // https://bugs.webkit.org/show_bug.cgi?id=148819
235 , m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && isStrictMode())
236 , m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval())
237 , m_derivedContextType(codeBlock->derivedContextType())
239 for (auto& constantRegister : m_linkTimeConstantRegisters)
240 constantRegister = nullptr;
242 if (m_isBuiltinFunction)
243 m_shouldEmitDebugHooks = false;
245 allocateCalleeSaveSpace();
247 SymbolTable* functionSymbolTable = SymbolTable::create(*m_vm);
248 functionSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval);
249 int symbolTableConstantIndex = 0;
251 FunctionParameters& parameters = *functionNode->parameters();
252 // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
253 // This implements IsSimpleParameterList in the Ecma 2015 spec.
254 // If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
255 // IsSimpleParameterList is false if the argument list contains any default parameter values,
256 // a rest parameter, or any destructuring patterns.
257 // If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope.
258 bool isSimpleParameterList = parameters.isSimpleParameterList();
260 SourceParseMode parseMode = codeBlock->parseMode();
262 bool containsArrowOrEvalButNotInArrowBlock = ((functionNode->usesArrowFunction() && functionNode->doAnyInnerArrowFunctionsUseAnyFeature()) || functionNode->usesEval()) && !m_codeBlock->isArrowFunction();
263 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || functionNode->needsActivation() || containsArrowOrEvalButNotInArrowBlock;
265 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
266 bool needsArguments = ((functionNode->usesArguments() && !codeBlock->isArrowFunction()) || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction()));
268 if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode)) {
269 // Generator and AsyncFunction never provides "arguments". "arguments" reference will be resolved in an upper generator function scope.
270 needsArguments = false;
272 // Generator and AsyncFunction uses the var scope to save and resume its variables. So the lexical scope is always instantiated.
273 shouldCaptureSomeOfTheThings = true;
276 if (isGeneratorOrAsyncFunctionWrapperParseMode(parseMode) && needsArguments) {
277 // Generator does not provide "arguments". Instead, wrapping GeneratorFunction provides "arguments".
278 // This is because arguments of a generator should be evaluated before starting it.
279 // To workaround it, we evaluate these arguments as arguments of a wrapping generator function, and reference it from a generator.
281 // function *gen(a, b = hello())
284 // @generatorNext: function (@generator, @generatorState, @generatorValue, @generatorResumeMode, @generatorFrame)
286 // arguments; // This `arguments` should reference to the gen's arguments.
291 shouldCaptureSomeOfTheThings = true;
294 if (shouldCaptureAllOfTheThings)
295 functionNode->varDeclarations().markAllVariablesAsCaptured();
297 auto captures = [&] (UniquedStringImpl* uid) -> bool {
298 if (!shouldCaptureSomeOfTheThings)
300 if (needsArguments && uid == propertyNames().arguments.impl()) {
301 // Actually, we only need to capture the arguments object when we "need full activation"
302 // because of name scopes. But historically we did it this way, so for now we just preserve
304 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=143072
307 return functionNode->captures(uid);
309 auto varKind = [&] (UniquedStringImpl* uid) -> VarKind {
310 return captures(uid) ? VarKind::Scope : VarKind::Stack;
313 m_calleeRegister.setIndex(CallFrameSlot::callee);
315 initializeParameters(parameters);
316 ASSERT(!(isSimpleParameterList && m_restParameter));
320 if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode))
321 m_generatorRegister = &m_parameters[1];
323 allocateAndEmitScope();
327 if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())) {
328 ASSERT(parseMode != SourceParseMode::GeneratorBodyMode);
329 ASSERT(!isAsyncFunctionBodyParseMode(parseMode));
330 bool isDynamicScope = functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode());
331 bool isFunctionNameCaptured = captures(functionNode->ident().impl());
332 bool markAsCaptured = isDynamicScope || isFunctionNameCaptured;
333 emitPushFunctionNameScope(functionNode->ident(), &m_calleeRegister, markAsCaptured);
336 if (shouldCaptureSomeOfTheThings)
337 m_lexicalEnvironmentRegister = addVar();
339 if (shouldCaptureSomeOfTheThings || vm.typeProfiler())
340 symbolTableConstantIndex = addConstantValue(functionSymbolTable)->index();
342 // We can allocate the "var" environment if we don't have default parameter expressions. If we have
343 // default parameter expressions, we have to hold off on allocating the "var" environment because
344 // the parent scope of the "var" environment is the parameter environment.
345 if (isSimpleParameterList)
346 initializeVarLexicalEnvironment(symbolTableConstantIndex, functionSymbolTable, shouldCaptureSomeOfTheThings);
348 // Figure out some interesting facts about our arguments.
349 bool capturesAnyArgumentByName = false;
350 if (functionNode->hasCapturedVariables()) {
351 FunctionParameters& parameters = *functionNode->parameters();
352 for (size_t i = 0; i < parameters.size(); ++i) {
353 auto pattern = parameters.at(i).first;
354 if (!pattern->isBindingNode())
356 const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
357 capturesAnyArgumentByName |= captures(ident.impl());
361 if (capturesAnyArgumentByName)
362 ASSERT(m_lexicalEnvironmentRegister);
364 // Need to know what our functions are called. Parameters have some goofy behaviors when it
365 // comes to functions of the same name.
366 for (FunctionMetadataNode* function : functionNode->functionStack())
367 m_functions.add(function->ident().impl());
369 if (needsArguments) {
370 // Create the arguments object now. We may put the arguments object into the activation if
371 // it is captured. Either way, we create two arguments object variables: one is our
372 // private variable that is immutable, and another that is the user-visible variable. The
373 // immutable one is only used here, or during formal parameter resolutions if we opt for
376 m_argumentsRegister = addVar();
377 m_argumentsRegister->ref();
380 if (needsArguments && !codeBlock->isStrictMode() && isSimpleParameterList) {
381 // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
382 // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
385 if (capturesAnyArgumentByName) {
386 functionSymbolTable->setArgumentsLength(vm, parameters.size());
388 // For each parameter, we have two possibilities:
389 // Either it's a binding node with no function overlap, in which case it gets a name
390 // in the symbol table - or it just gets space reserved in the symbol table. Either
391 // way we lift the value into the scope.
392 for (unsigned i = 0; i < parameters.size(); ++i) {
393 ScopeOffset offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
394 functionSymbolTable->setArgumentOffset(vm, i, offset);
395 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first)) {
396 VarOffset varOffset(offset);
397 SymbolTableEntry entry(varOffset);
398 // Stores to these variables via the ScopedArguments object will not do
399 // notifyWrite(), since that would be cumbersome. Also, watching formal
400 // parameters when "arguments" is in play is unlikely to be super profitable.
401 // So, we just disable it.
402 entry.disableWatching(*m_vm);
403 functionSymbolTable->set(NoLockingNecessary, name, entry);
405 emitOpcode(op_put_to_scope);
406 instructions().append(m_lexicalEnvironmentRegister->index());
407 instructions().append(UINT_MAX);
408 instructions().append(virtualRegisterForArgument(1 + i).offset());
409 instructions().append(GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization).operand());
410 instructions().append(symbolTableConstantIndex);
411 instructions().append(offset.offset());
414 // This creates a scoped arguments object and copies the overflow arguments into the
415 // scope. It's the equivalent of calling ScopedArguments::createByCopying().
416 emitOpcode(op_create_scoped_arguments);
417 instructions().append(m_argumentsRegister->index());
418 instructions().append(m_lexicalEnvironmentRegister->index());
420 // We're going to put all parameters into the DirectArguments object. First ensure
421 // that the symbol table knows that this is happening.
422 for (unsigned i = 0; i < parameters.size(); ++i) {
423 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first))
424 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
427 emitOpcode(op_create_direct_arguments);
428 instructions().append(m_argumentsRegister->index());
430 } else if (isSimpleParameterList) {
431 // Create the formal parameters the normal way. Any of them could be captured, or not. If
432 // captured, lift them into the scope. We cannot do this if we have default parameter expressions
433 // because when default parameter expressions exist, they belong in their own lexical environment
434 // separate from the "var" lexical environment.
435 for (unsigned i = 0; i < parameters.size(); ++i) {
436 UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first);
440 if (!captures(name)) {
441 // This is the easy case - just tell the symbol table about the argument. It will
442 // be accessed directly.
443 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
447 ScopeOffset offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
448 const Identifier& ident =
449 static_cast<const BindingNode*>(parameters.at(i).first)->boundProperty();
450 functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(offset)));
452 emitOpcode(op_put_to_scope);
453 instructions().append(m_lexicalEnvironmentRegister->index());
454 instructions().append(addConstant(ident));
455 instructions().append(virtualRegisterForArgument(1 + i).offset());
456 instructions().append(GetPutInfo(ThrowIfNotFound, LocalClosureVar, InitializationMode::NotInitialization).operand());
457 instructions().append(symbolTableConstantIndex);
458 instructions().append(offset.offset());
462 if (needsArguments && (codeBlock->isStrictMode() || !isSimpleParameterList)) {
463 // Allocate a cloned arguments object.
464 emitOpcode(op_create_cloned_arguments);
465 instructions().append(m_argumentsRegister->index());
468 // There are some variables that need to be preinitialized to something other than Undefined:
470 // - "arguments": unless it's used as a function or parameter, this should refer to the
473 // - functions: these always override everything else.
475 // The most logical way to do all of this is to initialize none of the variables until now,
476 // and then initialize them in BytecodeGenerator::generate() in such an order that the rules
477 // for how these things override each other end up holding. We would initialize "arguments" first,
478 // then all arguments, then the functions.
480 // But some arguments are already initialized by default, since if they aren't captured and we
481 // don't have "arguments" then we just point the symbol table at the stack slot of those
482 // arguments. We end up initializing the rest of the arguments that have an uncomplicated
483 // binding (i.e. don't involve destructuring) above when figuring out how to lay them out,
484 // because that's just the simplest thing. This means that when we initialize them, we have to
485 // watch out for the things that override arguments (namely, functions).
487 // This is our final act of weirdness. "arguments" is overridden by everything except the
488 // callee. We add it to the symbol table if it's not already there and it's not an argument.
489 bool shouldCreateArgumentsVariableInParameterScope = false;
490 if (needsArguments) {
491 // If "arguments" is overridden by a function or destructuring parameter name, then it's
492 // OK for us to call createVariable() because it won't change anything. It's also OK for
493 // us to them tell BytecodeGenerator::generate() to write to it because it will do so
494 // before it initializes functions and destructuring parameters. But if "arguments" is
495 // overridden by a "simple" function parameter, then we have to bail: createVariable()
496 // would assert and BytecodeGenerator::generate() would write the "arguments" after the
497 // argument value had already been properly initialized.
499 bool haveParameterNamedArguments = false;
500 for (unsigned i = 0; i < parameters.size(); ++i) {
501 UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first);
502 if (name == propertyNames().arguments.impl()) {
503 haveParameterNamedArguments = true;
508 bool shouldCreateArgumensVariable = !haveParameterNamedArguments
509 && !SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(m_codeBlock->parseMode());
510 shouldCreateArgumentsVariableInParameterScope = shouldCreateArgumensVariable && !isSimpleParameterList;
511 // Do not create arguments variable in case of Arrow function. Value will be loaded from parent scope
512 if (shouldCreateArgumensVariable && !shouldCreateArgumentsVariableInParameterScope) {
514 propertyNames().arguments, varKind(propertyNames().arguments.impl()), functionSymbolTable);
516 m_needToInitializeArguments = true;
520 for (FunctionMetadataNode* function : functionNode->functionStack()) {
521 const Identifier& ident = function->ident();
522 createVariable(ident, varKind(ident.impl()), functionSymbolTable);
523 m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
525 for (auto& entry : functionNode->varDeclarations()) {
526 ASSERT(!entry.value.isLet() && !entry.value.isConst());
527 if (!entry.value.isVar()) // This is either a parameter or callee.
529 if (shouldCreateArgumentsVariableInParameterScope && entry.key.get() == propertyNames().arguments.impl())
531 createVariable(Identifier::fromUid(m_vm, entry.key.get()), varKind(entry.key.get()), functionSymbolTable, IgnoreExisting);
535 m_newTargetRegister = addVar();
537 case SourceParseMode::GeneratorWrapperFunctionMode: {
538 m_generatorRegister = addVar();
540 // FIXME: Emit to_this only when Generator uses it.
541 // https://bugs.webkit.org/show_bug.cgi?id=151586
542 m_codeBlock->addPropertyAccessInstruction(instructions().size());
543 emitOpcode(op_to_this);
544 instructions().append(kill(&m_thisRegister));
545 instructions().append(0);
546 instructions().append(0);
548 emitMove(m_generatorRegister, &m_calleeRegister);
549 emitCreateThis(m_generatorRegister);
553 case SourceParseMode::AsyncArrowFunctionMode:
554 case SourceParseMode::AsyncMethodMode:
555 case SourceParseMode::AsyncFunctionMode: {
556 ASSERT(!isConstructor());
557 ASSERT(constructorKind() == ConstructorKind::None);
558 m_generatorRegister = addVar();
559 m_promiseCapabilityRegister = addVar();
561 if (parseMode != SourceParseMode::AsyncArrowFunctionMode) {
562 // FIXME: Emit to_this only when AsyncFunctionBody uses it.
563 // https://bugs.webkit.org/show_bug.cgi?id=151586
564 m_codeBlock->addPropertyAccessInstruction(instructions().size());
565 emitOpcode(op_to_this);
566 instructions().append(kill(&m_thisRegister));
567 instructions().append(0);
568 instructions().append(0);
571 emitNewObject(m_generatorRegister);
573 // let promiseCapability be @newPromiseCapability(@Promise)
574 auto varNewPromiseCapability = variable(propertyNames().builtinNames().newPromiseCapabilityPrivateName());
575 RefPtr<RegisterID> scope = newTemporary();
576 moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), varNewPromiseCapability));
577 RefPtr<RegisterID> newPromiseCapability = emitGetFromScope(newTemporary(), scope.get(), varNewPromiseCapability, ThrowIfNotFound);
579 CallArguments args(*this, nullptr, 1);
580 emitLoad(args.thisRegister(), jsUndefined());
582 auto varPromiseConstructor = variable(propertyNames().builtinNames().PromisePrivateName());
583 moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), varPromiseConstructor));
584 emitGetFromScope(args.argumentRegister(0), scope.get(), varPromiseConstructor, ThrowIfNotFound);
586 // JSTextPosition(int _line, int _offset, int _lineStartOffset)
587 JSTextPosition divot(m_scopeNode->firstLine(), m_scopeNode->startOffset(), m_scopeNode->lineStartOffset());
588 emitCall(promiseCapabilityRegister(), newPromiseCapability.get(), NoExpectedFunction, args, divot, divot, divot, DebuggableCall::No);
592 case SourceParseMode::AsyncFunctionBodyMode:
593 case SourceParseMode::AsyncArrowFunctionBodyMode:
594 case SourceParseMode::GeneratorBodyMode: {
595 // |this| is already filled correctly before here.
596 emitLoad(m_newTargetRegister, jsUndefined());
601 if (SourceParseMode::ArrowFunctionMode != parseMode) {
602 if (isConstructor()) {
603 emitMove(m_newTargetRegister, &m_thisRegister);
604 if (constructorKind() == ConstructorKind::Extends) {
605 Ref<Label> isDerived = newLabel();
606 Ref<Label> done = newLabel();
607 m_isDerivedConstuctor = addVar();
608 emitGetById(m_isDerivedConstuctor, &m_calleeRegister, propertyNames().builtinNames().isDerivedConstructorPrivateName());
609 emitJumpIfTrue(m_isDerivedConstuctor, isDerived.get());
610 emitCreateThis(&m_thisRegister);
611 emitJump(done.get());
612 emitLabel(isDerived.get());
613 emitMoveEmptyValue(&m_thisRegister);
614 emitLabel(done.get());
616 emitCreateThis(&m_thisRegister);
617 } else if (constructorKind() != ConstructorKind::None)
618 emitThrowTypeError("Cannot call a class constructor without |new|");
620 bool shouldEmitToThis = false;
621 if (functionNode->usesThis() || codeBlock->usesEval() || m_scopeNode->doAnyInnerArrowFunctionsUseThis() || m_scopeNode->doAnyInnerArrowFunctionsUseEval())
622 shouldEmitToThis = true;
623 else if ((functionNode->usesSuperProperty() || m_scopeNode->doAnyInnerArrowFunctionsUseSuperProperty()) && !codeBlock->isStrictMode()) {
624 // We must emit to_this when we're not in strict mode because we
625 // will convert |this| to an object, and that object may be passed
626 // to a strict function as |this|. This is observable because that
627 // strict function's to_this will just return the object.
629 // We don't need to emit this for strict-mode code because
630 // strict-mode code may call another strict function, which will
631 // to_this if it directly uses this; this is OK, because we defer
632 // to_this until |this| is used directly. Strict-mode code might
633 // also call a sloppy mode function, and that will to_this, which
634 // will defer the conversion, again, until necessary.
635 shouldEmitToThis = true;
638 if (shouldEmitToThis) {
639 m_codeBlock->addPropertyAccessInstruction(instructions().size());
640 emitOpcode(op_to_this);
641 instructions().append(kill(&m_thisRegister));
642 instructions().append(0);
643 instructions().append(0);
651 // We need load |super| & |this| for arrow function before initializeDefaultParameterValuesAndSetupFunctionScopeStack
652 // if we have default parameter expression. Because |super| & |this| values can be used there
653 if ((SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(parseMode) && !isSimpleParameterList) || parseMode == SourceParseMode::AsyncArrowFunctionBodyMode) {
654 if (functionNode->usesThis() || functionNode->usesSuperProperty())
655 emitLoadThisFromArrowFunctionLexicalEnvironment();
657 if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
658 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
661 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) {
662 bool canReuseLexicalEnvironment = isSimpleParameterList;
663 initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable, canReuseLexicalEnvironment);
664 emitPutThisToArrowFunctionContextScope();
665 emitPutNewTargetToArrowFunctionContextScope();
666 emitPutDerivedConstructorToArrowFunctionContextScope();
669 // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called
670 // because a function's default parameter ExpressionNodes will use temporary registers.
671 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ);
673 Ref<Label> catchLabel = newLabel();
674 TryData* tryFormalParametersData = nullptr;
675 bool needTryCatch = isAsyncFunctionWrapperParseMode(parseMode) && !isSimpleParameterList;
677 Ref<Label> tryFormalParametersStart = newEmittedLabel();
678 tryFormalParametersData = pushTry(tryFormalParametersStart.get(), catchLabel.get(), HandlerType::SynthesizedCatch);
681 initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, isSimpleParameterList, functionNode, functionSymbolTable, symbolTableConstantIndex, captures, shouldCreateArgumentsVariableInParameterScope);
684 Ref<Label> didNotThrow = newLabel();
685 emitJump(didNotThrow.get());
686 emitLabel(catchLabel.get());
687 popTry(tryFormalParametersData, catchLabel.get());
689 RefPtr<RegisterID> thrownValue = newTemporary();
690 RegisterID* unused = newTemporary();
691 emitCatch(unused, thrownValue.get());
693 // return promiseCapability.@reject(thrownValue)
694 RefPtr<RegisterID> reject = emitGetById(newTemporary(), promiseCapabilityRegister(), m_vm->propertyNames->builtinNames().rejectPrivateName());
696 CallArguments args(*this, nullptr, 1);
697 emitLoad(args.thisRegister(), jsUndefined());
698 emitMove(args.argumentRegister(0), thrownValue.get());
700 JSTextPosition divot(functionNode->firstLine(), functionNode->startOffset(), functionNode->lineStartOffset());
702 RefPtr<RegisterID> result = emitCall(newTemporary(), reject.get(), NoExpectedFunction, args, divot, divot, divot, DebuggableCall::No);
703 emitReturn(emitGetById(newTemporary(), promiseCapabilityRegister(), m_vm->propertyNames->builtinNames().promisePrivateName()));
705 emitLabel(didNotThrow.get());
708 // If we don't have default parameter expression, then loading |this| inside an arrow function must be done
709 // after initializeDefaultParameterValuesAndSetupFunctionScopeStack() because that function sets up the
710 // SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment() consults the SymbolTable stack
711 if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(parseMode) && isSimpleParameterList) {
712 if (functionNode->usesThis() || functionNode->usesSuperProperty())
713 emitLoadThisFromArrowFunctionLexicalEnvironment();
715 if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
716 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
719 // 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.
720 // Since they are symbol keyed, these variables cannot be reached from the usual code.
721 if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode)) {
722 ASSERT(m_lexicalEnvironmentRegister);
723 m_generatorFrameSymbolTable.set(*m_vm, functionSymbolTable);
724 m_generatorFrameSymbolTableIndex = symbolTableConstantIndex;
725 emitMove(generatorFrameRegister(), m_lexicalEnvironmentRegister);
726 emitPutById(generatorRegister(), propertyNames().builtinNames().generatorFramePrivateName(), generatorFrameRegister());
729 bool shouldInitializeBlockScopedFunctions = false; // We generate top-level function declarations in ::generate().
730 pushLexicalScope(m_scopeNode, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions);
733 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
734 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
735 , m_scopeNode(evalNode)
736 , m_codeBlock(vm, codeBlock)
737 , m_thisRegister(CallFrame::thisArgumentOffset())
738 , m_codeType(EvalCode)
740 , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
741 , m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval())
742 , m_derivedContextType(codeBlock->derivedContextType())
744 for (auto& constantRegister : m_linkTimeConstantRegisters)
745 constantRegister = nullptr;
747 allocateCalleeSaveSpace();
749 m_codeBlock->setNumParameters(1);
751 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ);
755 allocateAndEmitScope();
759 const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
760 for (size_t i = 0; i < functionStack.size(); ++i)
761 m_codeBlock->addFunctionDecl(makeFunction(functionStack[i]));
763 const VariableEnvironment& varDeclarations = evalNode->varDeclarations();
764 unsigned numVariables = varDeclarations.size();
765 Vector<Identifier, 0, UnsafeVectorOverflow> variables;
766 variables.reserveCapacity(numVariables);
767 for (auto& entry : varDeclarations) {
768 ASSERT(entry.value.isVar());
769 ASSERT(entry.key->isAtomic() || entry.key->isSymbol());
770 variables.append(Identifier::fromUid(m_vm, entry.key.get()));
772 codeBlock->adoptVariables(variables);
774 if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
775 m_newTargetRegister = addVar();
777 if (codeBlock->isArrowFunctionContext() && (evalNode->usesThis() || evalNode->usesSuperProperty()))
778 emitLoadThisFromArrowFunctionLexicalEnvironment();
780 if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
781 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
783 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunctionContext() && !isDerivedConstructorContext()) {
784 initializeArrowFunctionContextScopeIfNeeded();
785 emitPutThisToArrowFunctionContextScope();
788 bool shouldInitializeBlockScopedFunctions = false; // We generate top-level function declarations in ::generate().
789 pushLexicalScope(m_scopeNode, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions);
792 BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables)
793 : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
794 , m_scopeNode(moduleProgramNode)
795 , m_codeBlock(vm, codeBlock)
796 , m_thisRegister(CallFrame::thisArgumentOffset())
797 , m_codeType(ModuleCode)
799 , m_usesNonStrictEval(false)
800 , m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval())
802 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size());
804 for (auto& constantRegister : m_linkTimeConstantRegisters)
805 constantRegister = nullptr;
807 if (m_isBuiltinFunction)
808 m_shouldEmitDebugHooks = false;
810 allocateCalleeSaveSpace();
812 SymbolTable* moduleEnvironmentSymbolTable = SymbolTable::create(*m_vm);
813 moduleEnvironmentSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval);
814 moduleEnvironmentSymbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope);
816 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
817 if (shouldCaptureAllOfTheThings)
818 moduleProgramNode->varDeclarations().markAllVariablesAsCaptured();
820 auto captures = [&] (UniquedStringImpl* uid) -> bool {
821 return moduleProgramNode->captures(uid);
823 auto lookUpVarKind = [&] (UniquedStringImpl* uid, const VariableEnvironmentEntry& entry) -> VarKind {
824 // Allocate the exported variables in the module environment.
825 if (entry.isExported())
826 return VarKind::Scope;
828 // Allocate the namespace variables in the module environment to instantiate
829 // it from the outside of the module code.
830 if (entry.isImportedNamespace())
831 return VarKind::Scope;
833 if (entry.isCaptured())
834 return VarKind::Scope;
835 return captures(uid) ? VarKind::Scope : VarKind::Stack;
840 allocateAndEmitScope();
844 m_calleeRegister.setIndex(CallFrameSlot::callee);
846 m_codeBlock->setNumParameters(1); // Allocate space for "this"
848 // Now declare all variables.
850 for (auto& entry : moduleProgramNode->varDeclarations()) {
851 ASSERT(!entry.value.isLet() && !entry.value.isConst());
852 if (!entry.value.isVar()) // This is either a parameter or callee.
854 // Imported bindings are not allocated in the module environment as usual variables' way.
855 // These references remain the "Dynamic" in the unlinked code block. Later, when linking
856 // the code block, we resolve the reference to the "ModuleVar".
857 if (entry.value.isImported() && !entry.value.isImportedNamespace())
859 createVariable(Identifier::fromUid(m_vm, entry.key.get()), lookUpVarKind(entry.key.get(), entry.value), moduleEnvironmentSymbolTable, IgnoreExisting);
862 VariableEnvironment& lexicalVariables = moduleProgramNode->lexicalVariables();
863 instantiateLexicalVariables(lexicalVariables, moduleEnvironmentSymbolTable, ScopeRegisterType::Block, lookUpVarKind);
865 // We keep the symbol table in the constant pool.
866 RegisterID* constantSymbolTable = nullptr;
867 if (vm.typeProfiler())
868 constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable);
870 constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable->cloneScopePart(*m_vm));
872 pushTDZVariables(lexicalVariables, TDZCheckOptimization::Optimize, TDZRequirement::UnderTDZ);
873 bool isWithScope = false;
874 m_lexicalScopeStack.append({ moduleEnvironmentSymbolTable, m_topMostScope, isWithScope, constantSymbolTable->index() });
875 emitPrefillStackTDZVariables(lexicalVariables, moduleEnvironmentSymbolTable);
877 // makeFunction assumes that there's correct TDZ stack entries.
878 // So it should be called after putting our lexical environment to the TDZ stack correctly.
880 for (FunctionMetadataNode* function : moduleProgramNode->functionStack()) {
881 const auto& iterator = moduleProgramNode->varDeclarations().find(function->ident().impl());
882 RELEASE_ASSERT(iterator != moduleProgramNode->varDeclarations().end());
883 RELEASE_ASSERT(!iterator->value.isImported());
885 VarKind varKind = lookUpVarKind(iterator->key.get(), iterator->value);
886 if (varKind == VarKind::Scope) {
887 // http://www.ecma-international.org/ecma-262/6.0/#sec-moduledeclarationinstantiation
888 // Section 15.2.1.16.4, step 16-a-iv-1.
889 // All heap allocated function declarations should be instantiated when the module environment
890 // is created. They include the exported function declarations and not-exported-but-heap-allocated
891 // function declarations. This is required because exported function should be instantiated before
892 // executing the any module in the dependency graph. This enables the modules to link the imported
893 // bindings before executing the any module code.
895 // And since function declarations are instantiated before executing the module body code, the spec
896 // allows the functions inside the module to be executed before its module body is executed under
897 // the circular dependencies. The following is the example.
899 // Module A (executed first):
900 // import { b } from "B";
901 // // Here, the module "B" is not executed yet, but the function declaration is already instantiated.
902 // // So we can call the function exported from "B".
905 // export function a() {
908 // Module B (executed second):
909 // import { a } from "A";
911 // export function b() {
915 // // c is not exported, but since it is referenced from the b, we should instantiate it before
916 // // executing the "B" module code.
921 // Module EntryPoint (executed last):
925 m_codeBlock->addFunctionDecl(makeFunction(function));
927 // Stack allocated functions can be allocated when executing the module's body.
928 m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
932 // Remember the constant register offset to the top-most symbol table. This symbol table will be
933 // cloned in the code block linking. After that, to create the module environment, we retrieve
934 // the cloned symbol table from the linked code block by using this offset.
935 codeBlock->setModuleEnvironmentSymbolTableConstantRegisterOffset(constantSymbolTable->index());
938 BytecodeGenerator::~BytecodeGenerator()
942 void BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack(
943 FunctionParameters& parameters, bool isSimpleParameterList, FunctionNode* functionNode, SymbolTable* functionSymbolTable,
944 int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures, bool shouldCreateArgumentsVariableInParameterScope)
946 Vector<std::pair<Identifier, RefPtr<RegisterID>>> valuesToMoveIntoVars;
947 ASSERT(!(isSimpleParameterList && shouldCreateArgumentsVariableInParameterScope));
948 if (!isSimpleParameterList) {
949 // Refer to the ES6 spec section 9.2.12: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
950 // This implements step 21.
951 VariableEnvironment environment;
952 Vector<Identifier> allParameterNames;
953 for (unsigned i = 0; i < parameters.size(); i++)
954 parameters.at(i).first->collectBoundIdentifiers(allParameterNames);
955 if (shouldCreateArgumentsVariableInParameterScope)
956 allParameterNames.append(propertyNames().arguments);
957 IdentifierSet parameterSet;
958 for (auto& ident : allParameterNames) {
959 parameterSet.add(ident.impl());
960 auto addResult = environment.add(ident);
961 addResult.iterator->value.setIsLet(); // When we have default parameter expressions, parameters act like "let" variables.
962 if (captures(ident.impl()))
963 addResult.iterator->value.setIsCaptured();
965 // This implements step 25 of section 9.2.12.
966 pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
968 if (shouldCreateArgumentsVariableInParameterScope) {
969 Variable argumentsVariable = variable(propertyNames().arguments);
970 initializeVariable(argumentsVariable, m_argumentsRegister);
971 liftTDZCheckIfPossible(argumentsVariable);
974 RefPtr<RegisterID> temp = newTemporary();
975 for (unsigned i = 0; i < parameters.size(); i++) {
976 std::pair<DestructuringPatternNode*, ExpressionNode*> parameter = parameters.at(i);
977 if (parameter.first->isRestParameter())
979 if ((i + 1) < m_parameters.size())
980 emitMove(temp.get(), &m_parameters[i + 1]);
982 emitGetArgument(temp.get(), i);
983 if (parameter.second) {
984 RefPtr<RegisterID> condition = emitIsUndefined(newTemporary(), temp.get());
985 Ref<Label> skipDefaultParameterBecauseNotUndefined = newLabel();
986 emitJumpIfFalse(condition.get(), skipDefaultParameterBecauseNotUndefined.get());
987 emitNode(temp.get(), parameter.second);
988 emitLabel(skipDefaultParameterBecauseNotUndefined.get());
991 parameter.first->bindValue(*this, temp.get());
994 // Final act of weirdness for default parameters. If a "var" also
995 // has the same name as a parameter, it should start out as the
996 // value of that parameter. Note, though, that they will be distinct
998 // This is step 28 of section 9.2.12.
999 for (auto& entry : functionNode->varDeclarations()) {
1000 if (!entry.value.isVar()) // This is either a parameter or callee.
1003 if (parameterSet.contains(entry.key)) {
1004 Identifier ident = Identifier::fromUid(m_vm, entry.key.get());
1005 Variable var = variable(ident);
1006 RegisterID* scope = emitResolveScope(nullptr, var);
1007 RefPtr<RegisterID> value = emitGetFromScope(newTemporary(), scope, var, DoNotThrowIfNotFound);
1008 valuesToMoveIntoVars.append(std::make_pair(ident, value));
1012 // Functions with default parameter expressions must have a separate environment
1013 // record for parameters and "var"s. The "var" environment record must have the
1014 // parameter environment record as its parent.
1015 // See step 28 of section 9.2.12.
1016 bool hasCapturedVariables = !!m_lexicalEnvironmentRegister;
1017 initializeVarLexicalEnvironment(symbolTableConstantIndex, functionSymbolTable, hasCapturedVariables);
1020 // This completes step 28 of section 9.2.12.
1021 for (unsigned i = 0; i < valuesToMoveIntoVars.size(); i++) {
1022 ASSERT(!isSimpleParameterList);
1023 Variable var = variable(valuesToMoveIntoVars[i].first);
1024 RegisterID* scope = emitResolveScope(nullptr, var);
1025 emitPutToScope(scope, var, valuesToMoveIntoVars[i].second.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
1029 bool BytecodeGenerator::needsDerivedConstructorInArrowFunctionLexicalEnvironment()
1031 ASSERT(m_codeBlock->isClassContext() || !(isConstructor() && constructorKind() == ConstructorKind::Extends));
1032 return m_codeBlock->isClassContext() && isSuperUsedInInnerArrowFunction();
1035 void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable, bool canReuseLexicalEnvironment)
1037 ASSERT(!m_arrowFunctionContextLexicalEnvironmentRegister);
1039 if (canReuseLexicalEnvironment && m_lexicalEnvironmentRegister) {
1040 RELEASE_ASSERT(!m_codeBlock->isArrowFunction());
1041 RELEASE_ASSERT(functionSymbolTable);
1043 m_arrowFunctionContextLexicalEnvironmentRegister = m_lexicalEnvironmentRegister;
1047 if (isThisUsedInInnerArrowFunction()) {
1048 offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
1049 functionSymbolTable->set(NoLockingNecessary, propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset)));
1052 if (m_codeType == FunctionCode && isNewTargetUsedInInnerArrowFunction()) {
1053 offset = functionSymbolTable->takeNextScopeOffset();
1054 functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().newTargetLocalPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
1057 if (needsDerivedConstructorInArrowFunctionLexicalEnvironment()) {
1058 offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
1059 functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().derivedConstructorPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
1065 VariableEnvironment environment;
1067 if (isThisUsedInInnerArrowFunction()) {
1068 auto addResult = environment.add(propertyNames().thisIdentifier);
1069 addResult.iterator->value.setIsCaptured();
1070 addResult.iterator->value.setIsLet();
1073 if (m_codeType == FunctionCode && isNewTargetUsedInInnerArrowFunction()) {
1074 auto addTarget = environment.add(propertyNames().builtinNames().newTargetLocalPrivateName());
1075 addTarget.iterator->value.setIsCaptured();
1076 addTarget.iterator->value.setIsLet();
1079 if (needsDerivedConstructorInArrowFunctionLexicalEnvironment()) {
1080 auto derivedConstructor = environment.add(propertyNames().builtinNames().derivedConstructorPrivateName());
1081 derivedConstructor.iterator->value.setIsCaptured();
1082 derivedConstructor.iterator->value.setIsLet();
1085 if (environment.size() > 0) {
1086 size_t size = m_lexicalScopeStack.size();
1087 pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
1089 ASSERT_UNUSED(size, m_lexicalScopeStack.size() == size + 1);
1091 m_arrowFunctionContextLexicalEnvironmentRegister = m_lexicalScopeStack.last().m_scope;
1095 RegisterID* BytecodeGenerator::initializeNextParameter()
1097 VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
1098 m_parameters.grow(m_parameters.size() + 1);
1099 auto& parameter = registerFor(reg);
1100 parameter.setIndex(reg.offset());
1101 m_codeBlock->addParameter();
1105 void BytecodeGenerator::initializeParameters(FunctionParameters& parameters)
1107 // Make sure the code block knows about all of our parameters, and make sure that parameters
1108 // needing destructuring are noted.
1109 m_thisRegister.setIndex(initializeNextParameter()->index()); // this
1111 bool nonSimpleArguments = false;
1112 for (unsigned i = 0; i < parameters.size(); ++i) {
1113 auto parameter = parameters.at(i);
1114 auto pattern = parameter.first;
1115 if (pattern->isRestParameter()) {
1116 RELEASE_ASSERT(!m_restParameter);
1117 m_restParameter = static_cast<RestParameterNode*>(pattern);
1118 nonSimpleArguments = true;
1121 if (parameter.second) {
1122 nonSimpleArguments = true;
1125 if (!nonSimpleArguments)
1126 initializeNextParameter();
1130 void BytecodeGenerator::initializeVarLexicalEnvironment(int symbolTableConstantIndex, SymbolTable* functionSymbolTable, bool hasCapturedVariables)
1132 if (hasCapturedVariables) {
1133 RELEASE_ASSERT(m_lexicalEnvironmentRegister);
1134 emitOpcode(op_create_lexical_environment);
1135 instructions().append(m_lexicalEnvironmentRegister->index());
1136 instructions().append(scopeRegister()->index());
1137 instructions().append(symbolTableConstantIndex);
1138 instructions().append(addConstantValue(jsUndefined())->index());
1141 instructions().append(scopeRegister()->index());
1142 instructions().append(m_lexicalEnvironmentRegister->index());
1144 pushLocalControlFlowScope();
1146 bool isWithScope = false;
1147 m_lexicalScopeStack.append({ functionSymbolTable, m_lexicalEnvironmentRegister, isWithScope, symbolTableConstantIndex });
1148 m_varScopeLexicalScopeStackIndex = m_lexicalScopeStack.size() - 1;
1151 UniquedStringImpl* BytecodeGenerator::visibleNameForParameter(DestructuringPatternNode* pattern)
1153 if (pattern->isBindingNode()) {
1154 const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
1155 if (!m_functions.contains(ident.impl()))
1156 return ident.impl();
1161 RegisterID* BytecodeGenerator::newRegister()
1163 m_calleeLocals.append(virtualRegisterForLocal(m_calleeLocals.size()));
1164 int numCalleeLocals = max<int>(m_codeBlock->m_numCalleeLocals, m_calleeLocals.size());
1165 numCalleeLocals = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numCalleeLocals);
1166 m_codeBlock->m_numCalleeLocals = numCalleeLocals;
1167 return &m_calleeLocals.last();
1170 void BytecodeGenerator::reclaimFreeRegisters()
1172 while (m_calleeLocals.size() && !m_calleeLocals.last().refCount())
1173 m_calleeLocals.removeLast();
1176 RegisterID* BytecodeGenerator::newBlockScopeVariable()
1178 reclaimFreeRegisters();
1180 return newRegister();
1183 RegisterID* BytecodeGenerator::newTemporary()
1185 reclaimFreeRegisters();
1187 RegisterID* result = newRegister();
1188 result->setTemporary();
1192 LabelScopePtr BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
1194 // Reclaim free label scopes.
1195 while (m_labelScopes.size() && !m_labelScopes.last().refCount())
1196 m_labelScopes.removeLast();
1198 // Allocate new label scope.
1199 LabelScope scope(type, name, labelScopeDepth(), newLabel(), type == LabelScope::Loop ? RefPtr<Label>(newLabel()) : RefPtr<Label>()); // Only loops have continue targets.
1200 m_labelScopes.append(WTFMove(scope));
1201 return LabelScopePtr(m_labelScopes, m_labelScopes.size() - 1);
1204 Ref<Label> BytecodeGenerator::newLabel()
1206 // Reclaim free label IDs.
1207 while (m_labels.size() && !m_labels.last().refCount())
1208 m_labels.removeLast();
1210 // Allocate new label ID.
1211 m_labels.append(*this);
1212 return m_labels.last();
1215 Ref<Label> BytecodeGenerator::newEmittedLabel()
1217 Ref<Label> label = newLabel();
1218 emitLabel(label.get());
1222 void BytecodeGenerator::emitLabel(Label& l0)
1224 unsigned newLabelIndex = instructions().size();
1225 l0.setLocation(newLabelIndex);
1227 if (m_codeBlock->numberOfJumpTargets()) {
1228 unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
1229 ASSERT(lastLabelIndex <= newLabelIndex);
1230 if (newLabelIndex == lastLabelIndex) {
1231 // Peephole optimizations have already been disabled by emitting the last label
1236 m_codeBlock->addJumpTarget(newLabelIndex);
1238 // This disables peephole optimizations when an instruction is a jump target
1239 m_lastOpcodeID = op_end;
1242 void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
1245 size_t opcodePosition = instructions().size();
1246 ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
1247 m_lastOpcodePosition = opcodePosition;
1249 instructions().append(opcodeID);
1250 m_lastOpcodeID = opcodeID;
1253 UnlinkedArrayProfile BytecodeGenerator::newArrayProfile()
1255 return m_codeBlock->addArrayProfile();
1258 UnlinkedArrayAllocationProfile BytecodeGenerator::newArrayAllocationProfile()
1260 return m_codeBlock->addArrayAllocationProfile();
1263 UnlinkedObjectAllocationProfile BytecodeGenerator::newObjectAllocationProfile()
1265 return m_codeBlock->addObjectAllocationProfile();
1268 UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
1270 UnlinkedValueProfile result = m_codeBlock->addValueProfile();
1271 emitOpcode(opcodeID);
1275 void BytecodeGenerator::emitEnter()
1277 emitOpcode(op_enter);
1280 void BytecodeGenerator::emitLoopHint()
1282 emitOpcode(op_loop_hint);
1286 void BytecodeGenerator::emitCheckTraps()
1288 emitOpcode(op_check_traps);
1291 void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
1293 ASSERT(instructions().size() >= 4);
1294 size_t size = instructions().size();
1295 dstIndex = instructions().at(size - 3).u.operand;
1296 src1Index = instructions().at(size - 2).u.operand;
1297 src2Index = instructions().at(size - 1).u.operand;
1300 void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
1302 ASSERT(instructions().size() >= 3);
1303 size_t size = instructions().size();
1304 dstIndex = instructions().at(size - 2).u.operand;
1305 srcIndex = instructions().at(size - 1).u.operand;
1308 void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
1310 ASSERT(instructions().size() >= 4);
1311 instructions().shrink(instructions().size() - 4);
1312 m_lastOpcodeID = op_end;
1315 void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
1317 ASSERT(instructions().size() >= 3);
1318 instructions().shrink(instructions().size() - 3);
1319 m_lastOpcodeID = op_end;
1322 void BytecodeGenerator::emitJump(Label& target)
1324 size_t begin = instructions().size();
1326 instructions().append(target.bind(begin, instructions().size()));
1329 void BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label& target)
1331 if (m_lastOpcodeID == op_less) {
1336 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1338 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1341 size_t begin = instructions().size();
1342 emitOpcode(op_jless);
1343 instructions().append(src1Index);
1344 instructions().append(src2Index);
1345 instructions().append(target.bind(begin, instructions().size()));
1348 } else if (m_lastOpcodeID == op_lesseq) {
1353 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1355 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1358 size_t begin = instructions().size();
1359 emitOpcode(op_jlesseq);
1360 instructions().append(src1Index);
1361 instructions().append(src2Index);
1362 instructions().append(target.bind(begin, instructions().size()));
1365 } else if (m_lastOpcodeID == op_greater) {
1370 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1372 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1375 size_t begin = instructions().size();
1376 emitOpcode(op_jgreater);
1377 instructions().append(src1Index);
1378 instructions().append(src2Index);
1379 instructions().append(target.bind(begin, instructions().size()));
1382 } else if (m_lastOpcodeID == op_greatereq) {
1387 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1389 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1392 size_t begin = instructions().size();
1393 emitOpcode(op_jgreatereq);
1394 instructions().append(src1Index);
1395 instructions().append(src2Index);
1396 instructions().append(target.bind(begin, instructions().size()));
1399 } else if (m_lastOpcodeID == op_eq_null && target.isForward()) {
1403 retrieveLastUnaryOp(dstIndex, srcIndex);
1405 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1408 size_t begin = instructions().size();
1409 emitOpcode(op_jeq_null);
1410 instructions().append(srcIndex);
1411 instructions().append(target.bind(begin, instructions().size()));
1414 } else if (m_lastOpcodeID == op_neq_null && target.isForward()) {
1418 retrieveLastUnaryOp(dstIndex, srcIndex);
1420 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1423 size_t begin = instructions().size();
1424 emitOpcode(op_jneq_null);
1425 instructions().append(srcIndex);
1426 instructions().append(target.bind(begin, instructions().size()));
1431 size_t begin = instructions().size();
1433 emitOpcode(op_jtrue);
1434 instructions().append(cond->index());
1435 instructions().append(target.bind(begin, instructions().size()));
1438 void BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label& target)
1440 if (m_lastOpcodeID == op_less && target.isForward()) {
1445 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1447 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1450 size_t begin = instructions().size();
1451 emitOpcode(op_jnless);
1452 instructions().append(src1Index);
1453 instructions().append(src2Index);
1454 instructions().append(target.bind(begin, instructions().size()));
1457 } else if (m_lastOpcodeID == op_lesseq && target.isForward()) {
1462 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1464 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1467 size_t begin = instructions().size();
1468 emitOpcode(op_jnlesseq);
1469 instructions().append(src1Index);
1470 instructions().append(src2Index);
1471 instructions().append(target.bind(begin, instructions().size()));
1474 } else if (m_lastOpcodeID == op_greater && target.isForward()) {
1479 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1481 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1484 size_t begin = instructions().size();
1485 emitOpcode(op_jngreater);
1486 instructions().append(src1Index);
1487 instructions().append(src2Index);
1488 instructions().append(target.bind(begin, instructions().size()));
1491 } else if (m_lastOpcodeID == op_greatereq && target.isForward()) {
1496 retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
1498 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1501 size_t begin = instructions().size();
1502 emitOpcode(op_jngreatereq);
1503 instructions().append(src1Index);
1504 instructions().append(src2Index);
1505 instructions().append(target.bind(begin, instructions().size()));
1508 } else if (m_lastOpcodeID == op_not) {
1512 retrieveLastUnaryOp(dstIndex, srcIndex);
1514 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1517 size_t begin = instructions().size();
1518 emitOpcode(op_jtrue);
1519 instructions().append(srcIndex);
1520 instructions().append(target.bind(begin, instructions().size()));
1523 } else if (m_lastOpcodeID == op_eq_null && target.isForward()) {
1527 retrieveLastUnaryOp(dstIndex, srcIndex);
1529 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1532 size_t begin = instructions().size();
1533 emitOpcode(op_jneq_null);
1534 instructions().append(srcIndex);
1535 instructions().append(target.bind(begin, instructions().size()));
1538 } else if (m_lastOpcodeID == op_neq_null && target.isForward()) {
1542 retrieveLastUnaryOp(dstIndex, srcIndex);
1544 if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
1547 size_t begin = instructions().size();
1548 emitOpcode(op_jeq_null);
1549 instructions().append(srcIndex);
1550 instructions().append(target.bind(begin, instructions().size()));
1555 size_t begin = instructions().size();
1556 emitOpcode(op_jfalse);
1557 instructions().append(cond->index());
1558 instructions().append(target.bind(begin, instructions().size()));
1561 void BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label& target)
1563 size_t begin = instructions().size();
1565 emitOpcode(op_jneq_ptr);
1566 instructions().append(cond->index());
1567 instructions().append(Special::CallFunction);
1568 instructions().append(target.bind(begin, instructions().size()));
1569 instructions().append(0);
1572 void BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label& target)
1574 size_t begin = instructions().size();
1576 emitOpcode(op_jneq_ptr);
1577 instructions().append(cond->index());
1578 instructions().append(Special::ApplyFunction);
1579 instructions().append(target.bind(begin, instructions().size()));
1580 instructions().append(0);
1583 bool BytecodeGenerator::hasConstant(const Identifier& ident) const
1585 UniquedStringImpl* rep = ident.impl();
1586 return m_identifierMap.contains(rep);
1589 unsigned BytecodeGenerator::addConstant(const Identifier& ident)
1591 UniquedStringImpl* rep = ident.impl();
1592 IdentifierMap::AddResult result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
1593 if (result.isNewEntry)
1594 m_codeBlock->addIdentifier(ident);
1596 return result.iterator->value;
1599 // We can't hash JSValue(), so we use a dedicated data member to cache it.
1600 RegisterID* BytecodeGenerator::addConstantEmptyValue()
1602 if (!m_emptyValueRegister) {
1603 int index = m_nextConstantOffset;
1604 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1605 ++m_nextConstantOffset;
1606 m_codeBlock->addConstant(JSValue());
1607 m_emptyValueRegister = &m_constantPoolRegisters[index];
1610 return m_emptyValueRegister;
1613 RegisterID* BytecodeGenerator::addConstantValue(JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
1616 return addConstantEmptyValue();
1618 int index = m_nextConstantOffset;
1620 if (sourceCodeRepresentation == SourceCodeRepresentation::Double && v.isInt32())
1621 v = jsDoubleNumber(v.asNumber());
1622 EncodedJSValueWithRepresentation valueMapKey { JSValue::encode(v), sourceCodeRepresentation };
1623 JSValueMap::AddResult result = m_jsValueMap.add(valueMapKey, m_nextConstantOffset);
1624 if (result.isNewEntry) {
1625 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1626 ++m_nextConstantOffset;
1627 m_codeBlock->addConstant(v, sourceCodeRepresentation);
1629 index = result.iterator->value;
1630 return &m_constantPoolRegisters[index];
1633 RegisterID* BytecodeGenerator::emitMoveLinkTimeConstant(RegisterID* dst, LinkTimeConstant type)
1635 unsigned constantIndex = static_cast<unsigned>(type);
1636 if (!m_linkTimeConstantRegisters[constantIndex]) {
1637 int index = m_nextConstantOffset;
1638 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1639 ++m_nextConstantOffset;
1640 m_codeBlock->addConstant(type);
1641 m_linkTimeConstantRegisters[constantIndex] = &m_constantPoolRegisters[index];
1645 return m_linkTimeConstantRegisters[constantIndex];
1648 instructions().append(dst->index());
1649 instructions().append(m_linkTimeConstantRegisters[constantIndex]->index());
1654 unsigned BytecodeGenerator::addRegExp(RegExp* r)
1656 return m_codeBlock->addRegExp(r);
1659 RegisterID* BytecodeGenerator::emitMoveEmptyValue(RegisterID* dst)
1661 RefPtr<RegisterID> emptyValue = addConstantEmptyValue();
1664 instructions().append(dst->index());
1665 instructions().append(emptyValue->index());
1669 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
1671 ASSERT(src != m_emptyValueRegister);
1673 m_staticPropertyAnalyzer.mov(dst->index(), src->index());
1675 instructions().append(dst->index());
1676 instructions().append(src->index());
1681 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1683 ASSERT_WITH_MESSAGE(op_to_number != opcodeID, "op_to_number has a Value Profile.");
1684 ASSERT_WITH_MESSAGE(op_negate != opcodeID, "op_negate has an Arith Profile.");
1685 emitOpcode(opcodeID);
1686 instructions().append(dst->index());
1687 instructions().append(src->index());
1692 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, OperandTypes types)
1694 ASSERT_WITH_MESSAGE(op_to_number != opcodeID, "op_to_number has a Value Profile.");
1695 emitOpcode(opcodeID);
1696 instructions().append(dst->index());
1697 instructions().append(src->index());
1699 if (opcodeID == op_negate)
1700 instructions().append(ArithProfile(types.first()).bits());
1704 RegisterID* BytecodeGenerator::emitUnaryOpProfiled(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1706 UnlinkedValueProfile profile = emitProfiledOpcode(opcodeID);
1707 instructions().append(dst->index());
1708 instructions().append(src->index());
1709 instructions().append(profile);
1713 RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
1716 instructions().append(srcDst->index());
1720 RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
1723 instructions().append(srcDst->index());
1727 RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
1729 emitOpcode(opcodeID);
1730 instructions().append(dst->index());
1731 instructions().append(src1->index());
1732 instructions().append(src2->index());
1734 if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
1735 opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
1736 instructions().append(ArithProfile(types.first(), types.second()).bits());
1741 RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
1743 if (m_lastOpcodeID == op_typeof) {
1747 retrieveLastUnaryOp(dstIndex, srcIndex);
1749 if (src1->index() == dstIndex
1750 && src1->isTemporary()
1751 && m_codeBlock->isConstantRegisterIndex(src2->index())
1752 && m_codeBlock->constantRegister(src2->index()).get().isString()) {
1753 const String& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
1754 if (value == "undefined") {
1756 emitOpcode(op_is_undefined);
1757 instructions().append(dst->index());
1758 instructions().append(srcIndex);
1761 if (value == "boolean") {
1763 emitOpcode(op_is_boolean);
1764 instructions().append(dst->index());
1765 instructions().append(srcIndex);
1768 if (value == "number") {
1770 emitOpcode(op_is_number);
1771 instructions().append(dst->index());
1772 instructions().append(srcIndex);
1775 if (value == "string") {
1777 emitOpcode(op_is_cell_with_type);
1778 instructions().append(dst->index());
1779 instructions().append(srcIndex);
1780 instructions().append(StringType);
1783 if (value == "symbol") {
1785 emitOpcode(op_is_cell_with_type);
1786 instructions().append(dst->index());
1787 instructions().append(srcIndex);
1788 instructions().append(SymbolType);
1791 if (value == "object") {
1793 emitOpcode(op_is_object_or_null);
1794 instructions().append(dst->index());
1795 instructions().append(srcIndex);
1798 if (value == "function") {
1800 emitOpcode(op_is_function);
1801 instructions().append(dst->index());
1802 instructions().append(srcIndex);
1808 emitOpcode(opcodeID);
1809 instructions().append(dst->index());
1810 instructions().append(src1->index());
1811 instructions().append(src2->index());
1815 void BytecodeGenerator::emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1817 ASSERT(vm()->typeProfiler());
1819 unsigned start = startDivot.offset; // Ranges are inclusive of their endpoints, AND 0 indexed.
1820 unsigned end = endDivot.offset - 1; // End Ranges already go one past the inclusive range, so subtract 1.
1821 unsigned instructionOffset = instructions().size() - 1;
1822 m_codeBlock->addTypeProfilerExpressionInfo(instructionOffset, start, end);
1825 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag)
1827 if (!vm()->typeProfiler())
1830 if (!registerToProfile)
1833 emitOpcode(op_profile_type);
1834 instructions().append(registerToProfile->index());
1835 instructions().append(0);
1836 instructions().append(flag);
1837 instructions().append(0);
1838 instructions().append(resolveType());
1840 // Don't emit expression info for this version of profile type. This generally means
1841 // we're profiling information for something that isn't in the actual text of a JavaScript
1842 // program. For example, implicit return undefined from a function call.
1845 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1847 emitProfileType(registerToProfile, ProfileTypeBytecodeDoesNotHaveGlobalID, startDivot, endDivot);
1850 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1852 if (!vm()->typeProfiler())
1855 if (!registerToProfile)
1858 // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1859 emitOpcode(op_profile_type);
1860 instructions().append(registerToProfile->index());
1861 instructions().append(0);
1862 instructions().append(flag);
1863 instructions().append(0);
1864 instructions().append(resolveType());
1866 emitTypeProfilerExpressionInfo(startDivot, endDivot);
1869 void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const Variable& var, const JSTextPosition& startDivot, const JSTextPosition& endDivot)
1871 if (!vm()->typeProfiler())
1874 if (!registerToProfile)
1877 ProfileTypeBytecodeFlag flag;
1878 int symbolTableOrScopeDepth;
1879 if (var.local() || var.offset().isScope()) {
1880 flag = ProfileTypeBytecodeLocallyResolved;
1881 ASSERT(var.symbolTableConstantIndex());
1882 symbolTableOrScopeDepth = var.symbolTableConstantIndex();
1884 flag = ProfileTypeBytecodeClosureVar;
1885 symbolTableOrScopeDepth = localScopeDepth();
1888 // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
1889 emitOpcode(op_profile_type);
1890 instructions().append(registerToProfile->index());
1891 instructions().append(symbolTableOrScopeDepth);
1892 instructions().append(flag);
1893 instructions().append(addConstant(var.ident()));
1894 instructions().append(resolveType());
1896 emitTypeProfilerExpressionInfo(startDivot, endDivot);
1899 void BytecodeGenerator::emitProfileControlFlow(int textOffset)
1901 if (vm()->controlFlowProfiler()) {
1902 RELEASE_ASSERT(textOffset >= 0);
1903 size_t bytecodeOffset = instructions().size();
1904 m_codeBlock->addOpProfileControlFlowBytecodeOffset(bytecodeOffset);
1906 emitOpcode(op_profile_control_flow);
1907 instructions().append(textOffset);
1911 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
1913 return emitLoad(dst, jsBoolean(b));
1916 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
1918 ASSERT(!identifier.isSymbol());
1919 JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
1921 stringInMap = jsOwnedString(vm(), identifier.string());
1923 return emitLoad(dst, JSValue(stringInMap));
1926 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
1928 RegisterID* constantID = addConstantValue(v, sourceCodeRepresentation);
1930 return emitMove(dst, constantID);
1934 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, IdentifierSet& set)
1936 for (const auto& entry : m_codeBlock->constantIdentifierSets()) {
1937 if (entry.first != set)
1940 return &m_constantPoolRegisters[entry.second];
1943 unsigned index = m_nextConstantOffset;
1944 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1945 ++m_nextConstantOffset;
1946 m_codeBlock->addSetConstant(set);
1947 RegisterID* m_setRegister = &m_constantPoolRegisters[index];
1950 return emitMove(dst, m_setRegister);
1952 return m_setRegister;
1955 RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst)
1957 if (!m_globalObjectRegister) {
1958 int index = m_nextConstantOffset;
1959 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1960 ++m_nextConstantOffset;
1961 m_codeBlock->addConstant(JSValue());
1962 m_globalObjectRegister = &m_constantPoolRegisters[index];
1963 m_codeBlock->setGlobalObjectRegister(VirtualRegister(index));
1966 emitMove(dst, m_globalObjectRegister);
1967 return m_globalObjectRegister;
1970 template<typename LookUpVarKindFunctor>
1971 bool BytecodeGenerator::instantiateLexicalVariables(const VariableEnvironment& lexicalVariables, SymbolTable* symbolTable, ScopeRegisterType scopeRegisterType, LookUpVarKindFunctor lookUpVarKind)
1973 bool hasCapturedVariables = false;
1975 for (auto& entry : lexicalVariables) {
1976 ASSERT(entry.value.isLet() || entry.value.isConst() || entry.value.isFunction());
1977 ASSERT(!entry.value.isVar());
1978 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
1979 ASSERT(symbolTableEntry.isNull());
1981 // Imported bindings which are not the namespace bindings are not allocated
1982 // in the module environment as usual variables' way.
1983 // And since these types of the variables only seen in the module environment,
1984 // other lexical environment need not to take care this.
1985 if (entry.value.isImported() && !entry.value.isImportedNamespace())
1988 VarKind varKind = lookUpVarKind(entry.key.get(), entry.value);
1989 VarOffset varOffset;
1990 if (varKind == VarKind::Scope) {
1991 varOffset = VarOffset(symbolTable->takeNextScopeOffset(NoLockingNecessary));
1992 hasCapturedVariables = true;
1994 ASSERT(varKind == VarKind::Stack);
1996 if (scopeRegisterType == ScopeRegisterType::Block) {
1997 local = newBlockScopeVariable();
2001 varOffset = VarOffset(local->virtualRegister());
2004 SymbolTableEntry newEntry(varOffset, entry.value.isConst() ? ReadOnly : 0);
2005 symbolTable->add(NoLockingNecessary, entry.key.get(), newEntry);
2008 return hasCapturedVariables;
2011 void BytecodeGenerator::emitPrefillStackTDZVariables(const VariableEnvironment& lexicalVariables, SymbolTable* symbolTable)
2013 // Prefill stack variables with the TDZ empty value.
2014 // Scope variables will be initialized to the TDZ empty value when JSLexicalEnvironment is allocated.
2015 for (auto& entry : lexicalVariables) {
2016 // Imported bindings which are not the namespace bindings are not allocated
2017 // in the module environment as usual variables' way.
2018 // And since these types of the variables only seen in the module environment,
2019 // other lexical environment need not to take care this.
2020 if (entry.value.isImported() && !entry.value.isImportedNamespace())
2023 if (entry.value.isFunction())
2026 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
2027 ASSERT(!symbolTableEntry.isNull());
2028 VarOffset offset = symbolTableEntry.varOffset();
2029 if (offset.isScope())
2032 ASSERT(offset.isStack());
2033 emitMoveEmptyValue(®isterFor(offset.stackOffset()));
2037 void BytecodeGenerator::pushLexicalScope(VariableEnvironmentNode* node, TDZCheckOptimization tdzCheckOptimization, NestedScopeType nestedScopeType, RegisterID** constantSymbolTableResult, bool shouldInitializeBlockScopedFunctions)
2039 VariableEnvironment& environment = node->lexicalVariables();
2040 RegisterID* constantSymbolTableResultTemp = nullptr;
2041 pushLexicalScopeInternal(environment, tdzCheckOptimization, nestedScopeType, &constantSymbolTableResultTemp, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
2043 if (shouldInitializeBlockScopedFunctions)
2044 initializeBlockScopedFunctions(environment, node->functionStack(), constantSymbolTableResultTemp);
2046 if (constantSymbolTableResult && constantSymbolTableResultTemp)
2047 *constantSymbolTableResult = constantSymbolTableResultTemp;
2050 void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environment, TDZCheckOptimization tdzCheckOptimization, NestedScopeType nestedScopeType,
2051 RegisterID** constantSymbolTableResult, TDZRequirement tdzRequirement, ScopeType scopeType, ScopeRegisterType scopeRegisterType)
2053 if (!environment.size())
2056 if (m_shouldEmitDebugHooks)
2057 environment.markAllVariablesAsCaptured();
2059 SymbolTable* symbolTable = SymbolTable::create(*m_vm);
2060 switch (scopeType) {
2061 case ScopeType::CatchScope:
2062 symbolTable->setScopeType(SymbolTable::ScopeType::CatchScope);
2064 case ScopeType::LetConstScope:
2065 symbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope);
2067 case ScopeType::FunctionNameScope:
2068 symbolTable->setScopeType(SymbolTable::ScopeType::FunctionNameScope);
2072 if (nestedScopeType == NestedScopeType::IsNested)
2073 symbolTable->markIsNestedLexicalScope();
2075 auto lookUpVarKind = [] (UniquedStringImpl*, const VariableEnvironmentEntry& entry) -> VarKind {
2076 return entry.isCaptured() ? VarKind::Scope : VarKind::Stack;
2079 bool hasCapturedVariables = instantiateLexicalVariables(environment, symbolTable, scopeRegisterType, lookUpVarKind);
2081 RegisterID* newScope = nullptr;
2082 RegisterID* constantSymbolTable = nullptr;
2083 int symbolTableConstantIndex = 0;
2084 if (vm()->typeProfiler()) {
2085 constantSymbolTable = addConstantValue(symbolTable);
2086 symbolTableConstantIndex = constantSymbolTable->index();
2088 if (hasCapturedVariables) {
2089 if (scopeRegisterType == ScopeRegisterType::Block) {
2090 newScope = newBlockScopeVariable();
2093 newScope = addVar();
2094 if (!constantSymbolTable) {
2095 ASSERT(!vm()->typeProfiler());
2096 constantSymbolTable = addConstantValue(symbolTable->cloneScopePart(*m_vm));
2097 symbolTableConstantIndex = constantSymbolTable->index();
2099 if (constantSymbolTableResult)
2100 *constantSymbolTableResult = constantSymbolTable;
2102 emitOpcode(op_create_lexical_environment);
2103 instructions().append(newScope->index());
2104 instructions().append(scopeRegister()->index());
2105 instructions().append(constantSymbolTable->index());
2106 instructions().append(addConstantValue(tdzRequirement == TDZRequirement::UnderTDZ ? jsTDZValue() : jsUndefined())->index());
2108 emitMove(scopeRegister(), newScope);
2110 pushLocalControlFlowScope();
2113 bool isWithScope = false;
2114 m_lexicalScopeStack.append({ symbolTable, newScope, isWithScope, symbolTableConstantIndex });
2115 pushTDZVariables(environment, tdzCheckOptimization, tdzRequirement);
2117 if (tdzRequirement == TDZRequirement::UnderTDZ)
2118 emitPrefillStackTDZVariables(environment, symbolTable);
2121 void BytecodeGenerator::initializeBlockScopedFunctions(VariableEnvironment& environment, FunctionStack& functionStack, RegisterID* constantSymbolTable)
2124 * We must transform block scoped function declarations in strict mode like so:
2128 * function foo() { ... }
2131 * function baz() { ... }
2139 * let foo = function foo() { ... }
2140 * let baz = function baz() { ... }
2146 * But without the TDZ checks.
2149 if (!environment.size()) {
2150 RELEASE_ASSERT(!functionStack.size());
2154 if (!functionStack.size())
2157 SymbolTable* symbolTable = m_lexicalScopeStack.last().m_symbolTable;
2158 RegisterID* scope = m_lexicalScopeStack.last().m_scope;
2159 RefPtr<RegisterID> temp = newTemporary();
2160 int symbolTableIndex = constantSymbolTable ? constantSymbolTable->index() : 0;
2161 for (FunctionMetadataNode* function : functionStack) {
2162 const Identifier& name = function->ident();
2163 auto iter = environment.find(name.impl());
2164 RELEASE_ASSERT(iter != environment.end());
2165 RELEASE_ASSERT(iter->value.isFunction());
2166 // We purposefully don't hold the symbol table lock around this loop because emitNewFunctionExpressionCommon may GC.
2167 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, name.impl());
2168 RELEASE_ASSERT(!entry.isNull());
2169 emitNewFunctionExpressionCommon(temp.get(), function);
2170 bool isLexicallyScoped = true;
2171 emitPutToScope(scope, variableForLocalEntry(name, entry, symbolTableIndex, isLexicallyScoped), temp.get(), DoNotThrowIfNotFound, InitializationMode::Initialization);
2175 void BytecodeGenerator::hoistSloppyModeFunctionIfNecessary(const Identifier& functionName)
2177 if (m_scopeNode->hasSloppyModeHoistedFunction(functionName.impl())) {
2178 Variable currentFunctionVariable = variable(functionName);
2179 RefPtr<RegisterID> currentValue;
2180 if (RegisterID* local = currentFunctionVariable.local())
2181 currentValue = local;
2183 RefPtr<RegisterID> scope = emitResolveScope(nullptr, currentFunctionVariable);
2184 currentValue = emitGetFromScope(newTemporary(), scope.get(), currentFunctionVariable, DoNotThrowIfNotFound);
2187 ASSERT(m_varScopeLexicalScopeStackIndex);
2188 ASSERT(*m_varScopeLexicalScopeStackIndex < m_lexicalScopeStack.size());
2189 LexicalScopeStackEntry varScope = m_lexicalScopeStack[*m_varScopeLexicalScopeStackIndex];
2190 SymbolTable* varSymbolTable = varScope.m_symbolTable;
2191 ASSERT(varSymbolTable->scopeType() == SymbolTable::ScopeType::VarScope);
2192 SymbolTableEntry entry = varSymbolTable->get(NoLockingNecessary, functionName.impl());
2193 if (functionName == propertyNames().arguments && entry.isNull()) {
2194 // "arguments" might be put in the parameter scope when we have a non-simple
2195 // parameter list since "arguments" is visible to expressions inside the
2196 // parameter evaluation list.
2198 // function foo(x = arguments) { { function arguments() { } } }
2199 RELEASE_ASSERT(*m_varScopeLexicalScopeStackIndex > 0);
2200 varScope = m_lexicalScopeStack[*m_varScopeLexicalScopeStackIndex - 1];
2201 SymbolTable* parameterSymbolTable = varScope.m_symbolTable;
2202 entry = parameterSymbolTable->get(NoLockingNecessary, functionName.impl());
2204 RELEASE_ASSERT(!entry.isNull());
2205 bool isLexicallyScoped = false;
2206 emitPutToScope(varScope.m_scope, variableForLocalEntry(functionName, entry, varScope.m_symbolTableConstantIndex, isLexicallyScoped), currentValue.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2210 void BytecodeGenerator::popLexicalScope(VariableEnvironmentNode* node)
2212 VariableEnvironment& environment = node->lexicalVariables();
2213 popLexicalScopeInternal(environment);
2216 void BytecodeGenerator::popLexicalScopeInternal(VariableEnvironment& environment)
2218 // NOTE: This function only makes sense for scopes that aren't ScopeRegisterType::Var (only function name scope right now is ScopeRegisterType::Var).
2219 // This doesn't make sense for ScopeRegisterType::Var because we deref RegisterIDs here.
2220 if (!environment.size())
2223 if (m_shouldEmitDebugHooks)
2224 environment.markAllVariablesAsCaptured();
2226 auto stackEntry = m_lexicalScopeStack.takeLast();
2227 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2228 bool hasCapturedVariables = false;
2229 for (auto& entry : environment) {
2230 if (entry.value.isCaptured()) {
2231 hasCapturedVariables = true;
2234 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, entry.key.get());
2235 ASSERT(!symbolTableEntry.isNull());
2236 VarOffset offset = symbolTableEntry.varOffset();
2237 ASSERT(offset.isStack());
2238 RegisterID* local = ®isterFor(offset.stackOffset());
2242 if (hasCapturedVariables) {
2243 RELEASE_ASSERT(stackEntry.m_scope);
2244 emitPopScope(scopeRegister(), stackEntry.m_scope);
2245 popLocalControlFlowScope();
2246 stackEntry.m_scope->deref();
2249 m_TDZStack.removeLast();
2252 void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode* node, RegisterID* loopSymbolTable)
2254 VariableEnvironment& environment = node->lexicalVariables();
2255 if (!environment.size())
2257 if (m_shouldEmitDebugHooks)
2258 environment.markAllVariablesAsCaptured();
2259 if (!environment.hasCapturedVariables())
2262 RELEASE_ASSERT(loopSymbolTable);
2264 // This function needs to do setup for a for loop's activation if any of
2265 // the for loop's lexically declared variables are captured (that is, variables
2266 // declared in the loop header, not the loop body). This function needs to
2267 // make a copy of the current activation and copy the values from the previous
2268 // activation into the new activation because each iteration of a for loop
2269 // gets a new activation.
2271 auto stackEntry = m_lexicalScopeStack.last();
2272 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2273 RegisterID* loopScope = stackEntry.m_scope;
2274 ASSERT(symbolTable->scopeSize());
2276 Vector<std::pair<RegisterID*, Identifier>> activationValuesToCopyOver;
2279 activationValuesToCopyOver.reserveInitialCapacity(symbolTable->scopeSize());
2281 for (auto end = symbolTable->end(NoLockingNecessary), ptr = symbolTable->begin(NoLockingNecessary); ptr != end; ++ptr) {
2282 if (!ptr->value.varOffset().isScope())
2285 RefPtr<UniquedStringImpl> ident = ptr->key;
2286 Identifier identifier = Identifier::fromUid(m_vm, ident.get());
2288 RegisterID* transitionValue = newBlockScopeVariable();
2289 transitionValue->ref();
2290 emitGetFromScope(transitionValue, loopScope, variableForLocalEntry(identifier, ptr->value, loopSymbolTable->index(), true), DoNotThrowIfNotFound);
2291 activationValuesToCopyOver.uncheckedAppend(std::make_pair(transitionValue, identifier));
2295 // We need this dynamic behavior of the executing code to ensure
2296 // each loop iteration has a new activation object. (It's pretty ugly).
2297 // Also, this new activation needs to be assigned to the same register
2298 // as the previous scope because the loop body is compiled under
2299 // the assumption that the scope's register index is constant even
2300 // though the value in that register will change on each loop iteration.
2301 RefPtr<RegisterID> parentScope = emitGetParentScope(newTemporary(), loopScope);
2302 emitMove(scopeRegister(), parentScope.get());
2304 emitOpcode(op_create_lexical_environment);
2305 instructions().append(loopScope->index());
2306 instructions().append(scopeRegister()->index());
2307 instructions().append(loopSymbolTable->index());
2308 instructions().append(addConstantValue(jsTDZValue())->index());
2310 emitMove(scopeRegister(), loopScope);
2313 for (auto pair : activationValuesToCopyOver) {
2314 const Identifier& identifier = pair.second;
2315 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, identifier.impl());
2316 RELEASE_ASSERT(!entry.isNull());
2317 RegisterID* transitionValue = pair.first;
2318 emitPutToScope(loopScope, variableForLocalEntry(identifier, entry, loopSymbolTable->index(), true), transitionValue, DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2319 transitionValue->deref();
2324 Variable BytecodeGenerator::variable(const Identifier& property, ThisResolutionType thisResolutionType)
2326 if (property == propertyNames().thisIdentifier && thisResolutionType == ThisResolutionType::Local) {
2327 return Variable(property, VarOffset(thisRegister()->virtualRegister()), thisRegister(),
2328 ReadOnly, Variable::SpecialVariable, 0, false);
2331 // We can optimize lookups if the lexical variable is found before a "with" or "catch"
2332 // scope because we're guaranteed static resolution. If we have to pass through
2333 // a "with" or "catch" scope we loose this guarantee.
2334 // We can't optimize cases like this:
2338 // doSomethingWith(x);
2341 // Because we can't gaurantee static resolution on x.
2342 // But, in this case, we are guaranteed static resolution:
2347 // doSomethingWith(x);
2350 for (unsigned i = m_lexicalScopeStack.size(); i--; ) {
2351 auto& stackEntry = m_lexicalScopeStack[i];
2352 if (stackEntry.m_isWithScope)
2353 return Variable(property);
2354 SymbolTable* symbolTable = stackEntry.m_symbolTable;
2355 SymbolTableEntry symbolTableEntry = symbolTable->get(NoLockingNecessary, property.impl());
2356 if (symbolTableEntry.isNull())
2358 bool resultIsCallee = false;
2359 if (symbolTable->scopeType() == SymbolTable::ScopeType::FunctionNameScope) {
2360 if (m_usesNonStrictEval) {
2361 // We don't know if an eval has introduced a "var" named the same thing as the function name scope variable name.
2362 // We resort to dynamic lookup to answer this question.
2363 Variable result = Variable(property);
2366 resultIsCallee = true;
2368 Variable result = variableForLocalEntry(property, symbolTableEntry, stackEntry.m_symbolTableConstantIndex, symbolTable->scopeType() == SymbolTable::ScopeType::LexicalScope);
2370 result.setIsReadOnly();
2374 return Variable(property);
2377 Variable BytecodeGenerator::variableForLocalEntry(
2378 const Identifier& property, const SymbolTableEntry& entry, int symbolTableConstantIndex, bool isLexicallyScoped)
2380 VarOffset offset = entry.varOffset();
2383 if (offset.isStack())
2384 local = ®isterFor(offset.stackOffset());
2388 return Variable(property, offset, local, entry.getAttributes(), Variable::NormalVariable, symbolTableConstantIndex, isLexicallyScoped);
2391 void BytecodeGenerator::createVariable(
2392 const Identifier& property, VarKind varKind, SymbolTable* symbolTable, ExistingVariableMode existingVariableMode)
2394 ASSERT(property != propertyNames().thisIdentifier);
2395 SymbolTableEntry entry = symbolTable->get(NoLockingNecessary, property.impl());
2397 if (!entry.isNull()) {
2398 if (existingVariableMode == IgnoreExisting)
2401 // Do some checks to ensure that the variable we're being asked to create is sufficiently
2402 // compatible with the one we have already created.
2404 VarOffset offset = entry.varOffset();
2406 // We can't change our minds about whether it's captured.
2407 if (offset.kind() != varKind) {
2409 "Trying to add variable called ", property, " as ", varKind,
2410 " but it was already added as ", offset, ".\n");
2411 RELEASE_ASSERT_NOT_REACHED();
2417 VarOffset varOffset;
2418 if (varKind == VarKind::Scope)
2419 varOffset = VarOffset(symbolTable->takeNextScopeOffset(NoLockingNecessary));
2421 ASSERT(varKind == VarKind::Stack);
2422 varOffset = VarOffset(virtualRegisterForLocal(m_calleeLocals.size()));
2424 SymbolTableEntry newEntry(varOffset, 0);
2425 symbolTable->add(NoLockingNecessary, property.impl(), newEntry);
2427 if (varKind == VarKind::Stack) {
2428 RegisterID* local = addVar();
2429 RELEASE_ASSERT(local->index() == varOffset.stackOffset().offset());
2433 RegisterID* BytecodeGenerator::emitOverridesHasInstance(RegisterID* dst, RegisterID* constructor, RegisterID* hasInstanceValue)
2435 emitOpcode(op_overrides_has_instance);
2436 instructions().append(dst->index());
2437 instructions().append(constructor->index());
2438 instructions().append(hasInstanceValue->index());
2442 // Indicates the least upper bound of resolve type based on local scope. The bytecode linker
2443 // will start with this ResolveType and compute the least upper bound including intercepting scopes.
2444 ResolveType BytecodeGenerator::resolveType()
2446 for (unsigned i = m_lexicalScopeStack.size(); i--; ) {
2447 if (m_lexicalScopeStack[i].m_isWithScope)
2449 if (m_usesNonStrictEval && m_lexicalScopeStack[i].m_symbolTable->scopeType() == SymbolTable::ScopeType::FunctionNameScope) {
2450 // We never want to assign to a FunctionNameScope. Returning Dynamic here achieves this goal.
2451 // If we aren't in non-strict eval mode, then NodesCodeGen needs to take care not to emit
2452 // a put_to_scope with the destination being the function name scope variable.
2457 if (m_usesNonStrictEval)
2458 return GlobalPropertyWithVarInjectionChecks;
2459 return GlobalProperty;
2462 RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& variable)
2464 switch (variable.offset().kind()) {
2465 case VarKind::Stack:
2468 case VarKind::DirectArgument:
2469 return argumentsRegister();
2471 case VarKind::Scope: {
2472 // This always refers to the activation that *we* allocated, and not the current scope that code
2473 // lives in. Note that this will change once we have proper support for block scoping. Once that
2474 // changes, it will be correct for this code to return scopeRegister(). The only reason why we
2475 // don't do that already is that m_lexicalEnvironment is required by ConstDeclNode. ConstDeclNode
2476 // requires weird things because it is a shameful pile of nonsense, but block scoping would make
2477 // that code sensible and obviate the need for us to do bad things.
2478 for (unsigned i = m_lexicalScopeStack.size(); i--; ) {
2479 auto& stackEntry = m_lexicalScopeStack[i];
2480 // We should not resolve a variable to VarKind::Scope if a "with" scope lies in between the current
2481 // scope and the resolved scope.
2482 RELEASE_ASSERT(!stackEntry.m_isWithScope);
2484 if (stackEntry.m_symbolTable->get(NoLockingNecessary, variable.ident().impl()).isNull())
2487 RegisterID* scope = stackEntry.m_scope;
2488 RELEASE_ASSERT(scope);
2492 RELEASE_ASSERT_NOT_REACHED();
2496 case VarKind::Invalid:
2497 // Indicates non-local resolution.
2499 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2501 // resolve_scope dst, id, ResolveType, depth
2502 dst = tempDestination(dst);
2503 emitOpcode(op_resolve_scope);
2504 instructions().append(kill(dst));
2505 instructions().append(scopeRegister()->index());
2506 instructions().append(addConstant(variable.ident()));
2507 instructions().append(resolveType());
2508 instructions().append(localScopeDepth());
2509 instructions().append(0);
2513 RELEASE_ASSERT_NOT_REACHED();
2517 RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable& variable, ResolveMode resolveMode)
2519 switch (variable.offset().kind()) {
2520 case VarKind::Stack:
2521 return emitMove(dst, variable.local());
2523 case VarKind::DirectArgument: {
2524 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_arguments);
2525 instructions().append(kill(dst));
2526 instructions().append(scope->index());
2527 instructions().append(variable.offset().capturedArgumentsOffset().offset());
2528 instructions().append(profile);
2532 case VarKind::Scope:
2533 case VarKind::Invalid: {
2534 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2536 // get_from_scope dst, scope, id, GetPutInfo, Structure, Operand
2537 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
2538 instructions().append(kill(dst));
2539 instructions().append(scope->index());
2540 instructions().append(addConstant(variable.ident()));
2541 instructions().append(GetPutInfo(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType(), InitializationMode::NotInitialization).operand());
2542 instructions().append(localScopeDepth());
2543 instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
2544 instructions().append(profile);
2548 RELEASE_ASSERT_NOT_REACHED();
2551 RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode, InitializationMode initializationMode)
2553 switch (variable.offset().kind()) {
2554 case VarKind::Stack:
2555 emitMove(variable.local(), value);
2558 case VarKind::DirectArgument:
2559 emitOpcode(op_put_to_arguments);
2560 instructions().append(scope->index());
2561 instructions().append(variable.offset().capturedArgumentsOffset().offset());
2562 instructions().append(value->index());
2565 case VarKind::Scope:
2566 case VarKind::Invalid: {
2567 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2569 // put_to_scope scope, id, value, GetPutInfo, Structure, Operand
2570 emitOpcode(op_put_to_scope);
2571 instructions().append(scope->index());
2572 instructions().append(addConstant(variable.ident()));
2573 instructions().append(value->index());
2575 if (variable.offset().isScope()) {
2576 offset = variable.offset().scopeOffset();
2577 instructions().append(GetPutInfo(resolveMode, LocalClosureVar, initializationMode).operand());
2578 instructions().append(variable.symbolTableConstantIndex());
2580 ASSERT(resolveType() != LocalClosureVar);
2581 instructions().append(GetPutInfo(resolveMode, resolveType(), initializationMode).operand());
2582 instructions().append(localScopeDepth());
2584 instructions().append(!!offset ? offset.offset() : 0);
2588 RELEASE_ASSERT_NOT_REACHED();
2591 RegisterID* BytecodeGenerator::initializeVariable(const Variable& variable, RegisterID* value)
2593 RELEASE_ASSERT(variable.offset().kind() != VarKind::Invalid);
2594 RegisterID* scope = emitResolveScope(nullptr, variable);
2595 return emitPutToScope(scope, variable, value, ThrowIfNotFound, InitializationMode::NotInitialization);
2598 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
2600 emitOpcode(op_instanceof);
2601 instructions().append(dst->index());
2602 instructions().append(value->index());
2603 instructions().append(basePrototype->index());
2607 RegisterID* BytecodeGenerator::emitInstanceOfCustom(RegisterID* dst, RegisterID* value, RegisterID* constructor, RegisterID* hasInstanceValue)
2609 emitOpcode(op_instanceof_custom);
2610 instructions().append(dst->index());
2611 instructions().append(value->index());
2612 instructions().append(constructor->index());
2613 instructions().append(hasInstanceValue->index());
2617 RegisterID* BytecodeGenerator::emitIn(RegisterID* dst, RegisterID* property, RegisterID* base)
2619 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2621 instructions().append(dst->index());
2622 instructions().append(base->index());
2623 instructions().append(property->index());
2624 instructions().append(arrayProfile);
2628 RegisterID* BytecodeGenerator::emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
2630 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties are not supported with tryGetById.");
2632 UnlinkedValueProfile profile = emitProfiledOpcode(op_try_get_by_id);
2633 instructions().append(kill(dst));
2634 instructions().append(base->index());
2635 instructions().append(addConstant(property));
2636 instructions().append(profile);
2640 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
2642 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
2644 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2646 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id);
2647 instructions().append(kill(dst));
2648 instructions().append(base->index());
2649 instructions().append(addConstant(property));
2650 instructions().append(0);
2651 instructions().append(0);
2652 instructions().append(0);
2653 instructions().append(Options::prototypeHitCountForLLIntCaching());
2654 instructions().append(profile);
2658 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, RegisterID* thisVal, const Identifier& property)
2660 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
2662 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id_with_this);
2663 instructions().append(kill(dst));
2664 instructions().append(base->index());
2665 instructions().append(thisVal->index());
2666 instructions().append(addConstant(property));
2667 instructions().append(profile);
2671 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
2673 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val.");
2675 unsigned propertyIndex = addConstant(property);
2677 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2679 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2681 emitOpcode(op_put_by_id);
2682 instructions().append(base->index());
2683 instructions().append(propertyIndex);
2684 instructions().append(value->index());
2685 instructions().append(0); // old structure
2686 instructions().append(0); // offset
2687 instructions().append(0); // new structure
2688 instructions().append(0); // structure chain
2689 instructions().append(static_cast<int>(PutByIdNone)); // is not direct
2694 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, RegisterID* thisValue, const Identifier& property, RegisterID* value)
2696 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val.");
2698 unsigned propertyIndex = addConstant(property);
2700 emitOpcode(op_put_by_id_with_this);
2701 instructions().append(base->index());
2702 instructions().append(thisValue->index());
2703 instructions().append(propertyIndex);
2704 instructions().append(value->index());
2709 RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType putType)
2711 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val(direct).");
2713 unsigned propertyIndex = addConstant(property);
2715 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2717 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2719 emitOpcode(op_put_by_id);
2720 instructions().append(base->index());
2721 instructions().append(propertyIndex);
2722 instructions().append(value->index());
2723 instructions().append(0); // old structure
2724 instructions().append(0); // offset
2725 instructions().append(0); // new structure
2726 instructions().append(0); // structure chain (unused if direct)
2727 instructions().append(static_cast<int>((putType == PropertyNode::KnownDirect || property != m_vm->propertyNames->underscoreProto) ? PutByIdIsDirect : PutByIdNone));
2731 void BytecodeGenerator::emitPutGetterById(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter)
2733 unsigned propertyIndex = addConstant(property);
2734 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2736 emitOpcode(op_put_getter_by_id);
2737 instructions().append(base->index());
2738 instructions().append(propertyIndex);
2739 instructions().append(attributes);
2740 instructions().append(getter->index());
2743 void BytecodeGenerator::emitPutSetterById(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* setter)
2745 unsigned propertyIndex = addConstant(property);
2746 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2748 emitOpcode(op_put_setter_by_id);
2749 instructions().append(base->index());
2750 instructions().append(propertyIndex);
2751 instructions().append(attributes);
2752 instructions().append(setter->index());
2755 void BytecodeGenerator::emitPutGetterSetter(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter, RegisterID* setter)
2757 unsigned propertyIndex = addConstant(property);
2759 m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
2761 emitOpcode(op_put_getter_setter_by_id);
2762 instructions().append(base->index());
2763 instructions().append(propertyIndex);
2764 instructions().append(attributes);
2765 instructions().append(getter->index());
2766 instructions().append(setter->index());
2769 void BytecodeGenerator::emitPutGetterByVal(RegisterID* base, RegisterID* property, unsigned attributes, RegisterID* getter)
2771 emitOpcode(op_put_getter_by_val);
2772 instructions().append(base->index());
2773 instructions().append(property->index());
2774 instructions().append(attributes);
2775 instructions().append(getter->index());
2778 void BytecodeGenerator::emitPutSetterByVal(RegisterID* base, RegisterID* property, unsigned attributes, RegisterID* setter)
2780 emitOpcode(op_put_setter_by_val);
2781 instructions().append(base->index());
2782 instructions().append(property->index());
2783 instructions().append(attributes);
2784 instructions().append(setter->index());
2787 void BytecodeGenerator::emitPutGeneratorFields(RegisterID* nextFunction)
2789 // FIXME: Currently, we just create an object and store generator related fields as its properties for ease.
2790 // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties.
2791 // https://bugs.webkit.org/show_bug.cgi?id=151545
2793 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorNextPrivateName(), nextFunction, PropertyNode::KnownDirect);
2795 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorThisPrivateName(), &m_thisRegister, PropertyNode::KnownDirect);
2797 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorStatePrivateName(), emitLoad(nullptr, jsNumber(0)), PropertyNode::KnownDirect);
2799 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().generatorFramePrivateName(), emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
2802 RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
2804 emitOpcode(op_del_by_id);
2805 instructions().append(dst->index());
2806 instructions().append(base->index());
2807 instructions().append(addConstant(property));
2811 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
2813 for (size_t i = m_forInContextStack.size(); i > 0; i--) {
2814 ForInContext& context = m_forInContextStack[i - 1].get();
2815 if (context.local() != property)
2818 if (!context.isValid())
2821 if (context.type() == ForInContext::IndexedForInContextType) {
2822 property = static_cast<IndexedForInContext&>(context).index();
2826 ASSERT(context.type() == ForInContext::StructureForInContextType);
2827 StructureForInContext& structureContext = static_cast<StructureForInContext&>(context);
2828 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_direct_pname);
2829 instructions().append(kill(dst));
2830 instructions().append(base->index());
2831 instructions().append(property->index());
2832 instructions().append(structureContext.index()->index());
2833 instructions().append(structureContext.enumerator()->index());
2834 instructions().append(profile);
2838 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2839 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val);
2840 instructions().append(kill(dst));
2841 instructions().append(base->index());
2842 instructions().append(property->index());
2843 instructions().append(arrayProfile);
2844 instructions().append(profile);
2848 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property)
2850 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val_with_this);
2851 instructions().append(kill(dst));
2852 instructions().append(base->index());
2853 instructions().append(thisValue->index());
2854 instructions().append(property->index());
2855 instructions().append(profile);
2859 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
2861 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2862 emitOpcode(op_put_by_val);
2863 instructions().append(base->index());
2864 instructions().append(property->index());
2865 instructions().append(value->index());
2866 instructions().append(arrayProfile);
2871 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value)
2873 emitOpcode(op_put_by_val_with_this);
2874 instructions().append(base->index());
2875 instructions().append(thisValue->index());
2876 instructions().append(property->index());
2877 instructions().append(value->index());
2882 RegisterID* BytecodeGenerator::emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
2884 UnlinkedArrayProfile arrayProfile = newArrayProfile();
2885 emitOpcode(op_put_by_val_direct);
2886 instructions().append(base->index());
2887 instructions().append(property->index());
2888 instructions().append(value->index());
2889 instructions().append(arrayProfile);
2893 RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
2895 emitOpcode(op_del_by_val);
2896 instructions().append(dst->index());
2897 instructions().append(base->index());
2898 instructions().append(property->index());
2902 RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
2904 emitOpcode(op_put_by_index);
2905 instructions().append(base->index());
2906 instructions().append(index);
2907 instructions().append(value->index());
2911 RegisterID* BytecodeGenerator::emitAssert(RegisterID* condition, int line)
2913 emitOpcode(op_assert);
2914 instructions().append(condition->index());
2915 instructions().append(line);
2919 RegisterID* BytecodeGenerator::emitGetArgument(RegisterID* dst, int32_t index)
2921 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument);
2922 instructions().append(dst->index());
2923 instructions().append(index + 1); // Including |this|.
2924 instructions().append(profile);
2928 RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
2930 size_t begin = instructions().size();
2931 m_staticPropertyAnalyzer.createThis(dst->index(), begin + 3);
2933 m_codeBlock->addPropertyAccessInstruction(instructions().size());
2934 emitOpcode(op_create_this);
2935 instructions().append(dst->index());
2936 instructions().append(dst->index());
2937 instructions().append(0);
2938 instructions().append(0);
2942 void BytecodeGenerator::emitTDZCheck(RegisterID* target)
2944 emitOpcode(op_check_tdz);
2945 instructions().append(target->index());
2948 bool BytecodeGenerator::needsTDZCheck(const Variable& variable)
2950 for (unsigned i = m_TDZStack.size(); i--;) {
2951 auto iter = m_TDZStack[i].find(variable.ident().impl());
2952 if (iter == m_TDZStack[i].end())
2954 return iter->value != TDZNecessityLevel::NotNeeded;
2960 void BytecodeGenerator::emitTDZCheckIfNecessary(const Variable& variable, RegisterID* target, RegisterID* scope)
2962 if (needsTDZCheck(variable)) {
2964 emitTDZCheck(target);
2966 RELEASE_ASSERT(!variable.isLocal() && scope);
2967 RefPtr<RegisterID> result = emitGetFromScope(newTemporary(), scope, variable, DoNotThrowIfNotFound);
2968 emitTDZCheck(result.get());
2973 void BytecodeGenerator::liftTDZCheckIfPossible(const Variable& variable)
2975 RefPtr<UniquedStringImpl> identifier(variable.ident().impl());
2976 for (unsigned i = m_TDZStack.size(); i--;) {
2977 auto iter = m_TDZStack[i].find(identifier);
2978 if (iter != m_TDZStack[i].end()) {
2979 if (iter->value == TDZNecessityLevel::Optimize)
2980 iter->value = TDZNecessityLevel::NotNeeded;
2986 void BytecodeGenerator::pushTDZVariables(const VariableEnvironment& environment, TDZCheckOptimization optimization, TDZRequirement requirement)
2988 if (!environment.size())
2991 TDZNecessityLevel level;
2992 if (requirement == TDZRequirement::UnderTDZ) {
2993 if (optimization == TDZCheckOptimization::Optimize)
2994 level = TDZNecessityLevel::Optimize;
2996 level = TDZNecessityLevel::DoNotOptimize;
2998 level = TDZNecessityLevel::NotNeeded;
3001 for (const auto& entry : environment)
3002 map.add(entry.key, entry.value.isFunction() ? TDZNecessityLevel::NotNeeded : level);
3004 m_TDZStack.append(WTFMove(map));
3007 void BytecodeGenerator::getVariablesUnderTDZ(VariableEnvironment& result)
3009 // We keep track of variablesThatDontNeedTDZ in this algorithm to prevent
3010 // reporting that "x" is under TDZ if this function is called at "...".
3020 SmallPtrSet<UniquedStringImpl*, 16> variablesThatDontNeedTDZ;
3021 for (unsigned i = m_TDZStack.size(); i--; ) {
3022 auto& map = m_TDZStack[i];
3023 for (auto& entry : map) {
3024 if (entry.value != TDZNecessityLevel::NotNeeded) {
3025 if (!variablesThatDontNeedTDZ.contains(entry.key.get()))
3026 result.add(entry.key.get());
3028 variablesThatDontNeedTDZ.add(entry.key.get());
3033 RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
3035 size_t begin = instructions().size();
3036 m_staticPropertyAnalyzer.newObject(dst->index(), begin + 2);
3038 emitOpcode(op_new_object);
3039 instructions().append(dst->index());
3040 instructions().append(0);
3041 instructions().append(newObjectAllocationProfile());
3045 unsigned BytecodeGenerator::addConstantBuffer(unsigned length)
3047 return m_codeBlock->addConstantBuffer(length);
3050 JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
3052 JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
3054 stringInMap = jsString(vm(), identifier.string());
3055 addConstantValue(stringInMap);
3060 RegisterID* BytecodeGenerator::addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&& templateRegistryKey)
3062 return m_templateRegistryKeyMap.ensure(templateRegistryKey.copyRef(), [&] {
3063 auto* result = JSTemplateRegistryKey::create(*vm(), WTFMove(templateRegistryKey));
3064 unsigned index = m_nextConstantOffset;
3065 m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
3066 ++m_nextConstantOffset;
3067 m_codeBlock->addConstant(result);
3068 return &m_constantPoolRegisters[index];
3072 RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
3074 #if !ASSERT_DISABLED
3075 unsigned checkLength = 0;
3077 bool hadVariableExpression = false;
3079 for (ElementNode* n = elements; n; n = n->next()) {
3080 if (!n->value()->isConstant()) {
3081 hadVariableExpression = true;
3086 #if !ASSERT_DISABLED
3090 if (!hadVariableExpression) {
3091 ASSERT(length == checkLength);
3092 unsigned constantBufferIndex = addConstantBuffer(length);
3093 JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex).data();
3095 for (ElementNode* n = elements; index < length; n = n->next()) {
3096 ASSERT(n->value()->isConstant());
3097 constantBuffer[index++] = static_cast<ConstantNode*>(n->value())->jsValue(*this);
3099 emitOpcode(op_new_array_buffer);
3100 instructions().append(dst->index());
3101 instructions().append(constantBufferIndex);
3102 instructions().append(length);
3103 instructions().append(newArrayAllocationProfile());
3108 Vector<RefPtr<RegisterID>, 16, UnsafeVectorOverflow> argv;
3109 for (ElementNode* n = elements; n; n = n->next()) {
3113 ASSERT(!n->value()->isSpreadExpression());
3114 argv.append(newTemporary());
3115 // op_new_array requires the initial values to be a sequential range of registers
3116 ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() - 1);
3117 emitNode(argv.last().get(), n->value());
3120 emitOpcode(op_new_array);
3121 instructions().append(dst->index());
3122 instructions().append(argv.size() ? argv[0]->index() : 0); // argv
3123 instructions().append(argv.size()); // argc
3124 instructions().append(newArrayAllocationProfile());
3128 RegisterID* BytecodeGenerator::emitNewArrayWithSpread(RegisterID* dst, ElementNode* elements)
3130 BitVector bitVector;
3131 Vector<RefPtr<RegisterID>, 16> argv;
3132 for (ElementNode* node = elements; node; node = node->next()) {
3133 bitVector.set(argv.size(), node->value()->isSpreadExpression());
3135 argv.append(newTemporary());
3136 // op_new_array_with_spread requires the initial values to be a sequential range of registers.
3137 RELEASE_ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() - 1);
3140 RELEASE_ASSERT(argv.size());
3144 for (ElementNode* node = elements; node; node = node->next()) {
3145 if (node->value()->isSpreadExpression()) {
3146 ExpressionNode* expression = static_cast<SpreadExpressionNode*>(node->value())->expression();
3147 RefPtr<RegisterID> tmp = newTemporary();
3148 emitNode(tmp.get(), expression);
3150 emitOpcode(op_spread);
3151 instructions().append(argv[i].get()->index());
3152 instructions().append(tmp.get()->index());
3154 ExpressionNode* expression = node->value();
3155 emitNode(argv[i].get(), expression);
3161 unsigned bitVectorIndex = m_codeBlock->addBitVector(WTFMove(bitVector));
3162 emitOpcode(op_new_array_with_spread);
3163 instructions().append(dst->index());