void ESTreeIRGen::emitFunctionPrologue(
    ESTree::FunctionLikeNode *funcNode,
    BasicBlock *entry,
    InitES5CaptureState doInitES5CaptureState,
    DoEmitParameters doEmitParameters) {
  auto *newFunc = curFunction()->function;
  auto *semInfo = curFunction()->getSemInfo();
  LLVM_DEBUG(
      dbgs() << "Hoisting "
             << (semInfo->varDecls.size() + semInfo->closures.size())
             << " variable decls.\n");

  Builder.setLocation(newFunc->getSourceRange().Start);

  // Start pumping instructions into the entry basic block.
  Builder.setInsertionBlock(entry);

  // Always insert a CreateArgumentsInst. We will delete it later if it is
  // unused.
  curFunction()->createArgumentsInst = Builder.createCreateArgumentsInst();

  // Create variable declarations for each of the hoisted variables and
  // functions. Initialize only the variables to undefined.
  for (auto decl : semInfo->varDecls) {
    auto res = declareVariableOrGlobalProperty(
        newFunc, decl.kind, getNameFieldFromID(decl.identifier));
    // If this is not a frame variable or it was already declared, skip.
    auto *var = llvh::dyn_cast<Variable>(res.first);
    if (!var || !res.second)
      continue;

    // Otherwise, initialize it to undefined.
    Builder.createStoreFrameInst(Builder.getLiteralUndefined(), var);
    if (var->getRelatedVariable()) {
      Builder.createStoreFrameInst(
          Builder.getLiteralUndefined(), var->getRelatedVariable());
    }
  }
  for (auto *fd : semInfo->closures) {
    declareVariableOrGlobalProperty(
        newFunc, VarDecl::Kind::Var, getNameFieldFromID(fd->_id));
  }

  // Always create the "this" parameter. It needs to be created before we
  // initialized the ES5 capture state.
  Builder.createParameter(newFunc, "this");

  if (doInitES5CaptureState != InitES5CaptureState::No)
    initCaptureStateInES5FunctionHelper();

  // Construct the parameter list. Create function parameters and register
  // them in the scope.
  if (doEmitParameters == DoEmitParameters::Yes) {
    emitParameters(funcNode);
  } else {
    newFunc->setExpectedParamCountIncludingThis(
        countExpectedArgumentsIncludingThis(funcNode));
  }

  // Generate the code for import declarations before generating the rest of the
  // body.
  for (auto importDecl : semInfo->imports) {
    genImportDeclaration(importDecl);
  }

  // Generate and initialize the code for the hoisted function declarations
  // before generating the rest of the body.
  for (auto funcDecl : semInfo->closures) {
    genFunctionDeclaration(funcDecl);
  }
}
void ESTreeIRGen::emitFunctionPrologue(
    ESTree::FunctionLikeNode *funcNode,
    BasicBlock *entry,
    InitES5CaptureState doInitES5CaptureState,
    DoEmitParameters doEmitParameters) {
  auto *newFunc = curFunction()->function;
  auto *semInfo = curFunction()->getSemInfo();
  LLVM_DEBUG(
      dbgs() << "Hoisting "
             << (semInfo->varDecls.size() + semInfo->closures.size())
             << " variable decls.\n");

  Builder.setLocation(newFunc->getSourceRange().Start);

   
  Builder.setInsertionBlock(entry);

   
   
  curFunction()->createArgumentsInst = Builder.createCreateArgumentsInst();

   
   
  for (auto decl : semInfo->varDecls) {
    auto res = declareVariableOrGlobalProperty(
        newFunc, decl.kind, getNameFieldFromID(decl.identifier));
     
    auto *var = llvh::dyn_cast<Variable>(res.first);
    if (!var || !res.second)
      continue;

     
    Builder.createStoreFrameInst(Builder.getLiteralUndefined(), var);
    if (var->getRelatedVariable()) {
      Builder.createStoreFrameInst(
          Builder.getLiteralUndefined(), var->getRelatedVariable());
    }
  }
  for (auto *fd : semInfo->closures) {
    declareVariableOrGlobalProperty(
        newFunc, VarDecl::Kind::Var, getNameFieldFromID(fd->_id));
  }

   
   
  Builder.createParameter(newFunc, "this");

  if (doInitES5CaptureState != InitES5CaptureState::No)
    initCaptureStateInES5FunctionHelper();

   
   
  if (doEmitParameters == DoEmitParameters::Yes) {
    emitParameters(funcNode);
  } else {
    newFunc->setExpectedParamCountIncludingThis(
        countExpectedArgumentsIncludingThis(funcNode));
  }

   
   
  for (auto importDecl : semInfo->imports) {
    genImportDeclaration(importDecl);
  }

   
   
  for (auto funcDecl : semInfo->closures) {
    genFunctionDeclaration(funcDecl);
  }
}