// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_HANDLER_TABLE_H_
#define V8_HANDLER_TABLE_H_

#include "src/assert-scope.h"
#include "src/globals.h"
#include "src/utils.h"

namespace v8 {
namespace internal {

class Assembler;
class ByteArray;
class BytecodeArray;

// HandlerTable is a byte array containing entries for exception handlers in
// the code object it is associated with. The tables come in two flavors:
// 1) Based on ranges: Used for unoptimized code. Stored in a {ByteArray} that
//    is attached to each {BytecodeArray}. Contains one entry per exception
//    handler and a range representing the try-block covered by that handler.
//    Layout looks as follows:
//      [ range-start , range-end , handler-offset , handler-data ]
// 2) Based on return addresses: Used for turbofanned code. Stored directly in
//    the instruction stream of the {Code} object. Contains one entry per
//    call-site that could throw an exception. Layout looks as follows:
//      [ return-address-offset , handler-offset ]
class V8_EXPORT_PRIVATE HandlerTable {
 public:
  // Conservative prediction whether a given handler will locally catch an
  // exception or cause a re-throw to outside the code boundary. Since this is
  // undecidable it is merely an approximation (e.g. useful for debugger).
  enum CatchPrediction {
    UNCAUGHT,     // The handler will (likely) rethrow the exception.
    CAUGHT,       // The exception will be caught by the handler.
    PROMISE,      // The exception will be caught and cause a promise rejection.
    DESUGARING,   // The exception will be caught, but both the exception and
                  // the catching are part of a desugaring and should therefore
                  // not be visible to the user (we won't notify the debugger of
                  // such exceptions).
    ASYNC_AWAIT,  // The exception will be caught and cause a promise rejection
                  // in the desugaring of an async function, so special
                  // async/await handling in the debugger can take place.
  };

  // Constructors for the various encodings.
  explicit HandlerTable(Code* code);
  explicit HandlerTable(ByteArray* byte_array);
  explicit HandlerTable(BytecodeArray* bytecode_array);
  explicit HandlerTable(Address instruction_start, size_t handler_table_offset);

  // Getters for handler table based on ranges.
  int GetRangeStart(int index) const;
  int GetRangeEnd(int index) const;
  int GetRangeHandler(int index) const;
  int GetRangeData(int index) const;

  // Setters for handler table based on ranges.
  void SetRangeStart(int index, int value);
  void SetRangeEnd(int index, int value);
  void SetRangeHandler(int index, int offset, CatchPrediction pred);
  void SetRangeData(int index, int value);

  // Returns the required length of the underlying byte array.
  static int LengthForRange(int entries);

  // Emitters for handler table based on return addresses.
  static int EmitReturnTableStart(Assembler* masm, int entries);
  static void EmitReturnEntry(Assembler* masm, int offset, int handler);

  // Lookup handler in a table based on ranges. The {pc_offset} is an offset to
  // the start of the potentially throwing instruction (using return addresses
  // for this value would be invalid).
  int LookupRange(int pc_offset, int* data, CatchPrediction* prediction);

  // Lookup handler in a table based on return addresses.
  int LookupReturn(int pc_offset);

  // Returns the number of entries in the table.
  int NumberOfRangeEntries() const;
  int NumberOfReturnEntries() const;

#ifdef ENABLE_DISASSEMBLER
  void HandlerTableRangePrint(std::ostream& os);   // NOLINT
  void HandlerTableReturnPrint(std::ostream& os);  // NOLINT
#endif

 private:
  enum EncodingMode { kRangeBasedEncoding, kReturnAddressBasedEncoding };

  // Getters for handler table based on ranges.
  CatchPrediction GetRangePrediction(int index) const;

  // Getters for handler table based on return addresses.
  int GetReturnOffset(int index) const;
  int GetReturnHandler(int index) const;

  // Number of entries in the loaded handler table.
  int number_of_entries_;

#ifdef DEBUG
  // The encoding mode of the table. Mostly useful for debugging to check that
  // used accessors and constructors fit together.
  EncodingMode mode_;
#endif

  // Direct pointer into the encoded data. This pointer points into object on
  // the GC heap (either {ByteArray} or {Code}) and hence would become stale
  // during a collection. Hence we disallow any allocation.
  Address raw_encoded_data_;
  DisallowHeapAllocation no_gc_;

  // Layout description for handler table based on ranges.
  static const int kRangeStartIndex = 0;
  static const int kRangeEndIndex = 1;
  static const int kRangeHandlerIndex = 2;
  static const int kRangeDataIndex = 3;
  static const int kRangeEntrySize = 4;

  // Layout description for handler table based on return addresses.
  static const int kReturnOffsetIndex = 0;
  static const int kReturnHandlerIndex = 1;
  static const int kReturnEntrySize = 2;

  // Encoding of the {handler} field.
  class HandlerPredictionField : public BitField<CatchPrediction, 0, 3> {};
  class HandlerOffsetField : public BitField<int, 3, 29> {};
};

}  // namespace internal
}  // namespace v8

#endif  // V8_HANDLER_TABLE_H_
