// 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.

#ifndef RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TO_IL_H_
#define RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TO_IL_H_

#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#include "vm/growable_array.h"
#include "vm/hash_map.h"

#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/ffi/marshaller.h"
#include "vm/compiler/ffi/native_type.h"
#include "vm/compiler/frontend/base_flow_graph_builder.h"
#include "vm/compiler/frontend/kernel_translation_helper.h"
#include "vm/compiler/frontend/scope_builder.h"
#include "vm/object_store.h"

namespace dart {

class InlineExitCollector;

namespace kernel {

class StreamingFlowGraphBuilder;
struct InferredTypeMetadata;
class BreakableBlock;
class CatchBlock;
class FlowGraphBuilder;
class SwitchBlock;
class TryCatchBlock;
class TryFinallyBlock;

enum class TypeChecksToBuild {
  kCheckAllTypeParameterBounds,
  kCheckNonCovariantTypeParameterBounds,
  kCheckCovariantTypeParameterBounds,
};

class FlowGraphBuilder : public BaseFlowGraphBuilder {
 public:
  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 = 1,
                   bool inlining_unchecked_entry = false,
                   const Function* caller = nullptr);
  virtual ~FlowGraphBuilder();

  FlowGraph* BuildGraph();

  // Returns true if given [function] is recognized for flow
  // graph building and its body is expressed in a custom-built IL.
  static bool IsRecognizedMethodForFlowGraph(const Function& function);

  // Returns true if custom flow graph for given [function]
  // needs an expression_temp_var().
  static bool IsExpressionTempVarUsedInRecognizedMethodFlowGraph(
      const Function& function);

  // [builder] can be nullptr if there is a guarantee that there are no
  // try_entries in the path from graph entry to osr instruction.
  static void RelinkToOsrEntry(FlowGraphBuilder* builder,
                               OsrEntryRelinkingInfo* info);

  void RelinkToOsrEntry(OsrEntryRelinkingInfo* info) {
    RelinkToOsrEntry(this, info);
  }

 private:
  BlockEntryInstr* BuildPrologue(BlockEntryInstr* normal_entry,
                                 PrologueInfo* prologue_info);

  // Return names of optional named parameters of [function].
  ArrayPtr GetOptionalParameterNames(const Function& function);

  // Generate fragment which pushes all explicit parameters of [function].
  Fragment PushExplicitParameters(
      const Function& function,
      const Function& target = Function::null_function());

  FlowGraph* BuildGraphOfMethodExtractor(const Function& method);
  FlowGraph* BuildGraphOfNoSuchMethodDispatcher(const Function& function);
  FlowGraph* BuildGraphOfRecordFieldGetter(const Function& function);

  struct ClosureCallInfo;

  // Tests whether the closure function is generic and branches to the
  // appropriate fragment.
  Fragment TestClosureFunctionGeneric(const ClosureCallInfo& info,
                                      Fragment generic,
                                      Fragment not_generic);

  // Tests whether the function parameter at the given index is required and
  // branches to the appropriate fragment. Loads the parameter index to
  // check from info.vars->current_param_index.
  Fragment TestClosureFunctionNamedParameterRequired(
      const ClosureCallInfo& info,
      Fragment set,
      Fragment not_set);

  // Builds a fragment that, if there are no provided function type arguments,
  // calculates the appropriate TAV to use instead. Stores either the provided
  // or calculated function type arguments in vars->function_type_args.
  Fragment BuildClosureCallDefaultTypeHandling(const ClosureCallInfo& info);

  // The BuildClosureCall...Check methods differs from the checks built in the
  // PrologueBuilder in that they are built for invoke field dispatchers,
  // where the ArgumentsDescriptor is known at compile time but the specific
  // closure function is retrieved at runtime.

  // Builds checks that the given named arguments have valid argument names
  // and, in the case of null safe code, that all required named parameters
  // are provided.
  Fragment BuildClosureCallNamedArgumentsCheck(const ClosureCallInfo& info);

  // Builds checks for checking the arguments of a call are valid for the
  // function retrieved at runtime from the closure.
  Fragment BuildClosureCallArgumentsValidCheck(const ClosureCallInfo& info);

  // Builds checks that the type arguments of a call are consistent with the
  // bounds of the closure function type parameters. Assumes that the closure
  // function is generic.
  Fragment BuildClosureCallTypeArgumentsTypeCheck(const ClosureCallInfo& info);

  // Builds checks for type checking a given argument of the closure call using
  // parameter information from the closure function retrieved at runtime.
  //
  // For named arguments, arg_name is a compile-time constant retrieved from
  // the saved arguments descriptor. For positional arguments, null is passed.
  Fragment BuildClosureCallArgumentTypeCheck(const ClosureCallInfo& info,
                                             LocalVariable* param_index,
                                             intptr_t arg_index,
                                             const String& arg_name);

  // Builds checks for type checking the arguments of a call using parameter
  // information for the function retrieved at runtime from the closure.
  Fragment BuildClosureCallArgumentTypeChecks(const ClosureCallInfo& info);

  // Main entry point for building checks.
  Fragment BuildDynamicClosureCallChecks(LocalVariable* closure);

  FlowGraph* BuildGraphOfInvokeFieldDispatcher(const Function& function);
  FlowGraph* BuildGraphOfFfiTrampoline(const Function& function);
  FlowGraph* BuildGraphOfSyncFfiCallback(const Function& function);
  FlowGraph* BuildGraphOfAsyncFfiCallback(const Function& function);

  // Resolves the address of a native symbol from the constant data of a
  // vm:ffi:native pragma.
  // Because it's used in optimized mode (as part of the implementation of
  // @Native functions), it pushes the value as an untagged value. This is safe
  // to use in unoptimized mode too as long as the untagged value is consumed
  // immediately.
  Fragment FfiNativeLookupAddress(const Instance& native);
  // Expects target address on stack.
  Fragment FfiCallFunctionBody(const Function& function,
                               const FunctionType& c_signature,
                               intptr_t first_argument_parameter_offset);
  Fragment FfiNativeFunctionBody(const Function& function);
  Fragment NativeFunctionBody(const Function& function,
                              LocalVariable* first_parameter);
  Fragment LoadNativeArg(const compiler::ffi::CallbackMarshaller& marshaller,
                         intptr_t arg_index);

  FlowGraph* BuildGraphOfRecognizedMethod(const Function& function);

  Fragment BuildTypedListGet(const Function& function, classid_t cid);
  Fragment BuildTypedListSet(const Function& function, classid_t cid);
  Fragment BuildTypedDataMemMove(const Function& function, classid_t cid);
  Fragment BuildTypedDataViewFactoryConstructor(const Function& function,
                                                classid_t cid);
  Fragment BuildTypedDataFactoryConstructor(const Function& function,
                                            classid_t cid);

  Fragment EnterScope(intptr_t kernel_offset,
                      const LocalScope** scope = nullptr);
  Fragment ExitScope(intptr_t kernel_offset);

  Fragment AdjustContextTo(int depth);

  Fragment PushContext(const LocalScope* scope);
  Fragment PopContext();

  Fragment LoadInstantiatorTypeArguments();
  Fragment LoadFunctionTypeArguments();
  Fragment TranslateInstantiatedTypeArguments(
      const TypeArguments& type_arguments);

  Fragment CatchBlockEntry(const Array& handler_types,
                           intptr_t handler_index,
                           bool needs_stacktrace,
                           bool is_synthesized);

  Fragment TryEntry(int try_handler_index);
  Fragment CheckStackOverflowInPrologue(TokenPosition position);
  Fragment CloneContext(const ZoneGrowableArray<const Slot*>& context_slots);

  Fragment 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 = Function::null_function(),
      const Function& tearoff_interface_target = Function::null_function(),
      const InferredTypeMetadata* result_type = nullptr,
      bool use_unchecked_entry = false,
      const CallSiteAttributesMetadata* call_site_attrs = nullptr,
      bool receiver_is_not_smi = false,
      bool is_call_on_this = false);

  Fragment FfiCall(const compiler::ffi::CallMarshaller& marshaller,
                   bool is_leaf);

  Fragment CallLeafRuntimeEntry(
      const RuntimeEntry& entry,
      Representation return_representation,
      const ZoneGrowableArray<Representation>& argument_representations);

  Fragment RethrowException(TokenPosition position, int catch_try_index);
  Fragment LoadLocal(LocalVariable* variable);
  IndirectGotoInstr* IndirectGoto(intptr_t target_count);
  Fragment StoreLateField(const Field& field,
                          LocalVariable* instance,
                          LocalVariable* setter_value);
  Fragment NativeCall(const String& name, const Function& function);
  Fragment Return(TokenPosition position, bool omit_result_type_check = false);
  void SetResultTypeForStaticCall(StaticCallInstr* call,
                                  const Function& target,
                                  intptr_t argument_count,
                                  const InferredTypeMetadata* result_type);
  Fragment StaticCall(TokenPosition position,
                      const Function& target,
                      intptr_t argument_count,
                      ICData::RebindRule rebind_rule);
  Fragment StaticCall(TokenPosition position,
                      const Function& target,
                      intptr_t argument_count,
                      const Array& argument_names,
                      ICData::RebindRule rebind_rule,
                      const InferredTypeMetadata* result_type = nullptr,
                      intptr_t type_args_len = 0,
                      bool use_unchecked_entry = false);
  Fragment CachableIdempotentCall(TokenPosition position,
                                  Representation representation,
                                  const Function& target,
                                  intptr_t argument_count,
                                  const Array& argument_names,
                                  intptr_t type_args_len = 0);
  Fragment StringInterpolateSingle(TokenPosition position);
  Fragment StringInterpolate(TokenPosition position);

  // [incompatible_arguments] should be true if the NSM is due to a mismatch
  // between the provided arguments and the function signature.
  Fragment ThrowNoSuchMethodError(TokenPosition position,
                                  const Function& target,
                                  bool incompatible_arguments,
                                  bool receiver_pushed = false);
  Fragment ThrowNoSuchMethodError(TokenPosition position,
                                  const String& selector,
                                  InvocationMirror::Level level,
                                  InvocationMirror::Kind kind,
                                  bool receiver_pushed = false);
  Fragment ThrowLateInitializationError(TokenPosition position,
                                        const char* throw_method_name,
                                        const String& name);
  Fragment BuildImplicitClosureCreation(TokenPosition position,
                                        const Function& target);

  Fragment EvaluateAssertion();
  Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type,
                                          const String& name_symbol);
  Fragment CheckAssignable(
      const AbstractType& dst_type,
      const String& dst_name,
      AssertAssignableInstr::Kind kind = AssertAssignableInstr::kUnknown,
      TokenPosition token_pos = TokenPosition::kNoSource);

  Fragment AssertAssignableLoadTypeArguments(
      TokenPosition position,
      const AbstractType& dst_type,
      const String& dst_name,
      AssertAssignableInstr::Kind kind = AssertAssignableInstr::kUnknown);
  Fragment AssertSubtype(TokenPosition position,
                         const AbstractType& sub_type,
                         const AbstractType& super_type,
                         const String& dst_name);
  // Assumes destination name, supertype, and subtype are the top of the stack.
  Fragment AssertSubtype(TokenPosition position);

  bool NeedsDebugStepCheck(const Function& function, TokenPosition position);
  bool NeedsDebugStepCheck(Value* value, TokenPosition position);

  // Deals with StoreIndexed not working with kUnboxedFloat.
  // TODO(dartbug.com/43448): Remove this workaround.
  Fragment StoreIndexedTypedDataUnboxed(Representation unboxed_representation,
                                        intptr_t index_scale,
                                        bool index_unboxed);
  // Deals with LoadIndexed not working with kUnboxedFloat.
  // TODO(dartbug.com/43448): Remove this workaround.
  Fragment LoadIndexedTypedDataUnboxed(Representation unboxed_representation,
                                       intptr_t index_scale,
                                       bool index_unboxed);

  // Truncates (instead of deoptimizing) if the origin does not fit into the
  // target representation.
  Fragment UnboxTruncate(Representation to);

  // Loads the (untagged) thread address.
  Fragment LoadThread();

  // Loads the (untagged) isolate address.
  Fragment LoadIsolate();

  // Loads the (untagged) current IsolateGroup address.
  Fragment LoadIsolateGroup();

  // Loads the (untagged) current ObjectStore address.
  Fragment LoadObjectStore();

  // Loads the (untagged) service extension stream address.
  Fragment LoadServiceExtensionStream();

  // Converts a true to 1 and false to 0.
  Fragment BoolToInt();

  // Converts 0 to false and the rest to true.
  Fragment IntToBool();

  // Compares arbitrary integers.
  Fragment IntRelationalOp(TokenPosition position, Token::Kind kind);

  // Pops a Dart object and push the unboxed native version, according to the
  // semantics of FFI argument translation.
  //
  // Works for FFI call arguments, and FFI callback return values.
  //
  // If `marshaller.IsCompoundPointer(arg_index)`, then [variable] must point to
  // a valid LocalVariable.
  Fragment FfiConvertPrimitiveToNative(
      const compiler::ffi::BaseMarshaller& marshaller,
      intptr_t arg_index,
      LocalVariable* variable = nullptr);

  // Pops an unboxed native value, and pushes a Dart object, according to the
  // semantics of FFI argument translation.
  //
  // Works for FFI call return values, and FFI callback arguments.
  Fragment FfiConvertPrimitiveToDart(
      const compiler::ffi::BaseMarshaller& marshaller,
      intptr_t arg_index);

  // We pass in `variable` instead of on top of the stack so that we can have
  // multiple consecutive calls that keep only compound parts on the stack with
  // no compound parts in between.
  Fragment LoadTail(LocalVariable* variable,
                    intptr_t size,
                    intptr_t offset_in_bytes,
                    Representation representation);
  Fragment FfiCallConvertCompoundArgumentToNative(
      LocalVariable* variable,
      const compiler::ffi::BaseMarshaller& marshaller,
      intptr_t arg_index);

  Fragment FfiCallConvertCompoundReturnToDart(
      const compiler::ffi::BaseMarshaller& marshaller,
      intptr_t arg_index);

  // We pass in multiple `definitions`, which are also expected to be the top
  // of the stack. This eases storing each definition in the resulting struct
  // or union.
  Fragment FfiCallbackConvertCompoundArgumentToDart(
      const compiler::ffi::BaseMarshaller& marshaller,
      intptr_t arg_index,
      ZoneGrowableArray<LocalVariable*>* definitions);

  Fragment FfiCallbackConvertCompoundReturnToNative(
      const compiler::ffi::CallbackMarshaller& marshaller,
      intptr_t arg_index);

  // Wraps a TypedDataBase from the stack and wraps it in a subclass of
  // _Compound.
  Fragment WrapTypedDataBaseInCompound(const AbstractType& compound_type);

  // Loads the _typedDataBase field from a subclass of _Compound.
  Fragment LoadTypedDataBaseFromCompound();
  Fragment LoadOffsetInBytesFromCompound();

  // Copy `definitions` into TypedData.
  //
  // Expects the TypedData on top of the stack and `definitions` right under it.
  //
  // Leaves TypedData on stack.
  //
  // The compound contents are heterogeneous, so pass in `representations` to
  // know what representation to load.
  Fragment PopFromStackToTypedDataBase(
      ZoneGrowableArray<LocalVariable*>* definitions,
      const GrowableArray<Representation>& representations);

  // Wrap the current exception and stacktrace in an unhandled exception.
  Fragment UnhandledException();

  // Return from a native -> Dart callback. Can only be used in conjunction with
  // NativeEntry and NativeParameter are used.
  Fragment NativeReturn(const compiler::ffi::CallbackMarshaller& marshaller);

  // Bit-wise cast between representations.
  // Pops the input and pushes the converted result.
  // Currently only works with equal sizes and floating point <-> integer.
  Fragment BitCast(Representation from, Representation to);

  // Generates Call1ArgStub instruction.
  Fragment Call1ArgStub(TokenPosition position,
                        Call1ArgStubInstr::StubId stub_id);

  // Generates Suspend instruction.
  Fragment Suspend(TokenPosition position, SuspendInstr::StubId stub_id);

  LocalVariable* LookupVariable(intptr_t kernel_offset);

  // Build type argument type checks for the current function.
  // ParsedFunction should have the following information:
  //  - is_forwarding_stub()
  //  - forwarding_stub_super_target()
  // Scope should be populated with parameter variables including
  //  - needs_type_check()
  //  - is_explicit_covariant_parameter()
  void BuildTypeArgumentTypeChecks(TypeChecksToBuild mode,
                                   Fragment* implicit_checks);

  // Build argument type checks for the current function.
  // ParsedFunction should have the following information:
  //  - is_forwarding_stub()
  //  - forwarding_stub_super_target()
  // Scope should be populated with parameter variables including
  //  - needs_type_check()
  //  - is_explicit_covariant_parameter()
  void BuildArgumentTypeChecks(Fragment* explicit_checks,
                               Fragment* implicit_checks,
                               Fragment* implicit_redefinitions);

  // Builds flow graph for noSuchMethod forwarder.
  //
  // If throw_no_such_method_error is set to true, an
  // instance of NoSuchMethodError is thrown. Otherwise, the instance
  // noSuchMethod is called.
  //
  // ParsedFunction should have the following information:
  //  - default_parameter_values()
  //  - is_forwarding_stub()
  //  - forwarding_stub_super_target()
  //
  // Scope should be populated with parameter variables including
  //  - needs_type_check()
  //  - is_explicit_covariant_parameter()
  //
  FlowGraph* BuildGraphOfNoSuchMethodForwarder(
      const Function& function,
      bool is_implicit_closure_function,
      bool throw_no_such_method_error);

  // If no type arguments are passed to a generic function, we need to fill the
  // type arguments in with the default types stored on the TypeParameter nodes
  // in Kernel.
  //
  // ParsedFunction should have the following information:
  //  - DefaultFunctionTypeArguments()
  //  - function_type_arguments()
  Fragment BuildDefaultTypeHandling(const Function& function);

  FunctionEntryInstr* BuildSharedUncheckedEntryPoint(
      Fragment prologue_from_normal_entry,
      Fragment skippable_checks,
      Fragment redefinitions_if_skipped,
      Fragment body);
  FunctionEntryInstr* BuildSeparateUncheckedEntryPoint(
      BlockEntryInstr* normal_entry,
      Fragment normal_prologue,
      Fragment extra_prologue,
      Fragment shared_prologue,
      Fragment body);

  // Builds flow graph for implicit closure function (tear-off).
  //
  // ParsedFunction should have the following information:
  //  - DefaultFunctionTypeArguments()
  //  - function_type_arguments()
  //  - default_parameter_values()
  //  - is_forwarding_stub()
  //  - forwarding_stub_super_target()
  //
  // Scope should be populated with parameter variables including
  //  - needs_type_check()
  //  - is_explicit_covariant_parameter()
  //
  FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);

  // Builds flow graph of implicit field getter, setter, or a
  // dynamic invocation forwarder to a field setter.
  //
  // If field is const, its value should be evaluated and stored in
  //  - StaticValue()
  //
  // Scope should be populated with parameter variables including
  //  - needs_type_check()
  //
  FlowGraph* BuildGraphOfFieldAccessor(const Function& function);

  // Builds flow graph of dynamic invocation forwarder.
  //
  // ParsedFunction should have the following information:
  //  - DefaultFunctionTypeArguments()
  //  - function_type_arguments()
  //  - default_parameter_values()
  //  - is_forwarding_stub()
  //  - forwarding_stub_super_target()
  //
  // Scope should be populated with parameter variables including
  //  - needs_type_check()
  //  - is_explicit_covariant_parameter()
  //
  FlowGraph* BuildGraphOfDynamicInvocationForwarder(const Function& function);

  void SetConstantRangeOfCurrentDefinition(const Fragment& fragment,
                                           int64_t min,
                                           int64_t max);

  // Extracts a packed field out of the unboxed value with representation [rep
  // on the top of the stack. Picks a sequence that keeps unboxed values on the
  // expression stack only as needed, switching to Smis as soon as possible.
  template <typename T>
  Fragment BuildExtractUnboxedSlotBitFieldIntoSmi(const Slot& slot) {
    // Currently this method is not used with any sign-extended BitFields.
    COMPILE_ASSERT(!T::sign_extended());
    ASSERT(RepresentationUtils::IsUnboxedInteger(slot.representation()));
    Fragment instructions;
    if (!Boxing::RequiresAllocation(slot.representation())) {
      // We don't need to allocate to box this value, so it already fits in
      // a Smi (and thus the mask must also).
      instructions += LoadNativeField(slot);
      instructions += Box(slot.representation());
      instructions += IntConstant(T::mask_in_place());
      instructions += SmiBinaryOp(Token::kBIT_AND);
    } else {
      // Since kBIT_AND never throws or deoptimizes, we require that the result
      // of masking the field in place fits into a Smi, so we can use Smi
      // operations for the shift.
      static_assert(T::mask_in_place() <= compiler::target::kSmiMax,
                    "Cannot fit results of masking in place into a Smi");
      instructions += LoadNativeField(slot);
      instructions +=
          UnboxedIntConstant(T::mask_in_place(), slot.representation());
      instructions += BinaryIntegerOp(Token::kBIT_AND, slot.representation());
      // Set the range of the definition that will be used as the value in the
      // box so that ValueFitsSmi() returns true even in unoptimized code.
      SetConstantRangeOfCurrentDefinition(instructions, 0, T::mask_in_place());
      instructions += Box(slot.representation());
    }
    if (T::shift() != 0) {
      // Only add the shift operation if it's necessary.
      instructions += IntConstant(T::shift());
      instructions += SmiBinaryOp(Token::kSHR);
    }
    return instructions;
  }

  Fragment BuildDoubleHashCode();
  Fragment BuildIntegerHashCode(bool smi);

  TranslationHelper translation_helper_;
  Thread* thread_;
  Zone* zone_;

  ParsedFunction* parsed_function_;
  ZoneGrowableArray<const ICData*>& ic_data_array_;

  intptr_t next_function_id_;
  intptr_t AllocateFunctionId() { return next_function_id_++; }

  intptr_t loop_depth_;
  intptr_t try_depth_;
  intptr_t catch_depth_;
  intptr_t block_expression_depth_;

  GraphEntryInstr* graph_entry_;

  ScopeBuildingResult* scopes_;

  LocalVariable* CurrentException() {
    return scopes_->exception_variables[catch_depth_ - 1];
  }
  LocalVariable* CurrentStackTrace() {
    return scopes_->stack_trace_variables[catch_depth_ - 1];
  }
  LocalVariable* CurrentRawException() {
    return scopes_->raw_exception_variables[catch_depth_ - 1];
  }
  LocalVariable* CurrentRawStackTrace() {
    return scopes_->raw_stack_trace_variables[catch_depth_ - 1];
  }
  LocalVariable* CurrentCatchContext() {
    return scopes_->catch_context_variables[try_depth_];
  }

  TryCatchBlock* CurrentTryCatchBlock() const { return try_catch_block_; }
  void SetCurrentTryCatchBlock(TryCatchBlock* try_catch_block);

  // A chained list of breakable blocks. Chaining and lookup is done by the
  // [BreakableBlock] class.
  BreakableBlock* breakable_block_;

  // A chained list of switch blocks. Chaining and lookup is done by the
  // [SwitchBlock] class.
  SwitchBlock* switch_block_;

  // A chained list of try-catch blocks. Chaining and lookup is done by the
  // [TryCatchBlock] class.
  TryCatchBlock* try_catch_block_;

  // A chained list of try-finally blocks. Chaining and lookup is done by the
  // [TryFinallyBlock] class.
  TryFinallyBlock* try_finally_block_;

  // A chained list of catch blocks. Chaining and lookup is done by the
  // [CatchBlock] class.
  CatchBlock* catch_block_;

  ActiveClass active_class_;

  // TryEntryInstr indexed by try_index
  GrowableArray<TryEntryInstr*> try_entries_;

  // Cached _PrependTypeArguments.
  Function& prepend_type_arguments_;

  // Returns the function _PrependTypeArguments from dart:_internal. If the
  // cached version is null, retrieves it and updates the cache.
  const Function& PrependTypeArgumentsFunction();

  friend class BreakableBlock;
  friend class CatchBlock;
  friend class ProgramState;
  friend class StreamingFlowGraphBuilder;
  friend class SwitchBlock;
  friend class TryCatchBlock;
  friend class TryFinallyBlock;

  DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder);
};

// Convenience class to save/restore program state.
// This snapshot denotes a partial state of the flow
// grap builder that is needed when recursing into
// the statements and expressions of a finalizer block.
class ProgramState {
 public:
  ProgramState(BreakableBlock* breakable_block,
               SwitchBlock* switch_block,
               intptr_t loop_depth,
               intptr_t try_depth,
               intptr_t catch_depth,
               intptr_t block_expression_depth)
      : breakable_block_(breakable_block),
        switch_block_(switch_block),
        loop_depth_(loop_depth),
        try_depth_(try_depth),
        catch_depth_(catch_depth),
        block_expression_depth_(block_expression_depth) {}

  void assignTo(FlowGraphBuilder* builder) const {
    builder->breakable_block_ = breakable_block_;
    builder->switch_block_ = switch_block_;
    builder->loop_depth_ = loop_depth_;
    builder->try_depth_ = try_depth_;
    builder->catch_depth_ = catch_depth_;
    builder->block_expression_depth_ = block_expression_depth_;
  }

 private:
  BreakableBlock* const breakable_block_;
  SwitchBlock* const switch_block_;
  const intptr_t loop_depth_;
  const intptr_t try_depth_;
  const intptr_t catch_depth_;
  const intptr_t block_expression_depth_;
};

class SwitchBlock {
 public:
  SwitchBlock(FlowGraphBuilder* builder, intptr_t case_count)
      : builder_(builder),
        outer_(builder->switch_block_),
        outer_finally_(builder->try_finally_block_),
        case_count_(case_count),
        context_depth_(builder->context_depth_),
        try_index_(builder->CurrentTryIndex()) {
    builder_->switch_block_ = this;
    if (outer_ != nullptr) {
      depth_ = outer_->depth_ + outer_->case_count_;
    } else {
      depth_ = 0;
    }
  }
  ~SwitchBlock() { builder_->switch_block_ = outer_; }

  bool HadJumper(intptr_t case_num) {
    return destinations_.Lookup(case_num) != nullptr;
  }

  // Get destination via absolute target number (i.e. the correct destination
  // is not necessarily in this block).
  JoinEntryInstr* Destination(intptr_t target_index,
                              TryFinallyBlock** outer_finally = nullptr,
                              intptr_t* context_depth = nullptr) {
    // Verify consistency of program state.
    ASSERT(builder_->switch_block_ == this);
    // Find corresponding destination.
    SwitchBlock* block = this;
    while (block->depth_ > target_index) {
      block = block->outer_;
      ASSERT(block != nullptr);
    }

    // Set the outer finally block.
    if (outer_finally != nullptr) {
      *outer_finally = block->outer_finally_;
      *context_depth = block->context_depth_;
    }

    // Ensure there's [JoinEntryInstr] for that [SwitchCase].
    return block->EnsureDestination(target_index - block->depth_);
  }

  // Get destination via relative target number (i.e. relative to this block,
  // 0 is first case in this block etc).
  JoinEntryInstr* DestinationDirect(intptr_t case_num,
                                    TryFinallyBlock** outer_finally = nullptr,
                                    intptr_t* context_depth = nullptr) {
    // Set the outer finally block.
    if (outer_finally != nullptr) {
      *outer_finally = outer_finally_;
      *context_depth = context_depth_;
    }

    // Ensure there's [JoinEntryInstr] for that [SwitchCase].
    return EnsureDestination(case_num);
  }

 private:
  JoinEntryInstr* EnsureDestination(intptr_t case_num) {
    JoinEntryInstr* cached_inst = destinations_.Lookup(case_num);
    if (cached_inst == nullptr) {
      JoinEntryInstr* inst = builder_->BuildJoinEntry(try_index_);
      destinations_.Insert(case_num, inst);
      return inst;
    }
    return cached_inst;
  }

  FlowGraphBuilder* builder_;
  SwitchBlock* outer_;

  IntMap<JoinEntryInstr*> destinations_;

  TryFinallyBlock* outer_finally_;
  intptr_t case_count_;
  intptr_t depth_;
  intptr_t context_depth_;
  intptr_t try_index_;
};

class TryCatchBlock {
 public:
  explicit TryCatchBlock(FlowGraphBuilder* builder,
                         intptr_t try_handler_index = -1)
      : builder_(builder),
        outer_(builder->CurrentTryCatchBlock()),
        try_index_(try_handler_index == -1 ? builder->AllocateTryIndex()
                                           : try_handler_index) {
    builder->SetCurrentTryCatchBlock(this);
  }

  ~TryCatchBlock() { builder_->SetCurrentTryCatchBlock(outer_); }

  intptr_t try_index() { return try_index_; }
  TryCatchBlock* outer() const { return outer_; }

 private:
  FlowGraphBuilder* const builder_;
  TryCatchBlock* const outer_;
  intptr_t const try_index_;

  DISALLOW_COPY_AND_ASSIGN(TryCatchBlock);
};

class TryFinallyBlock {
 public:
  TryFinallyBlock(FlowGraphBuilder* builder, intptr_t finalizer_kernel_offset)
      : builder_(builder),
        outer_(builder->try_finally_block_),
        finalizer_kernel_offset_(finalizer_kernel_offset),
        context_depth_(builder->context_depth_),
        try_index_(builder_->CurrentTryIndex()),
        // Finalizers are executed outside of the try block hence
        // try depth of finalizers are one less than current try
        // depth. For others, program state is snapshot of current.
        state_(builder_->breakable_block_,
               builder_->switch_block_,
               builder_->loop_depth_,
               builder_->try_depth_ - 1,
               builder_->catch_depth_,
               builder_->block_expression_depth_) {
    builder_->try_finally_block_ = this;
  }
  ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; }

  TryFinallyBlock* outer() const { return outer_; }
  intptr_t finalizer_kernel_offset() const { return finalizer_kernel_offset_; }
  intptr_t context_depth() const { return context_depth_; }
  intptr_t try_index() const { return try_index_; }
  const ProgramState& state() const { return state_; }

 private:
  FlowGraphBuilder* const builder_;
  TryFinallyBlock* const outer_;
  const intptr_t finalizer_kernel_offset_;
  const intptr_t context_depth_;
  const intptr_t try_index_;
  const ProgramState state_;

  DISALLOW_COPY_AND_ASSIGN(TryFinallyBlock);
};

class BreakableBlock {
 public:
  explicit BreakableBlock(FlowGraphBuilder* builder)
      : builder_(builder),
        outer_(builder->breakable_block_),
        destination_(nullptr),
        outer_finally_(builder->try_finally_block_),
        context_depth_(builder->context_depth_),
        try_index_(builder->CurrentTryIndex()) {
    if (builder_->breakable_block_ == nullptr) {
      index_ = 0;
    } else {
      index_ = builder_->breakable_block_->index_ + 1;
    }
    builder_->breakable_block_ = this;
  }
  ~BreakableBlock() { builder_->breakable_block_ = outer_; }

  bool HadJumper() { return destination_ != nullptr; }

  JoinEntryInstr* destination() { return destination_; }

  JoinEntryInstr* BreakDestination(intptr_t label_index,
                                   TryFinallyBlock** outer_finally,
                                   intptr_t* context_depth) {
    // Verify consistency of program state.
    ASSERT(builder_->breakable_block_ == this);
    // Find corresponding destination.
    BreakableBlock* block = this;
    while (block->index_ != label_index) {
      block = block->outer_;
      ASSERT(block != nullptr);
    }
    *outer_finally = block->outer_finally_;
    *context_depth = block->context_depth_;
    return block->EnsureDestination();
  }

 private:
  JoinEntryInstr* EnsureDestination() {
    if (destination_ == nullptr) {
      destination_ = builder_->BuildJoinEntry(try_index_);
    }
    return destination_;
  }

  FlowGraphBuilder* builder_;
  intptr_t index_;
  BreakableBlock* outer_;
  JoinEntryInstr* destination_;
  TryFinallyBlock* outer_finally_;
  intptr_t context_depth_;
  intptr_t try_index_;

  DISALLOW_COPY_AND_ASSIGN(BreakableBlock);
};

class CatchBlock {
 public:
  CatchBlock(FlowGraphBuilder* builder,
             LocalVariable* exception_var,
             LocalVariable* stack_trace_var,
             intptr_t catch_try_index)
      : builder_(builder),
        outer_(builder->catch_block_),
        exception_var_(exception_var),
        stack_trace_var_(stack_trace_var),
        catch_try_index_(catch_try_index) {
    builder_->catch_block_ = this;
  }
  ~CatchBlock() { builder_->catch_block_ = outer_; }

  LocalVariable* exception_var() { return exception_var_; }
  LocalVariable* stack_trace_var() { return stack_trace_var_; }
  intptr_t catch_try_index() { return catch_try_index_; }

 private:
  FlowGraphBuilder* builder_;
  CatchBlock* outer_;
  LocalVariable* exception_var_;
  LocalVariable* stack_trace_var_;
  intptr_t catch_try_index_;

  DISALLOW_COPY_AND_ASSIGN(CatchBlock);
};

enum SwitchDispatch {
  kSwitchDispatchAuto = -1,
  kSwitchDispatchLinearScan,
  kSwitchDispatchBinarySearch,
  kSwitchDispatchJumpTable,
};

// Collected information for a switch expression.
class SwitchExpression {
 public:
  SwitchExpression(intptr_t case_index,
                   TokenPosition position,
                   const Instance& value)
      : case_index_(case_index), position_(position), value_(&value) {}

  intptr_t case_index() const { return case_index_; }
  const TokenPosition& position() const { return position_; }
  // Constant value of the expression.
  const Instance& value() const { return *value_; }

  // Integer representation of the expression.
  // For Integers it is the value itself and for Enums it is the index.
  const Integer& integer() const {
    ASSERT(integer_ != nullptr);
    return *integer_;
  }

  void set_integer(const Integer& integer) {
    ASSERT(integer_ == nullptr);
    integer_ = &integer;
  }

 private:
  intptr_t case_index_;
  TokenPosition position_;
  const Instance* value_;
  const Integer* integer_ = nullptr;
};

// A range that is covered by a branch in a binary search switch.
// Leafs are represented by a range where min == max.
class SwitchRange {
 public:
  static SwitchRange Leaf(intptr_t index,
                          Fragment branch_instructions,
                          bool is_bounds_checked = false) {
    return SwitchRange(index, index, branch_instructions, is_bounds_checked);
  }

  static SwitchRange Branch(intptr_t min,
                            intptr_t max,
                            Fragment branch_instructions) {
    return SwitchRange(min, max, branch_instructions,
                       /*is_bounds_checked=*/false);
  }

  // min and max are indexes into a sorted array of case expressions.
  intptr_t min() const { return min_; }
  intptr_t max() const { return max_; }
  // The fragment to continue building code for the branch.
  Fragment branch_instructions() const { return branch_instructions_; }
  // For leafs, whether the branch is known to be in the bounds of the
  // overall switch.
  bool is_bounds_checked() const { return is_bounds_checked_; }
  bool is_leaf() const { return min_ == max_; }

 private:
  SwitchRange(intptr_t min,
              intptr_t max,
              Fragment branch_instructions,
              bool is_bounds_checked)
      : min_(min),
        max_(max),
        branch_instructions_(branch_instructions),
        is_bounds_checked_(is_bounds_checked) {}

  intptr_t min_;
  intptr_t max_;
  Fragment branch_instructions_;
  bool is_bounds_checked_;
};

// Helper for building flow graph for a switch statement.
class SwitchHelper {
 public:
  SwitchHelper(Zone* zone,
               TokenPosition position,
               bool is_exhaustive,
               const AbstractType& expression_type,
               SwitchBlock* switch_block,
               intptr_t case_count);

  // A switch statement is optimizable if static type of the scrutinee
  // expression is a non-nullable int or enum, and all case expressions
  // are instances of the scrutinee static type.
  bool is_optimizable() const { return is_optimizable_; }
  const TokenPosition& position() const { return position_; }
  bool is_exhaustive() const { return is_exhaustive_; }
  SwitchBlock* switch_block() { return switch_block_; }
  intptr_t case_count() const { return case_count_; }

  // Index of default case.
  intptr_t default_case() const { return default_case_; }
  void set_default_case(intptr_t index) {
    ASSERT(default_case_ == -1);
    default_case_ = index;
  }

  const GrowableArray<Fragment>& case_bodies() const { return case_bodies_; }

  // Array of the expression counts for all cases.
  const GrowableArray<intptr_t>& case_expression_counts() const {
    return case_expression_counts_;
  }

  const GrowableArray<SwitchExpression>& expressions() const {
    return expressions_;
  }

  const GrowableArray<SwitchExpression*>& sorted_expressions() const {
    return sorted_expressions_;
  }

  // Static type of the scrutinee expression.
  const AbstractType& expression_type() const { return expression_type_; }

  const Integer& expression_min() const {
    ASSERT(expression_min_ != nullptr);
    return *expression_min_;
  }
  const Integer& expression_max() const {
    ASSERT(expression_max_ != nullptr);
    return *expression_max_;
  }

  bool has_default() const { return default_case_ >= 0; }

  bool is_enum_switch() const { return is_enum_switch_; }

  // Returns size of [min..max] range, or kMaxInt64 on overflow.
  int64_t ExpressionRange() const;

  bool RequiresLowerBoundCheck() const;
  bool RequiresUpperBoundCheck() const;

  SwitchDispatch SelectDispatchStrategy();

  void AddCaseBody(Fragment body) { case_bodies_.Add(body); }

  void AddExpression(intptr_t case_index,
                     TokenPosition position,
                     const Instance& value);

 private:
  void PrepareForOptimizedSwitch();

  Zone* zone_;
  bool is_optimizable_ = false;
  bool is_enum_switch_ = false;
  const TokenPosition position_;
  const bool is_exhaustive_;
  const AbstractType& expression_type_;
  SwitchBlock* const switch_block_;
  const intptr_t case_count_;
  intptr_t default_case_ = -1;
  GrowableArray<Fragment> case_bodies_;
  GrowableArray<intptr_t> case_expression_counts_;
  GrowableArray<SwitchExpression> expressions_;
  GrowableArray<SwitchExpression*> sorted_expressions_;
  const Integer* expression_min_ = nullptr;
  const Integer* expression_max_ = nullptr;
};

}  // namespace kernel
}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TO_IL_H_
