// Copyright (c) 2018, 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_BYTECODE_READER_H_
#define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_

#include "vm/compiler/frontend/kernel_translation_helper.h"
#include "vm/constants_kbc.h"
#include "vm/object.h"

#if !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {
namespace kernel {

class BytecodeComponentData;

// Helper class which provides access to bytecode metadata.
class BytecodeMetadataHelper : public MetadataHelper {
 public:
  static const char* tag() { return "vm.bytecode"; }

  explicit BytecodeMetadataHelper(KernelReaderHelper* helper,
                                  ActiveClass* active_class);

  void ParseBytecodeFunction(ParsedFunction* parsed_function);

  // Read all library declarations.
  bool ReadLibraries();

  // Read specific library declaration.
  void ReadLibrary(const Library& library);

  // Scan through libraries in the bytecode component and figure out if any of
  // them will replace libraries which are already loaded.
  // Return true if bytecode component is found.
  bool FindModifiedLibrariesForHotReload(BitVector* modified_libs,
                                         bool* is_empty_program,
                                         intptr_t* p_num_classes,
                                         intptr_t* p_num_procedures);

  RawLibrary* GetMainLibrary();

  RawArray* GetBytecodeComponent();
  RawArray* ReadBytecodeComponent();

 private:
  ActiveClass* const active_class_;

  DISALLOW_COPY_AND_ASSIGN(BytecodeMetadataHelper);
};

// Helper class for reading bytecode.
class BytecodeReaderHelper : public ValueObject {
 public:
  explicit BytecodeReaderHelper(TranslationHelper* translation_helper,
                                ActiveClass* active_class,
                                BytecodeComponentData* bytecode_component);

  Reader& reader() { return reader_; }

  void ReadCode(const Function& function, intptr_t code_offset);

  RawArray* CreateForwarderChecks(const Function& function);

  void ReadMembers(const Class& cls, bool discard_fields);

  void ReadFieldDeclarations(const Class& cls, bool discard_fields);
  void ReadFunctionDeclarations(const Class& cls);
  void ReadClassDeclaration(const Class& cls);
  void ReadLibraryDeclaration(const Library& library, bool lookup_classes);
  void ReadLibraryDeclarations(intptr_t num_libraries);
  void FindAndReadSpecificLibrary(const Library& library,
                                  intptr_t num_libraries);
  void FindModifiedLibrariesForHotReload(BitVector* modified_libs,
                                         intptr_t num_libraries);

  void ParseBytecodeFunction(ParsedFunction* parsed_function,
                             const Function& function);

  RawLibrary* ReadMain();

  RawArray* ReadBytecodeComponent(intptr_t md_offset);
  void ResetObjects();

  // Fills in [is_covariant] and [is_generic_covariant_impl] vectors
  // according to covariance attributes of [function] parameters.
  //
  // [function] should be declared in bytecode.
  // [is_covariant] and [is_generic_covariant_impl] should contain bitvectors
  // of function.NumParameters() length.
  void ReadParameterCovariance(const Function& function,
                               BitVector* is_covariant,
                               BitVector* is_generic_covariant_impl);

  // Returns an flattened array of tuples {isFinal, defaultValue, metadata},
  // or an Error.
  RawObject* BuildParameterDescriptor(const Function& function);

  // Read bytecode PackedObject.
  RawObject* ReadObject();

 private:
  // These constants should match corresponding constants in class ObjectHandle
  // (pkg/vm/lib/bytecode/object_table.dart).
  static const int kReferenceBit = 1 << 0;
  static const int kIndexShift = 1;
  static const int kKindShift = 1;
  static const int kKindMask = 0x0f;
  static const int kFlagBit0 = 1 << 5;
  static const int kFlagBit1 = 1 << 6;
  static const int kFlagBit2 = 1 << 7;
  static const int kFlagBit3 = 1 << 8;
  static const int kFlagsMask = (kFlagBit0 | kFlagBit1 | kFlagBit2 | kFlagBit3);

  // Code flags, must be in sync with Code constants in
  // pkg/vm/lib/bytecode/declarations.dart.
  struct Code {
    static const int kHasExceptionsTableFlag = 1 << 0;
    static const int kHasSourcePositionsFlag = 1 << 1;
    static const int kHasNullableFieldsFlag = 1 << 2;
    static const int kHasClosuresFlag = 1 << 3;
    static const int kHasParameterFlagsFlag = 1 << 4;
    static const int kHasForwardingStubTargetFlag = 1 << 5;
    static const int kHasDefaultFunctionTypeArgsFlag = 1 << 6;
    static const int kHasLocalVariablesFlag = 1 << 7;
  };

  // Closure code flags, must be in sync with ClosureCode constants in
  // pkg/vm/lib/bytecode/declarations.dart.
  struct ClosureCode {
    static const int kHasExceptionsTableFlag = 1 << 0;
    static const int kHasSourcePositionsFlag = 1 << 1;
    static const int kHasLocalVariablesFlag = 1 << 2;
  };

  // Parameter flags, must be in sync with ParameterDeclaration constants in
  // pkg/vm/lib/bytecode/declarations.dart.
  struct Parameter {
    static const int kIsCovariantFlag = 1 << 0;
    static const int kIsGenericCovariantImplFlag = 1 << 1;
    static const int kIsFinalFlag = 1 << 2;
  };

  class FunctionTypeScope : public ValueObject {
   public:
    explicit FunctionTypeScope(BytecodeReaderHelper* bytecode_reader)
        : bytecode_reader_(bytecode_reader),
          saved_type_parameters_(
              bytecode_reader->function_type_type_parameters_) {}

    ~FunctionTypeScope() {
      bytecode_reader_->function_type_type_parameters_ = saved_type_parameters_;
    }

   private:
    BytecodeReaderHelper* bytecode_reader_;
    const TypeArguments* const saved_type_parameters_;
  };

  class FunctionScope : public ValueObject {
   public:
    FunctionScope(BytecodeReaderHelper* bytecode_reader,
                  const Function& function,
                  const String& name,
                  const Class& cls)
        : bytecode_reader_(bytecode_reader) {
      ASSERT(bytecode_reader_->scoped_function_.IsNull());
      ASSERT(bytecode_reader_->scoped_function_name_.IsNull());
      ASSERT(bytecode_reader_->scoped_function_class_.IsNull());
      ASSERT(name.IsSymbol());
      bytecode_reader_->scoped_function_ = function.raw();
      bytecode_reader_->scoped_function_name_ = name.raw();
      bytecode_reader_->scoped_function_class_ = cls.raw();
    }

    ~FunctionScope() {
      bytecode_reader_->scoped_function_ = Function::null();
      bytecode_reader_->scoped_function_name_ = String::null();
      bytecode_reader_->scoped_function_class_ = Class::null();
    }

   private:
    BytecodeReaderHelper* bytecode_reader_;
  };

  void ReadClosureDeclaration(const Function& function, intptr_t closureIndex);
  RawType* ReadFunctionSignature(const Function& func,
                                 bool has_optional_positional_params,
                                 bool has_optional_named_params,
                                 bool has_type_params,
                                 bool has_positional_param_names);
  void ReadTypeParametersDeclaration(const Class& parameterized_class,
                                     const Function& parameterized_function);

  // Read portion of constant pool corresponding to one function/closure.
  // Start with [start_index], and stop when reaching EndClosureFunctionScope.
  // Return index of the last read constant pool entry.
  intptr_t ReadConstantPool(const Function& function,
                            const ObjectPool& pool,
                            intptr_t start_index);

  RawBytecode* ReadBytecode(const ObjectPool& pool);
  void ReadExceptionsTable(const Bytecode& bytecode, bool has_exceptions_table);
  void ReadSourcePositions(const Bytecode& bytecode, bool has_source_positions);
  void ReadLocalVariables(const Bytecode& bytecode, bool has_local_variables);
  RawTypedData* NativeEntry(const Function& function,
                            const String& external_name);
  RawString* ConstructorName(const Class& cls, const String& name);

  RawObject* ReadObjectContents(uint32_t header);
  RawObject* ReadConstObject(intptr_t tag);
  RawObject* ReadType(intptr_t tag);
  RawString* ReadString(bool is_canonical = true);
  RawScript* ReadSourceFile(const String& uri, intptr_t offset);
  RawTypeArguments* ReadTypeArguments();
  RawPatchClass* GetPatchClass(const Class& cls, const Script& script);
  void ParseForwarderFunction(ParsedFunction* parsed_function,
                              const Function& function,
                              const Function& target);

  bool IsExpressionEvaluationLibrary(const Library& library) const {
    return expression_evaluation_library_ != nullptr &&
           expression_evaluation_library_->raw() == library.raw();
  }

  // Similar to cls.EnsureClassDeclaration, but may be more efficient if
  // class is from the current kernel binary.
  void LoadReferencedClass(const Class& cls);

  Reader reader_;
  TranslationHelper& translation_helper_;
  ActiveClass* const active_class_;
  Thread* const thread_;
  Zone* const zone_;
  BytecodeComponentData* const bytecode_component_;
  Array* closures_ = nullptr;
  const TypeArguments* function_type_type_parameters_ = nullptr;
  GrowableObjectArray* pending_recursive_types_ = nullptr;
  PatchClass* patch_class_ = nullptr;
  Array* functions_ = nullptr;
  intptr_t function_index_ = 0;
  Function& scoped_function_;
  String& scoped_function_name_;
  Class& scoped_function_class_;
  Library* expression_evaluation_library_ = nullptr;
  bool loading_native_wrappers_library_ = false;
  bool reading_type_arguments_of_recursive_type_ = false;

  DISALLOW_COPY_AND_ASSIGN(BytecodeReaderHelper);
};

class BytecodeComponentData : ValueObject {
 public:
  enum {
    kVersion,
    kStringsHeaderOffset,
    kStringsContentsOffset,
    kObjectOffsetsOffset,
    kNumObjects,
    kObjectsContentsOffset,
    kMainOffset,
    kNumLibraries,
    kLibraryIndexOffset,
    kLibrariesOffset,
    kNumClasses,
    kClassesOffset,
    kMembersOffset,
    kNumCodes,
    kCodesOffset,
    kSourcePositionsOffset,
    kSourceFilesOffset,
    kLineStartsOffset,
    kLocalVariablesOffset,
    kAnnotationsOffset,
    kNumFields
  };

  explicit BytecodeComponentData(Array* data) : data_(*data) {}

  void Init(const Array& data) { data_ = data.raw(); }

  intptr_t GetVersion() const;
  intptr_t GetStringsHeaderOffset() const;
  intptr_t GetStringsContentsOffset() const;
  intptr_t GetObjectOffsetsOffset() const;
  intptr_t GetNumObjects() const;
  intptr_t GetObjectsContentsOffset() const;
  intptr_t GetMainOffset() const;
  intptr_t GetNumLibraries() const;
  intptr_t GetLibraryIndexOffset() const;
  intptr_t GetLibrariesOffset() const;
  intptr_t GetNumClasses() const;
  intptr_t GetClassesOffset() const;
  intptr_t GetMembersOffset() const;
  intptr_t GetNumCodes() const;
  intptr_t GetCodesOffset() const;
  intptr_t GetSourcePositionsOffset() const;
  intptr_t GetSourceFilesOffset() const;
  intptr_t GetLineStartsOffset() const;
  intptr_t GetLocalVariablesOffset() const;
  intptr_t GetAnnotationsOffset() const;
  void SetObject(intptr_t index, const Object& obj) const;
  RawObject* GetObject(intptr_t index) const;

  bool IsNull() const { return data_.IsNull(); }

  static RawArray* New(Zone* zone,
                       intptr_t version,
                       intptr_t num_objects,
                       intptr_t strings_header_offset,
                       intptr_t strings_contents_offset,
                       intptr_t object_offsets_offset,
                       intptr_t objects_contents_offset,
                       intptr_t main_offset,
                       intptr_t num_libraries,
                       intptr_t library_index_offset,
                       intptr_t libraries_offset,
                       intptr_t num_classes,
                       intptr_t classes_offset,
                       intptr_t members_offset,
                       intptr_t num_codes,
                       intptr_t codes_offset,
                       intptr_t source_positions_offset,
                       intptr_t source_files_offset,
                       intptr_t line_starts_offset,
                       intptr_t local_variables_offset,
                       intptr_t annotations_offset,
                       Heap::Space space);

 private:
  Array& data_;
};

class BytecodeReader : public AllStatic {
 public:
  // Reads bytecode for the given function and sets its bytecode field.
  // Returns error (if any), or null.
  static RawError* ReadFunctionBytecode(Thread* thread,
                                        const Function& function);

  // Read annotations for the given annotation field.
  static RawObject* ReadAnnotation(const Field& annotation_field);
  // Read the |count| annotations following given annotation field.
  static RawArray* ReadExtendedAnnotations(const Field& annotation_field,
                                           intptr_t count);

  static void ResetObjectTable(const KernelProgramInfo& info);

  // Read declaration of the given library.
  static void LoadLibraryDeclaration(const Library& library);

  // Read declaration of the given class.
  static void LoadClassDeclaration(const Class& cls);

  // Read members of the given class.
  static void FinishClassLoading(const Class& cls);

#if !defined(PRODUCT)
  // Compute local variable descriptors for [function] with [bytecode].
  static RawLocalVarDescriptors* ComputeLocalVarDescriptors(
      Zone* zone,
      const Function& function,
      const Bytecode& bytecode);
#endif
};

class BytecodeSourcePositionsIterator : ValueObject {
 public:
  // These constants should match corresponding constants in class
  // SourcePositions (pkg/vm/lib/bytecode/source_positions.dart).
  static const intptr_t kSyntheticCodeMarker = -1;
  static const intptr_t kYieldPointMarker = -2;

  BytecodeSourcePositionsIterator(Zone* zone, const Bytecode& bytecode)
      : reader_(ExternalTypedData::Handle(zone, bytecode.GetBinary(zone))) {
    if (bytecode.HasSourcePositions()) {
      reader_.set_offset(bytecode.source_positions_binary_offset());
      pairs_remaining_ = reader_.ReadUInt();
    }
  }

  bool MoveNext() {
    if (pairs_remaining_ == 0) {
      return false;
    }
    ASSERT(pairs_remaining_ > 0);
    --pairs_remaining_;
    cur_bci_ += reader_.ReadUInt();
    cur_token_pos_ += reader_.ReadSLEB128();
    is_yield_point_ = false;
    if (cur_token_pos_ == kYieldPointMarker) {
      const bool result = MoveNext();
      is_yield_point_ = true;
      return result;
    }
    return true;
  }

  uword PcOffset() const { return cur_bci_; }

  TokenPosition TokenPos() const {
    return (cur_token_pos_ == kSyntheticCodeMarker)
               ? TokenPosition::kNoSource
               : TokenPosition(cur_token_pos_);
  }

  bool IsYieldPoint() const { return is_yield_point_; }

 private:
  Reader reader_;
  intptr_t pairs_remaining_ = 0;
  intptr_t cur_bci_ = 0;
  intptr_t cur_token_pos_ = 0;
  bool is_yield_point_ = false;
};

class BytecodeLocalVariablesIterator : ValueObject {
 public:
  // These constants should match corresponding constants in
  // pkg/vm/lib/bytecode/local_variable_table.dart.
  enum {
    kInvalid,
    kScope,
    kVariableDeclaration,
    kContextVariable,
  };

  static const intptr_t kKindMask = 0xF;
  static const intptr_t kIsCapturedFlag = 1 << 4;

  BytecodeLocalVariablesIterator(Zone* zone, const Bytecode& bytecode)
      : reader_(ExternalTypedData::Handle(zone, bytecode.GetBinary(zone))),
        object_pool_(ObjectPool::Handle(zone, bytecode.object_pool())) {
    if (bytecode.HasLocalVariablesInfo()) {
      reader_.set_offset(bytecode.local_variables_binary_offset());
      entries_remaining_ = reader_.ReadUInt();
    }
  }

  bool MoveNext() {
    if (entries_remaining_ <= 0) {
      // Finished looking at the last entry, now we're done.
      entries_remaining_ = -1;
      return false;
    }
    --entries_remaining_;
    cur_kind_and_flags_ = reader_.ReadByte();
    cur_start_pc_ += reader_.ReadSLEB128();
    switch (Kind()) {
      case kScope:
        cur_end_pc_ = cur_start_pc_ + reader_.ReadUInt();
        cur_index_ = reader_.ReadSLEB128();
        cur_token_pos_ = reader_.ReadPosition();
        cur_end_token_pos_ = reader_.ReadPosition();
        break;
      case kVariableDeclaration:
        cur_index_ = reader_.ReadSLEB128();
        cur_name_ = reader_.ReadUInt();
        cur_type_ = reader_.ReadUInt();
        cur_declaration_token_pos_ = reader_.ReadPosition();
        cur_token_pos_ = reader_.ReadPosition();
        break;
      case kContextVariable:
        cur_index_ = reader_.ReadSLEB128();
        break;
    }
    return true;
  }

  // Returns true after iterator moved past the last entry and
  // MoveNext() returned false.
  bool IsDone() const { return entries_remaining_ < 0; }

  intptr_t Kind() const { return cur_kind_and_flags_ & kKindMask; }
  bool IsScope() const { return Kind() == kScope; }
  bool IsVariableDeclaration() const { return Kind() == kVariableDeclaration; }
  bool IsContextVariable() const { return Kind() == kContextVariable; }

  intptr_t StartPC() const { return cur_start_pc_; }
  intptr_t EndPC() const {
    ASSERT(IsScope() || IsVariableDeclaration());
    return cur_end_pc_;
  }
  intptr_t ContextLevel() const {
    ASSERT(IsScope());
    return cur_index_;
  }
  TokenPosition StartTokenPos() const {
    ASSERT(IsScope() || IsVariableDeclaration());
    return cur_token_pos_;
  }
  TokenPosition EndTokenPos() const {
    ASSERT(IsScope() || IsVariableDeclaration());
    return cur_end_token_pos_;
  }
  intptr_t Index() const {
    ASSERT(IsVariableDeclaration() || IsContextVariable());
    return cur_index_;
  }
  RawString* Name() const {
    ASSERT(IsVariableDeclaration());
    return String::RawCast(object_pool_.ObjectAt(cur_name_));
  }
  RawAbstractType* Type() const {
    ASSERT(IsVariableDeclaration());
    return AbstractType::RawCast(object_pool_.ObjectAt(cur_type_));
  }
  TokenPosition DeclarationTokenPos() const {
    ASSERT(IsVariableDeclaration());
    return cur_declaration_token_pos_;
  }
  bool IsCaptured() const {
    ASSERT(IsVariableDeclaration());
    return (cur_kind_and_flags_ & kIsCapturedFlag) != 0;
  }

 private:
  Reader reader_;
  const ObjectPool& object_pool_;
  intptr_t entries_remaining_ = 0;
  intptr_t cur_kind_and_flags_ = 0;
  intptr_t cur_start_pc_ = 0;
  intptr_t cur_end_pc_ = 0;
  intptr_t cur_index_ = -1;
  intptr_t cur_name_ = -1;
  intptr_t cur_type_ = -1;
  TokenPosition cur_token_pos_ = TokenPosition::kNoSource;
  TokenPosition cur_declaration_token_pos_ = TokenPosition::kNoSource;
  TokenPosition cur_end_token_pos_ = TokenPosition::kNoSource;
};

bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
                                               Zone* zone);

}  // namespace kernel
}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
#endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_
