// 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/log.h"
#include "vm/object.h"
#include "vm/reusable_handles.h"
#include "vm/symbols.h"

namespace dart {

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

intptr_t MethodRecognizer::ResultCidFromPragma(
    const Object& function_or_field) {
  auto T = Thread::Current();
  auto Z = T->zone();
  auto& option = Object::Handle(Z);
  if (Library::FindPragma(T, /*only_core=*/true, function_or_field,
                          Symbols::vm_exact_result_type(),
                          /*multiple=*/false, &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& tmp =
            String::Handle(String::SubString(str, 0, library_end, Heap::kOld));
        const auto& library = Library::Handle(Library::LookupLibrary(T, tmp));
        if (!library.IsNull()) {
          tmp = String::SubString(str, library_end + 1,
                                  str.Length() - library_end - 1, Heap::kOld);
          const auto& klass =
              Class::Handle(library.LookupClassAllowPrivate(tmp));
          if (!klass.IsNull()) {
            return klass.id();
          }
        }
      }
    } else if (option.IsArray()) {
      const Array& array = Array::Cast(option);
      if (array.Length() > 0) {
        const Object& type = Object::Handle(Array::Cast(option).At(0));
        if (type.IsType()) {
          return Type::Cast(type).type_class_id();
        }
      }
    }
  }

  return kDynamicCid;
}

intptr_t MethodRecognizer::MethodKindToReceiverCid(Kind kind) {
  switch (kind) {
    case kObjectArrayGetIndexed:
    case kObjectArraySetIndexed:
    case kObjectArraySetIndexedUnchecked:
      return kArrayCid;

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

#define TYPED_DATA_GET_SET_INDEXED_CASES(clazz)                                \
  case k##clazz##ArrayGetIndexed:                                              \
  case k##clazz##ArraySetIndexed:                                              \
    return kTypedData##clazz##ArrayCid;                                        \
  case kExternal##clazz##ArrayGetIndexed:                                      \
    return kExternalTypedData##clazz##ArrayCid;                                \
  case k##clazz##ArrayViewGetIndexed:                                          \
    return kTypedData##clazz##ArrayViewCid;

      DART_CLASS_LIST_TYPED_DATA(TYPED_DATA_GET_SET_INDEXED_CASES);
#undef TYPED_DATA_GET_SET_INDEXED_CASES

    case kExternalUint8ArraySetIndexed:
      return kExternalTypedDataUint8ArrayCid;

    case kExternalUint8ClampedArraySetIndexed:
      return kExternalTypedDataUint8ClampedArrayCid;

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

static const struct {
  const char* const function_name;
  const char* const enum_name;
} recognized_methods[MethodRecognizer::kNumRecognizedMethods] = {
    {"", "Unknown"},
#define RECOGNIZE_METHOD(library, class_name, function_name, enum_name, fp)    \
  {"" #function_name, #enum_name},
    RECOGNIZED_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD
};

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

const char* MethodRecognizer::KindToFunctionNameCString(Kind kind) {
  if (kind >= kUnknown && kind < kNumRecognizedMethods)
    return recognized_methods[kind].function_name;
  return "?";
}

// Is this method marked with the vm:recognized pragma?
bool MethodRecognizer::IsMarkedAsRecognized(const Function& function,
                                            const char* kind) {
  const Function* functionp =
      function.IsDynamicInvocationForwarder()
          ? &Function::Handle(function.ForwardingTarget())
          : &function;
  Object& options = Object::Handle();
  bool is_recognized = Library::FindPragma(
      Thread::Current(), /*only_core=*/true, *functionp,
      Symbols::vm_recognized(), /*multiple=*/false, &options);
  if (!is_recognized) return false;
  if (kind == nullptr) return true;

  ASSERT(options.IsString());
  ASSERT(String::Cast(options).Equals("asm-intrinsic") ||
         String::Cast(options).Equals("graph-intrinsic") ||
         String::Cast(options).Equals("other"));
  return String::Cast(options).Equals(kind);
}

static bool IsAssemblerIntrinsic(MethodRecognizer::Kind kind) {
  switch (kind) {
#define RECOGNIZE_METHOD(library, class_name, function_name, enum_name, fp)    \
  case MethodRecognizer::k##enum_name:
    ASM_INTRINSICS_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD
    return true;
    default:
      return false;
  }
}

static bool IsGraphIntrinsic(MethodRecognizer::Kind kind) {
  switch (kind) {
#define RECOGNIZE_METHOD(library, class_name, function_name, enum_name, fp)    \
  case MethodRecognizer::k##enum_name:
    GRAPH_INTRINSICS_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD
    return true;
    default:
      return false;
  }
}

void MethodRecognizer::InitializeState() {
  Library& lib = Library::Handle();
  Function& func = Function::Handle();
  bool fingerprints_match = true;

#define RECOGNIZE_METHOD(library, class_name, function_name, enum_name, fp)    \
  lib = Library::library();                                                    \
  func = Library::GetFunction(lib, #class_name, #function_name);               \
  if (!func.IsNull()) {                                                        \
    fingerprints_match =                                                       \
        func.CheckSourceFingerprint(fp) && fingerprints_match;                 \
    func.set_recognized_kind(k##enum_name);                                    \
    if (IsAssemblerIntrinsic(k##enum_name)) {                                  \
      func.reset_unboxed_parameters_and_return();                              \
      func.set_is_intrinsic(true);                                             \
    } else if (IsGraphIntrinsic(k##enum_name)) {                               \
      func.set_is_intrinsic(true);                                             \
    }                                                                          \
  } else if (!FLAG_precompiled_mode) {                                         \
    fingerprints_match = false;                                                \
    OS::PrintErr("Missing %s %s::%s\n", #library, #class_name,                 \
                 #function_name);                                              \
  }
  RECOGNIZED_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD

#define SET_FUNCTION_BIT(library, class_name, function_name, dest, fp, setter, \
                         value)                                                \
  lib = Library::library();                                                    \
  func = Library::GetFunction(lib, #class_name, #function_name);               \
  if (!func.IsNull()) {                                                        \
    fingerprints_match =                                                       \
        func.CheckSourceFingerprint(fp) && fingerprints_match;                 \
    func.setter(value);                                                        \
  } else if (!FLAG_precompiled_mode) {                                         \
    OS::PrintErr("Missing %s::%s\n", #class_name, #function_name);             \
    fingerprints_match = false;                                                \
  }

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

  POLYMORPHIC_TARGET_LIST(SET_IS_POLYMORPHIC_TARGET);

#undef SET_RECOGNIZED_KIND
#undef SET_IS_POLYMORPHIC_TARGET
#undef SET_FUNCTION_BIT

  if (!fingerprints_match) {
    // Private names are mangled. Mangling depends on Library::private_key_.
    // If registering a new bootstrap library, add at the end.
    FATAL(
        "FP mismatch while recognizing methods. If the behavior of "
        "these functions has changed, then changes are also needed in "
        "the VM's compiler. Otherwise the fingerprint can simply be "
        "updated in recognized_methods_list.h\n");
  }
}

static Token::Kind RecognizeTokenKindHelper(const String& name) {
  if (name.ptr() == Symbols::Plus().ptr()) {
    return Token::kADD;
  } else if (name.ptr() == Symbols::Minus().ptr()) {
    return Token::kSUB;
  } else if (name.ptr() == Symbols::Star().ptr()) {
    return Token::kMUL;
  } else if (name.ptr() == Symbols::Slash().ptr()) {
    return Token::kDIV;
  } else if (name.ptr() == Symbols::TruncDivOperator().ptr()) {
    return Token::kTRUNCDIV;
  } else if (name.ptr() == Symbols::Percent().ptr()) {
    return Token::kMOD;
  } else if (name.ptr() == Symbols::BitOr().ptr()) {
    return Token::kBIT_OR;
  } else if (name.ptr() == Symbols::Ampersand().ptr()) {
    return Token::kBIT_AND;
  } else if (name.ptr() == Symbols::Caret().ptr()) {
    return Token::kBIT_XOR;
  } else if (name.ptr() == Symbols::LeftShiftOperator().ptr()) {
    return Token::kSHL;
  } else if (name.ptr() == Symbols::RightShiftOperator().ptr()) {
    return Token::kSHR;
  } else if (name.ptr() == Symbols::UnsignedRightShiftOperator().ptr()) {
    return Token::kUSHR;
  } else if (name.ptr() == Symbols::Tilde().ptr()) {
    return Token::kBIT_NOT;
  } else if (name.ptr() == Symbols::UnaryMinus().ptr()) {
    return Token::kNEGATE;
  } else if (name.ptr() == Symbols::EqualOperator().ptr()) {
    return Token::kEQ;
  } else if (name.ptr() == Symbols::NotEqualOperator().ptr()) {
    return Token::kNE;
  } else if (name.ptr() == Symbols::LAngleBracket().ptr()) {
    return Token::kLT;
  } else if (name.ptr() == Symbols::RAngleBracket().ptr()) {
    return Token::kGT;
  } else if (name.ptr() == Symbols::LessEqualOperator().ptr()) {
    return Token::kLTE;
  } else if (name.ptr() == Symbols::GreaterEqualOperator().ptr()) {
    return Token::kGTE;
  } else if (Field::IsGetterName(name)) {
    return Token::kGET;
  } else if (Field::IsSetterName(name)) {
    return Token::kSET;
  }
  return Token::kILLEGAL;
}

Token::Kind MethodTokenRecognizer::RecognizeTokenKind(const String& name) {
  ASSERT(name.IsSymbol());
  if (Function::IsDynamicInvocationForwarderName(name)) {
    Thread* thread = Thread::Current();
    const auto& demangled_name = String::Handle(
        thread->zone(), Function::DemangleDynamicInvocationForwarderName(name));
    return RecognizeTokenKindHelper(demangled_name);
  } else {
    return RecognizeTokenKindHelper(name);
  }
}

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

static const struct {
  const intptr_t symbol_id;
  const intptr_t cid;
  const uint32_t finger_print;
  const char* const name;
} factory_recognizer_list[] = {RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY){
    Symbols::kEmptyId, kIllegalCid, 0, nullptr}};

#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.ptr() == Library::CoreLibrary()) ||
         (lib.ptr() == Library::TypedDataLibrary()));
  const String& factory_name = String::Handle(factory.name());
  for (intptr_t i = 0;
       factory_recognizer_list[i].symbol_id != Symbols::kEmptyId; i++) {
    if (String::EqualsIgnoringPrivateKey(
            factory_name,
            Symbols::Symbol(factory_recognizer_list[i].symbol_id))) {
      return factory_recognizer_list[i].cid;
    }
  }
  return kDynamicCid;
}

intptr_t FactoryRecognizer::GetResultCidOfListFactory(Zone* zone,
                                                      const Function& function,
                                                      intptr_t argument_count) {
  if (!function.IsFactory()) {
    return kDynamicCid;
  }

  const Class& owner = Class::Handle(zone, function.Owner());
  if ((owner.library() != Library::CoreLibrary()) &&
      (owner.library() != Library::TypedDataLibrary())) {
    return kDynamicCid;
  }

  if (owner.Name() == Symbols::List().ptr()) {
    if (function.name() == Symbols::ListFactory().ptr()) {
      ASSERT(argument_count == 1 || argument_count == 2);
      return (argument_count == 1) ? kGrowableObjectArrayCid : kArrayCid;
    } else if (function.name() == Symbols::ListFilledFactory().ptr()) {
      ASSERT(argument_count == 3 || argument_count == 4);
      return (argument_count == 3) ? kArrayCid : kDynamicCid;
    }
  }

  return ResultCid(function);
}

}  // namespace dart
