// Copyright (c) 2017, 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_BINARY_FLOWGRAPH_H_
#define RUNTIME_VM_COMPILER_FRONTEND_KERNEL_BINARY_FLOWGRAPH_H_

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

#include "vm/compiler/frontend/constant_reader.h"
#include "vm/compiler/frontend/kernel_to_il.h"
#include "vm/compiler/frontend/kernel_translation_helper.h"
#include "vm/compiler/frontend/scope_builder.h"
#include "vm/kernel.h"
#include "vm/kernel_binary.h"
#include "vm/object.h"

namespace dart {
namespace kernel {

class StreamingFlowGraphBuilder : public KernelReaderHelper {
 public:
  StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
                            const ExternalTypedData& data,
                            intptr_t data_program_offset)
      : KernelReaderHelper(
            flow_graph_builder->zone_,
            &flow_graph_builder->translation_helper_,
            Script::Handle(
                flow_graph_builder->zone_,
                flow_graph_builder->parsed_function_->function().script()),
            data,
            data_program_offset),
        flow_graph_builder_(flow_graph_builder),
        active_class_(&flow_graph_builder->active_class_),
        constant_reader_(this, active_class_),
        type_translator_(this,
                         &constant_reader_,
                         active_class_,
                         /* finalize= */ true),
        direct_call_metadata_helper_(this),
        inferred_type_metadata_helper_(this, &constant_reader_),
        procedure_attributes_metadata_helper_(this),
        call_site_attributes_metadata_helper_(this, &type_translator_),
        closure_owner_(Object::Handle(flow_graph_builder->zone_)) {}

  virtual ~StreamingFlowGraphBuilder() {}

  FlowGraph* BuildGraph();

  void ReportUnexpectedTag(const char* variant, Tag tag) override;

  Fragment BuildStatementAt(intptr_t kernel_offset);

  intptr_t num_ast_nodes() const { return num_ast_nodes_; }

 private:
  Thread* thread() const { return flow_graph_builder_->thread_; }

  void ParseKernelASTFunction();
  void ReadForwardingStubTarget(const Function& function);
  void SetupDefaultParameterValues();

  FlowGraph* BuildGraphOfFieldInitializer();
  Fragment BuildFieldInitializer(const Field& field,
                                 bool only_for_side_effects);
  Fragment BuildLateFieldInitializer(const Field& field, bool has_initializer);
  Fragment BuildInitializers(const Class& parent_class);
  FlowGraph* BuildGraphOfFunction(bool constructor);

  Fragment BuildExpression(TokenPosition* position = nullptr);
  Fragment BuildStatement(TokenPosition* position = nullptr);
  Fragment BuildStatementWithBranchCoverage(TokenPosition* position = nullptr);

  // Kernel offset:
  //   start of function expression -> end of function body statement
  Fragment BuildFunctionBody(const Function& dart_function,
                             LocalVariable* first_parameter,
                             bool constructor);

  // Pieces of the prologue. They are all agnostic to the current Kernel offset.
  Fragment BuildEveryTimePrologue(const Function& dart_function,
                                  TokenPosition token_position,
                                  intptr_t type_parameters_offset);
  Fragment BuildFirstTimePrologue(const Function& dart_function,
                                  LocalVariable* first_parameter,
                                  intptr_t type_parameters_offset);
  Fragment ClearRawParameters(const Function& dart_function);
  Fragment DebugStepCheckInPrologue(const Function& dart_function,
                                    TokenPosition position);
  Fragment SetAsyncStackTrace(const Function& dart_function);
  Fragment CheckStackOverflowInPrologue(const Function& dart_function);
  Fragment SetupCapturedParameters(const Function& dart_function);
  Fragment InitSuspendableFunction(const Function& dart_function);
  Fragment ShortcutForUserDefinedEquals(const Function& dart_function,
                                        LocalVariable* first_parameter);
  Fragment TypeArgumentsHandling(const Function& dart_function);
  Fragment CompleteBodyWithYieldContinuations(Fragment body);

  static UncheckedEntryPointStyle ChooseEntryPointStyle(
      const Function& dart_function,
      const Fragment& implicit_type_checks,
      const Fragment& first_time_prologue,
      const Fragment& every_time_prologue,
      const Fragment& type_args_handling);

  void loop_depth_inc();
  void loop_depth_dec();
  intptr_t for_in_depth();
  void for_in_depth_inc();
  void for_in_depth_dec();
  void catch_depth_inc();
  void catch_depth_dec();
  void try_depth_inc();
  void try_depth_dec();
  intptr_t block_expression_depth();
  void block_expression_depth_inc();
  void block_expression_depth_dec();
  intptr_t CurrentTryIndex();
  intptr_t AllocateTryIndex();
  LocalVariable* CurrentException();
  LocalVariable* CurrentStackTrace();
  CatchBlock* catch_block();
  ActiveClass* active_class();
  ScopeBuildingResult* scopes();
  void set_scopes(ScopeBuildingResult* scope);
  ParsedFunction* parsed_function();
  TryFinallyBlock* try_finally_block();
  SwitchBlock* switch_block();
  BreakableBlock* breakable_block();
  GrowableArray<YieldContinuation>& yield_continuations();
  Value* stack();
  void set_stack(Value* top);
  void Push(Definition* definition);
  Value* Pop();
  Class& GetSuperOrDie();

  Tag PeekArgumentsFirstPositionalTag();
  const TypeArguments& PeekArgumentsInstantiatedType(const Class& klass);
  intptr_t PeekArgumentsCount();

  // See BaseFlowGraphBuilder::MakeTemporary.
  LocalVariable* MakeTemporary(const char* suffix = nullptr);
  Fragment DropTemporary(LocalVariable** variable);

  LocalVariable* LookupVariable(intptr_t kernel_offset);
  Function& FindMatchingFunction(const Class& klass,
                                 const String& name,
                                 int type_args_len,
                                 int argument_count,
                                 const Array& argument_names);

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

  void InlineBailout(const char* reason);
  Fragment DebugStepCheck(TokenPosition position);
  Fragment LoadLocal(LocalVariable* variable);
  Fragment IndirectGoto(intptr_t target_count);
  Fragment Return(
      TokenPosition position,
      intptr_t yield_index = UntaggedPcDescriptors::kInvalidYieldIndex);
  Fragment EvaluateAssertion();
  Fragment RethrowException(TokenPosition position, int catch_try_index);
  Fragment ThrowNoSuchMethodError(const Function& target,
                                  bool incompatible_arguments);
  Fragment Constant(const Object& value);
  Fragment IntConstant(int64_t value);
  Fragment LoadStaticField(const Field& field, bool calls_initializer);
  Fragment RedefinitionWithType(const AbstractType& type);
  Fragment CheckNull(TokenPosition position,
                     LocalVariable* receiver,
                     const String& function_name,
                     bool clear_the_temp = true);
  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 InstanceCall(TokenPosition position,
                        const String& name,
                        Token::Kind kind,
                        intptr_t argument_count,
                        intptr_t checked_argument_count = 1);
  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,
      const Function& tearoff_interface_target,
      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 ThrowException(TokenPosition position);
  Fragment BooleanNegate();
  Fragment TranslateInstantiatedTypeArguments(
      const TypeArguments& type_arguments);
  Fragment StrictCompare(TokenPosition position,
                         Token::Kind kind,
                         bool number_check = false);
  Fragment AllocateObject(TokenPosition position,
                          const Class& klass,
                          intptr_t argument_count);
  Fragment AllocateContext(const ZoneGrowableArray<const Slot*>& context_slots);
  Fragment LoadNativeField(const Slot& field);
  Fragment StoreLocal(TokenPosition position, LocalVariable* variable);
  Fragment StoreStaticField(TokenPosition position, const Field& field);
  Fragment StringInterpolate(TokenPosition position);
  Fragment StringInterpolateSingle(TokenPosition position);
  Fragment ThrowTypeError();
  Fragment LoadInstantiatorTypeArguments();
  Fragment LoadFunctionTypeArguments();
  Fragment InstantiateType(const AbstractType& type);
  Fragment CreateArray();
  Fragment StoreIndexed(intptr_t class_id);
  Fragment CheckStackOverflow(TokenPosition position);
  Fragment CloneContext(const ZoneGrowableArray<const Slot*>& context_slots);
  Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally,
                                      intptr_t target_context_depth);
  Fragment BranchIfTrue(TargetEntryInstr** then_entry,
                        TargetEntryInstr** otherwise_entry,
                        bool negate);
  Fragment BranchIfEqual(TargetEntryInstr** then_entry,
                         TargetEntryInstr** otherwise_entry,
                         bool negate);
  Fragment BranchIfNull(TargetEntryInstr** then_entry,
                        TargetEntryInstr** otherwise_entry,
                        bool negate = false);
  Fragment CatchBlockEntry(const Array& handler_types,
                           intptr_t handler_index,
                           bool needs_stacktrace,
                           bool is_synthesized);
  Fragment TryCatch(int try_handler_index);
  Fragment Drop();

  // Drop given number of temps from the stack but preserve top of the stack.
  Fragment DropTempsPreserveTop(intptr_t num_temps_to_drop);

  Fragment MakeTemp();
  Fragment NullConstant();
  JoinEntryInstr* BuildJoinEntry();
  JoinEntryInstr* BuildJoinEntry(intptr_t try_index);
  Fragment Goto(JoinEntryInstr* destination);
  Fragment BuildImplicitClosureCreation(const Function& target);
  Fragment CheckBoolean(TokenPosition position);
  Fragment CheckArgumentType(LocalVariable* variable, const AbstractType& type);
  Fragment RecordCoverage(TokenPosition position);
  Fragment EnterScope(intptr_t kernel_offset,
                      const LocalScope** scope = nullptr);
  Fragment ExitScope(intptr_t kernel_offset);

  TestFragment TranslateConditionForControl();

  const TypeArguments& BuildTypeArguments();
  Fragment BuildArguments(Array* argument_names,
                          intptr_t* argument_count,
                          intptr_t* positional_argument_count);
  Fragment BuildArgumentsFromActualArguments(Array* argument_names);

  Fragment BuildInvalidExpression(TokenPosition* position);
  Fragment BuildVariableGet(TokenPosition* position);
  Fragment BuildVariableGet(uint8_t payload, TokenPosition* position);
  Fragment BuildVariableGetImpl(intptr_t variable_kernel_position,
                                TokenPosition position);
  Fragment BuildVariableSet(TokenPosition* position);
  Fragment BuildVariableSet(uint8_t payload, TokenPosition* position);
  Fragment BuildVariableSetImpl(TokenPosition position,
                                intptr_t variable_kernel_position);
  Fragment BuildInstanceGet(TokenPosition* position);
  Fragment BuildDynamicGet(TokenPosition* position);
  Fragment BuildInstanceTearOff(TokenPosition* position);
  Fragment BuildFunctionTearOff(TokenPosition* position);
  Fragment BuildInstanceSet(TokenPosition* position);
  Fragment BuildDynamicSet(TokenPosition* position);
  Fragment BuildAllocateInvocationMirrorCall(TokenPosition position,
                                             const String& name,
                                             intptr_t num_type_arguments,
                                             intptr_t num_arguments,
                                             const Array& argument_names,
                                             LocalVariable* actuals_array,
                                             Fragment build_rest_of_actuals);
  Fragment BuildSuperPropertyGet(TokenPosition* position);
  Fragment BuildSuperPropertySet(TokenPosition* position);
  Fragment BuildStaticGet(TokenPosition* position);
  Fragment BuildStaticSet(TokenPosition* position);
  Fragment BuildMethodInvocation(TokenPosition* position, bool is_dynamic);
  Fragment BuildLocalFunctionInvocation(TokenPosition* position);
  Fragment BuildFunctionInvocation(TokenPosition* position);
  Fragment BuildEqualsCall(TokenPosition* position);
  Fragment BuildEqualsNull(TokenPosition* position);
  Fragment BuildSuperMethodInvocation(TokenPosition* position);
  Fragment BuildStaticInvocation(TokenPosition* position);
  Fragment BuildConstructorInvocation(TokenPosition* position);
  Fragment BuildNot(TokenPosition* position);
  Fragment BuildNullCheck(TokenPosition* position);
  Fragment BuildLogicalExpression(TokenPosition* position);
  Fragment TranslateLogicalExpressionForValue(bool negated,
                                              TestFragment* side_exits);
  Fragment BuildConditionalExpression(TokenPosition* position);
  Fragment BuildStringConcatenation(TokenPosition* position);
  Fragment BuildIsExpression(TokenPosition* position);
  Fragment BuildAsExpression(TokenPosition* position);
  Fragment BuildTypeLiteral(TokenPosition* position);
  Fragment BuildThisExpression(TokenPosition* position);
  Fragment BuildRethrow(TokenPosition* position);
  Fragment BuildThrow(TokenPosition* position);
  Fragment BuildListLiteral(TokenPosition* position);
  Fragment BuildMapLiteral(TokenPosition* position);
  Fragment BuildFunctionExpression();
  Fragment BuildLet(TokenPosition* position);
  Fragment BuildBlockExpression();
  Fragment BuildBigIntLiteral(TokenPosition* position);
  Fragment BuildStringLiteral(TokenPosition* position);
  Fragment BuildIntLiteral(uint8_t payload, TokenPosition* position);
  Fragment BuildIntLiteral(bool is_negative, TokenPosition* position);
  Fragment BuildDoubleLiteral(TokenPosition* position);
  Fragment BuildBoolLiteral(bool value, TokenPosition* position);
  Fragment BuildNullLiteral(TokenPosition* position);
  Fragment BuildFutureNullValue(TokenPosition* position);
  Fragment BuildConstantExpression(TokenPosition* position, Tag tag);
  Fragment BuildPartialTearoffInstantiation(TokenPosition* position);
  Fragment BuildLibraryPrefixAction(TokenPosition* position,
                                    const String& selector);
  Fragment BuildAwaitExpression(TokenPosition* position);

  Fragment BuildExpressionStatement(TokenPosition* position);
  Fragment BuildBlock(TokenPosition* position);
  Fragment BuildEmptyStatement();
  Fragment BuildAssertBlock(TokenPosition* position);
  Fragment BuildAssertStatement(TokenPosition* position);
  Fragment BuildLabeledStatement(TokenPosition* position);
  Fragment BuildBreakStatement(TokenPosition* position);
  Fragment BuildWhileStatement(TokenPosition* position);
  Fragment BuildDoStatement(TokenPosition* position);
  Fragment BuildForStatement(TokenPosition* position);
  Fragment BuildForInStatement(bool async, TokenPosition* position);
  Fragment BuildSwitchStatement(TokenPosition* position);
  Fragment BuildContinueSwitchStatement(TokenPosition* position);
  Fragment BuildIfStatement(TokenPosition* position);
  Fragment BuildReturnStatement(TokenPosition* position);
  Fragment BuildTryCatch(TokenPosition* position);
  Fragment BuildTryFinally(TokenPosition* position);
  Fragment BuildYieldStatement(TokenPosition* position);
  Fragment BuildVariableDeclaration(TokenPosition* position);
  Fragment BuildFunctionDeclaration(intptr_t offset, TokenPosition* position);
  Fragment BuildFunctionNode(TokenPosition parent_position,
                             StringIndex name_index,
                             bool has_valid_annotation,
                             bool has_pragma,
                             intptr_t func_decl_offset);

  // Build flow graph for '_nativeEffect'.
  Fragment BuildNativeEffect();

  // Build flow graph for '_loadAbiSpecificInt' and
  // '_loadAbiSpecificIntAtIndex', '_storeAbiSpecificInt', and
  // '_storeAbiSpecificIntAtIndex' call sites.
  //
  // The second argument is either offsetInBytes (at_index==false), or
  // index (at_index==true).
  Fragment BuildLoadAbiSpecificInt(bool at_index);
  Fragment BuildStoreAbiSpecificInt(bool at_index);

  // Build FG for '_asFunctionInternal'. Reads an Arguments from the
  // Kernel buffer and pushes the resulting closure.
  Fragment BuildFfiAsFunctionInternal();

  // Build FG for '_nativeCallbackFunction'. Reads an Arguments from the
  // Kernel buffer and pushes the resulting Function object.
  Fragment BuildFfiNativeCallbackFunction();

  // Piece of a StringConcatenation.
  // Represents either a StringLiteral, or a Reader offset to the expression.
  struct ConcatPiece {
    intptr_t offset;
    const String* literal;
  };

  // Collector that automatically concatenates adjacent string ConcatPieces.
  struct PiecesCollector {
    explicit PiecesCollector(Zone* z, TranslationHelper* translation_helper)
        : pieces(5),
          literal_run(z, 1),
          translation_helper(translation_helper) {}

    GrowableArray<ConcatPiece> pieces;
    GrowableHandlePtrArray<const String> literal_run;
    TranslationHelper* translation_helper;

    void Add(const ConcatPiece& piece) {
      if (piece.literal != nullptr) {
        literal_run.Add(*piece.literal);
      } else {
        FlushRun();
        pieces.Add(piece);
      }
    }

    void FlushRun() {
      switch (literal_run.length()) {
        case 0:
          return;
        case 1:
          pieces.Add({-1, &literal_run[0]});
          break;
        default:
          pieces.Add({-1, &translation_helper->DartString(literal_run)});
      }
      literal_run.Clear();
    }
  };

  // Flattens and collects pieces of StringConcatenations such that:
  //   ["a", "", "b"] => ["ab"]
  //   ["a", StringConcat("b", "c")] => ["abc"]
  //   ["a", "", StringConcat("b", my_var), "c"] => ["ab", my_var, "c"]
  void FlattenStringConcatenation(PiecesCollector* collector);

  FlowGraphBuilder* flow_graph_builder_;
  ActiveClass* const active_class_;
  ConstantReader constant_reader_;
  TypeTranslator type_translator_;
  DirectCallMetadataHelper direct_call_metadata_helper_;
  InferredTypeMetadataHelper inferred_type_metadata_helper_;
  ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_;
  CallSiteAttributesMetadataHelper call_site_attributes_metadata_helper_;
  Object& closure_owner_;
  intptr_t num_ast_nodes_ = 0;

  friend class KernelLoader;

  DISALLOW_COPY_AND_ASSIGN(StreamingFlowGraphBuilder);
};

}  // namespace kernel
}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_FRONTEND_KERNEL_BINARY_FLOWGRAPH_H_
