// Copyright (c) 2011, 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/bootstrap_natives.h"

#include "lib/invocation_mirror.h"
#include "vm/bytecode_reader.h"
#include "vm/code_patcher.h"
#include "vm/dart_entry.h"
#include "vm/exceptions.h"
#include "vm/heap/heap.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
#include "vm/stack_frame.h"
#include "vm/symbols.h"

namespace dart {

DEFINE_NATIVE_ENTRY(DartAsync_fatal, 0, 1) {
  // The dart:async library code entered an unrecoverable state.
  const Instance& instance =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  const char* msg = instance.ToCString();
  OS::PrintErr("Fatal error in dart:async: %s\n", msg);
  FATAL("%s", msg);
  return Object::null();
}

DEFINE_NATIVE_ENTRY(Object_equals, 0, 1) {
  // Implemented in the flow graph builder.
  UNREACHABLE();
  return Object::null();
}

static intptr_t GetHash(Isolate* isolate, const ObjectPtr obj) {
#if defined(HASH_IN_OBJECT_HEADER)
  return Object::GetCachedHash(obj);
#else
  Heap* heap = isolate->group()->heap();
  ASSERT(obj->IsDartInstance());
  return heap->GetHash(obj);
#endif
}

DEFINE_NATIVE_ENTRY(Object_getHash, 0, 1) {
  // Please note that no handle is created for the argument.
  // This is safe since the argument is only used in a tail call.
  // The performance benefit is more than 5% when using hashCode.
  intptr_t hash = GetHash(isolate, arguments->NativeArgAt(0));
  if (LIKELY(hash != 0)) {
    return Smi::New(hash);
  }

  const Instance& instance =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  return instance.IdentityHashCode(arguments->thread());
}

DEFINE_NATIVE_ENTRY(Object_toString, 0, 1) {
  const Instance& instance =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  if (instance.IsString()) {
    return instance.ptr();
  }
  if (instance.IsAbstractType()) {
    return AbstractType::Cast(instance).UserVisibleName();
  }
  const char* c_str = instance.ToCString();
  return String::New(c_str);
}

DEFINE_NATIVE_ENTRY(Object_runtimeType, 0, 1) {
  const Instance& instance =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  return instance.GetType(Heap::kNew, TypeVisibility::kUserVisibleType);
}

static bool HaveSameRuntimeTypeHelper(Zone* zone,
                                      const Instance& left,
                                      const Instance& right) {
  const intptr_t left_cid = left.GetClassId();
  const intptr_t right_cid = right.GetClassId();

  if (left_cid != right_cid) {
    if (IsIntegerClassId(left_cid)) {
      return IsIntegerClassId(right_cid);
    } else if (IsStringClassId(left_cid)) {
      return IsStringClassId(right_cid);
    } else if (IsTypeClassId(left_cid)) {
      return IsTypeClassId(right_cid);
    } else if (IsArrayClassId(left_cid)) {
      if (!IsArrayClassId(right_cid)) {
        return false;
      }
      // Still need to check type arguments.
    } else {
      return false;
    }
  }

  if (left_cid == kClosureCid) {
    const auto& left_closure = Closure::Cast(left);
    const auto& right_closure = Closure::Cast(right);
    // If all the components that make up the instantiated signature are equal,
    // then no need to instantiate.
    if (left_closure.function_type_arguments() ==
            right_closure.function_type_arguments() &&
        left_closure.delayed_type_arguments() ==
            right_closure.delayed_type_arguments() &&
        left_closure.instantiator_type_arguments() ==
            right_closure.instantiator_type_arguments()) {
      const auto& left_fun = Function::Handle(zone, left_closure.function());
      const auto& right_fun = Function::Handle(zone, right_closure.function());
      if (left_fun.signature() == right_fun.signature()) {
        return true;
      }
    }
    const AbstractType& left_type =
        AbstractType::Handle(zone, left.GetType(Heap::kNew));
    const AbstractType& right_type =
        AbstractType::Handle(zone, right.GetType(Heap::kNew));
    return left_type.IsEquivalent(right_type, TypeEquality::kSyntactical);
  }

  if (left_cid == kRecordCid) {
    const auto& left_record = Record::Cast(left);
    const auto& right_record = Record::Cast(right);
    if (left_record.shape() != right_record.shape()) {
      return false;
    }
    Instance& left_field = Instance::Handle(zone);
    Instance& right_field = Instance::Handle(zone);
    const intptr_t num_fields = left_record.num_fields();
    for (intptr_t i = 0; i < num_fields; ++i) {
      left_field ^= left_record.FieldAt(i);
      right_field ^= right_record.FieldAt(i);
      if (!HaveSameRuntimeTypeHelper(zone, left_field, right_field)) {
        return false;
      }
    }
    return true;
  }

  const Class& cls = Class::Handle(zone, left.clazz());
  if (!cls.IsGeneric()) {
    return true;
  }

  if (left.GetTypeArguments() == right.GetTypeArguments()) {
    return true;
  }
  const TypeArguments& left_type_arguments =
      TypeArguments::Handle(zone, left.GetTypeArguments());
  const TypeArguments& right_type_arguments =
      TypeArguments::Handle(zone, right.GetTypeArguments());
  const intptr_t num_type_args = cls.NumTypeArguments();
  const intptr_t num_type_params = cls.NumTypeParameters();
  return left_type_arguments.IsSubvectorEquivalent(
      right_type_arguments, num_type_args - num_type_params, num_type_params,
      TypeEquality::kSyntactical);
}

DEFINE_NATIVE_ENTRY(Object_haveSameRuntimeType, 0, 2) {
  const Instance& left =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  const Instance& right =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(1));
  return Bool::Get(HaveSameRuntimeTypeHelper(zone, left, right)).ptr();
}

DEFINE_NATIVE_ENTRY(Object_instanceOf, 0, 4) {
  const Instance& instance =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  const TypeArguments& instantiator_type_arguments =
      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(1));
  const TypeArguments& function_type_arguments =
      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(2));
  const AbstractType& type =
      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(3));
  ASSERT(type.IsFinalized());
  const bool is_instance_of = instance.IsInstanceOf(
      type, instantiator_type_arguments, function_type_arguments);
  if (FLAG_trace_type_checks) {
    LogBlock lb;
    const char* result_str = is_instance_of ? "true" : "false";
    THR_Print("Native Object.instanceOf: result %s\n", result_str);
    const AbstractType& instance_type =
        AbstractType::Handle(zone, instance.GetType(Heap::kNew));
    THR_Print("  instance type: %s\n", instance_type.NameCString());
    THR_Print("  test type: %s\n", type.NameCString());
  }
  return Bool::Get(is_instance_of).ptr();
}

DEFINE_NATIVE_ENTRY(Object_simpleInstanceOf, 0, 2) {
  // This native is only called when the right hand side passes
  // SimpleInstanceOfType and it is a non-negative test.
  const Instance& instance =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  const AbstractType& type =
      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(1));
  ASSERT(type.IsFinalized());
  ASSERT(type.IsInstantiated());
  const bool is_instance_of = instance.IsInstanceOf(
      type, Object::null_type_arguments(), Object::null_type_arguments());
  return Bool::Get(is_instance_of).ptr();
}

DEFINE_NATIVE_ENTRY(AbstractType_toString, 0, 1) {
  const AbstractType& type =
      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(0));
  return type.UserVisibleName();
}

DEFINE_NATIVE_ENTRY(AbstractType_getHashCode, 0, 1) {
  const AbstractType& type =
      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(0));
  intptr_t hash_val = type.Hash();
  ASSERT(hash_val > 0);
  ASSERT(Smi::IsValid(hash_val));
  return Smi::New(hash_val);
}

DEFINE_NATIVE_ENTRY(AbstractType_equality, 0, 2) {
  const AbstractType& type =
      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(0));
  const Instance& other =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(1));
  if (type.ptr() == other.ptr()) {
    return Bool::True().ptr();
  }
  return Bool::Get(type.IsEquivalent(other, TypeEquality::kSyntactical)).ptr();
}

DEFINE_NATIVE_ENTRY(Type_equality, 0, 2) {
  const Type& type = Type::CheckedHandle(zone, arguments->NativeArgAt(0));
  const Instance& other =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(1));
  if (type.ptr() == other.ptr()) {
    return Bool::True().ptr();
  }
  return Bool::Get(type.IsEquivalent(other, TypeEquality::kSyntactical)).ptr();
}

DEFINE_NATIVE_ENTRY(LibraryPrefix_isLoaded, 0, 1) {
  const LibraryPrefix& prefix =
      LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
  return Bool::Get(isolate->IsPrefixLoaded(prefix)).ptr();
}

DEFINE_NATIVE_ENTRY(LibraryPrefix_setLoaded, 0, 1) {
  const LibraryPrefix& prefix =
      LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
  isolate->SetPrefixIsLoaded(prefix);
  return Instance::null();
}

DEFINE_NATIVE_ENTRY(LibraryPrefix_loadingUnit, 0, 1) {
  const LibraryPrefix& prefix =
      LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
  const Library& target = Library::Handle(zone, prefix.GetLibrary(0));
  const LoadingUnit& unit = LoadingUnit::Handle(zone, target.loading_unit());
  return Smi::New(unit.IsNull() ? LoadingUnit::kIllegalId : unit.id());
}

DEFINE_NATIVE_ENTRY(LibraryPrefix_issueLoad, 0, 1) {
  const Smi& id = Smi::CheckedHandle(zone, arguments->NativeArgAt(0));
  Array& units =
      Array::Handle(zone, isolate->group()->object_store()->loading_units());
  if (units.IsNull()) {
    // Not actually split.
    const Library& lib = Library::Handle(zone, Library::CoreLibrary());
    const String& sel = String::Handle(zone, String::New("_completeLoads"));
    const Function& func =
        Function::Handle(zone, lib.LookupFunctionAllowPrivate(sel));
    ASSERT(!func.IsNull());
    const Array& args = Array::Handle(zone, Array::New(3));
    args.SetAt(0, id);
    args.SetAt(1, String::Handle(zone));
    args.SetAt(2, Bool::Get(false));
    return DartEntry::InvokeFunction(func, args);
  }
  ASSERT(id.Value() != LoadingUnit::kIllegalId);
  LoadingUnit& unit = LoadingUnit::Handle(zone);
  unit ^= units.At(id.Value());
  return unit.IssueLoad();
}

DEFINE_NATIVE_ENTRY(Internal_unsafeCast, 0, 1) {
  UNREACHABLE();  // Should be erased at Kernel translation time.
  return arguments->NativeArgAt(0);
}

DEFINE_NATIVE_ENTRY(Internal_nativeEffect, 0, 1) {
  UNREACHABLE();
}

DEFINE_NATIVE_ENTRY(Internal_collectAllGarbage, 0, 0) {
  isolate->group()->heap()->CollectAllGarbage(GCReason::kDebugging,
                                              /*compact=*/true);
  return Object::null();
}

DEFINE_NATIVE_ENTRY(Internal_deoptimizeFunctionsOnStack, 0, 0) {
  DeoptimizeFunctionsOnStack();
  return Object::null();
}

DEFINE_NATIVE_ENTRY(Internal_allocateObjectInstructionsStart, 0, 0) {
  auto& stub = Code::Handle(
      zone, isolate->group()->object_store()->allocate_object_stub());
  ASSERT(!stub.IsUnknownDartCode());
  // We return the start offset in the isolate instructions instead of the
  // full address because that fits into small Smis on 32-bit architectures
  // or compressed pointer builds.
  const uword instructions_start =
      reinterpret_cast<uword>(isolate->source()->snapshot_instructions);
  return Smi::New(stub.PayloadStart() - instructions_start);
}

DEFINE_NATIVE_ENTRY(Internal_allocateObjectInstructionsEnd, 0, 0) {
  auto& stub = Code::Handle(
      zone, isolate->group()->object_store()->allocate_object_stub());
  ASSERT(!stub.IsUnknownDartCode());
  // We return the end offset in the isolate instructions instead of the
  // full address because that fits into small Smis on 32-bit architectures
  // or compressed pointer builds.
  const uword instructions_start =
      reinterpret_cast<uword>(isolate->source()->snapshot_instructions);
  return Smi::New((stub.PayloadStart() - instructions_start) + stub.Size());
}

static bool ExtractInterfaceTypeArgs(Zone* zone,
                                     const Class& instance_cls,
                                     const TypeArguments& instance_type_args,
                                     const Class& interface_cls,
                                     TypeArguments* interface_type_args) {
  Thread* thread = Thread::Current();
  Class& cur_cls = Class::Handle(zone, instance_cls.ptr());
  // The following code is a specialization of Class::IsSubtypeOf().
  Array& interfaces = Array::Handle(zone);
  Type& interface = Type::Handle(zone);
  Class& cur_interface_cls = Class::Handle(zone);
  TypeArguments& cur_interface_type_args = TypeArguments::Handle(zone);
  while (true) {
    // Additional subtyping rules related to 'FutureOr' are not applied.
    if (cur_cls.ptr() == interface_cls.ptr()) {
      *interface_type_args = instance_type_args.ptr();
      return true;
    }
    interfaces = cur_cls.interfaces();
    for (intptr_t i = 0; i < interfaces.Length(); i++) {
      interface ^= interfaces.At(i);
      ASSERT(interface.IsFinalized());
      cur_interface_cls = interface.type_class();
      cur_interface_type_args =
          interface.GetInstanceTypeArguments(thread, /*canonicalize=*/false);
      if (!cur_interface_type_args.IsNull() &&
          !cur_interface_type_args.IsInstantiated()) {
        cur_interface_type_args = cur_interface_type_args.InstantiateFrom(
            instance_type_args, Object::null_type_arguments(), kNoneFree,
            Heap::kNew);
      }
      if (ExtractInterfaceTypeArgs(zone, cur_interface_cls,
                                   cur_interface_type_args, interface_cls,
                                   interface_type_args)) {
        return true;
      }
    }
    cur_cls = cur_cls.SuperClass();
    if (cur_cls.IsNull()) {
      return false;
    }
  }
}

// for documentation see pkg/dart_internal/lib/extract_type_arguments.dart
DEFINE_NATIVE_ENTRY(Internal_extractTypeArguments, 0, 2) {
  const Instance& instance =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  const Instance& extract =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(1));

  Class& interface_cls = Class::Handle(zone);
  intptr_t num_type_args = 0;
  if (arguments->NativeTypeArgCount() >= 1) {
    const AbstractType& function_type_arg =
        AbstractType::Handle(zone, arguments->NativeTypeArgAt(0));
    if (function_type_arg.IsType() &&
        (Type::Cast(function_type_arg).arguments() == TypeArguments::null())) {
      interface_cls = function_type_arg.type_class();
      num_type_args = interface_cls.NumTypeParameters();
    }
  }
  if (num_type_args == 0) {
    Exceptions::ThrowArgumentError(String::Handle(
        zone,
        String::New(
            "single function type argument must specify a generic class")));
  }
  if (instance.IsNull()) {
    Exceptions::ThrowArgumentError(instance);
  }
  // Function 'extract' must be generic and accept the same number of type args,
  // unless we execute Dart 1.0 code.
  if (extract.IsNull() || !extract.IsClosure() ||
      ((num_type_args > 0) &&  // Dart 1.0 if num_type_args == 0.
       (Function::Handle(zone, Closure::Cast(extract).function())
            .NumTypeParameters() != num_type_args))) {
    Exceptions::ThrowArgumentError(String::Handle(
        zone,
        String::New("argument 'extract' is not a generic function or not one "
                    "accepting the correct number of type arguments")));
  }
  TypeArguments& extracted_type_args = TypeArguments::Handle(zone);
  if (num_type_args > 0) {
    // The passed instance must implement interface_cls.
    TypeArguments& interface_type_args = TypeArguments::Handle(zone);
    interface_type_args = TypeArguments::New(num_type_args);
    Class& instance_cls = Class::Handle(zone, instance.clazz());
    TypeArguments& instance_type_args = TypeArguments::Handle(zone);
    if (instance_cls.NumTypeArguments() > 0) {
      instance_type_args = instance.GetTypeArguments();
    }
    if (!ExtractInterfaceTypeArgs(zone, instance_cls, instance_type_args,
                                  interface_cls, &interface_type_args)) {
      Exceptions::ThrowArgumentError(String::Handle(
          zone, String::New("type of argument 'instance' is not a subtype of "
                            "the function type argument")));
    }
    if (!interface_type_args.IsNull()) {
      extracted_type_args = TypeArguments::New(num_type_args);
      const intptr_t offset = interface_cls.NumTypeArguments() - num_type_args;
      AbstractType& type_arg = AbstractType::Handle(zone);
      for (intptr_t i = 0; i < num_type_args; i++) {
        type_arg = interface_type_args.TypeAt(offset + i);
        extracted_type_args.SetTypeAt(i, type_arg);
      }
      extracted_type_args =
          extracted_type_args.Canonicalize(thread);  // Can be null.
    }
  }
  // Call the closure 'extract'.
  Array& args_desc = Array::Handle(zone);
  Array& args = Array::Handle(zone);
  if (extracted_type_args.IsNull()) {
    args_desc = ArgumentsDescriptor::NewBoxed(0, 1);
    args = Array::New(1);
    args.SetAt(0, extract);
  } else {
    args_desc = ArgumentsDescriptor::NewBoxed(num_type_args, 1);
    args = Array::New(2);
    args.SetAt(0, extracted_type_args);
    args.SetAt(1, extract);
  }
  const Object& result =
      Object::Handle(zone, DartEntry::InvokeClosure(thread, args, args_desc));
  if (result.IsError()) {
    Exceptions::PropagateError(Error::Cast(result));
    UNREACHABLE();
  }
  return result.ptr();
}

DEFINE_NATIVE_ENTRY(Internal_prependTypeArguments, 0, 4) {
  const TypeArguments& function_type_arguments =
      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
  const TypeArguments& parent_type_arguments =
      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(1));
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_parent_len, arguments->NativeArgAt(2));
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_len, arguments->NativeArgAt(3));
  return function_type_arguments.Prepend(
      zone, parent_type_arguments, smi_parent_len.Value(), smi_len.Value());
}

// Check that a set of type arguments satisfy the type parameter bounds on a
// closure.
// Arg0: Closure object
// Arg1: Type arguments to function
DEFINE_NATIVE_ENTRY(Internal_boundsCheckForPartialInstantiation, 0, 2) {
  const Closure& closure =
      Closure::CheckedHandle(zone, arguments->NativeArgAt(0));
  const Function& target = Function::Handle(zone, closure.function());
  ASSERT(target.IsGeneric());  // No need to check bounds for non-generics.
  const TypeParameters& type_params =
      TypeParameters::Handle(zone, target.type_parameters());
  if (type_params.IsNull() || type_params.AllDynamicBounds()) {
    // The function is not generic or the bounds are all dynamic.
    return Object::null();
  }

  const TypeArguments& type_args_to_check =
      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(1));

  // This should be guaranteed by the front-end.
  ASSERT(type_args_to_check.IsNull() ||
         type_params.Length() <= type_args_to_check.Length());

  // The bounds on the closure may need instantiation.
  const TypeArguments& instantiator_type_args =
      TypeArguments::Handle(zone, closure.instantiator_type_arguments());
  const TypeArguments& function_type_args = TypeArguments::Handle(
      zone,
      type_args_to_check.Prepend(
          zone, TypeArguments::Handle(zone, closure.function_type_arguments()),
          target.NumParentTypeArguments(), target.NumTypeArguments()));

  AbstractType& supertype = AbstractType::Handle(zone);
  AbstractType& subtype = AbstractType::Handle(zone);
  for (intptr_t i = 0; i < type_params.Length(); ++i) {
    supertype = type_params.BoundAt(i);
    subtype = type_args_to_check.IsNull() ? Object::dynamic_type().ptr()
                                          : type_args_to_check.TypeAt(i);

    ASSERT(!subtype.IsNull());
    ASSERT(!supertype.IsNull());

    // The supertype may not be instantiated.
    if (!AbstractType::InstantiateAndTestSubtype(
            &subtype, &supertype, instantiator_type_args, function_type_args)) {
      // Throw a dynamic type error.
      TokenPosition location = TokenPosition::kNoSource;
      {
        DartFrameIterator iterator(Thread::Current(),
                                   StackFrameIterator::kNoCrossThreadIteration);
        StackFrame* caller_frame = iterator.NextFrame();
        ASSERT(caller_frame != nullptr);
        location = caller_frame->GetTokenPos();
      }
      const auto& parameter_name = String::Handle(zone, type_params.NameAt(i));
      Exceptions::CreateAndThrowTypeError(location, subtype, supertype,
                                          parameter_name);
      UNREACHABLE();
    }
  }

  return Object::null();
}

DEFINE_NATIVE_ENTRY(Internal_loadDynamicModule, 0, 1) {
#if defined(DART_DYNAMIC_MODULES)
  GET_NON_NULL_NATIVE_ARGUMENT(TypedData, module_bytes,
                               arguments->NativeArgAt(0));

  const intptr_t length = module_bytes.LengthInBytes();
  uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(length));
  if (data == nullptr) {
    const auto& exception = Instance::Handle(
        zone, thread->isolate_group()->object_store()->out_of_memory());
    Exceptions::Throw(thread, exception);
  }
  {
    NoSafepointScope no_safepoint;
    // The memory does not overlap.
    memcpy(data, module_bytes.DataAddr(0), length);  // NOLINT
  }
  const ExternalTypedData& typed_data = ExternalTypedData::Handle(
      zone,
      ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, length));
  auto& function = Function::Handle();
  {
    SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
    bytecode::BytecodeLoader loader(thread, typed_data);
    function = loader.LoadBytecode();
  }

  if (function.IsNull()) {
    return Object::null();
  }
  ASSERT(function.is_static());
  ASSERT(function.is_declared_in_bytecode());
  auto& result = Object::Handle(zone);

  intptr_t num_arguments;
  for (num_arguments = 2; num_arguments >= 0; --num_arguments) {
    if (function.AreValidArgumentCounts(
            /*num_type_arguments=*/0, num_arguments,
            /*num_named_arguments=*/0, /*error_message=*/nullptr)) {
      break;
    }
  }
  if (num_arguments < 0) {
    Exceptions::ThrowUnsupportedError(
        "Unsupported number of arguments of dynamic module entry point.");
  }
  const auto& args = Array::Handle(zone, Array::New(num_arguments));
  if (num_arguments > 0) {
    // <String>[]
    const auto& arg0 = Array::Handle(
        zone, Array::New(0, Type::Handle(zone, Type::StringType())));
    args.SetAt(0, arg0);
  }
  result = DartEntry::InvokeFunction(function, args);
  if (result.IsError()) {
    Exceptions::PropagateError(Error::Cast(result));
  }
  return result.ptr();
#else
  Exceptions::ThrowUnsupportedError(
      "Loading of dynamic modules is not supported.");
  return Object::null();
#endif  // defined(DART_DYNAMIC_MODULES)
}

DEFINE_NATIVE_ENTRY(InvocationMirror_unpackTypeArguments, 0, 2) {
  const TypeArguments& type_arguments =
      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
  const Smi& num_type_arguments =
      Smi::CheckedHandle(zone, arguments->NativeArgAt(1));
  bool all_dynamic = type_arguments.IsNull();
  const intptr_t len =
      all_dynamic ? num_type_arguments.Value() : type_arguments.Length();
  const Array& type_list = Array::Handle(
      zone, Array::New(len, Type::Handle(zone, Type::DartTypeType())));
  AbstractType& type = AbstractType::Handle(zone);
  for (intptr_t i = 0; i < len; i++) {
    if (all_dynamic) {
      type_list.SetAt(i, Object::dynamic_type());
    } else {
      type = type_arguments.TypeAt(i);
      type_list.SetAt(i, type);
    }
  }
  type_list.MakeImmutable();
  return type_list.ptr();
}

DEFINE_NATIVE_ENTRY(NoSuchMethodError_existingMethodSignature, 0, 3) {
  const Instance& receiver =
      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(String, method_name, arguments->NativeArgAt(1));
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, invocation_type, arguments->NativeArgAt(2));
  InvocationMirror::Level level;
  InvocationMirror::Kind kind;
  InvocationMirror::DecodeType(invocation_type.Value(), &level, &kind);

  Function& function = Function::Handle(zone);
  if (level == InvocationMirror::Level::kTopLevel) {
    if (receiver.IsString()) return receiver.ptr();
    ASSERT(receiver.IsNull());
    return String::null();
  }
  if (receiver.IsType()) {
    const auto& cls = Class::Handle(zone, Type::Cast(receiver).type_class());
    const auto& error = Error::Handle(zone, cls.EnsureIsFinalized(thread));
    if (!error.IsNull()) {
      Exceptions::PropagateError(error);
      UNREACHABLE();
    }
    if (level == InvocationMirror::kConstructor) {
      function = cls.LookupConstructor(method_name);
      if (function.IsNull()) {
        function = cls.LookupFactory(method_name);
      }
    } else {
      function = cls.LookupStaticFunction(method_name);
    }
  } else if (receiver.IsClosure()) {
    function = Closure::Cast(receiver).function();
  } else {
    auto& cls = Class::Handle(zone, receiver.clazz());
    if (level == InvocationMirror::kSuper) {
      cls = cls.SuperClass();
    }
    function = Resolver::ResolveDynamicAnyArgs(zone, cls, method_name,
                                               /*allow_add=*/false);
  }
  if (!function.IsNull()) {
    return function.UserVisibleSignature();
  }
  return String::null();
}

}  // namespace dart
