// 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_TOKEN_POSITION_H_
#define RUNTIME_VM_TOKEN_POSITION_H_

#include "platform/utils.h"
#include "vm/allocation.h"

namespace dart {

// The token space is organized as follows:
//
// Sentinel values start at -1 and move towards negative infinity:
// kNoSourcePos                -> -1
// ClassifyingTokenPositions 1 -> -1 - 1
// ClassifyingTokenPositions N -> -1 - N
//
// Synthetically created AstNodes are given real source positions but encoded
// as negative numbers from [kSmiMin32, -1 - N]. For example:
//
// A source position of 0 in a synthetic AstNode would be encoded as -2 - N.
// A source position of 1 in a synthetic AstNode would be encoded as -3 - N.
//
// All other AstNodes are given real source positions encoded as positive
// integers.
//
// This organization allows for ~1 billion token positions.

#define SENTINEL_TOKEN_DESCRIPTORS(V)                                          \
  V(NoSource, -1)                                                              \
  V(Box, -2)                                                                   \
  V(ParallelMove, -3)                                                          \
  V(TempMove, -4)                                                              \
  V(Constant, -5)                                                              \
  V(PushArgument, -6)                                                          \
  V(ControlFlow, -7)                                                           \
  V(Context, -8)                                                               \
  V(MethodExtractor, -9)                                                       \
  V(DeferredSlowPath, -10)                                                     \
  V(DeferredDeoptInfo, -11)                                                    \
  V(DartCodePrologue, -12)                                                     \
  V(DartCodeEpilogue, -13)                                                     \
  V(Last, -14)  // Always keep this at the end.

// A token position representing a debug safe source (real) position,
// non-debug safe source (synthetic) positions, or a classifying value used
// by the profiler.
class TokenPosition {
 public:
  TokenPosition() : value_(kNoSource.value()) {}

  explicit TokenPosition(intptr_t value) : value_(value) {}

  bool operator==(const TokenPosition& b) const { return value() == b.value(); }

  bool operator!=(const TokenPosition& b) const { return !(*this == b); }

  bool operator<(const TokenPosition& b) const {
    // TODO(johnmccutchan): Assert that this is a source position.
    return value() < b.value();
  }

  bool operator>(const TokenPosition& b) const {
    // TODO(johnmccutchan): Assert that this is a source position.
    return b < *this;
  }

  bool operator<=(const TokenPosition& b) {
    // TODO(johnmccutchan): Assert that this is a source position.
    return !(*this > b);
  }

  bool operator>=(const TokenPosition& b) {
    // TODO(johnmccutchan): Assert that this is a source position.
    return !(*this < b);
  }

  static const intptr_t kMaxSentinelDescriptors = 64;

#define DECLARE_VALUES(name, value) static const TokenPosition k##name;
  SENTINEL_TOKEN_DESCRIPTORS(DECLARE_VALUES);
#undef DECLARE_VALUES
  static const TokenPosition kMinSource;
  static const TokenPosition kMaxSource;

  // Decode from a snapshot.
  static TokenPosition SnapshotDecode(int32_t value);

  // Encode for writing into a snapshot.
  int32_t SnapshotEncode();

  // Increment the token position.
  TokenPosition Next() {
    ASSERT(IsReal());
    value_++;
    return *this;
  }

  // The raw value.
  // TODO(johnmccutchan): Make this private.
  intptr_t value() const { return value_; }

  // Return the source position.
  intptr_t Pos() const {
    if (IsSynthetic()) {
      return FromSynthetic().Pos();
    }
    return value_;
  }

  // Token position constants.
  static const intptr_t kNoSourcePos = -1;
  static const intptr_t kMinSourcePos = 0;
  static const intptr_t kMaxSourcePos = kSmiMax32 - kMaxSentinelDescriptors - 2;

  // Is |this| a classifying sentinel source position?
  // Classifying positions are used by the profiler to group instructions whose
  // cost isn't naturally attributable to a source location.
  bool IsClassifying() const {
    return (value_ >= kBox.value()) && (value_ <= kLast.value());
  }

  // Is |this| the no source position sentinel?
  bool IsNoSource() const { return *this == kNoSource; }

  // Is |this| a synthetic source position?
  // Synthetic source positions are used by the profiler to attribute ticks to a
  // pieces of source, but ignored by the debugger as potential breakpoints.
  bool IsSynthetic() const;

  // Is |this| a real source position?
  bool IsReal() const { return value_ >= kMinSourcePos; }

  // Is |this| a source position?
  bool IsSourcePosition() const {
    return IsReal() || IsNoSource() || IsSynthetic();
  }

  // Is |this| a debug pause source position?
  bool IsDebugPause() const {
    // Sanity check some values here.
    ASSERT(kNoSource.value() == kNoSourcePos);
    ASSERT(kLast.value() < kNoSource.value());
    ASSERT(kLast.value() > -kMaxSentinelDescriptors);
    return IsReal();
  }

  // Convert |this| into a synthetic source position. Sentinel values remain
  // unchanged.
  TokenPosition ToSynthetic() const {
    const intptr_t value = value_;
    if (IsClassifying() || IsNoSource()) {
      return *this;
    }
    if (IsSynthetic()) {
      return *this;
    }
    const TokenPosition synthetic_value =
        TokenPosition((kLast.value() - 1) - value);
    ASSERT(synthetic_value.IsSynthetic());
    ASSERT(synthetic_value.value() < kLast.value());
    return synthetic_value;
  }

  // Convert |this| from a synthetic source position. Sentinel values remain
  // unchanged.
  TokenPosition FromSynthetic() const {
    const intptr_t synthetic_value = value_;
    if (IsClassifying() || IsNoSource()) {
      return *this;
    }
    if (!IsSynthetic()) {
      return *this;
    }
    const TokenPosition value =
        TokenPosition(-synthetic_value + (kLast.value() - 1));
    ASSERT(!value.IsSynthetic());
    return value;
  }

  const char* ToCString() const;

 private:
  int32_t value_;

  DISALLOW_ALLOCATION();
};

}  // namespace dart

#endif  // RUNTIME_VM_TOKEN_POSITION_H_
