/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_PRIMITIVE_H_
#define ART_RUNTIME_PRIMITIVE_H_

#include <sys/types.h>

#include <android-base/logging.h>

#include "base/macros.h"

namespace art {

static constexpr size_t kObjectReferenceSize = 4;

constexpr size_t ComponentSizeShiftWidth(size_t component_size) {
  return component_size == 1u ? 0u :
      component_size == 2u ? 1u :
          component_size == 4u ? 2u :
              component_size == 8u ? 3u : 0u;
}

class Primitive {
 public:
  enum Type {
    kPrimNot = 0,
    kPrimBoolean,
    kPrimByte,
    kPrimChar,
    kPrimShort,
    kPrimInt,
    kPrimLong,
    kPrimFloat,
    kPrimDouble,
    kPrimVoid,
    kPrimLast = kPrimVoid
  };

  static constexpr Type GetType(char type) {
    switch (type) {
      case 'B':
        return kPrimByte;
      case 'C':
        return kPrimChar;
      case 'D':
        return kPrimDouble;
      case 'F':
        return kPrimFloat;
      case 'I':
        return kPrimInt;
      case 'J':
        return kPrimLong;
      case 'S':
        return kPrimShort;
      case 'Z':
        return kPrimBoolean;
      case 'V':
        return kPrimVoid;
      default:
        return kPrimNot;
    }
  }

  static constexpr size_t ComponentSizeShift(Type type) {
    switch (type) {
      case kPrimVoid:
      case kPrimBoolean:
      case kPrimByte:    return 0;
      case kPrimChar:
      case kPrimShort:   return 1;
      case kPrimInt:
      case kPrimFloat:   return 2;
      case kPrimLong:
      case kPrimDouble:  return 3;
      case kPrimNot:     return ComponentSizeShiftWidth(kObjectReferenceSize);
    }
    LOG(FATAL) << "Invalid type " << static_cast<int>(type);
    UNREACHABLE();
  }

  static constexpr size_t ComponentSize(Type type) {
    switch (type) {
      case kPrimVoid:    return 0;
      case kPrimBoolean:
      case kPrimByte:    return 1;
      case kPrimChar:
      case kPrimShort:   return 2;
      case kPrimInt:
      case kPrimFloat:   return 4;
      case kPrimLong:
      case kPrimDouble:  return 8;
      case kPrimNot:     return kObjectReferenceSize;
    }
    LOG(FATAL) << "Invalid type " << static_cast<int>(type);
    UNREACHABLE();
  }

  static const char* Descriptor(Type type) {
    switch (type) {
      case kPrimBoolean:
        return "Z";
      case kPrimByte:
        return "B";
      case kPrimChar:
        return "C";
      case kPrimShort:
        return "S";
      case kPrimInt:
        return "I";
      case kPrimFloat:
        return "F";
      case kPrimLong:
        return "J";
      case kPrimDouble:
        return "D";
      case kPrimVoid:
        return "V";
      default:
        LOG(FATAL) << "Primitive char conversion on invalid type " << static_cast<int>(type);
        return nullptr;
    }
  }

  static const char* PrettyDescriptor(Type type);

  // Returns the descriptor corresponding to the boxed type of |type|.
  static const char* BoxedDescriptor(Type type);

  // Returns true if |type| is an numeric type.
  static constexpr bool IsNumericType(Type type) {
    switch (type) {
      case Primitive::Type::kPrimNot: return false;
      case Primitive::Type::kPrimBoolean: return false;
      case Primitive::Type::kPrimByte: return true;
      case Primitive::Type::kPrimChar: return true;
      case Primitive::Type::kPrimShort: return true;
      case Primitive::Type::kPrimInt: return true;
      case Primitive::Type::kPrimLong: return true;
      case Primitive::Type::kPrimFloat: return true;
      case Primitive::Type::kPrimDouble: return true;
      case Primitive::Type::kPrimVoid: return false;
    }
    LOG(FATAL) << "Invalid type " << static_cast<int>(type);
    UNREACHABLE();
  }

  // Return trues if |type| is a signed numeric type.
  static constexpr bool IsSignedNumericType(Type type) {
    switch (type) {
      case Primitive::Type::kPrimNot: return false;
      case Primitive::Type::kPrimBoolean: return false;
      case Primitive::Type::kPrimByte: return true;
      case Primitive::Type::kPrimChar: return false;
      case Primitive::Type::kPrimShort: return true;
      case Primitive::Type::kPrimInt: return true;
      case Primitive::Type::kPrimLong: return true;
      case Primitive::Type::kPrimFloat: return true;
      case Primitive::Type::kPrimDouble: return true;
      case Primitive::Type::kPrimVoid: return false;
    }
    LOG(FATAL) << "Invalid type " << static_cast<int>(type);
    UNREACHABLE();
  }

  // Returns the number of bits required to hold the largest
  // positive number that can be represented by |type|.
  static constexpr size_t BitsRequiredForLargestValue(Type type) {
    switch (type) {
      case Primitive::Type::kPrimNot: return 0u;
      case Primitive::Type::kPrimBoolean: return 1u;
      case Primitive::Type::kPrimByte: return 7u;
      case Primitive::Type::kPrimChar: return 16u;
      case Primitive::Type::kPrimShort: return 15u;
      case Primitive::Type::kPrimInt: return 31u;
      case Primitive::Type::kPrimLong: return 63u;
      case Primitive::Type::kPrimFloat: return 128u;
      case Primitive::Type::kPrimDouble: return 1024u;
      case Primitive::Type::kPrimVoid: return 0u;
    }
  }

  // Returns true if it is possible to widen type |from| to type |to|. Both |from| and
  // |to| should be numeric primitive types.
  static bool IsWidenable(Type from, Type to) {
    if (!IsNumericType(from) || !IsNumericType(to)) {
      // Widening is only applicable between numeric types.
      return false;
    }
    if (IsSignedNumericType(from) && !IsSignedNumericType(to)) {
      // Nowhere to store the sign bit in |to|.
      return false;
    }
    if (BitsRequiredForLargestValue(from) > BitsRequiredForLargestValue(to)) {
      // The from,to pair corresponds to a narrowing.
      return false;
    }
    return true;
  }

  static bool Is64BitType(Type type) {
    return type == kPrimLong || type == kPrimDouble;
  }

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(Primitive);
};

std::ostream& operator<<(std::ostream& os, Primitive::Type state);

}  // namespace art

#endif  // ART_RUNTIME_PRIMITIVE_H_
