// Copyright (c) 2014, 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.

#include "vm/compiler/method_recognizer.h"

#include "vm/object.h"
#include "vm/reusable_handles.h"
#include "vm/symbols.h"

namespace dart {

MethodRecognizer::Kind MethodRecognizer::RecognizeKind(
    const Function& function) {
  return function.recognized_kind();
}

bool MethodRecognizer::AlwaysInline(const Function& function) {
  return function.always_inline();
}

bool MethodRecognizer::PolymorphicTarget(const Function& function) {
  return function.is_polymorphic_target();
}

intptr_t MethodRecognizer::NumArgsCheckedForStaticCall(
    const Function& function) {
  switch (RecognizeKind(function)) {
    case MethodRecognizer::kDoubleFromInteger:
    case MethodRecognizer::kMathMin:
    case MethodRecognizer::kMathMax:
      return 2;
    default:
      return 0;
  }
}

intptr_t MethodRecognizer::ResultCid(const Function& function) {
  // Use the 'vm:exact-result-type' annotation if available. This can only be
  // used within the core library, see 'result_type_pragma.md', detail 1.2 for
  // explanation.
  Class& cls = Thread::Current()->ClassHandle();
  Library& lib = Thread::Current()->LibraryHandle();
  cls = function.Owner();
  lib = cls.library();
  const bool can_use_pragma = lib.IsAnyCoreLibrary();
  cls = Class::null();
  if (can_use_pragma) {
    Isolate* I = Isolate::Current();
    auto& option = Object::Handle();
    if (function.FindPragma(I, Symbols::vm_exact_result_type(), &option)) {
      if (option.IsType()) {
        return Type::Cast(option).type_class_id();
      } else if (option.IsString()) {
        auto& str = String::Cast(option);
        // 'str' should match the pattern '([^#]+)#([^#\?]+)' where group 1
        // is the library URI and group 2 is the class name.
        bool parse_failure = false;
        intptr_t library_end = -1;
        for (intptr_t i = 0; i < str.Length(); ++i) {
          if (str.CharAt(i) == '#') {
            if (library_end != -1) {
              parse_failure = true;
              break;
            } else {
              library_end = i;
            }
          }
        }
        if (!parse_failure && library_end > 0) {
          auto& libraryUri = String::Handle(
              String::SubString(str, 0, library_end, Heap::kOld));
          auto& className = String::Handle(
              String::SubString(str, library_end + 1,
                                str.Length() - library_end - 1, Heap::kOld));

          Library& lib = Library::Handle(
              Library::LookupLibrary(Thread::Current(), libraryUri));
          if (!lib.IsNull()) {
            Class& klass =
                Class::Handle(lib.LookupClassAllowPrivate(className));
            if (!klass.IsNull()) {
              return klass.id();
            }
          }
        }
      }
    }
  }

  // No result-type annotation can be used, so fall back on the table of
  // recognized methods.
  switch (function.recognized_kind()) {
#define DEFINE_CASE(cname, fname, ename, result_type, fingerprint)             \
  case k##ename: {                                                             \
    const intptr_t cid = k##result_type##Cid;                                  \
    if (FLAG_strong && cid != kDynamicCid) {                                   \
      String& err = String::Handle();                                          \
      err = function.QualifiedScrubbedName();                                  \
      err = String::Concat(                                                    \
          err,                                                                 \
          String::Handle(String::New(" (MethodRecognizer::k" #ename            \
                                     ") should be using pragma annotation"     \
                                     " rather than method recognizer.",        \
                                     Heap::kOld)),                             \
          Heap::kOld);                                                         \
      FATAL(err.ToCString());                                                  \
    }                                                                          \
    return cid;                                                                \
  }
    RECOGNIZED_LIST(DEFINE_CASE)
#undef DEFINE_CASE
    default:
      return kDynamicCid;
  }
}

intptr_t MethodRecognizer::MethodKindToReceiverCid(Kind kind) {
  switch (kind) {
    case kImmutableArrayGetIndexed:
      return kImmutableArrayCid;

    case kObjectArrayGetIndexed:
    case kObjectArraySetIndexed:
    case kObjectArraySetIndexedUnchecked:
      return kArrayCid;

    case kGrowableArrayGetIndexed:
    case kGrowableArraySetIndexed:
    case kGrowableArraySetIndexedUnchecked:
      return kGrowableObjectArrayCid;

    case kFloat32ArrayGetIndexed:
    case kFloat32ArraySetIndexed:
      return kTypedDataFloat32ArrayCid;

    case kFloat64ArrayGetIndexed:
    case kFloat64ArraySetIndexed:
      return kTypedDataFloat64ArrayCid;

    case kInt8ArrayGetIndexed:
    case kInt8ArraySetIndexed:
      return kTypedDataInt8ArrayCid;

    case kUint8ArrayGetIndexed:
    case kUint8ArraySetIndexed:
      return kTypedDataUint8ArrayCid;

    case kUint8ClampedArrayGetIndexed:
    case kUint8ClampedArraySetIndexed:
      return kTypedDataUint8ClampedArrayCid;

    case kExternalUint8ArrayGetIndexed:
    case kExternalUint8ArraySetIndexed:
      return kExternalTypedDataUint8ArrayCid;

    case kExternalUint8ClampedArrayGetIndexed:
    case kExternalUint8ClampedArraySetIndexed:
      return kExternalTypedDataUint8ClampedArrayCid;

    case kInt16ArrayGetIndexed:
    case kInt16ArraySetIndexed:
      return kTypedDataInt16ArrayCid;

    case kUint16ArrayGetIndexed:
    case kUint16ArraySetIndexed:
      return kTypedDataUint16ArrayCid;

    case kInt32ArrayGetIndexed:
    case kInt32ArraySetIndexed:
      return kTypedDataInt32ArrayCid;

    case kUint32ArrayGetIndexed:
    case kUint32ArraySetIndexed:
      return kTypedDataUint32ArrayCid;

    case kInt64ArrayGetIndexed:
    case kInt64ArraySetIndexed:
      return kTypedDataInt64ArrayCid;

    case kUint64ArrayGetIndexed:
    case kUint64ArraySetIndexed:
      return kTypedDataUint64ArrayCid;

    case kFloat32x4ArrayGetIndexed:
    case kFloat32x4ArraySetIndexed:
      return kTypedDataFloat32x4ArrayCid;

    case kInt32x4ArrayGetIndexed:
    case kInt32x4ArraySetIndexed:
      return kTypedDataInt32x4ArrayCid;

    case kFloat64x2ArrayGetIndexed:
    case kFloat64x2ArraySetIndexed:
      return kTypedDataFloat64x2ArrayCid;

    default:
      break;
  }
  UNREACHABLE();
  return kIllegalCid;
}

#define KIND_TO_STRING(class_name, function_name, enum_name, type, fp)         \
  #enum_name,
static const char* recognized_list_method_name[] = {
    "Unknown", RECOGNIZED_LIST(KIND_TO_STRING)};
#undef KIND_TO_STRING

const char* MethodRecognizer::KindToCString(Kind kind) {
  if (kind > kUnknown && kind < kNumRecognizedMethods)
    return recognized_list_method_name[kind];
  return "?";
}

#if !defined(DART_PRECOMPILED_RUNTIME)
void MethodRecognizer::InitializeState() {
  GrowableArray<Library*> libs(3);
  Libraries(&libs);
  Function& func = Function::Handle();

#define SET_RECOGNIZED_KIND(class_name, function_name, enum_name, type, fp)    \
  func = Library::GetFunction(libs, #class_name, #function_name);              \
  if (!func.IsNull()) {                                                        \
    CHECK_FINGERPRINT3(func, class_name, function_name, enum_name, fp);        \
    func.set_recognized_kind(k##enum_name);                                    \
  } else if (!FLAG_precompiled_mode) {                                         \
    OS::PrintErr("Missing %s::%s\n", #class_name, #function_name);             \
    UNREACHABLE();                                                             \
  }

  RECOGNIZED_LIST(SET_RECOGNIZED_KIND);

#define SET_FUNCTION_BIT(class_name, function_name, dest, fp, setter, value)   \
  func = Library::GetFunction(libs, #class_name, #function_name);              \
  if (!func.IsNull()) {                                                        \
    CHECK_FINGERPRINT3(func, class_name, function_name, dest, fp);             \
    func.setter(value);                                                        \
  } else if (!FLAG_precompiled_mode) {                                         \
    OS::PrintErr("Missing %s::%s\n", #class_name, #function_name);             \
    UNREACHABLE();                                                             \
  }

#define SET_IS_ALWAYS_INLINE(class_name, function_name, dest, fp)              \
  SET_FUNCTION_BIT(class_name, function_name, dest, fp, set_always_inline, true)

#define SET_IS_NEVER_INLINE(class_name, function_name, dest, fp)               \
  SET_FUNCTION_BIT(class_name, function_name, dest, fp, set_is_inlinable, false)

#define SET_IS_POLYMORPHIC_TARGET(class_name, function_name, dest, fp)         \
  SET_FUNCTION_BIT(class_name, function_name, dest, fp,                        \
                   set_is_polymorphic_target, true)

  INLINE_WHITE_LIST(SET_IS_ALWAYS_INLINE);
  INLINE_BLACK_LIST(SET_IS_NEVER_INLINE);
  POLYMORPHIC_TARGET_LIST(SET_IS_POLYMORPHIC_TARGET);

#undef SET_RECOGNIZED_KIND
#undef SET_IS_ALWAYS_INLINE
#undef SET_IS_POLYMORPHIC_TARGET
#undef SET_FUNCTION_BIT
}

void MethodRecognizer::Libraries(GrowableArray<Library*>* libs) {
  libs->Add(&Library::ZoneHandle(Library::CoreLibrary()));
  libs->Add(&Library::ZoneHandle(Library::CollectionLibrary()));
  libs->Add(&Library::ZoneHandle(Library::MathLibrary()));
  libs->Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
  libs->Add(&Library::ZoneHandle(Library::InternalLibrary()));
  libs->Add(&Library::ZoneHandle(Library::DeveloperLibrary()));
  libs->Add(&Library::ZoneHandle(Library::AsyncLibrary()));
}

RawGrowableObjectArray* MethodRecognizer::QueryRecognizedMethods(Zone* zone) {
  const GrowableObjectArray& methods =
      GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
  Function& func = Function::Handle(zone);

  GrowableArray<Library*> libs(3);
  Libraries(&libs);

#define ADD_RECOGNIZED_METHOD(class_name, function_name, enum_name, type, fp)  \
  func = Library::GetFunction(libs, #class_name, #function_name);              \
  methods.Add(func);

  RECOGNIZED_LIST(ADD_RECOGNIZED_METHOD);
#undef ADD_RECOGNIZED_METHOD

  return methods.raw();
}
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

Token::Kind MethodTokenRecognizer::RecognizeTokenKind(const String& name_) {
  Thread* thread = Thread::Current();
  REUSABLE_STRING_HANDLESCOPE(thread);
  String& name = thread->StringHandle();
  name = name_.raw();
  ASSERT(name.IsSymbol());
  if (Function::IsDynamicInvocationForwaderName(name)) {
    name = Function::DemangleDynamicInvocationForwarderName(name);
  }
  if (name.raw() == Symbols::Plus().raw()) {
    return Token::kADD;
  } else if (name.raw() == Symbols::Minus().raw()) {
    return Token::kSUB;
  } else if (name.raw() == Symbols::Star().raw()) {
    return Token::kMUL;
  } else if (name.raw() == Symbols::Slash().raw()) {
    return Token::kDIV;
  } else if (name.raw() == Symbols::TruncDivOperator().raw()) {
    return Token::kTRUNCDIV;
  } else if (name.raw() == Symbols::Percent().raw()) {
    return Token::kMOD;
  } else if (name.raw() == Symbols::BitOr().raw()) {
    return Token::kBIT_OR;
  } else if (name.raw() == Symbols::Ampersand().raw()) {
    return Token::kBIT_AND;
  } else if (name.raw() == Symbols::Caret().raw()) {
    return Token::kBIT_XOR;
  } else if (name.raw() == Symbols::LeftShiftOperator().raw()) {
    return Token::kSHL;
  } else if (name.raw() == Symbols::RightShiftOperator().raw()) {
    return Token::kSHR;
  } else if (name.raw() == Symbols::Tilde().raw()) {
    return Token::kBIT_NOT;
  } else if (name.raw() == Symbols::UnaryMinus().raw()) {
    return Token::kNEGATE;
  } else if (name.raw() == Symbols::EqualOperator().raw()) {
    return Token::kEQ;
  } else if (name.raw() == Symbols::Token(Token::kNE).raw()) {
    return Token::kNE;
  } else if (name.raw() == Symbols::LAngleBracket().raw()) {
    return Token::kLT;
  } else if (name.raw() == Symbols::RAngleBracket().raw()) {
    return Token::kGT;
  } else if (name.raw() == Symbols::LessEqualOperator().raw()) {
    return Token::kLTE;
  } else if (name.raw() == Symbols::GreaterEqualOperator().raw()) {
    return Token::kGTE;
  } else if (Field::IsGetterName(name)) {
    return Token::kGET;
  } else if (Field::IsSetterName(name)) {
    return Token::kSET;
  }
  return Token::kILLEGAL;
}

#define RECOGNIZE_FACTORY(symbol, class_name, constructor_name, cid, fp)       \
  {Symbols::k##symbol##Id, cid, fp, #symbol ", " #cid},  // NOLINT

static struct {
  intptr_t symbol_id;
  intptr_t cid;
  intptr_t finger_print;
  const char* name;
} factory_recognizer_list[] = {RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY){
    Symbols::kIllegal, -1, -1, NULL}};

#undef RECOGNIZE_FACTORY

intptr_t FactoryRecognizer::ResultCid(const Function& factory) {
  ASSERT(factory.IsFactory());
  const Class& function_class = Class::Handle(factory.Owner());
  const Library& lib = Library::Handle(function_class.library());
  ASSERT((lib.raw() == Library::CoreLibrary()) ||
         (lib.raw() == Library::TypedDataLibrary()));
  const String& factory_name = String::Handle(factory.name());
  for (intptr_t i = 0;
       factory_recognizer_list[i].symbol_id != Symbols::kIllegal; i++) {
    if (String::EqualsIgnoringPrivateKey(
            factory_name,
            Symbols::Symbol(factory_recognizer_list[i].symbol_id))) {
      return factory_recognizer_list[i].cid;
    }
  }
  return kDynamicCid;
}

}  // namespace dart
