// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/compiler/frontend/kernel_to_il.h"

#include "platform/assert.h"
#include "platform/globals.h"
#include "vm/class_id.h"
#include "vm/compiler/aot/precompiler.h"
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/locations.h"
#include "vm/compiler/backend/range_analysis.h"
#include "vm/compiler/ffi/abi.h"
#include "vm/compiler/ffi/marshaller.h"
#include "vm/compiler/ffi/native_calling_convention.h"
#include "vm/compiler/ffi/native_type.h"
#include "vm/compiler/ffi/recognized_method.h"
#include "vm/compiler/frontend/kernel_binary_flowgraph.h"
#include "vm/compiler/frontend/kernel_translation_helper.h"
#include "vm/compiler/frontend/prologue_builder.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/compiler/runtime_api.h"
#include "vm/kernel_isolate.h"
#include "vm/kernel_loader.h"
#include "vm/log.h"
#include "vm/longjump.h"
#include "vm/native_entry.h"
#include "vm/object_store.h"
#include "vm/report.h"
#include "vm/resolver.h"
#include "vm/runtime_entry.h"
#include "vm/scopes.h"
#include "vm/stack_frame.h"
#include "vm/symbols.h"

namespace dart {

DEFINE_FLAG(bool,
            print_huge_methods,
            false,
            "Print huge methods (less optimized)");

namespace kernel {

#define Z (zone_)
#define H (translation_helper_)
#define T (type_translator_)
#define I Isolate::Current()
#define IG IsolateGroup::Current()

FlowGraphBuilder::FlowGraphBuilder(
    ParsedFunction* parsed_function,
    ZoneGrowableArray<const ICData*>* ic_data_array,
    ZoneGrowableArray<intptr_t>* context_level_array,
    InlineExitCollector* exit_collector,
    bool optimizing,
    intptr_t osr_id,
    intptr_t first_block_id,
    bool inlining_unchecked_entry)
    : BaseFlowGraphBuilder(parsed_function,
                           first_block_id - 1,
                           osr_id,
                           context_level_array,
                           exit_collector,
                           inlining_unchecked_entry),
      translation_helper_(Thread::Current()),
      thread_(translation_helper_.thread()),
      zone_(translation_helper_.zone()),
      parsed_function_(parsed_function),
      optimizing_(optimizing),
      ic_data_array_(*ic_data_array),
      next_function_id_(0),
      loop_depth_(0),
      try_depth_(0),
      catch_depth_(0),
      for_in_depth_(0),
      block_expression_depth_(0),
      graph_entry_(NULL),
      scopes_(NULL),
      breakable_block_(NULL),
      switch_block_(NULL),
      try_catch_block_(NULL),
      try_finally_block_(NULL),
      catch_block_(NULL),
      prepend_type_arguments_(Function::ZoneHandle(zone_)),
      throw_new_null_assertion_(Function::ZoneHandle(zone_)) {
  const Script& script =
      Script::Handle(Z, parsed_function->function().script());
  H.InitFromScript(script);
}

FlowGraphBuilder::~FlowGraphBuilder() {}

Fragment FlowGraphBuilder::EnterScope(
    intptr_t kernel_offset,
    const LocalScope** context_scope /* = nullptr */) {
  Fragment instructions;
  const LocalScope* scope = scopes_->scopes.Lookup(kernel_offset);
  if (scope->num_context_variables() > 0) {
    instructions += PushContext(scope);
    instructions += Drop();
  }
  if (context_scope != nullptr) {
    *context_scope = scope;
  }
  return instructions;
}

Fragment FlowGraphBuilder::ExitScope(intptr_t kernel_offset) {
  Fragment instructions;
  const intptr_t context_size =
      scopes_->scopes.Lookup(kernel_offset)->num_context_variables();
  if (context_size > 0) {
    instructions += PopContext();
  }
  return instructions;
}

Fragment FlowGraphBuilder::AdjustContextTo(int depth) {
  ASSERT(depth <= context_depth_ && depth >= 0);
  Fragment instructions;
  if (depth < context_depth_) {
    instructions += LoadContextAt(depth);
    instructions += StoreLocal(TokenPosition::kNoSource,
                               parsed_function_->current_context_var());
    instructions += Drop();
    context_depth_ = depth;
  }
  return instructions;
}

Fragment FlowGraphBuilder::PushContext(const LocalScope* scope) {
  ASSERT(scope->num_context_variables() > 0);
  Fragment instructions = AllocateContext(scope->context_slots());
  LocalVariable* context = MakeTemporary();
  instructions += LoadLocal(context);
  instructions += LoadLocal(parsed_function_->current_context_var());
  instructions += StoreNativeField(
      Slot::Context_parent(), StoreInstanceFieldInstr::Kind::kInitializing);
  instructions += StoreLocal(TokenPosition::kNoSource,
                             parsed_function_->current_context_var());
  ++context_depth_;
  return instructions;
}

Fragment FlowGraphBuilder::PopContext() {
  return AdjustContextTo(context_depth_ - 1);
}

Fragment FlowGraphBuilder::LoadInstantiatorTypeArguments() {
  // TODO(27590): We could use `active_class_->IsGeneric()`.
  Fragment instructions;
  if (scopes_ != nullptr && scopes_->type_arguments_variable != nullptr) {
#ifdef DEBUG
    Function& function =
        Function::Handle(Z, parsed_function_->function().ptr());
    while (function.IsClosureFunction()) {
      function = function.parent_function();
    }
    ASSERT(function.IsFactory());
#endif
    instructions += LoadLocal(scopes_->type_arguments_variable);
  } else if (parsed_function_->has_receiver_var() &&
             active_class_.ClassNumTypeArguments() > 0) {
    ASSERT(!parsed_function_->function().IsFactory());
    instructions += LoadLocal(parsed_function_->receiver_var());
    instructions += LoadNativeField(
        Slot::GetTypeArgumentsSlotFor(thread_, *active_class_.klass));
  } else {
    instructions += NullConstant();
  }
  return instructions;
}

// This function is responsible for pushing a type arguments vector which
// contains all type arguments of enclosing functions prepended to the type
// arguments of the current function.
Fragment FlowGraphBuilder::LoadFunctionTypeArguments() {
  Fragment instructions;

  const Function& function = parsed_function_->function();

  if (function.IsGeneric() || function.HasGenericParent()) {
    ASSERT(parsed_function_->function_type_arguments() != NULL);
    instructions += LoadLocal(parsed_function_->function_type_arguments());
  } else {
    instructions += NullConstant();
  }

  return instructions;
}

Fragment FlowGraphBuilder::TranslateInstantiatedTypeArguments(
    const TypeArguments& type_arguments) {
  Fragment instructions;

  if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
    // There are no type references to type parameters so we can just take it.
    instructions += Constant(type_arguments);
  } else {
    // The [type_arguments] vector contains a type reference to a type
    // parameter we need to resolve it.
    if (type_arguments.CanShareInstantiatorTypeArguments(
            *active_class_.klass)) {
      // If the instantiator type arguments are just passed on, we don't need to
      // resolve the type parameters.
      //
      // This is for example the case here:
      //     class Foo<T> {
      //       newList() => new List<T>();
      //     }
      // We just use the type argument vector from the [Foo] object and pass it
      // directly to the `new List<T>()` factory constructor.
      instructions += LoadInstantiatorTypeArguments();
    } else if (type_arguments.CanShareFunctionTypeArguments(
                   parsed_function_->function())) {
      instructions += LoadFunctionTypeArguments();
    } else {
      // Otherwise we need to resolve [TypeParameterType]s in the type
      // expression based on the current instantiator type argument vector.
      if (!type_arguments.IsInstantiated(kCurrentClass)) {
        instructions += LoadInstantiatorTypeArguments();
      } else {
        instructions += NullConstant();
      }
      if (!type_arguments.IsInstantiated(kFunctions)) {
        instructions += LoadFunctionTypeArguments();
      } else {
        instructions += NullConstant();
      }
      instructions += InstantiateTypeArguments(type_arguments);
    }
  }
  return instructions;
}

Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
                                           intptr_t handler_index,
                                           bool needs_stacktrace,
                                           bool is_synthesized) {
  LocalVariable* exception_var = CurrentException();
  LocalVariable* stacktrace_var = CurrentStackTrace();
  LocalVariable* raw_exception_var = CurrentRawException();
  LocalVariable* raw_stacktrace_var = CurrentRawStackTrace();

  CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
      is_synthesized,  // whether catch block was synthesized by FE compiler
      AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types,
      handler_index, needs_stacktrace, GetNextDeoptId(), exception_var,
      stacktrace_var, raw_exception_var, raw_stacktrace_var);
  graph_entry_->AddCatchEntry(entry);

  Fragment instructions(entry);

  // Auxiliary variables introduced by the try catch can be captured if we are
  // inside a function with yield/resume points. In this case we first need
  // to restore the context to match the context at entry into the closure.
  const bool should_restore_closure_context =
      CurrentException()->is_captured() || CurrentCatchContext()->is_captured();
  LocalVariable* context_variable = parsed_function_->current_context_var();
  if (should_restore_closure_context) {
    ASSERT(parsed_function_->function().IsClosureFunction());

    LocalVariable* closure_parameter = parsed_function_->ParameterVariable(0);
    ASSERT(!closure_parameter->is_captured());
    instructions += LoadLocal(closure_parameter);
    instructions += LoadNativeField(Slot::Closure_context());
    instructions += StoreLocal(TokenPosition::kNoSource, context_variable);
    instructions += Drop();
  }

  if (exception_var->is_captured()) {
    instructions += LoadLocal(context_variable);
    instructions += LoadLocal(raw_exception_var);
    instructions += StoreNativeField(
        Slot::GetContextVariableSlotFor(thread_, *exception_var));
  }
  if (stacktrace_var->is_captured()) {
    instructions += LoadLocal(context_variable);
    instructions += LoadLocal(raw_stacktrace_var);
    instructions += StoreNativeField(
        Slot::GetContextVariableSlotFor(thread_, *stacktrace_var));
  }

  // :saved_try_context_var can be captured in the context of
  // of the closure, in this case CatchBlockEntryInstr restores
  // :current_context_var to point to closure context in the
  // same way as normal function prologue does.
  // Update current context depth to reflect that.
  const intptr_t saved_context_depth = context_depth_;
  ASSERT(!CurrentCatchContext()->is_captured() ||
         CurrentCatchContext()->owner()->context_level() == 0);
  context_depth_ = 0;
  instructions += LoadLocal(CurrentCatchContext());
  instructions += StoreLocal(TokenPosition::kNoSource,
                             parsed_function_->current_context_var());
  instructions += Drop();
  context_depth_ = saved_context_depth;

  return instructions;
}

Fragment FlowGraphBuilder::TryCatch(int try_handler_index) {
  // The body of the try needs to have it's own block in order to get a new try
  // index.
  //
  // => We therefore create a block for the body (fresh try index) and another
  //    join block (with current try index).
  Fragment body;
  JoinEntryInstr* entry = BuildJoinEntry(try_handler_index);
  body += LoadLocal(parsed_function_->current_context_var());
  body += StoreLocal(TokenPosition::kNoSource, CurrentCatchContext());
  body += Drop();
  body += Goto(entry);
  return Fragment(body.entry, entry);
}

Fragment FlowGraphBuilder::CheckStackOverflowInPrologue(
    TokenPosition position) {
  ASSERT(loop_depth_ == 0);
  return BaseFlowGraphBuilder::CheckStackOverflowInPrologue(position);
}

Fragment FlowGraphBuilder::CloneContext(
    const ZoneGrowableArray<const Slot*>& context_slots) {
  LocalVariable* context_variable = parsed_function_->current_context_var();

  Fragment instructions = LoadLocal(context_variable);

  CloneContextInstr* clone_instruction = new (Z) CloneContextInstr(
      InstructionSource(), Pop(), context_slots, GetNextDeoptId());
  instructions <<= clone_instruction;
  Push(clone_instruction);

  instructions += StoreLocal(TokenPosition::kNoSource, context_variable);
  instructions += Drop();
  return instructions;
}

Fragment FlowGraphBuilder::InstanceCall(
    TokenPosition position,
    const String& name,
    Token::Kind kind,
    intptr_t type_args_len,
    intptr_t argument_count,
    const Array& argument_names,
    intptr_t checked_argument_count,
    const Function& interface_target,
    const Function& tearoff_interface_target,
    const InferredTypeMetadata* result_type,
    bool use_unchecked_entry,
    const CallSiteAttributesMetadata* call_site_attrs,
    bool receiver_is_not_smi,
    bool is_call_on_this) {
  const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0);
  InputsArray* arguments = GetArguments(total_count);
  InstanceCallInstr* call = new (Z) InstanceCallInstr(
      InstructionSource(position), name, kind, arguments, type_args_len,
      argument_names, checked_argument_count, ic_data_array_, GetNextDeoptId(),
      interface_target, tearoff_interface_target);
  if ((result_type != NULL) && !result_type->IsTrivial()) {
    call->SetResultType(Z, result_type->ToCompileType(Z));
  }
  if (use_unchecked_entry) {
    call->set_entry_kind(Code::EntryKind::kUnchecked);
  }
  if (is_call_on_this) {
    call->mark_as_call_on_this();
  }
  if (call_site_attrs != nullptr && call_site_attrs->receiver_type != nullptr &&
      call_site_attrs->receiver_type->IsInstantiated()) {
    call->set_receivers_static_type(call_site_attrs->receiver_type);
  } else if (!interface_target.IsNull()) {
    const Class& owner = Class::Handle(Z, interface_target.Owner());
    const AbstractType& type =
        AbstractType::ZoneHandle(Z, owner.DeclarationType());
    call->set_receivers_static_type(&type);
  }
  call->set_receiver_is_not_smi(receiver_is_not_smi);
  Push(call);
  if (result_type != nullptr && result_type->IsConstant()) {
    Fragment instructions(call);
    instructions += Drop();
    instructions += Constant(result_type->constant_value);
    return instructions;
  }
  return Fragment(call);
}

Fragment FlowGraphBuilder::FfiCall(
    const compiler::ffi::CallMarshaller& marshaller) {
  Fragment body;

  FfiCallInstr* const call =
      new (Z) FfiCallInstr(Z, GetNextDeoptId(), marshaller,
                           parsed_function_->function().FfiIsLeaf());

  for (intptr_t i = call->InputCount() - 1; i >= 0; --i) {
    call->SetInputAt(i, Pop());
  }

  Push(call);
  body <<= call;

  return body;
}

Fragment FlowGraphBuilder::CCall(
    const compiler::ffi::NativeCallingConvention& native_calling_convention) {
  Fragment body;

  const intptr_t num_arguments =
      native_calling_convention.argument_locations().length() + 1;
  InputsArray* arguments = new (Z) InputsArray(num_arguments);
  arguments->FillWith(nullptr, 0, num_arguments);
  for (intptr_t i = num_arguments - 1; i >= 0; --i) {
    (*arguments)[i] = Pop();
  }
  auto* const call =
      new (Z) CCallInstr(Z, native_calling_convention, arguments);

  Push(call);
  body <<= call;

  return body;
}

Fragment FlowGraphBuilder::CCall(intptr_t num_arguments,
                                 Representation representation) {
  const auto& native_function_type =
      *compiler::ffi::NativeFunctionType::FromUnboxedRepresentation(
          Z, num_arguments, representation);
  const auto& native_calling_convention =
      compiler::ffi::NativeCallingConvention::FromSignature(
          Z, native_function_type);
  return CCall(native_calling_convention);
}

Fragment FlowGraphBuilder::RethrowException(TokenPosition position,
                                            int catch_try_index) {
  Fragment instructions;
  Value* stacktrace = Pop();
  Value* exception = Pop();
  instructions += Fragment(new (Z) ReThrowInstr(
                               InstructionSource(position), catch_try_index,
                               GetNextDeoptId(), exception, stacktrace))
                      .closed();
  // Use its side effect of leaving a constant on the stack (does not change
  // the graph).
  NullConstant();

  return instructions;
}

Fragment FlowGraphBuilder::LoadLocal(LocalVariable* variable) {
  // Captured 'this' is immutable, so within the outer method we don't need to
  // load it from the context.
  const ParsedFunction* pf = parsed_function_;
  if (pf->function().HasThisParameter() && pf->has_receiver_var() &&
      variable == pf->receiver_var()) {
    ASSERT(variable == pf->ParameterVariable(0));
    variable = pf->RawParameterVariable(0);
  }
  if (variable->is_captured()) {
    Fragment instructions;
    instructions += LoadContextAt(variable->owner()->context_level());
    instructions +=
        LoadNativeField(Slot::GetContextVariableSlotFor(thread_, *variable));
    return instructions;
  } else {
    return BaseFlowGraphBuilder::LoadLocal(variable);
  }
}

Fragment FlowGraphBuilder::IndirectGoto(intptr_t target_count) {
  Value* index = Pop();
  return Fragment(new (Z) IndirectGotoInstr(target_count, index));
}

Fragment FlowGraphBuilder::ThrowLateInitializationError(
    TokenPosition position,
    const char* throw_method_name,
    const String& name) {
  const Class& klass =
      Class::ZoneHandle(Z, Library::LookupCoreClass(Symbols::LateError()));
  ASSERT(!klass.IsNull());

  const auto& error = klass.EnsureIsFinalized(thread_);
  ASSERT(error == Error::null());
  const Function& throw_new =
      Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate(
                                  H.DartSymbolObfuscate(throw_method_name)));
  ASSERT(!throw_new.IsNull());

  Fragment instructions;

  // Call LateError._throwFoo.
  instructions += Constant(name);
  instructions += StaticCall(position, throw_new,
                             /* argument_count = */ 1, ICData::kStatic);
  instructions += Drop();

  return instructions;
}

Fragment FlowGraphBuilder::StoreLateField(const Field& field,
                                          LocalVariable* instance,
                                          LocalVariable* setter_value) {
  Fragment instructions;
  TargetEntryInstr* is_uninitialized;
  TargetEntryInstr* is_initialized;
  const TokenPosition position = field.token_pos();
  const bool is_static = field.is_static();
  const bool is_final = field.is_final();

  if (is_final) {
    // Check whether the field has been initialized already.
    if (is_static) {
      instructions += LoadStaticField(field, /*calls_initializer=*/false);
    } else {
      instructions += LoadLocal(instance);
      instructions += LoadField(field, /*calls_initializer=*/false);
    }
    instructions += Constant(Object::sentinel());
    instructions += BranchIfStrictEqual(&is_uninitialized, &is_initialized);
    JoinEntryInstr* join = BuildJoinEntry();

    {
      // If the field isn't initialized, do nothing.
      Fragment initialize(is_uninitialized);
      initialize += Goto(join);
    }

    {
      // If the field is already initialized, throw a LateInitializationError.
      Fragment already_initialized(is_initialized);
      already_initialized += ThrowLateInitializationError(
          position, "_throwFieldAlreadyInitialized",
          String::ZoneHandle(Z, field.name()));
      already_initialized += Goto(join);
    }

    instructions = Fragment(instructions.entry, join);
  }

  if (!is_static) {
    instructions += LoadLocal(instance);
  }
  instructions += LoadLocal(setter_value);
  if (is_static) {
    instructions += StoreStaticField(position, field);
  } else {
    instructions += StoreInstanceFieldGuarded(field);
  }

  return instructions;
}

Fragment FlowGraphBuilder::NativeCall(const String* name,
                                      const Function* function) {
  InlineBailout("kernel::FlowGraphBuilder::NativeCall");
  const intptr_t num_args =
      function->NumParameters() + (function->IsGeneric() ? 1 : 0);
  InputsArray* arguments = GetArguments(num_args);
  NativeCallInstr* call = new (Z)
      NativeCallInstr(name, function, FLAG_link_natives_lazily,
                      InstructionSource(function->end_token_pos()), arguments);
  Push(call);
  return Fragment(call);
}

Fragment FlowGraphBuilder::Return(TokenPosition position,
                                  bool omit_result_type_check,
                                  intptr_t yield_index) {
  Fragment instructions;
  const Function& function = parsed_function_->function();

  // Emit a type check of the return type in checked mode for all functions
  // and in strong mode for native functions.
  if (!omit_result_type_check && function.is_native()) {
    const AbstractType& return_type =
        AbstractType::Handle(Z, function.result_type());
    instructions += CheckAssignable(return_type, Symbols::FunctionResult());
  }

  if (NeedsDebugStepCheck(function, position)) {
    instructions += DebugStepCheck(position);
  }

  instructions += BaseFlowGraphBuilder::Return(position, yield_index);

  return instructions;
}

Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
                                      const Function& target,
                                      intptr_t argument_count,
                                      ICData::RebindRule rebind_rule) {
  return StaticCall(position, target, argument_count, Array::null_array(),
                    rebind_rule);
}

void FlowGraphBuilder::SetResultTypeForStaticCall(
    StaticCallInstr* call,
    const Function& target,
    intptr_t argument_count,
    const InferredTypeMetadata* result_type) {
  if (call->InitResultType(Z)) {
    ASSERT((result_type == NULL) || (result_type->cid == kDynamicCid) ||
           (result_type->cid == call->result_cid()));
    return;
  }
  if ((result_type != NULL) && !result_type->IsTrivial()) {
    call->SetResultType(Z, result_type->ToCompileType(Z));
  }
}

Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
                                      const Function& target,
                                      intptr_t argument_count,
                                      const Array& argument_names,
                                      ICData::RebindRule rebind_rule,
                                      const InferredTypeMetadata* result_type,
                                      intptr_t type_args_count,
                                      bool use_unchecked_entry) {
  const intptr_t total_count = argument_count + (type_args_count > 0 ? 1 : 0);
  InputsArray* arguments = GetArguments(total_count);
  StaticCallInstr* call = new (Z) StaticCallInstr(
      InstructionSource(position), target, type_args_count, argument_names,
      arguments, ic_data_array_, GetNextDeoptId(), rebind_rule);
  SetResultTypeForStaticCall(call, target, argument_count, result_type);
  if (use_unchecked_entry) {
    call->set_entry_kind(Code::EntryKind::kUnchecked);
  }
  Push(call);
  if (result_type != nullptr && result_type->IsConstant()) {
    Fragment instructions(call);
    instructions += Drop();
    instructions += Constant(result_type->constant_value);
    return instructions;
  }
  return Fragment(call);
}

Fragment FlowGraphBuilder::StringInterpolateSingle(TokenPosition position) {
  Fragment instructions;
  instructions += StaticCall(
      position, CompilerState::Current().StringBaseInterpolateSingle(),
      /* argument_count = */ 1, ICData::kStatic);
  return instructions;
}

Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) {
  Fragment instructions;
  instructions +=
      StaticCall(position, CompilerState::Current().StringBaseInterpolate(),
                 /* argument_count = */ 1, ICData::kStatic);
  return instructions;
}

Fragment FlowGraphBuilder::ThrowTypeError() {
  const Class& klass =
      Class::ZoneHandle(Z, Library::LookupCoreClass(Symbols::TypeError()));
  ASSERT(!klass.IsNull());
  GrowableHandlePtrArray<const String> pieces(Z, 3);
  pieces.Add(Symbols::TypeError());
  pieces.Add(Symbols::Dot());
  pieces.Add(H.DartSymbolObfuscate("_create"));

  const Function& constructor = Function::ZoneHandle(
      Z, klass.LookupConstructorAllowPrivate(
             String::ZoneHandle(Z, Symbols::FromConcatAll(thread_, pieces))));
  ASSERT(!constructor.IsNull());

  const String& url = H.DartString(
      parsed_function_->function().ToLibNamePrefixedQualifiedCString(),
      Heap::kOld);

  Fragment instructions;

  // Create instance of _FallThroughError
  instructions += AllocateObject(TokenPosition::kNoSource, klass, 0);
  LocalVariable* instance = MakeTemporary();

  // Call _TypeError._create constructor.
  instructions += LoadLocal(instance);                             // this
  instructions += Constant(url);                                   // url
  instructions += NullConstant();                                  // line
  instructions += IntConstant(0);                                  // column
  instructions += Constant(H.DartSymbolPlain("Malformed type."));  // message

  instructions += StaticCall(TokenPosition::kNoSource, constructor,
                             /* argument_count = */ 5, ICData::kStatic);
  instructions += Drop();

  // Throw the exception
  instructions += ThrowException(TokenPosition::kNoSource);

  return instructions;
}

Fragment FlowGraphBuilder::ThrowNoSuchMethodError(const Function& target,
                                                  bool incompatible_arguments) {
  const Class& klass = Class::ZoneHandle(
      Z, Library::LookupCoreClass(Symbols::NoSuchMethodError()));
  ASSERT(!klass.IsNull());
  const auto& error = klass.EnsureIsFinalized(H.thread());
  ASSERT(error == Error::null());
  const Function& throw_function = Function::ZoneHandle(
      Z, klass.LookupStaticFunctionAllowPrivate(Symbols::ThrowNew()));
  ASSERT(!throw_function.IsNull());

  Fragment instructions;

  const Class& owner = Class::Handle(Z, target.Owner());
  auto& receiver = Instance::ZoneHandle();
  InvocationMirror::Kind kind = InvocationMirror::Kind::kMethod;
  if (target.IsImplicitGetterFunction() || target.IsGetterFunction()) {
    kind = InvocationMirror::kGetter;
  } else if (target.IsImplicitSetterFunction() || target.IsSetterFunction()) {
    kind = InvocationMirror::kSetter;
  }
  InvocationMirror::Level level;
  if (owner.IsTopLevel()) {
    if (incompatible_arguments) {
      receiver = target.UserVisibleSignature();
    }
    level = InvocationMirror::Level::kTopLevel;
  } else {
    receiver = owner.RareType();
    if (target.kind() == UntaggedFunction::kConstructor) {
      level = InvocationMirror::Level::kConstructor;
    } else {
      level = InvocationMirror::Level::kStatic;
    }
  }

  // Call NoSuchMethodError._throwNew static function.
  instructions += Constant(receiver);                              // receiver
  instructions += Constant(String::ZoneHandle(Z, target.name()));  // memberName
  instructions += IntConstant(InvocationMirror::EncodeType(level, kind));
  instructions += IntConstant(0);  // type arguments length
  instructions += NullConstant();  // type arguments
  instructions += NullConstant();  // arguments
  instructions += NullConstant();  // argumentNames

  instructions += StaticCall(TokenPosition::kNoSource, throw_function,
                             /* argument_count = */ 7, ICData::kStatic);

  // Properly close graph with a ThrowInstr, although it is not executed.
  instructions += ThrowException(TokenPosition::kNoSource);
  instructions += Drop();

  return instructions;
}

LocalVariable* FlowGraphBuilder::LookupVariable(intptr_t kernel_offset) {
  LocalVariable* local = scopes_->locals.Lookup(kernel_offset);
  ASSERT(local != NULL);
  return local;
}

FlowGraph* FlowGraphBuilder::BuildGraph() {
  const Function& function = parsed_function_->function();

#ifdef DEBUG
  // If we attached the native name to the function after it's creation (namely
  // after reading the constant table from the kernel blob), we must have done
  // so before building flow graph for the functions (since FGB depends needs
  // the native name to be there).
  const Script& script = Script::Handle(Z, function.script());
  const KernelProgramInfo& info =
      KernelProgramInfo::Handle(script.kernel_program_info());
  ASSERT(info.IsNull() ||
         info.potential_natives() == GrowableObjectArray::null());

  // Check that all functions that are explicitly marked as recognized with the
  // vm:recognized annotation are in fact recognized. The check can't be done on
  // function creation, since the recognized status isn't set until later.
  if ((function.IsRecognized() !=
       MethodRecognizer::IsMarkedAsRecognized(function)) &&
      !function.IsDynamicInvocationForwarder()) {
    if (function.IsRecognized()) {
      FATAL1(
          "Recognized method %s is not marked with the vm:recognized pragma.",
          function.ToQualifiedCString());
    } else {
      FATAL1(
          "Non-recognized method %s is marked with the vm:recognized pragma.",
          function.ToQualifiedCString());
    }
  }
#endif

  auto& kernel_data = ExternalTypedData::Handle(Z, function.KernelData());
  intptr_t kernel_data_program_offset = function.KernelDataProgramOffset();

  StreamingFlowGraphBuilder streaming_flow_graph_builder(
      this, kernel_data, kernel_data_program_offset);
  auto result = streaming_flow_graph_builder.BuildGraph();

  FinalizeCoverageArray();
  result->set_coverage_array(coverage_array());

  if (streaming_flow_graph_builder.num_ast_nodes() >
      FLAG_huge_method_cutoff_in_ast_nodes) {
    if (FLAG_print_huge_methods) {
      OS::PrintErr(
          "Warning: \'%s\' from \'%s\' is too large. Some optimizations have "
          "been "
          "disabled, and the compiler might run out of memory. "
          "Consider refactoring this code into smaller components.\n",
          function.QualifiedUserVisibleNameCString(),
          String::Handle(Z, Library::Handle(
                                Z, Class::Handle(Z, function.Owner()).library())
                                .url())
              .ToCString());
    }
    result->mark_huge_method();
  }

  return result;
}

Fragment FlowGraphBuilder::NativeFunctionBody(const Function& function,
                                              LocalVariable* first_parameter) {
  ASSERT(function.is_native());
  ASSERT(!IsRecognizedMethodForFlowGraph(function));

  Fragment body;
  String& name = String::ZoneHandle(Z, function.native_name());
  if (function.IsGeneric()) {
    body += LoadLocal(parsed_function_->RawTypeArgumentsVariable());
  }
  for (intptr_t i = 0; i < function.NumParameters(); ++i) {
    body += LoadLocal(parsed_function_->RawParameterVariable(i));
  }
  body += NativeCall(&name, &function);
  // We typecheck results of native calls for type safety.
  body +=
      Return(TokenPosition::kNoSource, /* omit_result_type_check = */ false);
  return body;
}

#define LOAD_NATIVE_FIELD(V)                                                   \
  V(ByteDataViewLength, TypedDataBase_length)                                  \
  V(ByteDataViewOffsetInBytes, TypedDataView_offset_in_bytes)                  \
  V(ByteDataViewTypedData, TypedDataView_typed_data)                           \
  V(Finalizer_getCallback, Finalizer_callback)                                 \
  V(FinalizerBase_getAllEntries, FinalizerBase_all_entries)                    \
  V(FinalizerBase_getDetachments, FinalizerBase_detachments)                   \
  V(FinalizerEntry_getDetach, FinalizerEntry_detach)                           \
  V(FinalizerEntry_getNext, FinalizerEntry_next)                               \
  V(FinalizerEntry_getToken, FinalizerEntry_token)                             \
  V(FinalizerEntry_getValue, FinalizerEntry_value)                             \
  V(NativeFinalizer_getCallback, NativeFinalizer_callback)                     \
  V(GrowableArrayLength, GrowableObjectArray_length)                           \
  V(ImmutableLinkedHashBase_getData, ImmutableLinkedHashBase_data)             \
  V(ImmutableLinkedHashBase_getIndex, ImmutableLinkedHashBase_index)           \
  V(LinkedHashBase_getData, LinkedHashBase_data)                               \
  V(LinkedHashBase_getDeletedKeys, LinkedHashBase_deleted_keys)                \
  V(LinkedHashBase_getHashMask, LinkedHashBase_hash_mask)                      \
  V(LinkedHashBase_getIndex, LinkedHashBase_index)                             \
  V(LinkedHashBase_getUsedData, LinkedHashBase_used_data)                      \
  V(ObjectArrayLength, Array_length)                                           \
  V(SuspendState_getFunctionData, SuspendState_function_data)                  \
  V(SuspendState_getThenCallback, SuspendState_then_callback)                  \
  V(SuspendState_getErrorCallback, SuspendState_error_callback)                \
  V(TypedDataViewOffsetInBytes, TypedDataView_offset_in_bytes)                 \
  V(TypedDataViewTypedData, TypedDataView_typed_data)                          \
  V(TypedListBaseLength, TypedDataBase_length)                                 \
  V(WeakProperty_getKey, WeakProperty_key)                                     \
  V(WeakProperty_getValue, WeakProperty_value)                                 \
  V(WeakReference_getTarget, WeakReference_target)

#define STORE_NATIVE_FIELD(V)                                                  \
  V(Finalizer_setCallback, Finalizer_callback)                                 \
  V(FinalizerBase_setAllEntries, FinalizerBase_all_entries)                    \
  V(FinalizerBase_setDetachments, FinalizerBase_detachments)                   \
  V(FinalizerEntry_setToken, FinalizerEntry_token)                             \
  V(NativeFinalizer_setCallback, NativeFinalizer_callback)                     \
  V(LinkedHashBase_setData, LinkedHashBase_data)                               \
  V(LinkedHashBase_setIndex, LinkedHashBase_index)                             \
  V(SuspendState_setFunctionData, SuspendState_function_data)                  \
  V(SuspendState_setThenCallback, SuspendState_then_callback)                  \
  V(SuspendState_setErrorCallback, SuspendState_error_callback)                \
  V(WeakProperty_setKey, WeakProperty_key)                                     \
  V(WeakProperty_setValue, WeakProperty_value)                                 \
  V(WeakReference_setTarget, WeakReference_target)

#define STORE_NATIVE_FIELD_NO_BARRIER(V)                                       \
  V(LinkedHashBase_setDeletedKeys, LinkedHashBase_deleted_keys)                \
  V(LinkedHashBase_setHashMask, LinkedHashBase_hash_mask)                      \
  V(LinkedHashBase_setUsedData, LinkedHashBase_used_data)

bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph(
    const Function& function) {
  const MethodRecognizer::Kind kind = function.recognized_kind();

  switch (kind) {
    case MethodRecognizer::kSuspendState_resume:
    case MethodRecognizer::kTypedData_ByteDataView_factory:
    case MethodRecognizer::kTypedData_Int8ArrayView_factory:
    case MethodRecognizer::kTypedData_Uint8ArrayView_factory:
    case MethodRecognizer::kTypedData_Uint8ClampedArrayView_factory:
    case MethodRecognizer::kTypedData_Int16ArrayView_factory:
    case MethodRecognizer::kTypedData_Uint16ArrayView_factory:
    case MethodRecognizer::kTypedData_Int32ArrayView_factory:
    case MethodRecognizer::kTypedData_Uint32ArrayView_factory:
    case MethodRecognizer::kTypedData_Int64ArrayView_factory:
    case MethodRecognizer::kTypedData_Uint64ArrayView_factory:
    case MethodRecognizer::kTypedData_Float32ArrayView_factory:
    case MethodRecognizer::kTypedData_Float64ArrayView_factory:
    case MethodRecognizer::kTypedData_Float32x4ArrayView_factory:
    case MethodRecognizer::kTypedData_Int32x4ArrayView_factory:
    case MethodRecognizer::kTypedData_Float64x2ArrayView_factory:
    case MethodRecognizer::kTypedData_Int8Array_factory:
    case MethodRecognizer::kTypedData_Uint8Array_factory:
    case MethodRecognizer::kTypedData_Uint8ClampedArray_factory:
    case MethodRecognizer::kTypedData_Int16Array_factory:
    case MethodRecognizer::kTypedData_Uint16Array_factory:
    case MethodRecognizer::kTypedData_Int32Array_factory:
    case MethodRecognizer::kTypedData_Uint32Array_factory:
    case MethodRecognizer::kTypedData_Int64Array_factory:
    case MethodRecognizer::kTypedData_Uint64Array_factory:
    case MethodRecognizer::kTypedData_Float32Array_factory:
    case MethodRecognizer::kTypedData_Float64Array_factory:
    case MethodRecognizer::kTypedData_Float32x4Array_factory:
    case MethodRecognizer::kTypedData_Int32x4Array_factory:
    case MethodRecognizer::kTypedData_Float64x2Array_factory:
    case MethodRecognizer::kFfiLoadInt8:
    case MethodRecognizer::kFfiLoadInt16:
    case MethodRecognizer::kFfiLoadInt32:
    case MethodRecognizer::kFfiLoadInt64:
    case MethodRecognizer::kFfiLoadUint8:
    case MethodRecognizer::kFfiLoadUint16:
    case MethodRecognizer::kFfiLoadUint32:
    case MethodRecognizer::kFfiLoadUint64:
    case MethodRecognizer::kFfiLoadFloat:
    case MethodRecognizer::kFfiLoadFloatUnaligned:
    case MethodRecognizer::kFfiLoadDouble:
    case MethodRecognizer::kFfiLoadDoubleUnaligned:
    case MethodRecognizer::kFfiLoadPointer:
    case MethodRecognizer::kFfiStoreInt8:
    case MethodRecognizer::kFfiStoreInt16:
    case MethodRecognizer::kFfiStoreInt32:
    case MethodRecognizer::kFfiStoreInt64:
    case MethodRecognizer::kFfiStoreUint8:
    case MethodRecognizer::kFfiStoreUint16:
    case MethodRecognizer::kFfiStoreUint32:
    case MethodRecognizer::kFfiStoreUint64:
    case MethodRecognizer::kFfiStoreFloat:
    case MethodRecognizer::kFfiStoreFloatUnaligned:
    case MethodRecognizer::kFfiStoreDouble:
    case MethodRecognizer::kFfiStoreDoubleUnaligned:
    case MethodRecognizer::kFfiStorePointer:
    case MethodRecognizer::kFfiFromAddress:
    case MethodRecognizer::kFfiGetAddress:
    case MethodRecognizer::kFfiAsExternalTypedDataInt8:
    case MethodRecognizer::kFfiAsExternalTypedDataInt16:
    case MethodRecognizer::kFfiAsExternalTypedDataInt32:
    case MethodRecognizer::kFfiAsExternalTypedDataInt64:
    case MethodRecognizer::kFfiAsExternalTypedDataUint8:
    case MethodRecognizer::kFfiAsExternalTypedDataUint16:
    case MethodRecognizer::kFfiAsExternalTypedDataUint32:
    case MethodRecognizer::kFfiAsExternalTypedDataUint64:
    case MethodRecognizer::kFfiAsExternalTypedDataFloat:
    case MethodRecognizer::kFfiAsExternalTypedDataDouble:
    case MethodRecognizer::kGetNativeField:
    case MethodRecognizer::kFinalizerBase_exchangeEntriesCollectedWithNull:
    case MethodRecognizer::kFinalizerBase_getIsolateFinalizers:
    case MethodRecognizer::kFinalizerBase_setIsolate:
    case MethodRecognizer::kFinalizerBase_setIsolateFinalizers:
    case MethodRecognizer::kFinalizerEntry_allocate:
    case MethodRecognizer::kFinalizerEntry_getExternalSize:
    case MethodRecognizer::kObjectEquals:
    case MethodRecognizer::kStringBaseLength:
    case MethodRecognizer::kStringBaseIsEmpty:
    case MethodRecognizer::kClassIDgetID:
    case MethodRecognizer::kGrowableArrayAllocateWithData:
    case MethodRecognizer::kGrowableArrayCapacity:
    case MethodRecognizer::kListFactory:
    case MethodRecognizer::kObjectArrayAllocate:
    case MethodRecognizer::kCopyRangeFromUint8ListToOneByteString:
    case MethodRecognizer::kImmutableLinkedHashBase_setIndexStoreRelease:
    case MethodRecognizer::kFfiAbi:
    case MethodRecognizer::kUtf8DecoderScan:
    case MethodRecognizer::kHas63BitSmis:
    case MethodRecognizer::kExtensionStreamHasListener:
#define CASE(method, slot) case MethodRecognizer::k##method:
      LOAD_NATIVE_FIELD(CASE)
      STORE_NATIVE_FIELD(CASE)
      STORE_NATIVE_FIELD_NO_BARRIER(CASE)
#undef CASE
      return true;
    case MethodRecognizer::kDoubleToInteger:
    case MethodRecognizer::kDoubleMod:
    case MethodRecognizer::kDoubleRoundToDouble:
    case MethodRecognizer::kDoubleTruncateToDouble:
    case MethodRecognizer::kDoubleFloorToDouble:
    case MethodRecognizer::kDoubleCeilToDouble:
    case MethodRecognizer::kMathDoublePow:
    case MethodRecognizer::kMathSin:
    case MethodRecognizer::kMathCos:
    case MethodRecognizer::kMathTan:
    case MethodRecognizer::kMathAsin:
    case MethodRecognizer::kMathAcos:
    case MethodRecognizer::kMathAtan:
    case MethodRecognizer::kMathAtan2:
    case MethodRecognizer::kMathExp:
    case MethodRecognizer::kMathLog:
    case MethodRecognizer::kMathSqrt:
      return FlowGraphCompiler::SupportsUnboxedDoubles();
    case MethodRecognizer::kDoubleCeilToInt:
    case MethodRecognizer::kDoubleFloorToInt:
      if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
#if defined(TARGET_ARCH_X64)
      return CompilerState::Current().is_aot() || FLAG_target_unknown_cpu;
#elif defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_RISCV32) ||            \
    defined(TARGET_ARCH_RISCV64)
      return true;
#else
      return false;
#endif
    default:
      return false;
  }
}

FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
    const Function& function) {
  ASSERT(IsRecognizedMethodForFlowGraph(function));

  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  PrologueInfo prologue_info(-1, -1);
  BlockEntryInstr* instruction_cursor =
      BuildPrologue(normal_entry, &prologue_info);

  Fragment body(instruction_cursor);
  body += CheckStackOverflowInPrologue(function.token_pos());

  const MethodRecognizer::Kind kind = function.recognized_kind();
  switch (kind) {
    case MethodRecognizer::kSuspendState_resume: {
      const Code& resume_stub =
          Code::ZoneHandle(Z, IG->object_store()->resume_stub());
      body += NullConstant();
      body += TailCall(resume_stub);
      break;
    }
    case MethodRecognizer::kTypedData_ByteDataView_factory:
      body += BuildTypedDataViewFactoryConstructor(function, kByteDataViewCid);
      break;
    case MethodRecognizer::kTypedData_Int8ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(function,
                                                   kTypedDataInt8ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Uint8ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(function,
                                                   kTypedDataUint8ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Uint8ClampedArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataUint8ClampedArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Int16ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(function,
                                                   kTypedDataInt16ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Uint16ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataUint16ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Int32ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(function,
                                                   kTypedDataInt32ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Uint32ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataUint32ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Int64ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(function,
                                                   kTypedDataInt64ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Uint64ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataUint64ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Float32ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataFloat32ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Float64ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataFloat64ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Float32x4ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataFloat32x4ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Int32x4ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataInt32x4ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Float64x2ArrayView_factory:
      body += BuildTypedDataViewFactoryConstructor(
          function, kTypedDataFloat64x2ArrayViewCid);
      break;
    case MethodRecognizer::kTypedData_Int8Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataInt8ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Uint8Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataUint8ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Uint8ClampedArray_factory:
      body += BuildTypedDataFactoryConstructor(function,
                                               kTypedDataUint8ClampedArrayCid);
      break;
    case MethodRecognizer::kTypedData_Int16Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataInt16ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Uint16Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataUint16ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Int32Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataInt32ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Uint32Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataUint32ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Int64Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataInt64ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Uint64Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataUint64ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Float32Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataFloat32ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Float64Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataFloat64ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Float32x4Array_factory:
      body += BuildTypedDataFactoryConstructor(function,
                                               kTypedDataFloat32x4ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Int32x4Array_factory:
      body +=
          BuildTypedDataFactoryConstructor(function, kTypedDataInt32x4ArrayCid);
      break;
    case MethodRecognizer::kTypedData_Float64x2Array_factory:
      body += BuildTypedDataFactoryConstructor(function,
                                               kTypedDataFloat64x2ArrayCid);
      break;

    case MethodRecognizer::kObjectEquals:
      ASSERT_EQUAL(function.NumParameters(), 2);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadLocal(parsed_function_->RawParameterVariable(1));
      body += StrictCompare(Token::kEQ_STRICT);
      break;
    case MethodRecognizer::kStringBaseLength:
    case MethodRecognizer::kStringBaseIsEmpty:
      ASSERT_EQUAL(function.NumParameters(), 1);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadNativeField(Slot::String_length());
      if (kind == MethodRecognizer::kStringBaseIsEmpty) {
        body += IntConstant(0);
        body += StrictCompare(Token::kEQ_STRICT);
      }
      break;
    case MethodRecognizer::kClassIDgetID:
      ASSERT_EQUAL(function.NumParameters(), 1);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadClassId();
      break;
    case MethodRecognizer::kGrowableArrayAllocateWithData: {
      ASSERT(function.IsFactory());
      ASSERT_EQUAL(function.NumParameters(), 2);
      const Class& cls =
          Class::ZoneHandle(Z, compiler::GrowableObjectArrayClass().ptr());
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += AllocateObject(TokenPosition::kNoSource, cls, 1);
      LocalVariable* object = MakeTemporary();
      body += LoadLocal(object);
      body += LoadLocal(parsed_function_->RawParameterVariable(1));
      body += StoreNativeField(Slot::GrowableObjectArray_data(),
                               StoreInstanceFieldInstr::Kind::kInitializing,
                               kNoStoreBarrier);
      body += LoadLocal(object);
      body += IntConstant(0);
      body += StoreNativeField(Slot::GrowableObjectArray_length(),
                               StoreInstanceFieldInstr::Kind::kInitializing,
                               kNoStoreBarrier);
      break;
    }
    case MethodRecognizer::kGrowableArrayCapacity:
      ASSERT_EQUAL(function.NumParameters(), 1);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadNativeField(Slot::GrowableObjectArray_data());
      body += LoadNativeField(Slot::Array_length());
      break;
    case MethodRecognizer::kListFactory: {
      ASSERT(function.IsFactory() && (function.NumParameters() == 2) &&
             function.HasOptionalParameters());
      // factory List<E>([int length]) {
      //   return (:arg_desc.positional_count == 2) ? new _List<E>(length)
      //                                            : new _GrowableList<E>(0);
      // }
      const Library& core_lib = Library::Handle(Z, Library::CoreLibrary());

      TargetEntryInstr* allocate_non_growable;
      TargetEntryInstr* allocate_growable;

      body += LoadArgDescriptor();
      body += LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
      body += IntConstant(2);
      body += BranchIfStrictEqual(&allocate_non_growable, &allocate_growable);

      JoinEntryInstr* join = BuildJoinEntry();

      {
        const Class& cls = Class::Handle(
            Z, core_lib.LookupClass(
                   Library::PrivateCoreLibName(Symbols::_List())));
        ASSERT(!cls.IsNull());
        const Function& func = Function::ZoneHandle(
            Z, cls.LookupFactoryAllowPrivate(Symbols::_ListFactory()));
        ASSERT(!func.IsNull());

        Fragment allocate(allocate_non_growable);
        allocate += LoadLocal(parsed_function_->RawParameterVariable(0));
        allocate += LoadLocal(parsed_function_->RawParameterVariable(1));
        allocate +=
            StaticCall(TokenPosition::kNoSource, func, 2, ICData::kStatic);
        allocate += StoreLocal(TokenPosition::kNoSource,
                               parsed_function_->expression_temp_var());
        allocate += Drop();
        allocate += Goto(join);
      }

      {
        const Class& cls = Class::Handle(
            Z, core_lib.LookupClass(
                   Library::PrivateCoreLibName(Symbols::_GrowableList())));
        ASSERT(!cls.IsNull());
        const Function& func = Function::ZoneHandle(
            Z, cls.LookupFactoryAllowPrivate(Symbols::_GrowableListFactory()));
        ASSERT(!func.IsNull());

        Fragment allocate(allocate_growable);
        allocate += LoadLocal(parsed_function_->RawParameterVariable(0));
        allocate += IntConstant(0);
        allocate +=
            StaticCall(TokenPosition::kNoSource, func, 2, ICData::kStatic);
        allocate += StoreLocal(TokenPosition::kNoSource,
                               parsed_function_->expression_temp_var());
        allocate += Drop();
        allocate += Goto(join);
      }

      body = Fragment(body.entry, join);
      body += LoadLocal(parsed_function_->expression_temp_var());
      break;
    }
    case MethodRecognizer::kObjectArrayAllocate:
      ASSERT(function.IsFactory() && (function.NumParameters() == 2));
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadLocal(parsed_function_->RawParameterVariable(1));
      body += CreateArray();
      break;
    case MethodRecognizer::kCopyRangeFromUint8ListToOneByteString:
      ASSERT_EQUAL(function.NumParameters(), 5);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadLocal(parsed_function_->RawParameterVariable(1));
      body += LoadLocal(parsed_function_->RawParameterVariable(2));
      body += LoadLocal(parsed_function_->RawParameterVariable(3));
      body += LoadLocal(parsed_function_->RawParameterVariable(4));
      body += MemoryCopy(kTypedDataUint8ArrayCid, kOneByteStringCid);
      body += NullConstant();
      break;
    case MethodRecognizer::kImmutableLinkedHashBase_setIndexStoreRelease:
      ASSERT_EQUAL(function.NumParameters(), 2);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadLocal(parsed_function_->RawParameterVariable(1));
      // Uses a store-release barrier so that other isolates will see the
      // contents of the index after seeing the index itself.
      body +=
          StoreNativeField(Slot::ImmutableLinkedHashBase_index(),
                           StoreInstanceFieldInstr::Kind::kOther,
                           kEmitStoreBarrier, compiler::Assembler::kRelease);
      body += NullConstant();
      break;
    case MethodRecognizer::kUtf8DecoderScan:
      ASSERT_EQUAL(function.NumParameters(), 5);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));  // decoder
      body += LoadLocal(parsed_function_->RawParameterVariable(1));  // bytes
      body += LoadLocal(parsed_function_->RawParameterVariable(2));  // start
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      body += UnboxTruncate(kUnboxedIntPtr);
      body += LoadLocal(parsed_function_->RawParameterVariable(3));  // end
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      body += UnboxTruncate(kUnboxedIntPtr);
      body += LoadLocal(parsed_function_->RawParameterVariable(4));  // table
      body += Utf8Scan();
      body += Box(kUnboxedIntPtr);
      break;
    case MethodRecognizer::kFfiAbi:
      ASSERT_EQUAL(function.NumParameters(), 0);
      body += IntConstant(static_cast<int64_t>(compiler::ffi::TargetAbi()));
      break;
    case MethodRecognizer::kFfiLoadInt8:
    case MethodRecognizer::kFfiLoadInt16:
    case MethodRecognizer::kFfiLoadInt32:
    case MethodRecognizer::kFfiLoadInt64:
    case MethodRecognizer::kFfiLoadUint8:
    case MethodRecognizer::kFfiLoadUint16:
    case MethodRecognizer::kFfiLoadUint32:
    case MethodRecognizer::kFfiLoadUint64:
    case MethodRecognizer::kFfiLoadFloat:
    case MethodRecognizer::kFfiLoadFloatUnaligned:
    case MethodRecognizer::kFfiLoadDouble:
    case MethodRecognizer::kFfiLoadDoubleUnaligned:
    case MethodRecognizer::kFfiLoadPointer: {
      const classid_t ffi_type_arg_cid =
          compiler::ffi::RecognizedMethodTypeArgCid(kind);
      const AlignmentType alignment =
          compiler::ffi::RecognizedMethodAlignment(kind);
      const classid_t typed_data_cid =
          compiler::ffi::ElementTypedDataCid(ffi_type_arg_cid);

      ASSERT_EQUAL(function.NumParameters(), 2);
      LocalVariable* arg_pointer = parsed_function_->RawParameterVariable(0);
      LocalVariable* arg_offset = parsed_function_->RawParameterVariable(1);

      body += LoadLocal(arg_offset);
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      LocalVariable* arg_offset_not_null = MakeTemporary();

      body += LoadLocal(arg_pointer);
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      // No GC from here til LoadIndexed.
      body += LoadUntagged(compiler::target::PointerBase::data_offset());
      body += LoadLocal(arg_offset_not_null);
      body += UnboxTruncate(kUnboxedFfiIntPtr);
      body += LoadIndexed(typed_data_cid, /*index_scale=*/1,
                          /*index_unboxed=*/true, alignment);
      if (kind == MethodRecognizer::kFfiLoadFloat ||
          kind == MethodRecognizer::kFfiLoadFloatUnaligned) {
        body += FloatToDouble();
      }
      // Avoid any unnecessary (and potentially deoptimizing) int
      // conversions by using the representation returned from LoadIndexed.
      body +=
          Box(LoadIndexedInstr::RepresentationOfArrayElement(typed_data_cid));
      if (kind == MethodRecognizer::kFfiLoadPointer) {
        const auto class_table = thread_->isolate_group()->class_table();
        ASSERT(class_table->HasValidClassAt(kPointerCid));
        const auto& pointer_class =
            Class::ZoneHandle(H.zone(), class_table->At(kPointerCid));

        // We find the reified type to use for the pointer allocation.
        //
        // Call sites to this recognized method are guaranteed to pass a
        // Pointer<Pointer<X>> as RawParameterVariable(0). This function
        // will return a Pointer<X> object - for which we inspect the
        // reified type on the argument.
        //
        // The following is safe to do, as (1) we are guaranteed to have a
        // Pointer<Pointer<X>> as argument, and (2) the bound on the pointer
        // type parameter guarantees X is an interface type.
        ASSERT(function.NumTypeParameters() == 1);
        LocalVariable* address = MakeTemporary();
        body += LoadLocal(parsed_function_->RawParameterVariable(0));
        body += LoadNativeField(
            Slot::GetTypeArgumentsSlotFor(thread_, pointer_class));
        body += LoadNativeField(Slot::GetTypeArgumentsIndexSlot(
            thread_, Pointer::kNativeTypeArgPos));
        body += LoadNativeField(Slot::Type_arguments());
        body += AllocateObject(TokenPosition::kNoSource, pointer_class, 1);
        LocalVariable* pointer = MakeTemporary();
        body += LoadLocal(pointer);
        body += LoadLocal(address);
        body += UnboxTruncate(kUnboxedIntPtr);
        body += StoreNativeField(Slot::PointerBase_data());
        body += DropTempsPreserveTop(1);  // Drop [address] keep [pointer].
      }
      body += DropTempsPreserveTop(1);  // Drop [arg_offset].
    } break;
    case MethodRecognizer::kFfiStoreInt8:
    case MethodRecognizer::kFfiStoreInt16:
    case MethodRecognizer::kFfiStoreInt32:
    case MethodRecognizer::kFfiStoreInt64:
    case MethodRecognizer::kFfiStoreUint8:
    case MethodRecognizer::kFfiStoreUint16:
    case MethodRecognizer::kFfiStoreUint32:
    case MethodRecognizer::kFfiStoreUint64:
    case MethodRecognizer::kFfiStoreFloat:
    case MethodRecognizer::kFfiStoreFloatUnaligned:
    case MethodRecognizer::kFfiStoreDouble:
    case MethodRecognizer::kFfiStoreDoubleUnaligned:
    case MethodRecognizer::kFfiStorePointer: {
      const classid_t ffi_type_arg_cid =
          compiler::ffi::RecognizedMethodTypeArgCid(kind);
      const AlignmentType alignment =
          compiler::ffi::RecognizedMethodAlignment(kind);
      const classid_t typed_data_cid =
          compiler::ffi::ElementTypedDataCid(ffi_type_arg_cid);

      LocalVariable* arg_pointer = parsed_function_->RawParameterVariable(0);
      LocalVariable* arg_offset = parsed_function_->RawParameterVariable(1);
      LocalVariable* arg_value = parsed_function_->RawParameterVariable(2);

      if (kind == MethodRecognizer::kFfiStorePointer) {
        // Do type check before anything untagged is on the stack.
        const auto class_table = thread_->isolate_group()->class_table();
        ASSERT(class_table->HasValidClassAt(kPointerCid));
        const auto& pointer_class =
            Class::ZoneHandle(H.zone(), class_table->At(kPointerCid));
        const auto& pointer_type_param =
            TypeParameter::ZoneHandle(pointer_class.TypeParameterAt(0));

        // But we type check it as a method on a generic class at runtime.
        body += LoadLocal(arg_value);          // value.
        body += Constant(pointer_type_param);  // dst_type.
        // We pass the Pointer type argument as instantiator_type_args.
        //
        // Call sites to this recognized method are guaranteed to pass a
        // Pointer<Pointer<X>> as RawParameterVariable(0). This function
        // will takes a Pointer<X> object - for which we inspect the
        // reified type on the argument.
        //
        // The following is safe to do, as (1) we are guaranteed to have a
        // Pointer<Pointer<X>> as argument, and (2) the bound on the pointer
        // type parameter guarantees X is an interface type.
        body += LoadLocal(arg_pointer);
        body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
        body += LoadNativeField(
            Slot::GetTypeArgumentsSlotFor(thread_, pointer_class));
        body += NullConstant();  // function_type_args.
        body += AssertAssignable(TokenPosition::kNoSource, Symbols::Empty());
        body += Drop();
      }

      ASSERT_EQUAL(function.NumParameters(), 3);
      body += LoadLocal(arg_offset);
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      LocalVariable* arg_offset_not_null = MakeTemporary();
      body += LoadLocal(arg_value);
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      LocalVariable* arg_value_not_null = MakeTemporary();

      body += LoadLocal(arg_pointer);  // Pointer.
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      // No GC from here til StoreIndexed.
      body += LoadUntagged(compiler::target::PointerBase::data_offset());
      body += LoadLocal(arg_offset_not_null);
      body += UnboxTruncate(kUnboxedFfiIntPtr);
      body += LoadLocal(arg_value_not_null);
      if (kind == MethodRecognizer::kFfiStorePointer) {
        // This can only be Pointer, so it is always safe to LoadUntagged.
        body += LoadUntagged(compiler::target::PointerBase::data_offset());
        body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
      } else {
        // Avoid any unnecessary (and potentially deoptimizing) int
        // conversions by using the representation consumed by StoreIndexed.
        body += UnboxTruncate(
            StoreIndexedInstr::RepresentationOfArrayElement(typed_data_cid));
        if (kind == MethodRecognizer::kFfiStoreFloat ||
            kind == MethodRecognizer::kFfiStoreFloatUnaligned) {
          body += DoubleToFloat();
        }
      }
      body += StoreIndexedTypedData(typed_data_cid, /*index_scale=*/1,
                                    /*index_unboxed=*/true, alignment);
      body += Drop();  // Drop [arg_value].
      body += Drop();  // Drop [arg_offset].
      body += NullConstant();
    } break;
    case MethodRecognizer::kFfiFromAddress: {
      const auto class_table = thread_->isolate_group()->class_table();
      ASSERT(class_table->HasValidClassAt(kPointerCid));
      const auto& pointer_class =
          Class::ZoneHandle(H.zone(), class_table->At(kPointerCid));

      ASSERT(function.NumTypeParameters() == 1);
      ASSERT_EQUAL(function.NumParameters(), 1);
      body += LoadLocal(parsed_function_->RawTypeArgumentsVariable());
      body += AllocateObject(TokenPosition::kNoSource, pointer_class, 1);
      body += LoadLocal(MakeTemporary());  // Duplicate Pointer.
      body += LoadLocal(parsed_function_->RawParameterVariable(0));  // Address.
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      body += UnboxTruncate(kUnboxedIntPtr);
      body += StoreNativeField(Slot::PointerBase_data());
    } break;
    case MethodRecognizer::kFfiGetAddress: {
      ASSERT_EQUAL(function.NumParameters(), 1);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));  // Pointer.
      body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
      // This can only be Pointer, so it is always safe to LoadUntagged.
      body += LoadUntagged(compiler::target::PointerBase::data_offset());
      body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
      body += Box(kUnboxedFfiIntPtr);
    } break;
    case MethodRecognizer::kHas63BitSmis: {
#if defined(HAS_SMI_63_BITS)
      body += Constant(Bool::True());
#else
      body += Constant(Bool::False());
#endif  // defined(ARCH_IS_64_BIT)
    } break;
    case MethodRecognizer::kExtensionStreamHasListener: {
#ifdef PRODUCT
      body += Constant(Bool::False());
#else
      body += LoadServiceExtensionStream();
      body += RawLoadField(compiler::target::StreamInfo::enabled_offset());
      // StreamInfo::enabled_ is a std::atomic<intptr_t>. This is effectively
      // relaxed order access, which is acceptable for this use case.
      body += IntToBool();
#endif  // PRODUCT
    } break;
    case MethodRecognizer::kFfiAsExternalTypedDataInt8:
    case MethodRecognizer::kFfiAsExternalTypedDataInt16:
    case MethodRecognizer::kFfiAsExternalTypedDataInt32:
    case MethodRecognizer::kFfiAsExternalTypedDataInt64:
    case MethodRecognizer::kFfiAsExternalTypedDataUint8:
    case MethodRecognizer::kFfiAsExternalTypedDataUint16:
    case MethodRecognizer::kFfiAsExternalTypedDataUint32:
    case MethodRecognizer::kFfiAsExternalTypedDataUint64:
    case MethodRecognizer::kFfiAsExternalTypedDataFloat:
    case MethodRecognizer::kFfiAsExternalTypedDataDouble: {
      const classid_t ffi_type_arg_cid =
          compiler::ffi::RecognizedMethodTypeArgCid(kind);
      const classid_t external_typed_data_cid =
          compiler::ffi::ElementExternalTypedDataCid(ffi_type_arg_cid);

      auto class_table = thread_->isolate_group()->class_table();
      ASSERT(class_table->HasValidClassAt(external_typed_data_cid));
      const auto& typed_data_class =
          Class::ZoneHandle(H.zone(), class_table->At(external_typed_data_cid));

      // We assume that the caller has checked that the arguments are non-null
      // and length is in the range [0, kSmiMax/elementSize].
      ASSERT_EQUAL(function.NumParameters(), 2);
      LocalVariable* arg_pointer = parsed_function_->RawParameterVariable(0);
      LocalVariable* arg_length = parsed_function_->RawParameterVariable(1);

      body += AllocateObject(TokenPosition::kNoSource, typed_data_class, 0);
      LocalVariable* typed_data_object = MakeTemporary();

      // Initialize the result's length field.
      body += LoadLocal(typed_data_object);
      body += LoadLocal(arg_length);
      body += StoreNativeField(Slot::TypedDataBase_length(),
                               StoreInstanceFieldInstr::Kind::kInitializing,
                               kNoStoreBarrier);

      // Initialize the result's data pointer field.
      body += LoadLocal(typed_data_object);
      body += LoadLocal(arg_pointer);
      body += LoadUntagged(compiler::target::PointerBase::data_offset());
      body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
      body += StoreNativeField(Slot::PointerBase_data(),
                               StoreInstanceFieldInstr::Kind::kInitializing,
                               kNoStoreBarrier);
    } break;
    case MethodRecognizer::kGetNativeField: {
      auto& name = String::ZoneHandle(Z, function.name());
      // Note: This method is force optimized so we can push untagged, etc.
      // Load TypedDataArray from Instance Handle implementing
      // NativeFieldWrapper.
      body += LoadLocal(parsed_function_->RawParameterVariable(0));  // Object.
      body += CheckNullOptimized(name);
      body += LoadNativeField(Slot::Instance_native_fields_array());  // Fields.
      body += CheckNullOptimized(name);
      // Load the native field at index.
      body += IntConstant(0);  // Index.
      body += LoadIndexed(kIntPtrCid);
      body += Box(kUnboxedIntPtr);
    } break;
    case MethodRecognizer::kDoubleToInteger:
    case MethodRecognizer::kDoubleCeilToInt:
    case MethodRecognizer::kDoubleFloorToInt: {
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += DoubleToInteger(kind);
    } break;
    case MethodRecognizer::kDoubleMod:
    case MethodRecognizer::kDoubleRoundToDouble:
    case MethodRecognizer::kDoubleTruncateToDouble:
    case MethodRecognizer::kDoubleFloorToDouble:
    case MethodRecognizer::kDoubleCeilToDouble:
    case MethodRecognizer::kMathDoublePow:
    case MethodRecognizer::kMathSin:
    case MethodRecognizer::kMathCos:
    case MethodRecognizer::kMathTan:
    case MethodRecognizer::kMathAsin:
    case MethodRecognizer::kMathAcos:
    case MethodRecognizer::kMathAtan:
    case MethodRecognizer::kMathAtan2:
    case MethodRecognizer::kMathExp:
    case MethodRecognizer::kMathLog: {
      for (intptr_t i = 0, n = function.NumParameters(); i < n; ++i) {
        body += LoadLocal(parsed_function_->RawParameterVariable(i));
      }
      if (!CompilerState::Current().is_aot() &&
          TargetCPUFeatures::double_truncate_round_supported() &&
          ((kind == MethodRecognizer::kDoubleTruncateToDouble) ||
           (kind == MethodRecognizer::kDoubleFloorToDouble) ||
           (kind == MethodRecognizer::kDoubleCeilToDouble))) {
        body += DoubleToDouble(kind);
      } else {
        body += InvokeMathCFunction(kind, function.NumParameters());
      }
    } break;
    case MethodRecognizer::kMathSqrt: {
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += MathUnary(MathUnaryInstr::kSqrt);
    } break;
    case MethodRecognizer::kFinalizerBase_setIsolate:
      ASSERT_EQUAL(function.NumParameters(), 1);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadIsolate();
      body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
      body += StoreNativeField(Slot::FinalizerBase_isolate());
      body += NullConstant();
      break;
    case MethodRecognizer::kFinalizerBase_getIsolateFinalizers:
      ASSERT_EQUAL(function.NumParameters(), 0);
      body += LoadIsolate();
      body += RawLoadField(compiler::target::Isolate::finalizers_offset());
      break;
    case MethodRecognizer::kFinalizerBase_setIsolateFinalizers:
      ASSERT_EQUAL(function.NumParameters(), 1);
      body += LoadIsolate();
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += RawStoreField(compiler::target::Isolate::finalizers_offset());
      body += NullConstant();
      break;
    case MethodRecognizer::kFinalizerBase_exchangeEntriesCollectedWithNull:
      ASSERT_EQUAL(function.NumParameters(), 1);
      ASSERT(this->optimizing_);
      // This relies on being force-optimized to do an 'atomic' exchange w.r.t.
      // the GC.
      // As an alternative design we could introduce an ExchangeNativeFieldInstr
      // that uses the same machine code as std::atomic::exchange. Or we could
      // use an FfiNative to do that in C.
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      // No GC from here til StoreNativeField.
      body += LoadNativeField(Slot::FinalizerBase_entries_collected());
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += NullConstant();
      body += StoreNativeField(Slot::FinalizerBase_entries_collected());
      break;
    case MethodRecognizer::kFinalizerEntry_allocate: {
      // Object value, Object token, Object detach, FinalizerBase finalizer
      ASSERT_EQUAL(function.NumParameters(), 4);

      const auto class_table = thread_->isolate_group()->class_table();
      ASSERT(class_table->HasValidClassAt(kFinalizerEntryCid));
      const auto& finalizer_entry_class =
          Class::ZoneHandle(H.zone(), class_table->At(kFinalizerEntryCid));

      body +=
          AllocateObject(TokenPosition::kNoSource, finalizer_entry_class, 0);
      LocalVariable* const entry = MakeTemporary("entry");
      // No GC from here to the end.
      body += LoadLocal(entry);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += StoreNativeField(Slot::FinalizerEntry_value());
      body += LoadLocal(entry);
      body += LoadLocal(parsed_function_->RawParameterVariable(1));
      body += StoreNativeField(Slot::FinalizerEntry_token());
      body += LoadLocal(entry);
      body += LoadLocal(parsed_function_->RawParameterVariable(2));
      body += StoreNativeField(Slot::FinalizerEntry_detach());
      body += LoadLocal(entry);
      body += LoadLocal(parsed_function_->RawParameterVariable(3));
      body += StoreNativeField(Slot::FinalizerEntry_finalizer());
      body += LoadLocal(entry);
      body += UnboxedIntConstant(0, kUnboxedIntPtr);
      body += StoreNativeField(Slot::FinalizerEntry_external_size());
      break;
    }
    case MethodRecognizer::kFinalizerEntry_getExternalSize:
      ASSERT_EQUAL(function.NumParameters(), 1);
      body += LoadLocal(parsed_function_->RawParameterVariable(0));
      body += LoadNativeField(Slot::FinalizerEntry_external_size());
      body += Box(kUnboxedInt64);
      break;
#define IL_BODY(method, slot)                                                  \
  case MethodRecognizer::k##method:                                            \
    ASSERT_EQUAL(function.NumParameters(), 1);                                 \
    body += LoadLocal(parsed_function_->RawParameterVariable(0));              \
    body += LoadNativeField(Slot::slot());                                     \
    break;
      LOAD_NATIVE_FIELD(IL_BODY)
#undef IL_BODY
#define IL_BODY(method, slot)                                                  \
  case MethodRecognizer::k##method:                                            \
    ASSERT_EQUAL(function.NumParameters(), 2);                                 \
    body += LoadLocal(parsed_function_->RawParameterVariable(0));              \
    body += LoadLocal(parsed_function_->RawParameterVariable(1));              \
    body += StoreNativeField(Slot::slot());                                    \
    body += NullConstant();                                                    \
    break;
      STORE_NATIVE_FIELD(IL_BODY)
#undef IL_BODY
#define IL_BODY(method, slot)                                                  \
  case MethodRecognizer::k##method:                                            \
    ASSERT_EQUAL(function.NumParameters(), 2);                                 \
    body += LoadLocal(parsed_function_->RawParameterVariable(0));              \
    body += LoadLocal(parsed_function_->RawParameterVariable(1));              \
    body += StoreNativeField(                                                  \
        Slot::slot(), StoreInstanceFieldInstr::Kind::kOther, kNoStoreBarrier); \
    body += NullConstant();                                                    \
    break;
      STORE_NATIVE_FIELD_NO_BARRIER(IL_BODY)
#undef IL_BODY
    default: {
      UNREACHABLE();
      break;
    }
  }

  if (body.is_open()) {
    body +=
        Return(TokenPosition::kNoSource, /* omit_result_type_check = */ true);
  }

  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

Fragment FlowGraphBuilder::BuildTypedDataViewFactoryConstructor(
    const Function& function,
    classid_t cid) {
  auto token_pos = function.token_pos();
  auto class_table = Thread::Current()->isolate_group()->class_table();

  ASSERT(class_table->HasValidClassAt(cid));
  const auto& view_class = Class::ZoneHandle(H.zone(), class_table->At(cid));

  ASSERT(function.IsFactory() && (function.NumParameters() == 4));
  LocalVariable* typed_data = parsed_function_->RawParameterVariable(1);
  LocalVariable* offset_in_bytes = parsed_function_->RawParameterVariable(2);
  LocalVariable* length = parsed_function_->RawParameterVariable(3);

  Fragment body;

  body += AllocateObject(token_pos, view_class, /*arg_count=*/0);
  LocalVariable* view_object = MakeTemporary();

  body += LoadLocal(view_object);
  body += LoadLocal(typed_data);
  body += StoreNativeField(token_pos, Slot::TypedDataView_typed_data(),
                           StoreInstanceFieldInstr::Kind::kInitializing);

  body += LoadLocal(view_object);
  body += LoadLocal(offset_in_bytes);
  body += StoreNativeField(token_pos, Slot::TypedDataView_offset_in_bytes(),
                           StoreInstanceFieldInstr::Kind::kInitializing,
                           kNoStoreBarrier);

  body += LoadLocal(view_object);
  body += LoadLocal(length);
  body += StoreNativeField(token_pos, Slot::TypedDataBase_length(),
                           StoreInstanceFieldInstr::Kind::kInitializing,
                           kNoStoreBarrier);

  // Update the inner pointer.
  //
  // WARNING: Notice that we assume here no GC happens between those 4
  // instructions!
  body += LoadLocal(view_object);
  body += LoadLocal(typed_data);
  body += LoadUntagged(compiler::target::PointerBase::data_offset());
  body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
  body += LoadLocal(offset_in_bytes);
  body += UnboxSmiToIntptr();
  body += AddIntptrIntegers();
  body += StoreNativeField(Slot::PointerBase_data());

  return body;
}

Fragment FlowGraphBuilder::BuildTypedDataFactoryConstructor(
    const Function& function,
    classid_t cid) {
  const auto token_pos = function.token_pos();
  ASSERT(
      Thread::Current()->isolate_group()->class_table()->HasValidClassAt(cid));

  ASSERT(function.IsFactory() && (function.NumParameters() == 2));
  LocalVariable* length = parsed_function_->RawParameterVariable(1);

  Fragment instructions;
  instructions += LoadLocal(length);
  // AllocateTypedData instruction checks that length is valid (a non-negative
  // Smi below maximum allowed length).
  instructions += AllocateTypedData(token_pos, cid);
  return instructions;
}

static const LocalScope* MakeImplicitClosureScope(Zone* Z, const Class& klass) {
  ASSERT(!klass.IsNull());
  // Note that if klass is _Closure, DeclarationType will be _Closure,
  // and not the signature type.
  Type& klass_type = Type::ZoneHandle(Z, klass.DeclarationType());

  LocalVariable* receiver_variable = new (Z)
      LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
                    Symbols::This(), klass_type, /*param_type=*/nullptr);

  receiver_variable->set_is_captured();
  //  receiver_variable->set_is_final();
  LocalScope* scope = new (Z) LocalScope(NULL, 0, 0);
  scope->set_context_level(0);
  scope->AddVariable(receiver_variable);
  scope->AddContextVariable(receiver_variable);
  return scope;
}

Fragment FlowGraphBuilder::BuildImplicitClosureCreation(
    const Function& target) {
  // The function cannot be local and have parent generic functions.
  ASSERT(!target.HasGenericParent());

  Fragment fragment;
  fragment += Constant(target);

  // Allocate a context that closes over `this`.
  // Note: this must be kept in sync with ScopeBuilder::BuildScopes.
  const LocalScope* implicit_closure_scope =
      MakeImplicitClosureScope(Z, Class::Handle(Z, target.Owner()));
  fragment += AllocateContext(implicit_closure_scope->context_slots());
  LocalVariable* context = MakeTemporary();

  // Store `this`.  The context doesn't need a parent pointer because it doesn't
  // close over anything else.
  fragment += LoadLocal(context);
  fragment += LoadLocal(parsed_function_->receiver_var());
  fragment += StoreNativeField(
      Slot::GetContextVariableSlotFor(
          thread_, *implicit_closure_scope->context_variables()[0]),
      StoreInstanceFieldInstr::Kind::kInitializing);

  fragment += AllocateClosure();
  LocalVariable* closure = MakeTemporary();

  // The function signature can have uninstantiated class type parameters.
  if (!target.HasInstantiatedSignature(kCurrentClass)) {
    fragment += LoadLocal(closure);
    fragment += LoadInstantiatorTypeArguments();
    fragment += StoreNativeField(Slot::Closure_instantiator_type_arguments(),
                                 StoreInstanceFieldInstr::Kind::kInitializing);
  }

  if (target.IsGeneric()) {
    // Only generic functions need to have properly initialized
    // delayed_type_arguments.
    fragment += LoadLocal(closure);
    fragment += Constant(Object::empty_type_arguments());
    fragment += StoreNativeField(Slot::Closure_delayed_type_arguments(),
                                 StoreInstanceFieldInstr::Kind::kInitializing);
  }

  return fragment;
}

Fragment FlowGraphBuilder::CheckVariableTypeInCheckedMode(
    const AbstractType& dst_type,
    const String& name_symbol) {
  return Fragment();
}

bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function,
                                           TokenPosition position) {
  return position.IsDebugPause() && !function.is_native() &&
         function.is_debuggable();
}

bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value,
                                           TokenPosition position) {
  if (!position.IsDebugPause()) {
    return false;
  }
  Definition* definition = value->definition();
  if (definition->IsConstant() || definition->IsLoadStaticField()) {
    return true;
  }
  if (auto const alloc = definition->AsAllocateClosure()) {
    return !alloc->known_function().IsNull();
  }
  return definition->IsLoadLocal() || definition->IsAssertAssignable();
}

Fragment FlowGraphBuilder::EvaluateAssertion() {
  const Class& klass =
      Class::ZoneHandle(Z, Library::LookupCoreClass(Symbols::AssertionError()));
  ASSERT(!klass.IsNull());
  const auto& error = klass.EnsureIsFinalized(H.thread());
  ASSERT(error == Error::null());
  const Function& target = Function::ZoneHandle(
      Z, klass.LookupStaticFunctionAllowPrivate(Symbols::EvaluateAssertion()));
  ASSERT(!target.IsNull());
  return StaticCall(TokenPosition::kNoSource, target, /* argument_count = */ 1,
                    ICData::kStatic);
}

Fragment FlowGraphBuilder::CheckBoolean(TokenPosition position) {
  Fragment instructions;
  LocalVariable* top_of_stack = MakeTemporary();
  instructions += LoadLocal(top_of_stack);
  instructions += AssertBool(position);
  instructions += Drop();
  return instructions;
}

Fragment FlowGraphBuilder::CheckAssignable(const AbstractType& dst_type,
                                           const String& dst_name,
                                           AssertAssignableInstr::Kind kind,
                                           TokenPosition token_pos) {
  Fragment instructions;
  if (!dst_type.IsTopTypeForSubtyping()) {
    LocalVariable* top_of_stack = MakeTemporary();
    instructions += LoadLocal(top_of_stack);
    instructions +=
        AssertAssignableLoadTypeArguments(token_pos, dst_type, dst_name, kind);
    instructions += Drop();
  }
  return instructions;
}

Fragment FlowGraphBuilder::AssertAssignableLoadTypeArguments(
    TokenPosition position,
    const AbstractType& dst_type,
    const String& dst_name,
    AssertAssignableInstr::Kind kind) {
  Fragment instructions;

  instructions += Constant(AbstractType::ZoneHandle(dst_type.ptr()));

  if (!dst_type.IsInstantiated(kCurrentClass)) {
    instructions += LoadInstantiatorTypeArguments();
  } else {
    instructions += NullConstant();
  }

  if (!dst_type.IsInstantiated(kFunctions)) {
    instructions += LoadFunctionTypeArguments();
  } else {
    instructions += NullConstant();
  }

  instructions += AssertAssignable(position, dst_name, kind);

  return instructions;
}

Fragment FlowGraphBuilder::AssertSubtype(TokenPosition position,
                                         const AbstractType& sub_type_value,
                                         const AbstractType& super_type_value,
                                         const String& dst_name_value) {
  Fragment instructions;
  instructions += LoadInstantiatorTypeArguments();
  instructions += LoadFunctionTypeArguments();
  instructions += Constant(AbstractType::ZoneHandle(Z, sub_type_value.ptr()));
  instructions += Constant(AbstractType::ZoneHandle(Z, super_type_value.ptr()));
  instructions += Constant(String::ZoneHandle(Z, dst_name_value.ptr()));
  instructions += AssertSubtype(position);
  return instructions;
}

Fragment FlowGraphBuilder::AssertSubtype(TokenPosition position) {
  Fragment instructions;

  Value* dst_name = Pop();
  Value* super_type = Pop();
  Value* sub_type = Pop();
  Value* function_type_args = Pop();
  Value* instantiator_type_args = Pop();

  AssertSubtypeInstr* instr = new (Z) AssertSubtypeInstr(
      InstructionSource(position), instantiator_type_args, function_type_args,
      sub_type, super_type, dst_name, GetNextDeoptId());
  instructions += Fragment(instr);

  return instructions;
}

void FlowGraphBuilder::BuildTypeArgumentTypeChecks(TypeChecksToBuild mode,
                                                   Fragment* implicit_checks) {
  const Function& dart_function = parsed_function_->function();

  const Function* forwarding_target = nullptr;
  if (parsed_function_->is_forwarding_stub()) {
    forwarding_target = parsed_function_->forwarding_stub_super_target();
    ASSERT(!forwarding_target->IsNull());
  }

  TypeParameters& type_parameters = TypeParameters::Handle(Z);
  if (dart_function.IsFactory()) {
    type_parameters = Class::Handle(Z, dart_function.Owner()).type_parameters();
  } else {
    type_parameters = dart_function.type_parameters();
  }
  const intptr_t num_type_params = type_parameters.Length();
  if (num_type_params == 0) return;
  if (forwarding_target != nullptr) {
    type_parameters = forwarding_target->type_parameters();
    ASSERT(type_parameters.Length() == num_type_params);
  }
  if (type_parameters.AllDynamicBounds()) {
    return;  // All bounds are dynamic.
  }
  TypeParameter& type_param = TypeParameter::Handle(Z);
  String& name = String::Handle(Z);
  AbstractType& bound = AbstractType::Handle(Z);
  Fragment check_bounds;
  for (intptr_t i = 0; i < num_type_params; ++i) {
    bound = type_parameters.BoundAt(i);
    if (bound.IsTopTypeForSubtyping()) {
      continue;
    }

    switch (mode) {
      case TypeChecksToBuild::kCheckAllTypeParameterBounds:
        break;
      case TypeChecksToBuild::kCheckCovariantTypeParameterBounds:
        if (!type_parameters.IsGenericCovariantImplAt(i)) {
          continue;
        }
        break;
      case TypeChecksToBuild::kCheckNonCovariantTypeParameterBounds:
        if (type_parameters.IsGenericCovariantImplAt(i)) {
          continue;
        }
        break;
    }

    name = type_parameters.NameAt(i);

    if (forwarding_target != nullptr) {
      type_param = forwarding_target->TypeParameterAt(i);
    } else if (dart_function.IsFactory()) {
      type_param = Class::Handle(Z, dart_function.Owner()).TypeParameterAt(i);
    } else {
      type_param = dart_function.TypeParameterAt(i);
    }
    ASSERT(type_param.IsFinalized());
    if (bound.IsTypeRef()) {
      bound = TypeRef::Cast(bound).type();
    }
    check_bounds +=
        AssertSubtype(TokenPosition::kNoSource, type_param, bound, name);
  }

  // Type arguments passed through partial instantiation are guaranteed to be
  // bounds-checked at the point of partial instantiation, so we don't need to
  // check them again at the call-site.
  if (dart_function.IsClosureFunction() && !check_bounds.is_empty() &&
      FLAG_eliminate_type_checks) {
    LocalVariable* closure = parsed_function_->ParameterVariable(0);
    *implicit_checks += TestDelayedTypeArgs(closure, /*present=*/{},
                                            /*absent=*/check_bounds);
  } else {
    *implicit_checks += check_bounds;
  }
}

void FlowGraphBuilder::BuildArgumentTypeChecks(
    Fragment* explicit_checks,
    Fragment* implicit_checks,
    Fragment* implicit_redefinitions) {
  const Function& dart_function = parsed_function_->function();

  const Function* forwarding_target = nullptr;
  if (parsed_function_->is_forwarding_stub()) {
    forwarding_target = parsed_function_->forwarding_stub_super_target();
    ASSERT(!forwarding_target->IsNull());
  }

  const intptr_t num_params = dart_function.NumParameters();
  for (intptr_t i = dart_function.NumImplicitParameters(); i < num_params;
       ++i) {
    LocalVariable* param = parsed_function_->ParameterVariable(i);
    const String& name = param->name();
    if (!param->needs_type_check()) {
      continue;
    }
    if (param->is_captured()) {
      param = parsed_function_->RawParameterVariable(i);
    }

    const AbstractType* target_type = &param->type();
    if (forwarding_target != NULL) {
      // We add 1 to the parameter index to account for the receiver.
      target_type =
          &AbstractType::ZoneHandle(Z, forwarding_target->ParameterTypeAt(i));
    }

    if (target_type->IsTopTypeForSubtyping()) continue;

    const bool is_covariant = param->is_explicit_covariant_parameter();
    Fragment* checks = is_covariant ? explicit_checks : implicit_checks;

    *checks += LoadLocal(param);
    *checks += AssertAssignableLoadTypeArguments(
        TokenPosition::kNoSource, *target_type, name,
        AssertAssignableInstr::kParameterCheck);
    *checks += StoreLocal(param);
    *checks += Drop();

    if (!is_covariant && implicit_redefinitions != nullptr && optimizing_) {
      // We generate slightly different code in optimized vs. un-optimized code,
      // which is ok since we don't allocate any deopt ids.
      AssertNoDeoptIdsAllocatedScope no_deopt_allocation(thread_);

      *implicit_redefinitions += LoadLocal(param);
      *implicit_redefinitions += RedefinitionWithType(*target_type);
      *implicit_redefinitions += StoreLocal(TokenPosition::kNoSource, param);
      *implicit_redefinitions += Drop();
    }
  }
}

BlockEntryInstr* FlowGraphBuilder::BuildPrologue(BlockEntryInstr* normal_entry,
                                                 PrologueInfo* prologue_info) {
  const bool compiling_for_osr = IsCompiledForOsr();

  kernel::PrologueBuilder prologue_builder(
      parsed_function_, last_used_block_id_, compiling_for_osr, IsInlining());
  BlockEntryInstr* instruction_cursor =
      prologue_builder.BuildPrologue(normal_entry, prologue_info);

  last_used_block_id_ = prologue_builder.last_used_block_id();

  return instruction_cursor;
}

ArrayPtr FlowGraphBuilder::GetOptionalParameterNames(const Function& function) {
  if (!function.HasOptionalNamedParameters()) {
    return Array::null();
  }

  const intptr_t num_fixed_params = function.num_fixed_parameters();
  const intptr_t num_opt_params = function.NumOptionalNamedParameters();
  const auto& names = Array::Handle(Z, Array::New(num_opt_params, Heap::kOld));
  auto& name = String::Handle(Z);
  for (intptr_t i = 0; i < num_opt_params; ++i) {
    name = function.ParameterNameAt(num_fixed_params + i);
    names.SetAt(i, name);
  }
  return names.ptr();
}

Fragment FlowGraphBuilder::PushExplicitParameters(
    const Function& function,
    const Function& target /* = Function::null_function()*/) {
  Fragment instructions;
  for (intptr_t i = function.NumImplicitParameters(),
                n = function.NumParameters();
       i < n; ++i) {
    Fragment push_param = LoadLocal(parsed_function_->ParameterVariable(i));
    if (!target.IsNull() && target.is_unboxed_parameter_at(i)) {
      Representation to;
      if (target.is_unboxed_integer_parameter_at(i)) {
        to = kUnboxedInt64;
      } else {
        ASSERT(target.is_unboxed_double_parameter_at(i));
        to = kUnboxedDouble;
      }
      const auto unbox = UnboxInstr::Create(to, Pop(), DeoptId::kNone,
                                            Instruction::kNotSpeculative);
      Push(unbox);
      push_param += Fragment(unbox);
    }
    instructions += push_param;
  }
  return instructions;
}

FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor(
    const Function& method) {
  // A method extractor is the implicit getter for a method.
  const Function& function =
      Function::ZoneHandle(Z, method.extracted_method_closure());

  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  Fragment body(normal_entry);
  body += CheckStackOverflowInPrologue(method.token_pos());
  body += BuildImplicitClosureCreation(function);
  body += Return(TokenPosition::kNoSource);

  // There is no prologue code for a method extractor.
  PrologueInfo prologue_info(-1, -1);
  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodDispatcher(
    const Function& function) {
  // This function is specialized for a receiver class, a method name, and
  // the arguments descriptor at a call site.
  const ArgumentsDescriptor descriptor(saved_args_desc_array());

  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  PrologueInfo prologue_info(-1, -1);
  BlockEntryInstr* instruction_cursor =
      BuildPrologue(normal_entry, &prologue_info);

  Fragment body(instruction_cursor);
  body += CheckStackOverflowInPrologue(function.token_pos());

  // The receiver is the first argument to noSuchMethod, and it is the first
  // argument passed to the dispatcher function.
  body += LoadLocal(parsed_function_->ParameterVariable(0));

  // The second argument to noSuchMethod is an invocation mirror.  Push the
  // arguments for allocating the invocation mirror.  First, the name.
  body += Constant(String::ZoneHandle(Z, function.name()));

  // Second, the arguments descriptor.
  body += Constant(saved_args_desc_array());

  // Third, an array containing the original arguments.  Create it and fill
  // it in.
  const intptr_t receiver_index = descriptor.TypeArgsLen() > 0 ? 1 : 0;
  body += Constant(TypeArguments::ZoneHandle(Z, TypeArguments::null()));
  body += IntConstant(receiver_index + descriptor.Size());
  body += CreateArray();
  LocalVariable* array = MakeTemporary();
  if (receiver_index > 0) {
    LocalVariable* type_args = parsed_function_->function_type_arguments();
    ASSERT(type_args != NULL);
    body += LoadLocal(array);
    body += IntConstant(0);
    body += LoadLocal(type_args);
    body += StoreIndexed(kArrayCid);
  }
  for (intptr_t i = 0; i < descriptor.PositionalCount(); ++i) {
    body += LoadLocal(array);
    body += IntConstant(receiver_index + i);
    body += LoadLocal(parsed_function_->ParameterVariable(i));
    body += StoreIndexed(kArrayCid);
  }
  String& name = String::Handle(Z);
  for (intptr_t i = 0; i < descriptor.NamedCount(); ++i) {
    const intptr_t parameter_index = descriptor.PositionAt(i);
    name = descriptor.NameAt(i);
    name = Symbols::New(H.thread(), name);
    body += LoadLocal(array);
    body += IntConstant(receiver_index + parameter_index);
    body += LoadLocal(parsed_function_->ParameterVariable(parameter_index));
    body += StoreIndexed(kArrayCid);
  }

  // Fourth, false indicating this is not a super NoSuchMethod.
  body += Constant(Bool::False());

  const Class& mirror_class =
      Class::Handle(Z, Library::LookupCoreClass(Symbols::InvocationMirror()));
  ASSERT(!mirror_class.IsNull());
  const auto& error = mirror_class.EnsureIsFinalized(H.thread());
  ASSERT(error == Error::null());
  const Function& allocation_function = Function::ZoneHandle(
      Z, mirror_class.LookupStaticFunction(
             Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror())));
  ASSERT(!allocation_function.IsNull());
  body += StaticCall(TokenPosition::kMinSource, allocation_function,
                     /* argument_count = */ 4, ICData::kStatic);

  const int kTypeArgsLen = 0;
  ArgumentsDescriptor two_arguments(
      Array::Handle(Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, 2)));
  Function& no_such_method =
      Function::ZoneHandle(Z, Resolver::ResolveDynamicForReceiverClass(
                                  Class::Handle(Z, function.Owner()),
                                  Symbols::NoSuchMethod(), two_arguments));
  if (no_such_method.IsNull()) {
    // If noSuchMethod is not found on the receiver class, call
    // Object.noSuchMethod.
    no_such_method = Resolver::ResolveDynamicForReceiverClass(
        Class::Handle(Z, IG->object_store()->object_class()),
        Symbols::NoSuchMethod(), two_arguments);
  }
  body += StaticCall(TokenPosition::kMinSource, no_such_method,
                     /* argument_count = */ 2, ICData::kNSMDispatch);
  body += Return(TokenPosition::kNoSource);

  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

// Information used by the various dynamic closure call fragment builders.
struct FlowGraphBuilder::ClosureCallInfo {
  ClosureCallInfo(LocalVariable* closure,
                  JoinEntryInstr* throw_no_such_method,
                  const Array& arguments_descriptor_array,
                  ParsedFunction::DynamicClosureCallVars* const vars)
      : closure(ASSERT_NOTNULL(closure)),
        throw_no_such_method(ASSERT_NOTNULL(throw_no_such_method)),
        descriptor(arguments_descriptor_array),
        vars(ASSERT_NOTNULL(vars)) {}

  LocalVariable* const closure;
  JoinEntryInstr* const throw_no_such_method;
  const ArgumentsDescriptor descriptor;
  ParsedFunction::DynamicClosureCallVars* const vars;

  // Set up by BuildClosureCallDefaultTypeHandling() when needed. These values
  // are read-only, so they don't need real local variables and are created
  // using MakeTemporary().
  LocalVariable* signature = nullptr;
  LocalVariable* num_fixed_params = nullptr;
  LocalVariable* num_opt_params = nullptr;
  LocalVariable* num_max_params = nullptr;
  LocalVariable* has_named_params = nullptr;
  LocalVariable* named_parameter_names = nullptr;
  LocalVariable* parameter_types = nullptr;
  LocalVariable* type_parameters = nullptr;
  LocalVariable* num_type_parameters = nullptr;
  LocalVariable* type_parameter_flags = nullptr;
  LocalVariable* instantiator_type_args = nullptr;
  LocalVariable* parent_function_type_args = nullptr;
  LocalVariable* num_parent_type_args = nullptr;
};

Fragment FlowGraphBuilder::TestClosureFunctionGeneric(
    const ClosureCallInfo& info,
    Fragment generic,
    Fragment not_generic) {
  JoinEntryInstr* after_branch = BuildJoinEntry();

  Fragment check;
  check += LoadLocal(info.type_parameters);
  TargetEntryInstr* is_not_generic;
  TargetEntryInstr* is_generic;
  check += BranchIfNull(&is_not_generic, &is_generic);

  generic.Prepend(is_generic);
  generic += Goto(after_branch);

  not_generic.Prepend(is_not_generic);
  not_generic += Goto(after_branch);

  return Fragment(check.entry, after_branch);
}

Fragment FlowGraphBuilder::TestClosureFunctionNamedParameterRequired(
    const ClosureCallInfo& info,
    Fragment set,
    Fragment not_set) {
  // Required named arguments only exist if null_safety is enabled.
  if (!IG->use_strict_null_safety_checks()) return not_set;

  Fragment check_required;
  // We calculate the index to dereference in the parameter names array.
  check_required += LoadLocal(info.vars->current_param_index);
  check_required +=
      IntConstant(compiler::target::kNumParameterFlagsPerElementLog2);
  check_required += SmiBinaryOp(Token::kSHR);
  check_required += LoadLocal(info.num_opt_params);
  check_required += SmiBinaryOp(Token::kADD);
  LocalVariable* flags_index = MakeTemporary("flags_index");  // Read-only.

  // One read-only stack value (flag_index) that must be dropped
  // after we rejoin at after_check.
  JoinEntryInstr* after_check = BuildJoinEntry();

  // Now we check to see if the flags index is within the bounds of the
  // parameters names array. If not, it cannot be required.
  check_required += LoadLocal(flags_index);
  check_required += LoadLocal(info.named_parameter_names);
  check_required += LoadNativeField(Slot::Array_length());
  check_required += SmiRelationalOp(Token::kLT);
  TargetEntryInstr* valid_index;
  TargetEntryInstr* invalid_index;
  check_required += BranchIfTrue(&valid_index, &invalid_index);

  JoinEntryInstr* join_not_set = BuildJoinEntry();

  Fragment(invalid_index) + Goto(join_not_set);

  // Otherwise, we need to retrieve the value. We're guaranteed the Smis in
  // the flag slots are non-null, so after loading we can immediate check
  // the required flag bit for the given named parameter.
  check_required.current = valid_index;
  check_required += LoadLocal(info.named_parameter_names);
  check_required += LoadLocal(flags_index);
  check_required += LoadIndexed(
      kArrayCid, /*index_scale*/ compiler::target::kCompressedWordSize);
  check_required += LoadLocal(info.vars->current_param_index);
  check_required +=
      IntConstant(compiler::target::kNumParameterFlagsPerElement - 1);
  check_required += SmiBinaryOp(Token::kBIT_AND);
  // If the below changes, we'll need to multiply by the number of parameter
  // flags before shifting.
  static_assert(compiler::target::kNumParameterFlags == 1,
                "IL builder assumes only one flag bit per parameter");
  check_required += SmiBinaryOp(Token::kSHR);
  check_required +=
      IntConstant(1 << compiler::target::kRequiredNamedParameterFlag);
  check_required += SmiBinaryOp(Token::kBIT_AND);
  check_required += IntConstant(0);
  TargetEntryInstr* is_not_set;
  TargetEntryInstr* is_set;
  check_required += BranchIfEqual(&is_not_set, &is_set);

  Fragment(is_not_set) + Goto(join_not_set);

  set.Prepend(is_set);
  set += Goto(after_check);

  not_set.Prepend(join_not_set);
  not_set += Goto(after_check);

  // After rejoining, drop the introduced temporaries.
  check_required.current = after_check;
  check_required += DropTemporary(&flags_index);
  return check_required;
}

Fragment FlowGraphBuilder::BuildClosureCallDefaultTypeHandling(
    const ClosureCallInfo& info) {
  if (info.descriptor.TypeArgsLen() > 0) {
    ASSERT(parsed_function_->function_type_arguments() != nullptr);
    // A TAV was provided, so we don't need default type argument handling
    // and can just take the arguments we were given.
    Fragment store_provided;
    store_provided += LoadLocal(parsed_function_->function_type_arguments());
    store_provided += StoreLocal(info.vars->function_type_args);
    store_provided += Drop();
    return store_provided;
  }

  // Load the defaults, instantiating or replacing them with the other type
  // arguments as appropriate.
  Fragment store_default;
  store_default += LoadLocal(info.closure);
  store_default += LoadNativeField(Slot::Closure_function());
  store_default += LoadNativeField(Slot::Function_data());
  LocalVariable* closure_data = MakeTemporary("closure_data");

  store_default += LoadLocal(closure_data);
  const auto& slot = Slot::ClosureData_default_type_arguments_kind();
  store_default += LoadNativeField(slot);
  store_default += Box(slot.representation());
  LocalVariable* default_tav_kind = MakeTemporary("default_tav_kind");

  // Two locals to drop after join, closure_data and default_tav_kind.
  JoinEntryInstr* done = BuildJoinEntry();

  store_default += LoadLocal(default_tav_kind);
  TargetEntryInstr* is_instantiated;
  TargetEntryInstr* is_not_instantiated;
  store_default += IntConstant(static_cast<intptr_t>(
      ClosureData::DefaultTypeArgumentsKind::kIsInstantiated));
  store_default += BranchIfEqual(&is_instantiated, &is_not_instantiated);
  store_default.current = is_not_instantiated;  // Check next case.
  store_default += LoadLocal(default_tav_kind);
  TargetEntryInstr* needs_instantiation;
  TargetEntryInstr* can_share;
  store_default += IntConstant(static_cast<intptr_t>(
      ClosureData::DefaultTypeArgumentsKind::kNeedsInstantiation));
  store_default += BranchIfEqual(&needs_instantiation, &can_share);
  store_default.current = can_share;  // Check next case.
  store_default += LoadLocal(default_tav_kind);
  TargetEntryInstr* can_share_instantiator;
  TargetEntryInstr* can_share_function;
  store_default += IntConstant(static_cast<intptr_t>(
      ClosureData::DefaultTypeArgumentsKind::kSharesInstantiatorTypeArguments));
  store_default += BranchIfEqual(&can_share_instantiator, &can_share_function);

  Fragment instantiated(is_instantiated);
  instantiated += LoadLocal(info.type_parameters);
  instantiated += LoadNativeField(Slot::TypeParameters_defaults());
  instantiated += StoreLocal(info.vars->function_type_args);
  instantiated += Drop();
  instantiated += Goto(done);

  Fragment do_instantiation(needs_instantiation);
  // Load the instantiator type arguments.
  do_instantiation += LoadLocal(info.instantiator_type_args);
  // Load the parent function type arguments. (No local function type arguments
  // can be used within the defaults).
  do_instantiation += LoadLocal(info.parent_function_type_args);
  // Load the default type arguments to instantiate.
  do_instantiation += LoadLocal(info.type_parameters);
  do_instantiation += LoadNativeField(Slot::TypeParameters_defaults());
  do_instantiation += InstantiateDynamicTypeArguments();
  do_instantiation += StoreLocal(info.vars->function_type_args);
  do_instantiation += Drop();
  do_instantiation += Goto(done);

  Fragment share_instantiator(can_share_instantiator);
  share_instantiator += LoadLocal(info.instantiator_type_args);
  share_instantiator += StoreLocal(info.vars->function_type_args);
  share_instantiator += Drop();
  share_instantiator += Goto(done);

  Fragment share_function(can_share_function);
  // Since the defaults won't have local type parameters, these must all be
  // from the parent function type arguments, so we can just use it.
  share_function += LoadLocal(info.parent_function_type_args);
  share_function += StoreLocal(info.vars->function_type_args);
  share_function += Drop();
  share_function += Goto(done);

  store_default.current = done;  // Return here after branching.
  store_default += DropTemporary(&default_tav_kind);
  store_default += DropTemporary(&closure_data);

  Fragment store_delayed;
  store_delayed += LoadLocal(info.closure);
  store_delayed += LoadNativeField(Slot::Closure_delayed_type_arguments());
  store_delayed += StoreLocal(info.vars->function_type_args);
  store_delayed += Drop();

  // Use the delayed type args if present, else the default ones.
  return TestDelayedTypeArgs(info.closure, store_delayed, store_default);
}

Fragment FlowGraphBuilder::BuildClosureCallNamedArgumentsCheck(
    const ClosureCallInfo& info) {
  // When no named arguments are provided, we just need to check for possible
  // required named arguments.
  if (info.descriptor.NamedCount() == 0) {
    // No work to do if there are no possible required named parameters.
    if (!IG->use_strict_null_safety_checks()) {
      return Fragment();
    }
    // If the below changes, we can no longer assume that flag slots existing
    // means there are required parameters.
    static_assert(compiler::target::kNumParameterFlags == 1,
                  "IL builder assumes only one flag bit per parameter");
    // No named args were provided, so check for any required named params.
    // Here, we assume that the only parameter flag saved is the required bit
    // for named parameters. If this changes, we'll need to check each flag
    // entry appropriately for any set required bits.
    Fragment has_any;
    has_any += LoadLocal(info.num_opt_params);
    has_any += LoadLocal(info.named_parameter_names);
    has_any += LoadNativeField(Slot::Array_length());
    TargetEntryInstr* no_required;
    TargetEntryInstr* has_required;
    has_any += BranchIfEqual(&no_required, &has_required);

    Fragment(has_required) + Goto(info.throw_no_such_method);

    return Fragment(has_any.entry, no_required);
  }

  // Otherwise, we need to loop through the parameter names to check the names
  // of named arguments for validity (and possibly missing required ones).
  Fragment check_names;
  check_names += LoadLocal(info.vars->current_param_index);
  LocalVariable* old_index = MakeTemporary("old_index");  // Read-only.
  check_names += LoadLocal(info.vars->current_num_processed);
  LocalVariable* old_processed = MakeTemporary("old_processed");  // Read-only.

  // Two local stack values (old_index, old_processed) to drop after rejoining
  // at done.
  JoinEntryInstr* loop = BuildJoinEntry();
  JoinEntryInstr* done = BuildJoinEntry();

  check_names += IntConstant(0);
  check_names += StoreLocal(info.vars->current_num_processed);
  check_names += Drop();
  check_names += IntConstant(0);
  check_names += StoreLocal(info.vars->current_param_index);
  check_names += Drop();
  check_names += Goto(loop);

  Fragment loop_check(loop);
  loop_check += LoadLocal(info.vars->current_param_index);
  loop_check += LoadLocal(info.num_opt_params);
  loop_check += SmiRelationalOp(Token::kLT);
  TargetEntryInstr* no_more;
  TargetEntryInstr* more;
  loop_check += BranchIfTrue(&more, &no_more);

  Fragment(no_more) + Goto(done);

  Fragment loop_body(more);
  // First load the name we need to check against.
  loop_body += LoadLocal(info.named_parameter_names);
  loop_body += LoadLocal(info.vars->current_param_index);
  loop_body += LoadIndexed(
      kArrayCid, /*index_scale*/ compiler::target::kCompressedWordSize);
  LocalVariable* param_name = MakeTemporary("param_name");  // Read only.

  // One additional local value on the stack within the loop body (param_name)
  // that should be dropped after rejoining at loop_incr.
  JoinEntryInstr* loop_incr = BuildJoinEntry();

  // Now iterate over the ArgumentsDescriptor names and check for a match.
  for (intptr_t i = 0; i < info.descriptor.NamedCount(); i++) {
    const auto& name = String::ZoneHandle(Z, info.descriptor.NameAt(i));
    loop_body += Constant(name);
    loop_body += LoadLocal(param_name);
    TargetEntryInstr* match;
    TargetEntryInstr* mismatch;
    loop_body += BranchIfEqual(&match, &mismatch);
    loop_body.current = mismatch;

    // We have a match, so go to the next name after storing the corresponding
    // parameter index on the stack and incrementing the number of matched
    // arguments. (No need to check the required bit for provided parameters.)
    Fragment matched(match);
    matched += LoadLocal(info.vars->current_param_index);
    matched += LoadLocal(info.num_fixed_params);
    matched += SmiBinaryOp(Token::kADD, /*is_truncating=*/true);
    matched += StoreLocal(info.vars->named_argument_parameter_indices.At(i));
    matched += Drop();
    matched += LoadLocal(info.vars->current_num_processed);
    matched += IntConstant(1);
    matched += SmiBinaryOp(Token::kADD, /*is_truncating=*/true);
    matched += StoreLocal(info.vars->current_num_processed);
    matched += Drop();
    matched += Goto(loop_incr);
  }

  // None of the names in the arguments descriptor matched, so check if this
  // is a required parameter.
  loop_body += TestClosureFunctionNamedParameterRequired(
      info,
      /*set=*/Goto(info.throw_no_such_method),
      /*not_set=*/{});

  loop_body += Goto(loop_incr);

  Fragment incr_index(loop_incr);
  incr_index += DropTemporary(&param_name);
  incr_index += LoadLocal(info.vars->current_param_index);
  incr_index += IntConstant(1);
  incr_index += SmiBinaryOp(Token::kADD, /*is_truncating=*/true);
  incr_index += StoreLocal(info.vars->current_param_index);
  incr_index += Drop();
  incr_index += Goto(loop);

  Fragment check_processed(done);
  check_processed += LoadLocal(info.vars->current_num_processed);
  check_processed += IntConstant(info.descriptor.NamedCount());
  TargetEntryInstr* all_processed;
  TargetEntryInstr* bad_name;
  check_processed += BranchIfEqual(&all_processed, &bad_name);

  // Didn't find a matching parameter name for at least one argument name.
  Fragment(bad_name) + Goto(info.throw_no_such_method);

  // Drop the temporaries at the end of the fragment.
  check_names.current = all_processed;
  check_names += LoadLocal(old_processed);
  check_names += StoreLocal(info.vars->current_num_processed);
  check_names += Drop();
  check_names += DropTemporary(&old_processed);
  check_names += LoadLocal(old_index);
  check_names += StoreLocal(info.vars->current_param_index);
  check_names += Drop();
  check_names += DropTemporary(&old_index);
  return check_names;
}

Fragment FlowGraphBuilder::BuildClosureCallArgumentsValidCheck(
    const ClosureCallInfo& info) {
  Fragment check_entry;
  // We only need to check the length of any explicitly provided type arguments.
  if (info.descriptor.TypeArgsLen() > 0) {
    Fragment check_type_args_length;
    check_type_args_length += LoadLocal(info.type_parameters);
    TargetEntryInstr* null;
    TargetEntryInstr* not_null;
    check_type_args_length += BranchIfNull(&null, &not_null);
    check_type_args_length.current = not_null;  // Continue in non-error case.
    check_type_args_length += LoadLocal(info.signature);
    check_type_args_length += BuildExtractUnboxedSlotBitFieldIntoSmi<
        UntaggedFunctionType::PackedNumTypeParameters>(
        Slot::FunctionType_packed_type_parameter_counts());
    check_type_args_length += IntConstant(info.descriptor.TypeArgsLen());
    TargetEntryInstr* equal;
    TargetEntryInstr* not_equal;
    check_type_args_length += BranchIfEqual(&equal, &not_equal);
    check_type_args_length.current = equal;  // Continue in non-error case.

    // The function is not generic.
    Fragment(null) + Goto(info.throw_no_such_method);

    // An incorrect number of type arguments were passed.
    Fragment(not_equal) + Goto(info.throw_no_such_method);

    // Type arguments should not be provided if there are delayed type
    // arguments, as then the closure itself is not generic.
    check_entry += TestDelayedTypeArgs(
        info.closure, /*present=*/Goto(info.throw_no_such_method),
        /*absent=*/check_type_args_length);
  }

  check_entry += LoadLocal(info.has_named_params);
  TargetEntryInstr* has_named;
  TargetEntryInstr* has_positional;
  check_entry += BranchIfTrue(&has_named, &has_positional);
  JoinEntryInstr* join_after_optional = BuildJoinEntry();
  check_entry.current = join_after_optional;

  if (info.descriptor.NamedCount() > 0) {
    // No reason to continue checking, as this function doesn't take named args.
    Fragment(has_positional) + Goto(info.throw_no_such_method);
  } else {
    Fragment check_pos(has_positional);
    check_pos += LoadLocal(info.num_fixed_params);
    check_pos += IntConstant(info.descriptor.PositionalCount());
    check_pos += SmiRelationalOp(Token::kLTE);
    TargetEntryInstr* enough;
    TargetEntryInstr* too_few;
    check_pos += BranchIfTrue(&enough, &too_few);
    check_pos.current = enough;

    Fragment(too_few) + Goto(info.throw_no_such_method);

    check_pos += IntConstant(info.descriptor.PositionalCount());
    check_pos += LoadLocal(info.num_max_params);
    check_pos += SmiRelationalOp(Token::kLTE);
    TargetEntryInstr* valid;
    TargetEntryInstr* too_many;
    check_pos += BranchIfTrue(&valid, &too_many);
    check_pos.current = valid;

    Fragment(too_many) + Goto(info.throw_no_such_method);

    check_pos += Goto(join_after_optional);
  }

  Fragment check_named(has_named);

  TargetEntryInstr* same;
  TargetEntryInstr* different;
  check_named += LoadLocal(info.num_fixed_params);
  check_named += IntConstant(info.descriptor.PositionalCount());
  check_named += BranchIfEqual(&same, &different);
  check_named.current = same;

  Fragment(different) + Goto(info.throw_no_such_method);

  if (info.descriptor.NamedCount() > 0) {
    check_named += IntConstant(info.descriptor.NamedCount());
    check_named += LoadLocal(info.num_opt_params);
    check_named += SmiRelationalOp(Token::kLTE);
    TargetEntryInstr* valid;
    TargetEntryInstr* too_many;
    check_named += BranchIfTrue(&valid, &too_many);
    check_named.current = valid;

    Fragment(too_many) + Goto(info.throw_no_such_method);
  }

  // Check the names for optional arguments. If applicable, also check that all
  // required named parameters are provided.
  check_named += BuildClosureCallNamedArgumentsCheck(info);
  check_named += Goto(join_after_optional);

  check_entry.current = join_after_optional;
  return check_entry;
}

Fragment FlowGraphBuilder::BuildClosureCallTypeArgumentsTypeCheck(
    const ClosureCallInfo& info) {
  JoinEntryInstr* done = BuildJoinEntry();
  JoinEntryInstr* loop = BuildJoinEntry();

  // We assume that the value stored in :t_type_parameters is not null (i.e.,
  // the function stored in :t_function is generic).
  Fragment loop_init;

  // A null bounds vector represents a vector of dynamic and no check is needed.
  loop_init += LoadLocal(info.type_parameters);
  loop_init += LoadNativeField(Slot::TypeParameters_bounds());
  TargetEntryInstr* null_bounds;
  TargetEntryInstr* non_null_bounds;
  loop_init += BranchIfNull(&null_bounds, &non_null_bounds);

  Fragment(null_bounds) + Goto(done);

  loop_init.current = non_null_bounds;
  // Loop over the type parameters array.
  loop_init += IntConstant(0);
  loop_init += StoreLocal(info.vars->current_param_index);
  loop_init += Drop();
  loop_init += Goto(loop);

  Fragment loop_check(loop);
  loop_check += LoadLocal(info.vars->current_param_index);
  loop_check += LoadLocal(info.num_type_parameters);
  loop_check += SmiRelationalOp(Token::kLT);
  TargetEntryInstr* more;
  TargetEntryInstr* no_more;
  loop_check += BranchIfTrue(&more, &no_more);

  Fragment(no_more) + Goto(done);

  Fragment loop_test_flag(more);
  JoinEntryInstr* next = BuildJoinEntry();
  JoinEntryInstr* check = BuildJoinEntry();
  loop_test_flag += LoadLocal(info.type_parameter_flags);
  TargetEntryInstr* null_flags;
  TargetEntryInstr* non_null_flags;
  loop_test_flag += BranchIfNull(&null_flags, &non_null_flags);

  Fragment(null_flags) + Goto(check);  // Check type if null (non-covariant).

  loop_test_flag.current = non_null_flags;  // Test flags if not null.
  loop_test_flag += LoadLocal(info.type_parameter_flags);
  loop_test_flag += LoadLocal(info.vars->current_param_index);
  loop_test_flag += IntConstant(TypeParameters::kFlagsPerSmiShift);
  loop_test_flag += SmiBinaryOp(Token::kSHR);
  loop_test_flag += LoadIndexed(
      kArrayCid, /*index_scale*/ compiler::target::kCompressedWordSize);
  loop_test_flag += LoadLocal(info.vars->current_param_index);
  loop_test_flag += IntConstant(TypeParameters::kFlagsPerSmiMask);
  loop_test_flag += SmiBinaryOp(Token::kBIT_AND);
  loop_test_flag += SmiBinaryOp(Token::kSHR);
  loop_test_flag += IntConstant(1);
  loop_test_flag += SmiBinaryOp(Token::kBIT_AND);
  loop_test_flag += IntConstant(0);
  TargetEntryInstr* is_noncovariant;
  TargetEntryInstr* is_covariant;
  loop_test_flag += BranchIfEqual(&is_noncovariant, &is_covariant);

  Fragment(is_covariant) + Goto(next);      // Continue if covariant.
  Fragment(is_noncovariant) + Goto(check);  // Check type if non-covariant.

  Fragment loop_prep_type_param(check);
  JoinEntryInstr* dynamic_type_param = BuildJoinEntry();
  JoinEntryInstr* call = BuildJoinEntry();

  // Load type argument already stored in function_type_args if non null.
  loop_prep_type_param += LoadLocal(info.vars->function_type_args);
  TargetEntryInstr* null_ftav;
  TargetEntryInstr* non_null_ftav;
  loop_prep_type_param += BranchIfNull(&null_ftav, &non_null_ftav);

  Fragment(null_ftav) + Goto(dynamic_type_param);

  loop_prep_type_param.current = non_null_ftav;
  loop_prep_type_param += LoadLocal(info.vars->function_type_args);
  loop_prep_type_param += LoadLocal(info.vars->current_param_index);
  loop_prep_type_param += LoadLocal(info.num_parent_type_args);
  loop_prep_type_param += SmiBinaryOp(Token::kADD, /*is_truncating=*/true);
  loop_prep_type_param += LoadIndexed(
      kTypeArgumentsCid, /*index_scale*/ compiler::target::kCompressedWordSize);
  loop_prep_type_param += StoreLocal(info.vars->current_type_param);
  loop_prep_type_param += Drop();
  loop_prep_type_param += Goto(call);

  Fragment loop_dynamic_type_param(dynamic_type_param);
  // If function_type_args is null, the instantiated type param is dynamic.
  loop_dynamic_type_param += Constant(Type::ZoneHandle(Type::DynamicType()));
  loop_dynamic_type_param += StoreLocal(info.vars->current_type_param);
  loop_dynamic_type_param += Drop();
  loop_dynamic_type_param += Goto(call);

  Fragment loop_call_check(call);
  // Load instantiators.
  loop_call_check += LoadLocal(info.instantiator_type_args);
  loop_call_check += LoadLocal(info.vars->function_type_args);
  // Load instantiated type parameter.
  loop_call_check += LoadLocal(info.vars->current_type_param);
  // Load bound from type parameters.
  loop_call_check += LoadLocal(info.type_parameters);
  loop_call_check += LoadNativeField(Slot::TypeParameters_bounds());
  loop_call_check += LoadLocal(info.vars->current_param_index);
  loop_call_check += LoadIndexed(
      kTypeArgumentsCid, /*index_scale*/ compiler::target::kCompressedWordSize);
  // Load (canonicalized) name of type parameter in signature.
  loop_call_check += LoadLocal(info.type_parameters);
  loop_call_check += LoadNativeField(Slot::TypeParameters_names());
  loop_call_check += LoadLocal(info.vars->current_param_index);
  loop_call_check += LoadIndexed(
      kArrayCid, /*index_scale*/ compiler::target::kCompressedWordSize);
  // Assert that the passed-in type argument is consistent with the bound of
  // the corresponding type parameter.
  loop_call_check += AssertSubtype(TokenPosition::kNoSource);
  loop_call_check += Goto(next);

  Fragment loop_incr(next);
  loop_incr += LoadLocal(info.vars->current_param_index);
  loop_incr += IntConstant(1);
  loop_incr += SmiBinaryOp(Token::kADD, /*is_truncating=*/true);
  loop_incr += StoreLocal(info.vars->current_param_index);
  loop_incr += Drop();
  loop_incr += Goto(loop);

  return Fragment(loop_init.entry, done);
}

Fragment FlowGraphBuilder::BuildClosureCallArgumentTypeCheck(
    const ClosureCallInfo& info,
    LocalVariable* param_index,
    intptr_t arg_index,
    const String& arg_name) {
  Fragment instructions;

  // Load value.
  instructions += LoadLocal(parsed_function_->ParameterVariable(arg_index));
  // Load destination type.
  instructions += LoadLocal(info.parameter_types);
  instructions += LoadLocal(param_index);
  instructions += LoadIndexed(
      kArrayCid, /*index_scale*/ compiler::target::kCompressedWordSize);
  // Load instantiator type arguments.
  instructions += LoadLocal(info.instantiator_type_args);
  // Load the full set of function type arguments.
  instructions += LoadLocal(info.vars->function_type_args);
  // Check that the value has the right type.
  instructions += AssertAssignable(TokenPosition::kNoSource, arg_name,
                                   AssertAssignableInstr::kParameterCheck);
  // Make sure to store the result to keep data dependencies accurate.
  instructions += StoreLocal(parsed_function_->ParameterVariable(arg_index));
  instructions += Drop();

  return instructions;
}

Fragment FlowGraphBuilder::BuildClosureCallArgumentTypeChecks(
    const ClosureCallInfo& info) {
  Fragment instructions;

  // Only check explicit arguments (i.e., skip the receiver), as the receiver
  // is always assignable to its type (stored as dynamic).
  for (intptr_t i = 1; i < info.descriptor.PositionalCount(); i++) {
    instructions += IntConstant(i);
    LocalVariable* param_index = MakeTemporary("param_index");
    // We don't have a compile-time name, so this symbol signals the runtime
    // that it should recreate the type check using info from the stack.
    instructions += BuildClosureCallArgumentTypeCheck(
        info, param_index, i, Symbols::dynamic_assert_assignable_stc_check());
    instructions += DropTemporary(&param_index);
  }

  for (intptr_t i = 0; i < info.descriptor.NamedCount(); i++) {
    const intptr_t arg_index = info.descriptor.PositionAt(i);
    const auto& arg_name = String::ZoneHandle(Z, info.descriptor.NameAt(i));
    auto const param_index = info.vars->named_argument_parameter_indices.At(i);
    instructions += BuildClosureCallArgumentTypeCheck(info, param_index,
                                                      arg_index, arg_name);
  }

  return instructions;
}

Fragment FlowGraphBuilder::BuildDynamicClosureCallChecks(
    LocalVariable* closure) {
  ClosureCallInfo info(closure, BuildThrowNoSuchMethod(),
                       saved_args_desc_array(),
                       parsed_function_->dynamic_closure_call_vars());

  Fragment body;
  body += LoadLocal(info.closure);
  body += LoadNativeField(Slot::Closure_function());
  body += LoadNativeField(Slot::Function_signature());
  info.signature = MakeTemporary("signature");

  body += LoadLocal(info.signature);
  body += BuildExtractUnboxedSlotBitFieldIntoSmi<
      FunctionType::PackedNumFixedParameters>(
      Slot::FunctionType_packed_parameter_counts());
  info.num_fixed_params = MakeTemporary("num_fixed_params");

  body += LoadLocal(info.signature);
  body += BuildExtractUnboxedSlotBitFieldIntoSmi<
      FunctionType::PackedNumOptionalParameters>(
      Slot::FunctionType_packed_parameter_counts());
  info.num_opt_params = MakeTemporary("num_opt_params");

  body += LoadLocal(info.num_fixed_params);
  body += LoadLocal(info.num_opt_params);
  body += SmiBinaryOp(Token::kADD);
  info.num_max_params = MakeTemporary("num_max_params");

  body += LoadLocal(info.signature);
  body += BuildExtractUnboxedSlotBitFieldIntoSmi<
      FunctionType::PackedHasNamedOptionalParameters>(
      Slot::FunctionType_packed_parameter_counts());

  body += IntConstant(0);
  body += StrictCompare(Token::kNE_STRICT);
  info.has_named_params = MakeTemporary("has_named_params");

  body += LoadLocal(info.signature);
  body += LoadNativeField(Slot::FunctionType_named_parameter_names());
  info.named_parameter_names = MakeTemporary("named_parameter_names");

  body += LoadLocal(info.signature);
  body += LoadNativeField(Slot::FunctionType_parameter_types());
  info.parameter_types = MakeTemporary("parameter_types");

  body += LoadLocal(info.signature);
  body += LoadNativeField(Slot::FunctionType_type_parameters());
  info.type_parameters = MakeTemporary("type_parameters");

  body += LoadLocal(info.closure);
  body += LoadNativeField(Slot::Closure_instantiator_type_arguments());
  info.instantiator_type_args = MakeTemporary("instantiator_type_args");

  body += LoadLocal(info.closure);
  body += LoadNativeField(Slot::Closure_function_type_arguments());
  info.parent_function_type_args = MakeTemporary("parent_function_type_args");

  // At this point, all the read-only temporaries stored in the ClosureCallInfo
  // should be either loaded or still nullptr, if not needed for this function.
  // Now we check that the arguments to the closure call have the right shape.
  body += BuildClosureCallArgumentsValidCheck(info);

  // If the closure function is not generic, there are no local function type
  // args. Thus, use whatever was stored for the parent function type arguments,
  // which has already been checked against any parent type parameter bounds.
  Fragment not_generic;
  not_generic += LoadLocal(info.parent_function_type_args);
  not_generic += StoreLocal(info.vars->function_type_args);
  not_generic += Drop();

  // If the closure function is generic, then we first need to calculate the
  // full set of function type arguments, then check the local function type
  // arguments against the closure function's type parameter bounds.
  Fragment generic;
  // Calculate the number of parent type arguments and store them in
  // info.num_parent_type_args.
  generic += LoadLocal(info.signature);
  generic += BuildExtractUnboxedSlotBitFieldIntoSmi<
      UntaggedFunctionType::PackedNumParentTypeArguments>(
      Slot::FunctionType_packed_type_parameter_counts());
  info.num_parent_type_args = MakeTemporary("num_parent_type_args");

  // Hoist number of type parameters.
  generic += LoadLocal(info.signature);
  generic += BuildExtractUnboxedSlotBitFieldIntoSmi<
      UntaggedFunctionType::PackedNumTypeParameters>(
      Slot::FunctionType_packed_type_parameter_counts());
  info.num_type_parameters = MakeTemporary("num_type_parameters");

  // Hoist type parameter flags.
  generic += LoadLocal(info.type_parameters);
  generic += LoadNativeField(Slot::TypeParameters_flags());
  info.type_parameter_flags = MakeTemporary("type_parameter_flags");

  // Calculate the local function type arguments and store them in
  // info.vars->function_type_args.
  generic += BuildClosureCallDefaultTypeHandling(info);

  // Load the local function type args.
  generic += LoadLocal(info.vars->function_type_args);
  // Load the parent function type args.
  generic += LoadLocal(info.parent_function_type_args);
  // Load the number of parent type parameters.
  generic += LoadLocal(info.num_parent_type_args);
  // Load the number of total type parameters.
  generic += LoadLocal(info.num_parent_type_args);
  generic += LoadLocal(info.num_type_parameters);
  generic += SmiBinaryOp(Token::kADD, /*is_truncating=*/true);

  // Call the static function for prepending type arguments.
  generic += StaticCall(TokenPosition::kNoSource,
                        PrependTypeArgumentsFunction(), 4, ICData::kStatic);
  generic += StoreLocal(info.vars->function_type_args);
  generic += Drop();

  // Now that we have the full set of function type arguments, check them
  // against the type parameter bounds. However, if the local function type
  // arguments are delayed type arguments, they have already been checked by
  // the type system and need not be checked again at the call site.
  auto const check_bounds = BuildClosureCallTypeArgumentsTypeCheck(info);
  if (FLAG_eliminate_type_checks) {
    generic += TestDelayedTypeArgs(info.closure, /*present=*/{},
                                   /*absent=*/check_bounds);
  } else {
    generic += check_bounds;
  }
  generic += DropTemporary(&info.type_parameter_flags);
  generic += DropTemporary(&info.num_type_parameters);
  generic += DropTemporary(&info.num_parent_type_args);

  // Call the appropriate fragment for setting up the function type arguments
  // and performing any needed type argument checking.
  body += TestClosureFunctionGeneric(info, generic, not_generic);

  // Check that the values provided as arguments are assignable to the types
  // of the corresponding closure function parameters.
  body += BuildClosureCallArgumentTypeChecks(info);

  // Drop all the read-only temporaries at the end of the fragment.
  body += DropTemporary(&info.parent_function_type_args);
  body += DropTemporary(&info.instantiator_type_args);
  body += DropTemporary(&info.type_parameters);
  body += DropTemporary(&info.parameter_types);
  body += DropTemporary(&info.named_parameter_names);
  body += DropTemporary(&info.has_named_params);
  body += DropTemporary(&info.num_max_params);
  body += DropTemporary(&info.num_opt_params);
  body += DropTemporary(&info.num_fixed_params);
  body += DropTemporary(&info.signature);

  return body;
}

FlowGraph* FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher(
    const Function& function) {
  const ArgumentsDescriptor descriptor(saved_args_desc_array());
  // Find the name of the field we should dispatch to.
  const Class& owner = Class::Handle(Z, function.Owner());
  ASSERT(!owner.IsNull());
  auto& field_name = String::Handle(Z, function.name());
  // If the field name has a dyn: tag, then remove it. We don't add dynamic
  // invocation forwarders for field getters used for invoking, we just use
  // the tag in the name of the invoke field dispatcher to detect dynamic calls.
  const bool is_dynamic_call =
      Function::IsDynamicInvocationForwarderName(field_name);
  if (is_dynamic_call) {
    field_name = Function::DemangleDynamicInvocationForwarderName(field_name);
  }
  const String& getter_name = String::ZoneHandle(
      Z, Symbols::New(thread_,
                      String::Handle(Z, Field::GetterSymbol(field_name))));

  // Determine if this is `class Closure { get call => this; }`
  const Class& closure_class =
      Class::Handle(Z, IG->object_store()->closure_class());
  const bool is_closure_call = (owner.ptr() == closure_class.ptr()) &&
                               field_name.Equals(Symbols::Call());

  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  PrologueInfo prologue_info(-1, -1);
  BlockEntryInstr* instruction_cursor =
      BuildPrologue(normal_entry, &prologue_info);

  Fragment body(instruction_cursor);
  body += CheckStackOverflowInPrologue(function.token_pos());

  // Build any dynamic closure call checks before pushing arguments to the
  // final call on the stack to make debugging easier.
  LocalVariable* closure = nullptr;
  if (is_closure_call) {
    closure = parsed_function_->ParameterVariable(0);
    if (is_dynamic_call) {
      // The whole reason for making this invoke field dispatcher is that
      // this closure call needs checking, so we shouldn't inline a call to an
      // unchecked entry that can't tail call NSM.
      InlineBailout(
          "kernel::FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher");

      body += BuildDynamicClosureCallChecks(closure);
    }
  }

  if (descriptor.TypeArgsLen() > 0) {
    LocalVariable* type_args = parsed_function_->function_type_arguments();
    ASSERT(type_args != nullptr);
    body += LoadLocal(type_args);
  }

  if (is_closure_call) {
    // The closure itself is the first argument.
    body += LoadLocal(closure);
  } else {
    // Invoke the getter to get the field value.
    body += LoadLocal(parsed_function_->ParameterVariable(0));
    const intptr_t kTypeArgsLen = 0;
    const intptr_t kNumArgsChecked = 1;
    body += InstanceCall(TokenPosition::kMinSource, getter_name, Token::kGET,
                         kTypeArgsLen, 1, Array::null_array(), kNumArgsChecked);
  }

  // Push all arguments onto the stack.
  for (intptr_t pos = 1; pos < descriptor.Count(); pos++) {
    body += LoadLocal(parsed_function_->ParameterVariable(pos));
  }

  // Construct argument names array if necessary.
  const Array* argument_names = &Object::null_array();
  if (descriptor.NamedCount() > 0) {
    const auto& array_handle =
        Array::ZoneHandle(Z, Array::New(descriptor.NamedCount(), Heap::kNew));
    String& string_handle = String::Handle(Z);
    for (intptr_t i = 0; i < descriptor.NamedCount(); ++i) {
      const intptr_t named_arg_index =
          descriptor.PositionAt(i) - descriptor.PositionalCount();
      string_handle = descriptor.NameAt(i);
      array_handle.SetAt(named_arg_index, string_handle);
    }
    argument_names = &array_handle;
  }

  if (is_closure_call) {
    body += LoadLocal(closure);
    if (!FLAG_precompiled_mode) {
      // Lookup the function in the closure.
      body += LoadNativeField(Slot::Closure_function());
    }
    body += ClosureCall(TokenPosition::kNoSource, descriptor.TypeArgsLen(),
                        descriptor.Count(), *argument_names);
  } else {
    const intptr_t kNumArgsChecked = 1;
    body +=
        InstanceCall(TokenPosition::kMinSource,
                     is_dynamic_call ? Symbols::DynamicCall() : Symbols::Call(),
                     Token::kILLEGAL, descriptor.TypeArgsLen(),
                     descriptor.Count(), *argument_names, kNumArgsChecked);
  }

  body += Return(TokenPosition::kNoSource);

  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodForwarder(
    const Function& function,
    bool is_implicit_closure_function,
    bool throw_no_such_method_error) {
  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  PrologueInfo prologue_info(-1, -1);
  BlockEntryInstr* instruction_cursor =
      BuildPrologue(normal_entry, &prologue_info);

  Fragment body(instruction_cursor);
  body += CheckStackOverflowInPrologue(function.token_pos());

  // If we are inside the tearoff wrapper function (implicit closure), we need
  // to extract the receiver from the context. We just replace it directly on
  // the stack to simplify the rest of the code.
  if (is_implicit_closure_function && !function.is_static()) {
    if (parsed_function_->has_arg_desc_var()) {
      body += LoadArgDescriptor();
      body += LoadNativeField(Slot::ArgumentsDescriptor_size());
    } else {
      ASSERT(function.NumOptionalParameters() == 0);
      body += IntConstant(function.NumParameters());
    }
    body += LoadLocal(parsed_function_->current_context_var());
    body += LoadNativeField(Slot::GetContextVariableSlotFor(
        thread_, *parsed_function_->receiver_var()));
    body += StoreFpRelativeSlot(
        kWordSize * compiler::target::frame_layout.param_end_from_fp);
  }

  if (function.NeedsTypeArgumentTypeChecks()) {
    BuildTypeArgumentTypeChecks(TypeChecksToBuild::kCheckAllTypeParameterBounds,
                                &body);
  }

  if (function.NeedsArgumentTypeChecks()) {
    BuildArgumentTypeChecks(&body, &body, nullptr);
  }

  body += MakeTemp();
  LocalVariable* result = MakeTemporary();

  // Do "++argument_count" if any type arguments were passed.
  LocalVariable* argument_count_var = parsed_function_->expression_temp_var();
  body += IntConstant(0);
  body += StoreLocal(TokenPosition::kNoSource, argument_count_var);
  body += Drop();
  if (function.IsGeneric()) {
    Fragment then;
    Fragment otherwise;
    otherwise += IntConstant(1);
    otherwise += StoreLocal(TokenPosition::kNoSource, argument_count_var);
    otherwise += Drop();
    body += TestAnyTypeArgs(then, otherwise);
  }

  if (function.HasOptionalParameters()) {
    body += LoadArgDescriptor();
    body += LoadNativeField(Slot::ArgumentsDescriptor_size());
  } else {
    body += IntConstant(function.NumParameters());
  }
  body += LoadLocal(argument_count_var);
  body += SmiBinaryOp(Token::kADD, /* truncate= */ true);
  LocalVariable* argument_count = MakeTemporary();

  // We are generating code like the following:
  //
  // var arguments = new Array<dynamic>(argument_count);
  //
  // int i = 0;
  // if (any type arguments are passed) {
  //   arguments[0] = function_type_arguments;
  //   ++i;
  // }
  //
  // for (; i < argument_count; ++i) {
  //   arguments[i] = LoadFpRelativeSlot(
  //       kWordSize * (frame_layout.param_end_from_fp + argument_count - i));
  // }
  body += Constant(TypeArguments::ZoneHandle(Z, TypeArguments::null()));
  body += LoadLocal(argument_count);
  body += CreateArray();
  LocalVariable* arguments = MakeTemporary();

  {
    // int i = 0
    LocalVariable* index = parsed_function_->expression_temp_var();
    body += IntConstant(0);
    body += StoreLocal(TokenPosition::kNoSource, index);
    body += Drop();

    // if (any type arguments are passed) {
    //   arguments[0] = function_type_arguments;
    //   i = 1;
    // }
    if (function.IsGeneric()) {
      Fragment store;
      store += LoadLocal(arguments);
      store += IntConstant(0);
      store += LoadFunctionTypeArguments();
      store += StoreIndexed(kArrayCid);
      store += IntConstant(1);
      store += StoreLocal(TokenPosition::kNoSource, index);
      store += Drop();
      body += TestAnyTypeArgs(store, Fragment());
    }

    TargetEntryInstr* body_entry;
    TargetEntryInstr* loop_exit;

    Fragment condition;
    // i < argument_count
    condition += LoadLocal(index);
    condition += LoadLocal(argument_count);
    condition += SmiRelationalOp(Token::kLT);
    condition += BranchIfTrue(&body_entry, &loop_exit, /*negate=*/false);

    Fragment loop_body(body_entry);

    // arguments[i] = LoadFpRelativeSlot(
    //     kWordSize * (frame_layout.param_end_from_fp + argument_count - i));
    loop_body += LoadLocal(arguments);
    loop_body += LoadLocal(index);
    loop_body += LoadLocal(argument_count);
    loop_body += LoadLocal(index);
    loop_body += SmiBinaryOp(Token::kSUB, /*truncate=*/true);
    loop_body +=
        LoadFpRelativeSlot(compiler::target::kWordSize *
                               compiler::target::frame_layout.param_end_from_fp,
                           CompileType::Dynamic());
    loop_body += StoreIndexed(kArrayCid);

    // ++i
    loop_body += LoadLocal(index);
    loop_body += IntConstant(1);
    loop_body += SmiBinaryOp(Token::kADD, /*truncate=*/true);
    loop_body += StoreLocal(TokenPosition::kNoSource, index);
    loop_body += Drop();

    JoinEntryInstr* join = BuildJoinEntry();
    loop_body += Goto(join);

    Fragment loop(join);
    loop += condition;

    Instruction* entry =
        new (Z) GotoInstr(join, CompilerState::Current().GetNextDeoptId());
    body += Fragment(entry, loop_exit);
  }

  // Load receiver.
  if (is_implicit_closure_function) {
    if (throw_no_such_method_error) {
      const Function& parent =
          Function::ZoneHandle(Z, function.parent_function());
      const Class& owner = Class::ZoneHandle(Z, parent.Owner());
      AbstractType& type = AbstractType::ZoneHandle(Z);
      type = Type::New(owner, TypeArguments::Handle(Z));
      type = ClassFinalizer::FinalizeType(type);
      body += Constant(type);
    } else {
      body += LoadLocal(parsed_function_->current_context_var());
      body += LoadNativeField(Slot::GetContextVariableSlotFor(
          thread_, *parsed_function_->receiver_var()));
    }
  } else {
    body += LoadLocal(parsed_function_->ParameterVariable(0));
  }

  body += Constant(String::ZoneHandle(Z, function.name()));

  if (!parsed_function_->has_arg_desc_var()) {
    // If there is no variable for the arguments descriptor (this function's
    // signature doesn't require it), then we need to create one.
    Array& args_desc = Array::ZoneHandle(
        Z, ArgumentsDescriptor::NewBoxed(0, function.NumParameters()));
    body += Constant(args_desc);
  } else {
    body += LoadArgDescriptor();
  }

  body += LoadLocal(arguments);

  if (throw_no_such_method_error) {
    const Function& parent =
        Function::ZoneHandle(Z, function.parent_function());
    const Class& owner = Class::ZoneHandle(Z, parent.Owner());
    InvocationMirror::Level im_level = owner.IsTopLevel()
                                           ? InvocationMirror::kTopLevel
                                           : InvocationMirror::kStatic;
    InvocationMirror::Kind im_kind;
    if (function.IsImplicitGetterFunction() || function.IsGetterFunction()) {
      im_kind = InvocationMirror::kGetter;
    } else if (function.IsImplicitSetterFunction() ||
               function.IsSetterFunction()) {
      im_kind = InvocationMirror::kSetter;
    } else {
      im_kind = InvocationMirror::kMethod;
    }
    body += IntConstant(InvocationMirror::EncodeType(im_level, im_kind));
  } else {
    body += NullConstant();
  }

  // Push the number of delayed type arguments.
  if (function.IsClosureFunction()) {
    LocalVariable* closure = parsed_function_->ParameterVariable(0);
    Fragment then;
    then += IntConstant(function.NumTypeParameters());
    then += StoreLocal(TokenPosition::kNoSource, argument_count_var);
    then += Drop();
    Fragment otherwise;
    otherwise += IntConstant(0);
    otherwise += StoreLocal(TokenPosition::kNoSource, argument_count_var);
    otherwise += Drop();
    body += TestDelayedTypeArgs(closure, then, otherwise);
    body += LoadLocal(argument_count_var);
  } else {
    body += IntConstant(0);
  }

  const Class& mirror_class =
      Class::Handle(Z, Library::LookupCoreClass(Symbols::InvocationMirror()));
  ASSERT(!mirror_class.IsNull());
  const auto& error = mirror_class.EnsureIsFinalized(H.thread());
  ASSERT(error == Error::null());
  const Function& allocation_function = Function::ZoneHandle(
      Z, mirror_class.LookupStaticFunction(Library::PrivateCoreLibName(
             Symbols::AllocateInvocationMirrorForClosure())));
  ASSERT(!allocation_function.IsNull());
  body += StaticCall(TokenPosition::kMinSource, allocation_function,
                     /* argument_count = */ 5, ICData::kStatic);

  if (throw_no_such_method_error) {
    const Class& klass = Class::ZoneHandle(
        Z, Library::LookupCoreClass(Symbols::NoSuchMethodError()));
    ASSERT(!klass.IsNull());
    const auto& error = klass.EnsureIsFinalized(H.thread());
    ASSERT(error == Error::null());
    const Function& throw_function = Function::ZoneHandle(
        Z,
        klass.LookupStaticFunctionAllowPrivate(Symbols::ThrowNewInvocation()));
    ASSERT(!throw_function.IsNull());
    body += StaticCall(TokenPosition::kNoSource, throw_function, 2,
                       ICData::kStatic);
  } else {
    body += InstanceCall(
        TokenPosition::kNoSource, Symbols::NoSuchMethod(), Token::kILLEGAL,
        /*type_args_len=*/0, /*argument_count=*/2, Array::null_array(),
        /*checked_argument_count=*/1);
  }
  body += StoreLocal(TokenPosition::kNoSource, result);
  body += Drop();

  body += Drop();  // arguments
  body += Drop();  // argument count

  AbstractType& return_type = AbstractType::Handle(function.result_type());
  if (!return_type.IsTopTypeForSubtyping()) {
    body += AssertAssignableLoadTypeArguments(TokenPosition::kNoSource,
                                              return_type, Symbols::Empty());
  }
  body += Return(TokenPosition::kNoSource);

  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

Fragment FlowGraphBuilder::BuildDefaultTypeHandling(const Function& function) {
  if (function.IsGeneric()) {
    auto& default_types =
        TypeArguments::ZoneHandle(Z, function.InstantiateToBounds(thread_));

    if (!default_types.IsNull()) {
      Fragment then;
      Fragment otherwise;

      otherwise += TranslateInstantiatedTypeArguments(default_types);
      otherwise += StoreLocal(TokenPosition::kNoSource,
                              parsed_function_->function_type_arguments());
      otherwise += Drop();
      return TestAnyTypeArgs(then, otherwise);
    }
  }
  return Fragment();
}

FunctionEntryInstr* FlowGraphBuilder::BuildSharedUncheckedEntryPoint(
    Fragment shared_prologue_linked_in,
    Fragment skippable_checks,
    Fragment redefinitions_if_skipped,
    Fragment body) {
  ASSERT(shared_prologue_linked_in.entry == graph_entry_->normal_entry());
  ASSERT(parsed_function_->has_entry_points_temp_var());
  Instruction* prologue_start = shared_prologue_linked_in.entry->next();

  auto* join_entry = BuildJoinEntry();

  Fragment normal_entry(shared_prologue_linked_in.entry);
  normal_entry +=
      IntConstant(static_cast<intptr_t>(UncheckedEntryPointStyle::kNone));
  normal_entry += StoreLocal(TokenPosition::kNoSource,
                             parsed_function_->entry_points_temp_var());
  normal_entry += Drop();
  normal_entry += Goto(join_entry);

  auto* extra_target_entry = BuildFunctionEntry(graph_entry_);
  Fragment extra_entry(extra_target_entry);
  extra_entry += IntConstant(
      static_cast<intptr_t>(UncheckedEntryPointStyle::kSharedWithVariable));
  extra_entry += StoreLocal(TokenPosition::kNoSource,
                            parsed_function_->entry_points_temp_var());
  extra_entry += Drop();
  extra_entry += Goto(join_entry);

  if (prologue_start != nullptr) {
    join_entry->LinkTo(prologue_start);
  } else {
    // Prologue is empty.
    shared_prologue_linked_in.current = join_entry;
  }

  TargetEntryInstr* do_checks;
  TargetEntryInstr* skip_checks;
  shared_prologue_linked_in +=
      LoadLocal(parsed_function_->entry_points_temp_var());
  shared_prologue_linked_in += BuildEntryPointsIntrospection();
  shared_prologue_linked_in +=
      LoadLocal(parsed_function_->entry_points_temp_var());
  shared_prologue_linked_in += IntConstant(
      static_cast<intptr_t>(UncheckedEntryPointStyle::kSharedWithVariable));
  shared_prologue_linked_in +=
      BranchIfEqual(&skip_checks, &do_checks, /*negate=*/false);

  JoinEntryInstr* rest_entry = BuildJoinEntry();

  Fragment(do_checks) + skippable_checks + Goto(rest_entry);
  Fragment(skip_checks) + redefinitions_if_skipped + Goto(rest_entry);
  Fragment(rest_entry) + body;

  return extra_target_entry;
}

FunctionEntryInstr* FlowGraphBuilder::BuildSeparateUncheckedEntryPoint(
    BlockEntryInstr* normal_entry,
    Fragment normal_prologue,
    Fragment extra_prologue,
    Fragment shared_prologue,
    Fragment body) {
  auto* join_entry = BuildJoinEntry();
  auto* extra_entry = BuildFunctionEntry(graph_entry_);

  Fragment normal(normal_entry);
  normal += IntConstant(static_cast<intptr_t>(UncheckedEntryPointStyle::kNone));
  normal += BuildEntryPointsIntrospection();
  normal += normal_prologue;
  normal += Goto(join_entry);

  Fragment extra(extra_entry);
  extra +=
      IntConstant(static_cast<intptr_t>(UncheckedEntryPointStyle::kSeparate));
  extra += BuildEntryPointsIntrospection();
  extra += extra_prologue;
  extra += Goto(join_entry);

  Fragment(join_entry) + shared_prologue + body;
  return extra_entry;
}

FlowGraph* FlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
    const Function& function) {
  const Function& parent = Function::ZoneHandle(Z, function.parent_function());
  Function& target = Function::ZoneHandle(Z, function.ImplicitClosureTarget(Z));

  if (target.IsNull() ||
      (parent.num_fixed_parameters() != target.num_fixed_parameters())) {
    return BuildGraphOfNoSuchMethodForwarder(function, true,
                                             parent.is_static());
  }

  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  PrologueInfo prologue_info(-1, -1);
  BlockEntryInstr* instruction_cursor =
      BuildPrologue(normal_entry, &prologue_info);

  Fragment closure(instruction_cursor);
  closure += CheckStackOverflowInPrologue(function.token_pos());
  closure += BuildDefaultTypeHandling(function);

  // For implicit closure functions, any non-covariant checks are either
  // performed by the type system or a dynamic invocation layer (dynamic closure
  // call dispatcher, mirror, etc.). Static targets never have covariant
  // arguments, and for non-static targets, they already perform the covariant
  // checks internally. Thus, no checks are needed and we just need to invoke
  // the target with the right receiver (unless static).
  //
  // TODO(dartbug.com/44195): Consider replacing the argument pushes + static
  // call with stack manipulation and a tail call instead.

  intptr_t type_args_len = 0;
  if (function.IsGeneric()) {
    if (target.IsConstructor()) {
      const auto& result_type = AbstractType::Handle(Z, function.result_type());
      ASSERT(result_type.IsFinalized());
      // Instantiate a flattened type arguments vector which
      // includes type arguments corresponding to superclasses.
      // TranslateInstantiatedTypeArguments is smart enough to
      // avoid instantiation and resuse passed function type arguments
      // if there are no extra type arguments in the flattened vector.
      const auto& instantiated_type_arguments =
          TypeArguments::ZoneHandle(Z, result_type.arguments());
      closure +=
          TranslateInstantiatedTypeArguments(instantiated_type_arguments);
    } else {
      type_args_len = function.NumTypeParameters();
      ASSERT(parsed_function_->function_type_arguments() != NULL);
      closure += LoadLocal(parsed_function_->function_type_arguments());
    }
  } else if (target.IsFactory()) {
    // Factories always take an extra implicit argument for
    // type arguments even if their classes don't have type parameters.
    closure += NullConstant();
  }

  // Push receiver.
  if (target.IsGenerativeConstructor()) {
    const Class& cls = Class::ZoneHandle(Z, target.Owner());
    if (cls.NumTypeArguments() > 0) {
      if (!function.IsGeneric()) {
        Type& cls_type = Type::Handle(Z, cls.DeclarationType());
        closure += Constant(TypeArguments::ZoneHandle(Z, cls_type.arguments()));
      }
      closure += AllocateObject(function.token_pos(), cls, 1);
    } else {
      ASSERT(!function.IsGeneric());
      closure += AllocateObject(function.token_pos(), cls, 0);
    }
    LocalVariable* receiver = MakeTemporary();
    closure += LoadLocal(receiver);
  } else if (!target.is_static()) {
    // The context has a fixed shape: a single variable which is the
    // closed-over receiver.
    closure += LoadLocal(parsed_function_->ParameterVariable(0));
    closure += LoadNativeField(Slot::Closure_context());
    closure += LoadNativeField(Slot::GetContextVariableSlotFor(
        thread_, *parsed_function_->receiver_var()));
  }

  closure += PushExplicitParameters(function);

  // Forward parameters to the target.
  intptr_t argument_count = function.NumParameters() -
                            function.NumImplicitParameters() +
                            target.NumImplicitParameters();
  ASSERT(argument_count == target.NumParameters());

  Array& argument_names =
      Array::ZoneHandle(Z, GetOptionalParameterNames(function));

  closure += StaticCall(TokenPosition::kNoSource, target, argument_count,
                        argument_names, ICData::kNoRebind,
                        /* result_type = */ NULL, type_args_len);

  if (target.IsGenerativeConstructor()) {
    // Drop result of constructor invocation, leave receiver
    // instance on the stack.
    closure += Drop();
  }

  // Return the result.
  closure += Return(function.end_token_pos());

  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

FlowGraph* FlowGraphBuilder::BuildGraphOfFieldAccessor(
    const Function& function) {
  ASSERT(function.IsImplicitGetterOrSetter() ||
         function.IsDynamicInvocationForwarder());

  // Instead of building a dynamic invocation forwarder that checks argument
  // type and then invokes original setter we simply generate the type check
  // and inlined field store. Scope builder takes care of setting correct
  // type check mode in this case.
  const auto& target = Function::Handle(
      Z, function.IsDynamicInvocationForwarder() ? function.ForwardingTarget()
                                                 : function.ptr());
  ASSERT(target.IsImplicitGetterOrSetter());

  const bool is_method = !function.IsStaticFunction();
  const bool is_setter = target.IsImplicitSetterFunction();
  const bool is_getter = target.IsImplicitGetterFunction() ||
                         target.IsImplicitStaticGetterFunction();
  ASSERT(is_setter || is_getter);

  const auto& field = Field::ZoneHandle(Z, target.accessor_field());

  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  Fragment body(normal_entry);
  if (is_setter) {
    auto const setter_value =
        parsed_function_->ParameterVariable(is_method ? 1 : 0);
    if (is_method) {
      body += LoadLocal(parsed_function_->ParameterVariable(0));
    }
    body += LoadLocal(setter_value);

    // The dyn:* forwarder has to check the parameters that the
    // actual target will not check.
    // Though here we manually inline the target, so the dyn:* forwarder has to
    // check all parameters.
    const bool needs_type_check = function.IsDynamicInvocationForwarder() ||
                                  setter_value->needs_type_check();
    if (needs_type_check) {
      body += CheckAssignable(setter_value->type(), setter_value->name(),
                              AssertAssignableInstr::kParameterCheck,
                              field.token_pos());
    }
    body += BuildNullAssertions();
    if (field.is_late()) {
      if (is_method) {
        body += Drop();
      }
      body += Drop();
      body += StoreLateField(
          field, is_method ? parsed_function_->ParameterVariable(0) : nullptr,
          setter_value);
    } else {
      if (is_method) {
        body += StoreInstanceFieldGuarded(
            field, StoreInstanceFieldInstr::Kind::kOther);
      } else {
        body += StoreStaticField(TokenPosition::kNoSource, field);
      }
    }
    body += NullConstant();
  } else if (is_getter && is_method) {
    ASSERT(!field.needs_load_guard()
                NOT_IN_PRODUCT(|| IG->HasAttemptedReload()));
    body += LoadLocal(parsed_function_->ParameterVariable(0));
    body += LoadField(
        field, /*calls_initializer=*/field.NeedsInitializationCheckOnLoad());
    if (field.needs_load_guard()) {
#if defined(PRODUCT)
      UNREACHABLE();
#else
      body += CheckAssignable(AbstractType::Handle(Z, field.type()),
                              Symbols::FunctionResult());
#endif
    }
  } else if (field.is_const()) {
    const auto& value = Object::Handle(Z, field.StaticConstFieldValue());
    if (value.IsError()) {
      Report::LongJump(Error::Cast(value));
    }
    body += Constant(Instance::ZoneHandle(Z, Instance::RawCast(value.ptr())));
  } else {
    // Static fields
    //  - with trivial initializer
    //  - without initializer if they are not late
    // are initialized eagerly and do not have implicit getters.
    // Static fields with non-trivial initializer need getter to perform
    // lazy initialization. Late fields without initializer need getter
    // to make sure they are already initialized.
    ASSERT(field.has_nontrivial_initializer() ||
           (field.is_late() && !field.has_initializer()));
    body += LoadStaticField(field, /*calls_initializer=*/true);
    if (field.needs_load_guard()) {
#if defined(PRODUCT)
      UNREACHABLE();
#else
      ASSERT(IsolateGroup::Current()->HasAttemptedReload());
      body += CheckAssignable(AbstractType::Handle(Z, field.type()),
                              Symbols::FunctionResult());
#endif
    }
  }
  body += Return(TokenPosition::kNoSource);

  PrologueInfo prologue_info(-1, -1);
  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

FlowGraph* FlowGraphBuilder::BuildGraphOfDynamicInvocationForwarder(
    const Function& function) {
  auto& name = String::Handle(Z, function.name());
  name = Function::DemangleDynamicInvocationForwarderName(name);
  const auto& target = Function::ZoneHandle(Z, function.ForwardingTarget());
  ASSERT(!target.IsNull());

  if (target.IsImplicitSetterFunction() || target.IsImplicitGetterFunction()) {
    return BuildGraphOfFieldAccessor(function);
  }
  if (target.IsMethodExtractor()) {
    return BuildGraphOfMethodExtractor(target);
  }

  graph_entry_ = new (Z) GraphEntryInstr(*parsed_function_, osr_id_);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  PrologueInfo prologue_info(-1, -1);
  auto instruction_cursor = BuildPrologue(normal_entry, &prologue_info);

  Fragment body;
  if (!function.is_native()) {
    body += CheckStackOverflowInPrologue(function.token_pos());
  }

  ASSERT(parsed_function_->scope()->num_context_variables() == 0);

  // Should never build a dynamic invocation forwarder for equality
  // operator.
  ASSERT(function.name() != Symbols::EqualOperator().ptr());

  // Even if the caller did not pass argument vector we would still
  // call the target with instantiate-to-bounds type arguments.
  body += BuildDefaultTypeHandling(function);

  // Build argument type checks that complement those that are emitted in the
  // target.
  BuildTypeArgumentTypeChecks(
      TypeChecksToBuild::kCheckNonCovariantTypeParameterBounds, &body);
  BuildArgumentTypeChecks(&body, &body, nullptr);

  // Push all arguments and invoke the original method.

  intptr_t type_args_len = 0;
  if (function.IsGeneric()) {
    type_args_len = function.NumTypeParameters();
    ASSERT(parsed_function_->function_type_arguments() != nullptr);
    body += LoadLocal(parsed_function_->function_type_arguments());
  }

  // Push receiver.
  ASSERT(function.NumImplicitParameters() == 1);
  body += LoadLocal(parsed_function_->receiver_var());
  body += PushExplicitParameters(function, target);

  const intptr_t argument_count = function.NumParameters();
  const auto& argument_names =
      Array::ZoneHandle(Z, GetOptionalParameterNames(function));

  body += StaticCall(TokenPosition::kNoSource, target, argument_count,
                     argument_names, ICData::kNoRebind, nullptr, type_args_len);

  if (target.has_unboxed_integer_return()) {
    body += Box(kUnboxedInt64);
  } else if (target.has_unboxed_double_return()) {
    body += Box(kUnboxedDouble);
  }

  // Later optimization passes assume that result of a x.[]=(...) call is not
  // used. We must guarantee this invariant because violation will lead to an
  // illegal IL once we replace x.[]=(...) with a sequence that does not
  // actually produce any value. See http://dartbug.com/29135 for more details.
  if (name.ptr() == Symbols::AssignIndexToken().ptr()) {
    body += Drop();
    body += NullConstant();
  }

  body += Return(TokenPosition::kNoSource);

  instruction_cursor->LinkTo(body.entry);

  // When compiling for OSR, use a depth first search to find the OSR
  // entry and make graph entry jump to it instead of normal entry.
  // Catch entries are always considered reachable, even if they
  // become unreachable after OSR.
  if (IsCompiledForOsr()) {
    graph_entry_->RelinkToOsrEntry(Z, last_used_block_id_ + 1);
  }
  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

void FlowGraphBuilder::SetConstantRangeOfCurrentDefinition(
    const Fragment& fragment,
    int64_t min,
    int64_t max) {
  ASSERT(fragment.current->IsDefinition());
  Range range(RangeBoundary::FromConstant(min),
              RangeBoundary::FromConstant(max));
  fragment.current->AsDefinition()->set_range(range);
}

static classid_t TypedDataCidUnboxed(Representation unboxed_representation) {
  switch (unboxed_representation) {
    case kUnboxedFloat:
      // Note kTypedDataFloat32ArrayCid loads kUnboxedDouble.
      UNREACHABLE();
      return kTypedDataFloat32ArrayCid;
    case kUnboxedInt32:
      return kTypedDataInt32ArrayCid;
    case kUnboxedUint32:
      return kTypedDataUint32ArrayCid;
    case kUnboxedInt64:
      return kTypedDataInt64ArrayCid;
    case kUnboxedDouble:
      return kTypedDataFloat64ArrayCid;
    default:
      UNREACHABLE();
  }
  UNREACHABLE();
}

Fragment FlowGraphBuilder::StoreIndexedTypedDataUnboxed(
    Representation unboxed_representation,
    intptr_t index_scale,
    bool index_unboxed) {
  ASSERT(unboxed_representation == kUnboxedInt32 ||
         unboxed_representation == kUnboxedUint32 ||
         unboxed_representation == kUnboxedInt64 ||
         unboxed_representation == kUnboxedFloat ||
         unboxed_representation == kUnboxedDouble);
  Fragment fragment;
  if (unboxed_representation == kUnboxedFloat) {
    fragment += BitCast(kUnboxedFloat, kUnboxedInt32);
    unboxed_representation = kUnboxedInt32;
  }
  fragment += StoreIndexedTypedData(TypedDataCidUnboxed(unboxed_representation),
                                    index_scale, index_unboxed);
  return fragment;
}

Fragment FlowGraphBuilder::LoadIndexedTypedDataUnboxed(
    Representation unboxed_representation,
    intptr_t index_scale,
    bool index_unboxed) {
  ASSERT(unboxed_representation == kUnboxedInt32 ||
         unboxed_representation == kUnboxedUint32 ||
         unboxed_representation == kUnboxedInt64 ||
         unboxed_representation == kUnboxedFloat ||
         unboxed_representation == kUnboxedDouble);
  Representation representation_for_load = unboxed_representation;
  if (unboxed_representation == kUnboxedFloat) {
    representation_for_load = kUnboxedInt32;
  }
  Fragment fragment;
  fragment += LoadIndexed(TypedDataCidUnboxed(representation_for_load),
                          index_scale, index_unboxed);
  if (unboxed_representation == kUnboxedFloat) {
    fragment += BitCast(kUnboxedInt32, kUnboxedFloat);
  }
  return fragment;
}

Fragment FlowGraphBuilder::EnterHandleScope() {
  Fragment body;
  body += LoadThread();
  body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);  // argument.

  // LoadThread again, we can't store it in a temp because it will end up
  // in the environment of the FfiCall as untagged then.
  body += LoadThread();
  body += LoadUntagged(compiler::target::Thread::OffsetFromThread(
      &kEnterHandleScopeRuntimeEntry));
  body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);  // function address.

  body += CCall(/*num_arguments=*/1);

  return body;
}

Fragment FlowGraphBuilder::GetTopHandleScope() {
  Fragment body;
  body += LoadThread();
  body += LoadUntagged(compiler::target::Thread::api_top_scope_offset());
  body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
  return body;
}

Fragment FlowGraphBuilder::ExitHandleScope() {
  Fragment code;
  code += LoadThread();
  code += ConvertUntaggedToUnboxed(kUnboxedIntPtr);  // argument.

  code += LoadThread();
  code += LoadUntagged(compiler::target::Thread::OffsetFromThread(
      &kExitHandleScopeRuntimeEntry));
  code += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);  // function address.

  code += CCall(/*num_arguments=*/1);

  code += Drop();
  return code;
}

Fragment FlowGraphBuilder::AllocateHandle() {
  Fragment code;
  // Get a reference to the top handle scope.
  code += GetTopHandleScope();

  code += LoadThread();
  code += LoadUntagged(
      compiler::target::Thread::OffsetFromThread(&kAllocateHandleRuntimeEntry));
  code += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);  // function address.

  code += CCall(/*num_arguments=*/1);

  return code;
}

Fragment FlowGraphBuilder::RawLoadField(int32_t offset) {
  Fragment code;
  code += UnboxedIntConstant(offset, kUnboxedIntPtr);
  code += LoadIndexed(kArrayCid, /*index_scale=*/1, /*index_unboxed=*/true);
  return code;
}

Fragment FlowGraphBuilder::RawStoreField(int32_t offset) {
  Fragment code;
  Value* value = Pop();
  Value* base = Pop();
  auto* instr = new (Z) RawStoreFieldInstr(base, value, offset);
  code <<= instr;
  return code;
}

Fragment FlowGraphBuilder::WrapHandle() {
  Fragment code;
  LocalVariable* object = MakeTemporary();
  code += AllocateHandle();

  code += LoadLocal(MakeTemporary());  // Duplicate handle pointer.
  code += ConvertUnboxedToUntagged(kUnboxedIntPtr);
  code += LoadLocal(object);
  code += RawStoreField(compiler::target::LocalHandle::ptr_offset());

  code += DropTempsPreserveTop(1);  // Drop object below handle.
  return code;
}

Fragment FlowGraphBuilder::UnwrapHandle() {
  Fragment code;
  code += ConvertUnboxedToUntagged(kUnboxedIntPtr);
  code += RawLoadField(compiler::target::LocalHandle::ptr_offset());
  return code;
}

Fragment FlowGraphBuilder::UnhandledException() {
  const auto class_table = thread_->isolate_group()->class_table();
  ASSERT(class_table->HasValidClassAt(kUnhandledExceptionCid));
  const auto& klass =
      Class::ZoneHandle(H.zone(), class_table->At(kUnhandledExceptionCid));
  ASSERT(!klass.IsNull());
  Fragment body;
  body += AllocateObject(TokenPosition::kNoSource, klass, 0);
  LocalVariable* error_instance = MakeTemporary();

  body += LoadLocal(error_instance);
  body += LoadLocal(CurrentException());
  body += StoreNativeField(Slot::UnhandledException_exception(),
                           StoreInstanceFieldInstr::Kind::kInitializing,
                           kNoStoreBarrier);

  body += LoadLocal(error_instance);
  body += LoadLocal(CurrentStackTrace());
  body += StoreNativeField(Slot::UnhandledException_stacktrace(),
                           StoreInstanceFieldInstr::Kind::kInitializing,
                           kNoStoreBarrier);

  return body;
}

Fragment FlowGraphBuilder::UnboxTruncate(Representation to) {
  auto* unbox = UnboxInstr::Create(to, Pop(), DeoptId::kNone,
                                   Instruction::kNotSpeculative);
  Push(unbox);
  return Fragment(unbox);
}

Fragment FlowGraphBuilder::LoadThread() {
  LoadThreadInstr* instr = new (Z) LoadThreadInstr();
  Push(instr);
  return Fragment(instr);
}

Fragment FlowGraphBuilder::LoadIsolate() {
  Fragment body;
  body += LoadThread();
  body += LoadUntagged(compiler::target::Thread::isolate_offset());
  return body;
}

Fragment FlowGraphBuilder::LoadServiceExtensionStream() {
  Fragment body;
  body += LoadThread();
  body +=
      LoadUntagged(compiler::target::Thread::service_extension_stream_offset());
  return body;
}

// TODO(http://dartbug.com/47487): Support unboxed output value.
Fragment FlowGraphBuilder::BoolToInt() {
  // TODO(http://dartbug.com/36855) Build IfThenElseInstr, instead of letting
  // the optimizer turn this into that.

  LocalVariable* expression_temp = parsed_function_->expression_temp_var();

  Fragment instructions;
  TargetEntryInstr* is_true;
  TargetEntryInstr* is_false;

  instructions += BranchIfTrue(&is_true, &is_false);
  JoinEntryInstr* join = BuildJoinEntry();

  {
    Fragment store_1(is_true);
    store_1 += IntConstant(1);
    store_1 += StoreLocal(TokenPosition::kNoSource, expression_temp);
    store_1 += Drop();
    store_1 += Goto(join);
  }

  {
    Fragment store_0(is_false);
    store_0 += IntConstant(0);
    store_0 += StoreLocal(TokenPosition::kNoSource, expression_temp);
    store_0 += Drop();
    store_0 += Goto(join);
  }

  instructions = Fragment(instructions.entry, join);
  instructions += LoadLocal(expression_temp);
  return instructions;
}

Fragment FlowGraphBuilder::IntToBool() {
  Fragment body;
  body += IntConstant(0);
  body += StrictCompare(Token::kNE_STRICT);
  return body;
}

Fragment FlowGraphBuilder::NativeReturn(
    const compiler::ffi::CallbackMarshaller& marshaller) {
  auto* instr = new (Z)
      NativeReturnInstr(InstructionSource(), Pop(), marshaller, DeoptId::kNone);
  return Fragment(instr).closed();
}

Fragment FlowGraphBuilder::FfiPointerFromAddress(const Type& result_type) {
  LocalVariable* address = MakeTemporary();
  LocalVariable* result = parsed_function_->expression_temp_var();

  Class& result_class = Class::ZoneHandle(Z, result_type.type_class());
  // This class might only be instantiated as a return type of ffi calls.
  result_class.EnsureIsFinalized(thread_);

  TypeArguments& args = TypeArguments::ZoneHandle(Z, result_type.arguments());

  // A kernel transform for FFI in the front-end ensures that type parameters
  // do not appear in the type arguments to a any Pointer classes in an FFI
  // signature.
  ASSERT(args.IsNull() || args.IsInstantiated());
  args = args.Canonicalize(thread_, nullptr);

  Fragment code;
  code += Constant(args);
  code += AllocateObject(TokenPosition::kNoSource, result_class, 1);
  LocalVariable* pointer = MakeTemporary();
  code += LoadLocal(pointer);
  code += LoadLocal(address);
  code += UnboxTruncate(kUnboxedIntPtr);
  code += StoreNativeField(Slot::PointerBase_data());
  code += StoreLocal(TokenPosition::kNoSource, result);
  code += Drop();  // StoreLocal^
  code += Drop();  // address
  code += LoadLocal(result);

  return code;
}

Fragment FlowGraphBuilder::BitCast(Representation from, Representation to) {
  BitCastInstr* instr = new (Z) BitCastInstr(from, to, Pop());
  Push(instr);
  return Fragment(instr);
}

Fragment FlowGraphBuilder::Call1ArgStub(TokenPosition position,
                                        Call1ArgStubInstr::StubId stub_id) {
  Call1ArgStubInstr* instr = new (Z) Call1ArgStubInstr(
      InstructionSource(position), stub_id, Pop(), GetNextDeoptId());
  Push(instr);
  return Fragment(instr);
}

Fragment FlowGraphBuilder::Suspend(TokenPosition position,
                                   SuspendInstr::StubId stub_id) {
  SuspendInstr* instr =
      new (Z) SuspendInstr(InstructionSource(position), stub_id, Pop(),
                           GetNextDeoptId(), GetNextDeoptId());
  Push(instr);
  return Fragment(instr);
}

Fragment FlowGraphBuilder::WrapTypedDataBaseInCompound(
    const AbstractType& compound_type) {
  const auto& compound_sub_class =
      Class::ZoneHandle(Z, compound_type.type_class());
  compound_sub_class.EnsureIsFinalized(thread_);
  const auto& lib_ffi = Library::Handle(Z, Library::FfiLibrary());
  const auto& compound_class =
      Class::Handle(Z, lib_ffi.LookupClassAllowPrivate(Symbols::Compound()));
  const auto& compound_typed_data_base =
      Field::ZoneHandle(Z, compound_class.LookupInstanceFieldAllowPrivate(
                               Symbols::_typedDataBase()));
  ASSERT(!compound_typed_data_base.IsNull());

  Fragment body;
  LocalVariable* typed_data = MakeTemporary("typed_data_base");
  body += AllocateObject(TokenPosition::kNoSource, compound_sub_class, 0);
  body += LoadLocal(MakeTemporary("compound"));  // Duplicate Struct or Union.
  body += LoadLocal(typed_data);
  body += StoreInstanceField(compound_typed_data_base,
                             StoreInstanceFieldInstr::Kind::kInitializing);
  body += DropTempsPreserveTop(1);  // Drop TypedData.
  return body;
}

Fragment FlowGraphBuilder::LoadTypedDataBaseFromCompound() {
  const auto& lib_ffi = Library::Handle(Z, Library::FfiLibrary());
  const auto& compound_class =
      Class::Handle(Z, lib_ffi.LookupClassAllowPrivate(Symbols::Compound()));
  const auto& compound_typed_data_base =
      Field::ZoneHandle(Z, compound_class.LookupInstanceFieldAllowPrivate(
                               Symbols::_typedDataBase()));
  ASSERT(!compound_typed_data_base.IsNull());

  Fragment body;
  body += LoadField(compound_typed_data_base, /*calls_initializer=*/false);
  return body;
}

Fragment FlowGraphBuilder::CopyFromCompoundToStack(
    LocalVariable* variable,
    const GrowableArray<Representation>& representations) {
  Fragment body;
  const intptr_t num_defs = representations.length();
  int offset_in_bytes = 0;
  for (intptr_t i = 0; i < num_defs; i++) {
    body += LoadLocal(variable);
    body += LoadTypedDataBaseFromCompound();
    body += LoadUntagged(compiler::target::PointerBase::data_offset());
    body += IntConstant(offset_in_bytes);
    const Representation representation = representations[i];
    offset_in_bytes += RepresentationUtils::ValueSize(representation);
    body += LoadIndexedTypedDataUnboxed(representation, /*index_scale=*/1,
                                        /*index_unboxed=*/false);
  }
  return body;
}

Fragment FlowGraphBuilder::PopFromStackToTypedDataBase(
    ZoneGrowableArray<LocalVariable*>* definitions,
    const GrowableArray<Representation>& representations) {
  Fragment body;
  const intptr_t num_defs = representations.length();
  ASSERT(definitions->length() == num_defs);

  LocalVariable* uint8_list = MakeTemporary("uint8_list");
  int offset_in_bytes = 0;
  for (intptr_t i = 0; i < num_defs; i++) {
    const Representation representation = representations[i];
    body += LoadLocal(uint8_list);
    body += LoadUntagged(compiler::target::PointerBase::data_offset());
    body += IntConstant(offset_in_bytes);
    body += LoadLocal(definitions->At(i));
    body += StoreIndexedTypedDataUnboxed(representation, /*index_scale=*/1,
                                         /*index_unboxed=*/false);
    offset_in_bytes += RepresentationUtils::ValueSize(representation);
  }
  body += DropTempsPreserveTop(num_defs);  // Drop chunck defs keep TypedData.
  return body;
}

static intptr_t chunk_size(intptr_t bytes_left) {
  ASSERT(bytes_left >= 1);
  if (bytes_left >= 8 && compiler::target::kWordSize == 8) {
    return 8;
  }
  if (bytes_left >= 4) {
    return 4;
  }
  if (bytes_left >= 2) {
    return 2;
  }
  return 1;
}

static classid_t typed_data_cid(intptr_t chunk_size) {
  switch (chunk_size) {
    case 8:
      return kTypedDataInt64ArrayCid;
    case 4:
      return kTypedDataInt32ArrayCid;
    case 2:
      return kTypedDataInt16ArrayCid;
    case 1:
      return kTypedDataInt8ArrayCid;
  }
  UNREACHABLE();
}

Fragment FlowGraphBuilder::CopyFromTypedDataBaseToUnboxedAddress(
    intptr_t length_in_bytes) {
  Fragment body;
  Value* unboxed_address_value = Pop();
  LocalVariable* typed_data_base = MakeTemporary("typed_data_base");
  Push(unboxed_address_value->definition());
  LocalVariable* unboxed_address = MakeTemporary("unboxed_address");

  intptr_t offset_in_bytes = 0;
  while (offset_in_bytes < length_in_bytes) {
    const intptr_t bytes_left = length_in_bytes - offset_in_bytes;
    const intptr_t chunk_sizee = chunk_size(bytes_left);
    const classid_t typed_data_cidd = typed_data_cid(chunk_sizee);

    body += LoadLocal(typed_data_base);
    body += LoadUntagged(compiler::target::PointerBase::data_offset());
    body += IntConstant(offset_in_bytes);
    body += LoadIndexed(typed_data_cidd, /*index_scale=*/1,
                        /*index_unboxed=*/false);
    LocalVariable* chunk_value = MakeTemporary("chunk_value");

    body += LoadLocal(unboxed_address);
    body += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
    body += IntConstant(offset_in_bytes);
    body += LoadLocal(chunk_value);
    body += StoreIndexedTypedData(typed_data_cidd, /*index_scale=*/1,
                                  /*index_unboxed=*/false);
    body += DropTemporary(&chunk_value);

    offset_in_bytes += chunk_sizee;
  }
  ASSERT(offset_in_bytes == length_in_bytes);

  body += DropTemporary(&unboxed_address);
  body += DropTemporary(&typed_data_base);
  return body;
}

Fragment FlowGraphBuilder::CopyFromUnboxedAddressToTypedDataBase(
    intptr_t length_in_bytes) {
  Fragment body;
  Value* typed_data_base_value = Pop();
  LocalVariable* unboxed_address = MakeTemporary("unboxed_address");
  Push(typed_data_base_value->definition());
  LocalVariable* typed_data_base = MakeTemporary("typed_data_base");

  intptr_t offset_in_bytes = 0;
  while (offset_in_bytes < length_in_bytes) {
    const intptr_t bytes_left = length_in_bytes - offset_in_bytes;
    const intptr_t chunk_sizee = chunk_size(bytes_left);
    const classid_t typed_data_cidd = typed_data_cid(chunk_sizee);

    body += LoadLocal(unboxed_address);
    body += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
    body += IntConstant(offset_in_bytes);
    body += LoadIndexed(typed_data_cidd, /*index_scale=*/1,
                        /*index_unboxed=*/false);
    LocalVariable* chunk_value = MakeTemporary("chunk_value");

    body += LoadLocal(typed_data_base);
    body += LoadUntagged(compiler::target::PointerBase::data_offset());
    body += IntConstant(offset_in_bytes);
    body += LoadLocal(chunk_value);
    body += StoreIndexedTypedData(typed_data_cidd, /*index_scale=*/1,
                                  /*index_unboxed=*/false);
    body += DropTemporary(&chunk_value);

    offset_in_bytes += chunk_sizee;
  }
  ASSERT(offset_in_bytes == length_in_bytes);

  body += DropTemporary(&typed_data_base);
  body += DropTemporary(&unboxed_address);
  return body;
}

Fragment FlowGraphBuilder::FfiCallConvertCompoundArgumentToNative(
    LocalVariable* variable,
    const compiler::ffi::BaseMarshaller& marshaller,
    intptr_t arg_index) {
  Fragment body;
  const auto& native_loc = marshaller.Location(arg_index);
  if (native_loc.IsStack() || native_loc.IsMultiple()) {
    // Break struct in pieces to separate IL definitions to pass those
    // separate definitions into the FFI call.
    GrowableArray<Representation> representations;
    marshaller.RepsInFfiCall(arg_index, &representations);
    body += CopyFromCompoundToStack(variable, representations);
  } else {
    ASSERT(native_loc.IsPointerToMemory());
    // Only load the typed data, do copying in the FFI call machine code.
    body += LoadLocal(variable);  // User-defined struct.
    body += LoadTypedDataBaseFromCompound();
  }
  return body;
}

Fragment FlowGraphBuilder::FfiCallConvertCompoundReturnToDart(
    const compiler::ffi::BaseMarshaller& marshaller,
    intptr_t arg_index) {
  Fragment body;
  // The typed data is allocated before the FFI call, and is populated in
  // machine code. So, here, it only has to be wrapped in the struct class.
  const auto& compound_type =
      AbstractType::Handle(Z, marshaller.CType(arg_index));
  body += WrapTypedDataBaseInCompound(compound_type);
  return body;
}

Fragment FlowGraphBuilder::FfiCallbackConvertCompoundArgumentToDart(
    const compiler::ffi::BaseMarshaller& marshaller,
    intptr_t arg_index,
    ZoneGrowableArray<LocalVariable*>* definitions) {
  const intptr_t length_in_bytes =
      marshaller.Location(arg_index).payload_type().SizeInBytes();

  Fragment body;
  if ((marshaller.Location(arg_index).IsMultiple() ||
       marshaller.Location(arg_index).IsStack())) {
    // Allocate and populate a TypedData from the individual NativeParameters.
    body += IntConstant(length_in_bytes);
    body +=
        AllocateTypedData(TokenPosition::kNoSource, kTypedDataUint8ArrayCid);
    GrowableArray<Representation> representations;
    marshaller.RepsInFfiCall(arg_index, &representations);
    body += PopFromStackToTypedDataBase(definitions, representations);
  } else {
    ASSERT(marshaller.Location(arg_index).IsPointerToMemory());
    // Allocate a TypedData and copy contents pointed to by an address into it.
    LocalVariable* address_of_compound = MakeTemporary("address_of_compound");
    body += IntConstant(length_in_bytes);
    body +=
        AllocateTypedData(TokenPosition::kNoSource, kTypedDataUint8ArrayCid);
    LocalVariable* typed_data_base = MakeTemporary("typed_data_base");
    body += LoadLocal(address_of_compound);
    body += LoadLocal(typed_data_base);
    body += CopyFromUnboxedAddressToTypedDataBase(length_in_bytes);
    body += DropTempsPreserveTop(1);  // address_of_compound.
  }
  // Wrap typed data in compound class.
  const auto& compound_type =
      AbstractType::Handle(Z, marshaller.CType(arg_index));
  body += WrapTypedDataBaseInCompound(compound_type);
  return body;
}

Fragment FlowGraphBuilder::FfiCallbackConvertCompoundReturnToNative(
    const compiler::ffi::CallbackMarshaller& marshaller,
    intptr_t arg_index) {
  Fragment body;
  const auto& native_loc = marshaller.Location(arg_index);
  if (native_loc.IsMultiple()) {
    // We pass in typed data to native return instruction, and do the copying
    // in machine code.
    body += LoadTypedDataBaseFromCompound();
  } else {
    ASSERT(native_loc.IsPointerToMemory());
    // We copy the data into the right location in IL.
    const intptr_t length_in_bytes =
        marshaller.Location(arg_index).payload_type().SizeInBytes();

    body += LoadTypedDataBaseFromCompound();
    LocalVariable* typed_data_base = MakeTemporary("typed_data_base");

    auto* pointer_to_return =
        new (Z) NativeParameterInstr(marshaller, compiler::ffi::kResultIndex);
    Push(pointer_to_return);  // Address where return value should be stored.
    body <<= pointer_to_return;
    body += UnboxTruncate(kUnboxedFfiIntPtr);
    LocalVariable* unboxed_address = MakeTemporary("unboxed_address");

    body += LoadLocal(typed_data_base);
    body += LoadLocal(unboxed_address);
    body += CopyFromTypedDataBaseToUnboxedAddress(length_in_bytes);
    body += DropTempsPreserveTop(1);  // Keep address, drop typed_data_base.
  }
  return body;
}

Fragment FlowGraphBuilder::FfiConvertPrimitiveToDart(
    const compiler::ffi::BaseMarshaller& marshaller,
    intptr_t arg_index) {
  ASSERT(!marshaller.IsCompound(arg_index));

  Fragment body;
  if (marshaller.IsPointer(arg_index)) {
    body += Box(kUnboxedFfiIntPtr);
    body += FfiPointerFromAddress(
        Type::CheckedHandle(Z, marshaller.CType(arg_index)));
  } else if (marshaller.IsHandle(arg_index)) {
    body += UnwrapHandle();
  } else if (marshaller.IsVoid(arg_index)) {
    body += Drop();
    body += NullConstant();
  } else {
    if (marshaller.RequiresBitCast(arg_index)) {
      body += BitCast(
          marshaller.RepInFfiCall(marshaller.FirstDefinitionIndex(arg_index)),
          marshaller.RepInDart(arg_index));
    }

    body += Box(marshaller.RepInDart(arg_index));

    if (marshaller.IsBool(arg_index)) {
      body += IntToBool();
    }
  }
  return body;
}

Fragment FlowGraphBuilder::FfiConvertPrimitiveToNative(
    const compiler::ffi::BaseMarshaller& marshaller,
    intptr_t arg_index) {
  ASSERT(!marshaller.IsCompound(arg_index));

  Fragment body;
  if (marshaller.IsPointer(arg_index)) {
    // This can only be Pointer, so it is always safe to LoadUntagged.
    body += LoadUntagged(compiler::target::PointerBase::data_offset());
    body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
  } else if (marshaller.IsHandle(arg_index)) {
    body += WrapHandle();
  } else {
    if (marshaller.IsBool(arg_index)) {
      body += BoolToInt();
    }

    body += UnboxTruncate(marshaller.RepInDart(arg_index));
  }

  if (marshaller.RequiresBitCast(arg_index)) {
    body += BitCast(
        marshaller.RepInDart(arg_index),
        marshaller.RepInFfiCall(marshaller.FirstDefinitionIndex(arg_index)));
  }

  return body;
}

FlowGraph* FlowGraphBuilder::BuildGraphOfFfiTrampoline(
    const Function& function) {
  if (function.FfiCallbackTarget() != Function::null()) {
    return BuildGraphOfFfiCallback(function);
  } else {
    return BuildGraphOfFfiNative(function);
  }
}

FlowGraph* FlowGraphBuilder::BuildGraphOfFfiNative(const Function& function) {
  const intptr_t kClosureParameterOffset = 0;
  const intptr_t kFirstArgumentParameterOffset = kClosureParameterOffset + 1;

  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto normal_entry = BuildFunctionEntry(graph_entry_);
  graph_entry_->set_normal_entry(normal_entry);

  PrologueInfo prologue_info(-1, -1);

  BlockEntryInstr* instruction_cursor =
      BuildPrologue(normal_entry, &prologue_info);

  Fragment function_body(instruction_cursor);
  function_body += CheckStackOverflowInPrologue(function.token_pos());

  const char* error = nullptr;
  const auto marshaller_ptr =
      compiler::ffi::CallMarshaller::FromFunction(Z, function, &error);
  // AbiSpecific integers can be incomplete causing us to not know the calling
  // convention. However, this is caught in asFunction in both JIT/AOT.
  RELEASE_ASSERT(error == nullptr);
  RELEASE_ASSERT(marshaller_ptr != nullptr);
  const auto& marshaller = *marshaller_ptr;

  const bool signature_contains_handles = marshaller.ContainsHandles();

  // FFI trampolines are accessed via closures, so non-covariant argument types
  // and type arguments are either statically checked by the type system or
  // dynamically checked via dynamic closure call dispatchers.

  // Null check arguments before we go into the try catch, so that we don't
  // catch our own null errors.
  const intptr_t num_args = marshaller.num_args();
  for (intptr_t i = 0; i < num_args; i++) {
    if (marshaller.IsHandle(i)) {
      continue;
    }
    function_body += LoadLocal(
        parsed_function_->ParameterVariable(kFirstArgumentParameterOffset + i));
    // TODO(http://dartbug.com/47486): Support entry without checking for null.
    // Check for 'null'.
    function_body += CheckNullOptimized(
        String::ZoneHandle(
            Z, function.ParameterNameAt(kFirstArgumentParameterOffset + i)),
        CheckNullInstr::kArgumentError);
    function_body += StoreLocal(
        TokenPosition::kNoSource,
        parsed_function_->ParameterVariable(kFirstArgumentParameterOffset + i));
    function_body += Drop();
  }

  Fragment body;
  intptr_t try_handler_index = -1;
  if (signature_contains_handles) {
    // Wrap in Try catch to transition from Native to Generated on a throw from
    // the dart_api.
    try_handler_index = AllocateTryIndex();
    body += TryCatch(try_handler_index);
    ++try_depth_;
    // TODO(dartbug.com/48989): Remove scope for calls where we don't actually
    // need it.
    // We no longer need the scope for passing in Handle arguments, but the
    // native function might for instance be relying on this scope for Dart API.
    body += EnterHandleScope();
  }

  // Allocate typed data before FfiCall and pass it in to ffi call if needed.
  LocalVariable* typed_data = nullptr;
  if (marshaller.PassTypedData()) {
    body += IntConstant(marshaller.TypedDataSizeInBytes());
    body +=
        AllocateTypedData(TokenPosition::kNoSource, kTypedDataUint8ArrayCid);
    typed_data = MakeTemporary();
  }

  // Unbox and push the arguments.
  for (intptr_t i = 0; i < marshaller.num_args(); i++) {
    if (marshaller.IsCompound(i)) {
      body += FfiCallConvertCompoundArgumentToNative(
          parsed_function_->ParameterVariable(kFirstArgumentParameterOffset +
                                              i),
          marshaller, i);
    } else {
      body += LoadLocal(parsed_function_->ParameterVariable(
          kFirstArgumentParameterOffset + i));
      // FfiCallInstr specifies all handle locations as Stack, and will pass a
      // pointer to the stack slot as the native handle argument.
      // Therefore we do not need to wrap handles.
      if (!marshaller.IsHandle(i)) {
        body += FfiConvertPrimitiveToNative(marshaller, i);
      }
    }
  }

  // Push the function pointer, which is stored (as Pointer object) in the
  // first slot of the context.
  body +=
      LoadLocal(parsed_function_->ParameterVariable(kClosureParameterOffset));
  body += LoadNativeField(Slot::Closure_context());
  body += LoadNativeField(Slot::GetContextVariableSlotFor(
      thread_, *MakeImplicitClosureScope(
                    Z, Class::Handle(IG->object_store()->ffi_pointer_class()))
                    ->context_variables()[0]));

  // This can only be Pointer, so it is always safe to LoadUntagged.
  body += LoadUntagged(compiler::target::PointerBase::data_offset());
  body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);

  if (marshaller.PassTypedData()) {
    body += LoadLocal(typed_data);
  }

  body += FfiCall(marshaller);

  for (intptr_t i = 0; i < marshaller.num_args(); i++) {
    if (marshaller.IsPointer(i)) {
      body += LoadLocal(parsed_function_->ParameterVariable(
          kFirstArgumentParameterOffset + i));
      body += ReachabilityFence();
    }
  }

  const intptr_t num_defs = marshaller.NumReturnDefinitions();
  ASSERT(num_defs >= 1);
  auto defs = new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_defs);
  LocalVariable* def = MakeTemporary();
  defs->Add(def);

  if (marshaller.PassTypedData()) {
    // Drop call result, typed data with contents is already on the stack.
    body += Drop();
  }

  if (marshaller.IsCompound(compiler::ffi::kResultIndex)) {
    body += FfiCallConvertCompoundReturnToDart(marshaller,
                                               compiler::ffi::kResultIndex);
  } else {
    body += FfiConvertPrimitiveToDart(marshaller, compiler::ffi::kResultIndex);
  }

  if (signature_contains_handles) {
    // TODO(dartbug.com/48989): Remove scope for calls where we don't actually
    // need it.
    body += DropTempsPreserveTop(1);  // Drop api_local_scope.
    body += ExitHandleScope();
  }

  body += Return(TokenPosition::kNoSource);

  if (signature_contains_handles) {
    --try_depth_;
  }

  function_body += body;

  if (signature_contains_handles) {
    ++catch_depth_;
    Fragment catch_body =
        CatchBlockEntry(Array::empty_array(), try_handler_index,
                        /*needs_stacktrace=*/true, /*is_synthesized=*/true);

    // TODO(dartbug.com/48989): Remove scope for calls where we don't actually
    // need it.
    // TODO(41984): If we want to pass in the handle scope, move it out
    // of the try catch.
    catch_body += ExitHandleScope();

    catch_body += LoadLocal(CurrentException());
    catch_body += LoadLocal(CurrentStackTrace());
    catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index);
    --catch_depth_;
  }

  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

FlowGraph* FlowGraphBuilder::BuildGraphOfFfiCallback(const Function& function) {
  const char* error = nullptr;
  const auto marshaller_ptr =
      compiler::ffi::CallbackMarshaller::FromFunction(Z, function, &error);
  // AbiSpecific integers can be incomplete causing us to not know the calling
  // convention. However, this is caught fromFunction in both JIT/AOT.
  RELEASE_ASSERT(error == nullptr);
  RELEASE_ASSERT(marshaller_ptr != nullptr);
  const auto& marshaller = *marshaller_ptr;

  graph_entry_ =
      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);

  auto* const native_entry = new (Z) NativeEntryInstr(
      marshaller, graph_entry_, AllocateBlockId(), CurrentTryIndex(),
      GetNextDeoptId(), function.FfiCallbackId());

  graph_entry_->set_normal_entry(native_entry);

  Fragment function_body(native_entry);
  function_body += CheckStackOverflowInPrologue(function.token_pos());

  // Wrap the entire method in a big try/catch. This is important to ensure that
  // the VM does not crash if the callback throws an exception.
  const intptr_t try_handler_index = AllocateTryIndex();
  Fragment body = TryCatch(try_handler_index);
  ++try_depth_;

  // Box and push the arguments.
  for (intptr_t i = 0; i < marshaller.num_args(); i++) {
    const intptr_t num_defs = marshaller.NumDefinitions(i);
    auto defs = new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_defs);

    for (intptr_t j = 0; j < num_defs; j++) {
      const intptr_t def_index = marshaller.DefinitionIndex(j, i);
      auto* parameter = new (Z) NativeParameterInstr(marshaller, def_index);
      Push(parameter);
      body <<= parameter;
      LocalVariable* def = MakeTemporary();
      defs->Add(def);
    }

    if (marshaller.IsCompound(i)) {
      body += FfiCallbackConvertCompoundArgumentToDart(marshaller, i, defs);
    } else {
      body += FfiConvertPrimitiveToDart(marshaller, i);
    }
  }

  // Call the target.
  //
  // TODO(36748): Determine the hot-reload semantics of callbacks and update the
  // rebind-rule accordingly.
  body += StaticCall(TokenPosition::kNoSource,
                     Function::ZoneHandle(Z, function.FfiCallbackTarget()),
                     marshaller.num_args(), Array::empty_array(),
                     ICData::kNoRebind);
  if (marshaller.IsVoid(compiler::ffi::kResultIndex)) {
    body += Drop();
    body += IntConstant(0);
  } else if (!marshaller.IsHandle(compiler::ffi::kResultIndex)) {
    body +=
        CheckNullOptimized(String::ZoneHandle(Z, String::New("return_value")),
                           CheckNullInstr::kArgumentError);
  }

  if (marshaller.IsCompound(compiler::ffi::kResultIndex)) {
    body += FfiCallbackConvertCompoundReturnToNative(
        marshaller, compiler::ffi::kResultIndex);
  } else {
    body +=
        FfiConvertPrimitiveToNative(marshaller, compiler::ffi::kResultIndex);
  }

  body += NativeReturn(marshaller);

  --try_depth_;
  function_body += body;

  ++catch_depth_;
  Fragment catch_body = CatchBlockEntry(Array::empty_array(), try_handler_index,
                                        /*needs_stacktrace=*/false,
                                        /*is_synthesized=*/true);

  // Return the "exceptional return" value given in 'fromFunction'.
  //
  // For pointer and void return types, the exceptional return is always null --
  // return 0 instead.
  if (marshaller.IsPointer(compiler::ffi::kResultIndex) ||
      marshaller.IsVoid(compiler::ffi::kResultIndex)) {
    ASSERT(function.FfiCallbackExceptionalReturn() == Object::null());
    catch_body += UnboxedIntConstant(0, kUnboxedFfiIntPtr);
  } else if (marshaller.IsHandle(compiler::ffi::kResultIndex)) {
    catch_body += UnhandledException();
    catch_body +=
        FfiConvertPrimitiveToNative(marshaller, compiler::ffi::kResultIndex);

  } else if (marshaller.IsCompound(compiler::ffi::kResultIndex)) {
    ASSERT(function.FfiCallbackExceptionalReturn() == Object::null());
    // Manufacture empty result.
    const intptr_t size =
        Utils::RoundUp(marshaller.Location(compiler::ffi::kResultIndex)
                           .payload_type()
                           .SizeInBytes(),
                       compiler::target::kWordSize);
    catch_body += IntConstant(size);
    catch_body +=
        AllocateTypedData(TokenPosition::kNoSource, kTypedDataUint8ArrayCid);
    catch_body += WrapTypedDataBaseInCompound(
        AbstractType::Handle(Z, marshaller.CType(compiler::ffi::kResultIndex)));
    catch_body += FfiCallbackConvertCompoundReturnToNative(
        marshaller, compiler::ffi::kResultIndex);

  } else {
    catch_body += Constant(
        Instance::ZoneHandle(Z, function.FfiCallbackExceptionalReturn()));
    catch_body +=
        FfiConvertPrimitiveToNative(marshaller, compiler::ffi::kResultIndex);
  }

  catch_body += NativeReturn(marshaller);
  --catch_depth_;

  PrologueInfo prologue_info(-1, -1);
  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                           prologue_info);
}

void FlowGraphBuilder::SetCurrentTryCatchBlock(TryCatchBlock* try_catch_block) {
  try_catch_block_ = try_catch_block;
  SetCurrentTryIndex(try_catch_block == nullptr ? kInvalidTryIndex
                                                : try_catch_block->try_index());
}

bool FlowGraphBuilder::NeedsNullAssertion(const AbstractType& type) {
  if (!type.IsNonNullable()) {
    return false;
  }
  if (type.IsTypeRef()) {
    return NeedsNullAssertion(
        AbstractType::Handle(Z, TypeRef::Cast(type).type()));
  }
  if (type.IsTypeParameter()) {
    return NeedsNullAssertion(
        AbstractType::Handle(Z, TypeParameter::Cast(type).bound()));
  }
  if (type.IsFutureOrType()) {
    return NeedsNullAssertion(AbstractType::Handle(Z, type.UnwrapFutureOr()));
  }
  return true;
}

Fragment FlowGraphBuilder::NullAssertion(LocalVariable* variable) {
  Fragment code;
  if (!NeedsNullAssertion(variable->type())) {
    return code;
  }

  TargetEntryInstr* then;
  TargetEntryInstr* otherwise;

  code += LoadLocal(variable);
  code += NullConstant();
  code += BranchIfEqual(&then, &otherwise);

  const Script& script =
      Script::Handle(Z, parsed_function_->function().script());
  intptr_t line = -1;
  intptr_t column = -1;
  script.GetTokenLocation(variable->token_pos(), &line, &column);

  // Build equivalent of `throw _AssertionError._throwNewNullAssertion(name)`
  // expression. We build throw (even through _throwNewNullAssertion already
  // throws) because call is not a valid last instruction for the block.
  // Blocks can only terminate with explicit control flow instructions
  // (Branch, Goto, Return or Throw).
  Fragment null_code(then);
  null_code += Constant(variable->name());
  null_code += IntConstant(line);
  null_code += IntConstant(column);
  null_code += StaticCall(variable->token_pos(),
                          ThrowNewNullAssertionFunction(), 3, ICData::kStatic);
  null_code += ThrowException(TokenPosition::kNoSource);
  null_code += Drop();

  return Fragment(code.entry, otherwise);
}

Fragment FlowGraphBuilder::BuildNullAssertions() {
  Fragment code;
  if (IG->null_safety() || !IG->asserts() || !FLAG_null_assertions) {
    return code;
  }

  const Function& dart_function = parsed_function_->function();
  for (intptr_t i = dart_function.NumImplicitParameters(),
                n = dart_function.NumParameters();
       i < n; ++i) {
    LocalVariable* variable = parsed_function_->ParameterVariable(i);
    code += NullAssertion(variable);
  }
  return code;
}

const Function& FlowGraphBuilder::ThrowNewNullAssertionFunction() {
  if (throw_new_null_assertion_.IsNull()) {
    const Class& klass = Class::ZoneHandle(
        Z, Library::LookupCoreClass(Symbols::AssertionError()));
    ASSERT(!klass.IsNull());
    const auto& error = klass.EnsureIsFinalized(H.thread());
    ASSERT(error == Error::null());
    throw_new_null_assertion_ = klass.LookupStaticFunctionAllowPrivate(
        Symbols::ThrowNewNullAssertion());
    ASSERT(!throw_new_null_assertion_.IsNull());
  }
  return throw_new_null_assertion_;
}

const Function& FlowGraphBuilder::PrependTypeArgumentsFunction() {
  if (prepend_type_arguments_.IsNull()) {
    const auto& dart_internal = Library::Handle(Z, Library::InternalLibrary());
    prepend_type_arguments_ = dart_internal.LookupFunctionAllowPrivate(
        Symbols::PrependTypeArguments());
    ASSERT(!prepend_type_arguments_.IsNull());
  }
  return prepend_type_arguments_;
}

}  // namespace kernel

}  // namespace dart
