// 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:
    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;
}

bool MethodRecognizer::HasNonNullableResultTypeFromPragma(
    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_non_nullable_result_type(),
                          /*multiple=*/false, &option)) {
    return true;
  }

  // If nothing said otherwise, the return type is nullable.
  return false;
}

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 class_name;
  const char* const function_name;
  const char* const enum_name;
  const uint32_t fp;
} recognized_methods[MethodRecognizer::kNumRecognizedMethods] = {
    {"", "", "Unknown", 0},
#define RECOGNIZE_METHOD(class_name, function_name, enum_name, fp)             \
  {"" #class_name, "" #function_name, #enum_name, fp},
    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);
}

void MethodRecognizer::InitializeState() {
  GrowableArray<Library*> libs(3);
  Libraries(&libs);
  Function& func = Function::Handle();
  bool fingerprints_match = true;

  for (intptr_t i = 1; i < MethodRecognizer::kNumRecognizedMethods; i++) {
    const MethodRecognizer::Kind kind = static_cast<MethodRecognizer::Kind>(i);
    func = Library::GetFunction(libs, recognized_methods[i].class_name,
                                recognized_methods[i].function_name);
    if (!func.IsNull()) {
      fingerprints_match =
          func.CheckSourceFingerprint(recognized_methods[i].fp) &&
          fingerprints_match;
      func.set_recognized_kind(kind);
      switch (kind) {
#define RECOGNIZE_METHOD(class_name, function_name, enum_name, fp)             \
  case MethodRecognizer::k##enum_name:                                         \
    func.reset_unboxed_parameters_and_return();                                \
    break;
        ALL_INTRINSICS_LIST(RECOGNIZE_METHOD)
#undef RECOGNIZE_METHOD
        default:
          break;
      }
    } else if (!FLAG_precompiled_mode) {
      fingerprints_match = false;
      OS::PrintErr("Missing %s::%s\n", recognized_methods[i].class_name,
                   recognized_methods[i].function_name);
    }
  }

#define SET_FUNCTION_BIT(class_name, function_name, dest, fp, setter, value)   \
  func = Library::GetFunction(libs, #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(class_name, function_name, dest, fp)         \
  SET_FUNCTION_BIT(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");
  }
}

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::ConvertLibrary()));
  libs->Add(&Library::ZoneHandle(Library::InternalLibrary()));
  libs->Add(&Library::ZoneHandle(Library::IsolateLibrary()));
  libs->Add(&Library::ZoneHandle(Library::DeveloperLibrary()));
  libs->Add(&Library::ZoneHandle(Library::AsyncLibrary()));
  libs->Add(&Library::ZoneHandle(Library::FfiLibrary()));
  libs->Add(&Library::ZoneHandle(Library::NativeWrappersLibrary()));
}

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::Token(Token::kNE).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, 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::kIllegal, -1, 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::kIllegal; 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
