// 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/dart_entry.h"

#include "platform/safe_stack.h"
#include "vm/class_finalizer.h"
#include "vm/debugger.h"
#include "vm/dispatch_table.h"
#include "vm/heap/safepoint.h"
#include "vm/interpreter.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
#include "vm/runtime_entry.h"
#include "vm/simulator.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
#include "vm/zone_text_buffer.h"

#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/frontend/bytecode_reader.h"
#include "vm/compiler/jit/compiler.h"
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {

DECLARE_FLAG(bool, enable_interpreter);
DECLARE_FLAG(bool, precompiled_mode);

// A cache of VM heap allocated arguments descriptors.
ArrayPtr ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount];

ObjectPtr DartEntry::InvokeFunction(const Function& function,
                                    const Array& arguments) {
  ASSERT(Thread::Current()->IsMutatorThread());
  const int kTypeArgsLen = 0;  // No support to pass type args to generic func.
  const Array& arguments_descriptor = Array::Handle(
      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, arguments.Length()));
  return InvokeFunction(function, arguments, arguments_descriptor);
}

class ScopedIsolateStackLimits : public ValueObject {
 public:
  NO_SANITIZE_SAFE_STACK
  explicit ScopedIsolateStackLimits(Thread* thread, uword current_sp)
      : thread_(thread) {
    ASSERT(thread != NULL);
    // Save the Thread's current stack limit and adjust the stack limit.
    ASSERT(thread->isolate() == Isolate::Current());
    saved_stack_limit_ = thread->saved_stack_limit();
#if defined(USING_SIMULATOR)
    thread->SetStackLimit(Simulator::Current()->overflow_stack_limit());
#else
    thread->SetStackLimit(OSThread::Current()->overflow_stack_limit());
    // TODO(regis): For now, the interpreter is using its own stack limit.
#endif

#if defined(USING_SAFE_STACK)
    saved_safestack_limit_ = OSThread::GetCurrentSafestackPointer();
    thread->set_saved_safestack_limit(saved_safestack_limit_);
#endif
  }

  ~ScopedIsolateStackLimits() {
    ASSERT(thread_->isolate() == Isolate::Current());
    // Since we started with a stack limit of 0 we should be getting back
    // to a stack limit of 0 when all nested invocations are done and
    // we have bottomed out.
    thread_->SetStackLimit(saved_stack_limit_);
#if defined(USING_SAFE_STACK)
    thread_->set_saved_safestack_limit(saved_safestack_limit_);
#endif
  }

 private:
  Thread* thread_;
#if defined(USING_SAFE_STACK)
  uword saved_safestack_limit_ = 0;
#endif
  uword saved_stack_limit_ = 0;
};

// Clears/restores Thread::long_jump_base on construction/destruction.
// Ensures that we do not attempt to long jump across Dart frames.
class SuspendLongJumpScope : public ThreadStackResource {
 public:
  explicit SuspendLongJumpScope(Thread* thread)
      : ThreadStackResource(thread),
        saved_long_jump_base_(thread->long_jump_base()) {
    thread->set_long_jump_base(NULL);
  }

  ~SuspendLongJumpScope() {
    ASSERT(thread()->long_jump_base() == NULL);
    thread()->set_long_jump_base(saved_long_jump_base_);
  }

 private:
  LongJumpScope* saved_long_jump_base_;
};

ObjectPtr DartEntry::InvokeFunction(const Function& function,
                                    const Array& arguments,
                                    const Array& arguments_descriptor,
                                    uword current_sp) {
  // We use a kernel2kernel constant evaluator in Dart 2.0 AOT compilation
  // and never start the VM service isolate. So we should never end up invoking
  // any dart code in the Dart 2.0 AOT compiler.
  if (FLAG_precompiled_mode) {
#if !defined(DART_PRECOMPILED_RUNTIME)
    UNREACHABLE();
#else
    if (FLAG_use_bare_instructions) {
      Thread* thread = Thread::Current();
      thread->set_global_object_pool(
          thread->isolate()->object_store()->global_object_pool());
      const DispatchTable* dispatch_table = thread->isolate()->dispatch_table();
      if (dispatch_table != nullptr) {
        thread->set_dispatch_table_array(dispatch_table->ArrayOrigin());
      }
      ASSERT(thread->global_object_pool() != Object::null());
    }
#endif  // !defined(DART_PRECOMPILED_RUNTIME)
  }

  ASSERT(!function.IsNull());

  // Get the entrypoint corresponding to the function specified, this
  // will result in a compilation of the function if it is not already
  // compiled.
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  ASSERT(thread->IsMutatorThread());
  ScopedIsolateStackLimits stack_limit(thread, current_sp);
#if !defined(DART_PRECOMPILED_RUNTIME)
  if (!function.HasCode()) {
    if (FLAG_enable_interpreter && function.IsBytecodeAllowed(zone)) {
      if (!function.HasBytecode()) {
        ErrorPtr error =
            kernel::BytecodeReader::ReadFunctionBytecode(thread, function);
        if (error != Error::null()) {
          return error;
        }
      }

      // If we have bytecode but no native code then invoke the interpreter.
      if (function.HasBytecode() && (FLAG_compilation_counter_threshold != 0)) {
        ASSERT(thread->no_callback_scope_depth() == 0);
        SuspendLongJumpScope suspend_long_jump_scope(thread);
        TransitionToGenerated transition(thread);
        return Interpreter::Current()->Call(function, arguments_descriptor,
                                            arguments, thread);
      }

      // Fall back to compilation.
    }

    const Object& result =
        Object::Handle(zone, Compiler::CompileFunction(thread, function));
    if (result.IsError()) {
      return Error::Cast(result).raw();
    }

    // At this point we should have native code.
    ASSERT(function.HasCode());
  }
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  // Now Call the invoke stub which will invoke the dart function.
  const Code& code = Code::Handle(zone, function.CurrentCode());
  return InvokeCode(code, arguments_descriptor, arguments, thread);
}

extern "C" {
// Note: The invocation stub follows the C ABI, so we cannot pass C++ struct
// values like ObjectPtr. In some calling conventions (IA32), ObjectPtr is
// passed/returned different from a pointer.
typedef uword /*ObjectPtr*/ (*invokestub)(const Code& target_code,
                                          const Array& arguments_descriptor,
                                          const Array& arguments,
                                          Thread* thread);
}

NO_SANITIZE_SAFE_STACK
ObjectPtr DartEntry::InvokeCode(const Code& code,
                                const Array& arguments_descriptor,
                                const Array& arguments,
                                Thread* thread) {
  ASSERT(!code.IsNull());
  ASSERT(thread->no_callback_scope_depth() == 0);
  ASSERT(!Isolate::Current()->null_safety_not_set());

  invokestub entrypoint =
      reinterpret_cast<invokestub>(StubCode::InvokeDartCode().EntryPoint());
  SuspendLongJumpScope suspend_long_jump_scope(thread);
  TransitionToGenerated transition(thread);
#if defined(USING_SIMULATOR)
  return bit_copy<ObjectPtr, int64_t>(Simulator::Current()->Call(
      reinterpret_cast<intptr_t>(entrypoint), reinterpret_cast<intptr_t>(&code),
      reinterpret_cast<intptr_t>(&arguments_descriptor),
      reinterpret_cast<intptr_t>(&arguments),
      reinterpret_cast<intptr_t>(thread)));
#else
  return static_cast<ObjectPtr>(
      entrypoint(code, arguments_descriptor, arguments, thread));
#endif
}

ObjectPtr DartEntry::ResolveCallable(Thread* thread,
                                     const Array& arguments,
                                     const Array& arguments_descriptor) {
  auto isolate = thread->isolate();
  auto zone = thread->zone();

  const ArgumentsDescriptor args_desc(arguments_descriptor);
  const intptr_t receiver_index = args_desc.FirstArgIndex();
  const intptr_t type_args_len = args_desc.TypeArgsLen();
  const auto& getter_name = Symbols::GetCall();

  auto& instance = Instance::Handle(zone);
  auto& function = Function::Handle(zone);
  auto& cls = Class::Handle(zone);

  // The null instance cannot resolve to a callable, so we can stop there.
  for (instance ^= arguments.At(receiver_index); !instance.IsNull();
       instance ^= arguments.At(receiver_index)) {
    // The instance is a callable, so check that its function is compatible.
    if (instance.IsCallable(&function)) {
      bool matches = function.AreValidArguments(args_desc, nullptr);

      if (matches && type_args_len > 0 && function.IsClosureFunction()) {
        // Though the closure function is generic, the closure itself may
        // not be because it closes over delayed function type arguments.
        matches = Closure::Cast(instance).IsGeneric(thread);
      }

      if (matches) {
        return function.raw();
      }
    }

    // Special case: closures are implemented with a call getter instead of a
    // call method, so checking for a call getter would cause an infinite loop.
    if (instance.IsClosure()) {
      break;
    }

    cls = instance.clazz();
    // Find a call getter, if any, in the class hierarchy.
    function = Resolver::ResolveDynamicAnyArgs(zone, cls, getter_name,
                                               /*allow_add=*/false);
    if (function.IsNull()) {
      break;
    }
    if (!OSThread::Current()->HasStackHeadroom()) {
      const Instance& exception =
          Instance::Handle(zone, isolate->object_store()->stack_overflow());
      return UnhandledException::New(exception, StackTrace::Handle(zone));
    }

    const Array& getter_arguments = Array::Handle(zone, Array::New(1));
    getter_arguments.SetAt(0, instance);
    const Object& getter_result = Object::Handle(
        zone, DartEntry::InvokeFunction(function, getter_arguments));
    if (getter_result.IsError()) {
      return getter_result.raw();
    }
    ASSERT(getter_result.IsNull() || getter_result.IsInstance());

    // We have a new possibly compatible callable, so set the first argument
    // accordingly so it gets picked up in the main loop.
    arguments.SetAt(receiver_index, getter_result);
  }

  // No compatible callable was found.
  return Function::null();
}

ObjectPtr DartEntry::InvokeCallable(Thread* thread,
                                    const Function& callable_function,
                                    const Array& arguments,
                                    const Array& arguments_descriptor) {
  auto const zone = thread->zone();
  const ArgumentsDescriptor args_desc(arguments_descriptor);
  if (callable_function.IsNull()) {
    // No compatible callable was found, so invoke noSuchMethod.
    auto& instance =
        Instance::CheckedHandle(zone, arguments.At(args_desc.FirstArgIndex()));
    // For closures, use the name of the closure, not 'call'.
    const String* target_name = &Symbols::Call();
    if (instance.IsClosure()) {
      auto const& function =
          Function::Handle(zone, Closure::Cast(instance).function());
      target_name = &String::Handle(function.QualifiedUserVisibleName());
    }
    return InvokeNoSuchMethod(thread, instance, *target_name, arguments,
                              arguments_descriptor);
  }

  if (!callable_function.CanReceiveDynamicInvocation()) {
    const auto& result = Object::Handle(
        zone, callable_function.DoArgumentTypesMatch(arguments, args_desc));
    if (result.IsError()) {
      Exceptions::PropagateError(Error::Cast(result));
    }
  }

  return InvokeFunction(callable_function, arguments, arguments_descriptor);
}

ObjectPtr DartEntry::InvokeClosure(Thread* thread, const Array& arguments) {
  auto const zone = thread->zone();
  const int kTypeArgsLen = 0;  // No support to pass type args to generic func.

  // Closures always have boxed parameters
  const Array& arguments_descriptor = Array::Handle(
      zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, arguments.Length()));
  return InvokeClosure(thread, arguments, arguments_descriptor);
}

ObjectPtr DartEntry::InvokeClosure(Thread* thread,
                                   const Array& arguments,
                                   const Array& arguments_descriptor) {
  auto const zone = thread->zone();
  const Object& resolved_result = Object::Handle(
      zone, ResolveCallable(thread, arguments, arguments_descriptor));
  if (resolved_result.IsError()) {
    return resolved_result.raw();
  }

  const auto& function =
      Function::Handle(zone, Function::RawCast(resolved_result.raw()));
  return InvokeCallable(thread, function, arguments, arguments_descriptor);
}

ObjectPtr DartEntry::InvokeNoSuchMethod(Thread* thread,
                                        const Instance& receiver,
                                        const String& target_name,
                                        const Array& arguments,
                                        const Array& arguments_descriptor) {
  auto const zone = thread->zone();
  const ArgumentsDescriptor args_desc(arguments_descriptor);
  ASSERT(receiver.raw() == arguments.At(args_desc.FirstArgIndex()));
  // Allocate an Invocation object.
  const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());

  Class& invocation_mirror_class = Class::Handle(
      zone, core_lib.LookupClass(String::Handle(
                zone, core_lib.PrivateName(Symbols::InvocationMirror()))));
  ASSERT(!invocation_mirror_class.IsNull());
  const auto& error = invocation_mirror_class.EnsureIsFinalized(thread);
  ASSERT(error == Error::null());
  const String& function_name = String::Handle(
      zone, core_lib.PrivateName(Symbols::AllocateInvocationMirror()));
  const Function& allocation_function = Function::Handle(
      zone, invocation_mirror_class.LookupStaticFunction(function_name));
  ASSERT(!allocation_function.IsNull());
  const int kNumAllocationArgs = 4;
  const Array& allocation_args =
      Array::Handle(zone, Array::New(kNumAllocationArgs));
  allocation_args.SetAt(0, target_name);
  allocation_args.SetAt(1, arguments_descriptor);
  allocation_args.SetAt(2, arguments);
  allocation_args.SetAt(3, Bool::False());  // Not a super invocation.
  const Object& invocation_mirror = Object::Handle(
      zone, InvokeFunction(allocation_function, allocation_args));
  if (invocation_mirror.IsError()) {
    Exceptions::PropagateError(Error::Cast(invocation_mirror));
    UNREACHABLE();
  }

  // Now use the invocation mirror object and invoke NoSuchMethod.
  const int kTypeArgsLen = 0;
  const int kNumArguments = 2;
  const ArgumentsDescriptor nsm_args_desc(Array::Handle(
      zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
  Function& function = Function::Handle(
      zone, Resolver::ResolveDynamic(receiver, Symbols::NoSuchMethod(),
                                     nsm_args_desc));
  if (function.IsNull()) {
    ASSERT(!FLAG_lazy_dispatchers);
    // If noSuchMethod(invocation) is not found, call Object::noSuchMethod.
    function = Resolver::ResolveDynamicForReceiverClass(
        Class::Handle(zone, thread->isolate()->object_store()->object_class()),
        Symbols::NoSuchMethod(), nsm_args_desc);
  }
  ASSERT(!function.IsNull());
  const Array& args = Array::Handle(zone, Array::New(kNumArguments));
  args.SetAt(0, receiver);
  args.SetAt(1, invocation_mirror);
  return InvokeFunction(function, args);
}

ArgumentsDescriptor::ArgumentsDescriptor(const Array& array) : array_(array) {}

intptr_t ArgumentsDescriptor::TypeArgsLen() const {
  return Smi::Value(Smi::RawCast(array_.At(kTypeArgsLenIndex)));
}

intptr_t ArgumentsDescriptor::Count() const {
  return Smi::Value(Smi::RawCast(array_.At(kCountIndex)));
}

intptr_t ArgumentsDescriptor::Size() const {
  return Smi::Value(Smi::RawCast(array_.At(kSizeIndex)));
}

intptr_t ArgumentsDescriptor::PositionalCount() const {
  return Smi::Value(Smi::RawCast(array_.At(kPositionalCountIndex)));
}

StringPtr ArgumentsDescriptor::NameAt(intptr_t index) const {
  const intptr_t offset =
      kFirstNamedEntryIndex + (index * kNamedEntrySize) + kNameOffset;
  String& result = String::Handle();
  result ^= array_.At(offset);
  return result.raw();
}

intptr_t ArgumentsDescriptor::PositionAt(intptr_t index) const {
  const intptr_t offset =
      kFirstNamedEntryIndex + (index * kNamedEntrySize) + kPositionOffset;
  return Smi::Value(Smi::RawCast(array_.At(offset)));
}

bool ArgumentsDescriptor::MatchesNameAt(intptr_t index,
                                        const String& other) const {
  return NameAt(index) == other.raw();
}

ArrayPtr ArgumentsDescriptor::GetArgumentNames() const {
  const intptr_t num_named_args = NamedCount();
  if (num_named_args == 0) {
    return Array::null();
  }

  Zone* zone = Thread::Current()->zone();
  const Array& names =
      Array::Handle(zone, Array::New(num_named_args, Heap::kOld));
  String& name = String::Handle(zone);
  const intptr_t num_pos_args = PositionalCount();
  for (intptr_t i = 0; i < num_named_args; ++i) {
    const intptr_t index = PositionAt(i) - num_pos_args;
    name = NameAt(i);
    ASSERT(names.At(index) == Object::null());
    names.SetAt(index, name);
  }
  return names.raw();
}

void ArgumentsDescriptor::PrintTo(BaseTextBuffer* buffer) const {
  buffer->Printf("%" Pd " arg%s", Count(), Count() == 1 ? "" : "s");
  if (TypeArgsLen() > 0) {
    buffer->Printf(", %" Pd " type arg%s", TypeArgsLen(),
                   TypeArgsLen() == 1 ? "" : "s");
  }
  if (NamedCount() > 0) {
    buffer->AddString(", names [");
    auto& str = String::Handle();
    for (intptr_t i = 0; i < NamedCount(); i++) {
      if (i != 0) {
        buffer->AddString(", ");
      }
      str = NameAt(i);
      buffer->Printf("'%s'", str.ToCString());
    }
    buffer->Printf("]");
  }
}

const char* ArgumentsDescriptor::ToCString() const {
  ZoneTextBuffer buf(Thread::Current()->zone());
  PrintTo(&buf);
  return buf.buffer();
}

ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
                                  intptr_t num_arguments,
                                  intptr_t size_arguments,
                                  const Array& optional_arguments_names,
                                  Heap::Space space) {
  const intptr_t num_named_args =
      optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length();
  if (num_named_args == 0) {
    return ArgumentsDescriptor::New(type_args_len, num_arguments,
                                    size_arguments, space);
  }
  ASSERT(type_args_len >= 0);
  ASSERT(num_arguments >= 0);
  const intptr_t num_pos_args = num_arguments - num_named_args;

  // Build the arguments descriptor array, which consists of the the type
  // argument vector length (0 if none); total argument count; the positional
  // argument count; a sequence of (name, position) pairs, sorted by name, for
  // each named optional argument; and a terminating null to simplify iterating
  // in generated code.
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  const intptr_t descriptor_len = LengthFor(num_named_args);
  Array& descriptor = Array::Handle(zone, Array::New(descriptor_len, space));

  // Set length of type argument vector.
  descriptor.SetAt(kTypeArgsLenIndex, Smi::Handle(Smi::New(type_args_len)));
  // Set total number of passed arguments.
  descriptor.SetAt(kCountIndex, Smi::Handle(Smi::New(num_arguments)));
  // Set total number of passed arguments.
  descriptor.SetAt(kSizeIndex, Smi::Handle(Smi::New(size_arguments)));

  // Set number of positional arguments.
  descriptor.SetAt(kPositionalCountIndex, Smi::Handle(Smi::New(num_pos_args)));

  // Set alphabetically sorted entries for named arguments.
  String& name = String::Handle(zone);
  Smi& pos = Smi::Handle(zone);
  String& previous_name = String::Handle(zone);
  Smi& previous_pos = Smi::Handle(zone);
  for (intptr_t i = 0; i < num_named_args; i++) {
    name ^= optional_arguments_names.At(i);
    pos = Smi::New(num_pos_args + i);
    intptr_t insert_index = kFirstNamedEntryIndex + (kNamedEntrySize * i);
    // Shift already inserted pairs with "larger" names.
    while (insert_index > kFirstNamedEntryIndex) {
      intptr_t previous_index = insert_index - kNamedEntrySize;
      previous_name ^= descriptor.At(previous_index + kNameOffset);
      intptr_t result = name.CompareTo(previous_name);
      ASSERT(result != 0);  // Duplicate argument names checked in parser.
      if (result > 0) break;
      previous_pos ^= descriptor.At(previous_index + kPositionOffset);
      descriptor.SetAt(insert_index + kNameOffset, previous_name);
      descriptor.SetAt(insert_index + kPositionOffset, previous_pos);
      insert_index = previous_index;
    }
    // Insert pair in descriptor array.
    descriptor.SetAt(insert_index + kNameOffset, name);
    descriptor.SetAt(insert_index + kPositionOffset, pos);
  }
  // Set terminating null.
  descriptor.SetAt(descriptor_len - 1, Object::null_object());

  // Share the immutable descriptor when possible by canonicalizing it.
  descriptor.MakeImmutable();
  descriptor ^= descriptor.Canonicalize(thread);
  ASSERT(!descriptor.IsNull());
  return descriptor.raw();
}

ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
                                  intptr_t num_arguments,
                                  intptr_t size_arguments,
                                  Heap::Space space) {
  ASSERT(type_args_len >= 0);
  ASSERT(num_arguments >= 0);

  if ((type_args_len == 0) && (num_arguments < kCachedDescriptorCount) &&
      (num_arguments == size_arguments)) {
    return cached_args_descriptors_[num_arguments];
  }
  return NewNonCached(type_args_len, num_arguments, size_arguments, true,
                      space);
}

ArrayPtr ArgumentsDescriptor::NewNonCached(intptr_t type_args_len,
                                           intptr_t num_arguments,
                                           intptr_t size_arguments,
                                           bool canonicalize,
                                           Heap::Space space) {
  // Build the arguments descriptor array, which consists of the length of the
  // type argument vector, total argument count; the positional argument count;
  // and a terminating null to simplify iterating in generated code.
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  const intptr_t descriptor_len = LengthFor(0);
  Array& descriptor = Array::Handle(zone, Array::New(descriptor_len, space));
  const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments));
  const Smi& arg_size = Smi::Handle(zone, Smi::New(size_arguments));

  // Set type argument vector length.
  descriptor.SetAt(kTypeArgsLenIndex,
                   Smi::Handle(zone, Smi::New(type_args_len)));

  // Set total number of passed arguments.
  descriptor.SetAt(kCountIndex, arg_count);

  // Set total size of passed arguments.
  descriptor.SetAt(kSizeIndex, arg_size);

  // Set number of positional arguments.
  descriptor.SetAt(kPositionalCountIndex, arg_count);

  // Set terminating null.
  descriptor.SetAt((descriptor_len - 1), Object::null_object());

  // Share the immutable descriptor when possible by canonicalizing it.
  descriptor.MakeImmutable();
  if (canonicalize) {
    descriptor ^= descriptor.Canonicalize(thread);
  }
  ASSERT(!descriptor.IsNull());
  return descriptor.raw();
}

void ArgumentsDescriptor::Init() {
  for (int i = 0; i < kCachedDescriptorCount; i++) {
    cached_args_descriptors_[i] =
        NewNonCached(/*type_args_len=*/0, i, i, false, Heap::kOld);
  }
}

void ArgumentsDescriptor::Cleanup() {
  for (int i = 0; i < kCachedDescriptorCount; i++) {
    // Don't free pointers to RawArray objects managed by the VM.
    cached_args_descriptors_[i] = NULL;
  }
}

ObjectPtr DartLibraryCalls::InstanceCreate(const Library& lib,
                                           const String& class_name,
                                           const String& constructor_name,
                                           const Array& arguments) {
  const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name));
  ASSERT(!cls.IsNull());
  // For now, we only support a non-parameterized or raw type.
  const int kNumExtraArgs = 1;  // implicit rcvr arg.
  const Instance& exception_object = Instance::Handle(Instance::New(cls));
  const Array& constructor_arguments =
      Array::Handle(Array::New(arguments.Length() + kNumExtraArgs));
  constructor_arguments.SetAt(0, exception_object);
  Object& obj = Object::Handle();
  for (intptr_t i = 0; i < arguments.Length(); i++) {
    obj = arguments.At(i);
    constructor_arguments.SetAt((i + kNumExtraArgs), obj);
  }

  const String& function_name =
      String::Handle(String::Concat(class_name, constructor_name));
  const Function& constructor =
      Function::Handle(cls.LookupConstructorAllowPrivate(function_name));
  ASSERT(!constructor.IsNull());
  const Object& retval = Object::Handle(
      DartEntry::InvokeFunction(constructor, constructor_arguments));
  ASSERT(retval.IsNull() || retval.IsError());
  if (retval.IsError()) {
    return retval.raw();
  }
  return exception_object.raw();
}

ObjectPtr DartLibraryCalls::ToString(const Instance& receiver) {
  const int kTypeArgsLen = 0;
  const int kNumArguments = 1;  // Receiver.
  ArgumentsDescriptor args_desc(Array::Handle(
      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
  const Class& receiver_class = Class::Handle(receiver.clazz());
  const auto& error = receiver_class.EnsureIsFinalized(Thread::Current());
  ASSERT(error == Error::null());
  const Function& function = Function::Handle(
      Resolver::ResolveDynamic(receiver, Symbols::toString(), args_desc));
  ASSERT(!function.IsNull());
  const Array& args = Array::Handle(Array::New(kNumArguments));
  args.SetAt(0, receiver);
  const Object& result =
      Object::Handle(DartEntry::InvokeFunction(function, args));
  ASSERT(result.IsInstance() || result.IsError());
  return result.raw();
}

ObjectPtr DartLibraryCalls::HashCode(const Instance& receiver) {
  const int kTypeArgsLen = 0;
  const int kNumArguments = 1;  // Receiver.
  ArgumentsDescriptor args_desc(Array::Handle(
      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
  const Function& function = Function::Handle(
      Resolver::ResolveDynamic(receiver, Symbols::hashCode(), args_desc));
  ASSERT(!function.IsNull());
  const Array& args = Array::Handle(Array::New(kNumArguments));
  args.SetAt(0, receiver);
  const Object& result =
      Object::Handle(DartEntry::InvokeFunction(function, args));
  ASSERT(result.IsInstance() || result.IsError());
  return result.raw();
}

ObjectPtr DartLibraryCalls::Equals(const Instance& left,
                                   const Instance& right) {
  const int kTypeArgsLen = 0;
  const int kNumArguments = 2;
  ArgumentsDescriptor args_desc(Array::Handle(
      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
  const Function& function = Function::Handle(
      Resolver::ResolveDynamic(left, Symbols::EqualOperator(), args_desc));
  ASSERT(!function.IsNull());

  const Array& args = Array::Handle(Array::New(kNumArguments));
  args.SetAt(0, left);
  args.SetAt(1, right);
  const Object& result =
      Object::Handle(DartEntry::InvokeFunction(function, args));
  ASSERT(result.IsInstance() || result.IsError());
  return result.raw();
}

// On success, returns a RawInstance.  On failure, a RawError.
ObjectPtr DartLibraryCalls::IdentityHashCode(const Instance& object) {
  const int kNumArguments = 1;
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  const Library& libcore = Library::Handle(zone, Library::CoreLibrary());
  ASSERT(!libcore.IsNull());
  const Function& function = Function::Handle(
      zone, libcore.LookupFunctionAllowPrivate(Symbols::identityHashCode()));
  ASSERT(!function.IsNull());
  const Array& args = Array::Handle(zone, Array::New(kNumArguments));
  args.SetAt(0, object);
  const Object& result =
      Object::Handle(zone, DartEntry::InvokeFunction(function, args));
  ASSERT(result.IsInstance() || result.IsError());
  return result.raw();
}

ObjectPtr DartLibraryCalls::LookupHandler(Dart_Port port_id) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Function& function = Function::Handle(
      zone, thread->isolate()->object_store()->lookup_port_handler());
  const int kTypeArgsLen = 0;
  const int kNumArguments = 1;
  if (function.IsNull()) {
    Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary());
    ASSERT(!isolate_lib.IsNull());
    const String& class_name = String::Handle(
        zone, isolate_lib.PrivateName(Symbols::_RawReceivePortImpl()));
    const String& function_name = String::Handle(
        zone, isolate_lib.PrivateName(Symbols::_lookupHandler()));
    function = Resolver::ResolveStatic(isolate_lib, class_name, function_name,
                                       kTypeArgsLen, kNumArguments,
                                       Object::empty_array());
    ASSERT(!function.IsNull());
    thread->isolate()->object_store()->set_lookup_port_handler(function);
  }
  Array& args = Array::Handle(
      zone, thread->isolate()->isolate_object_store()->dart_args_1());
  if (args.IsNull()) {
    args = Array::New(kNumArguments);
    thread->isolate()->isolate_object_store()->set_dart_args_1(args);
  }
  args.SetAt(0, Integer::Handle(zone, Integer::New(port_id)));
  const Object& result =
      Object::Handle(zone, DartEntry::InvokeFunction(function, args));
  return result.raw();
}

ObjectPtr DartLibraryCalls::HandleMessage(const Object& handler,
                                          const Instance& message) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Isolate* isolate = thread->isolate();
  Function& function = Function::Handle(
      zone, isolate->object_store()->handle_message_function());
  const int kTypeArgsLen = 0;
  const int kNumArguments = 2;
  if (function.IsNull()) {
    Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary());
    ASSERT(!isolate_lib.IsNull());
    const String& class_name = String::Handle(
        zone, isolate_lib.PrivateName(Symbols::_RawReceivePortImpl()));
    const String& function_name = String::Handle(
        zone, isolate_lib.PrivateName(Symbols::_handleMessage()));
    function = Resolver::ResolveStatic(isolate_lib, class_name, function_name,
                                       kTypeArgsLen, kNumArguments,
                                       Object::empty_array());
    ASSERT(!function.IsNull());
    isolate->object_store()->set_handle_message_function(function);
  }
  Array& args = Array::Handle(
      zone, thread->isolate()->isolate_object_store()->dart_args_2());
  if (args.IsNull()) {
    args = Array::New(kNumArguments);
    thread->isolate()->isolate_object_store()->set_dart_args_2(args);
  }
  args.SetAt(0, handler);
  args.SetAt(1, message);
#if !defined(PRODUCT)
  if (isolate->debugger()->IsStepping()) {
    // If the isolate is being debugged and the debugger was stepping
    // through code, enable single stepping so debugger will stop
    // at the first location the user is interested in.
    isolate->debugger()->SetResumeAction(Debugger::kStepInto);
  }
#endif
  const Object& result =
      Object::Handle(zone, DartEntry::InvokeFunction(function, args));
  ASSERT(result.IsNull() || result.IsError());
  return result.raw();
}

ObjectPtr DartLibraryCalls::DrainMicrotaskQueue() {
  Zone* zone = Thread::Current()->zone();
  Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary());
  ASSERT(!isolate_lib.IsNull());
  Function& function =
      Function::Handle(zone, isolate_lib.LookupFunctionAllowPrivate(
                                 Symbols::_runPendingImmediateCallback()));
  const Object& result = Object::Handle(
      zone, DartEntry::InvokeFunction(function, Object::empty_array()));
  ASSERT(result.IsNull() || result.IsError());
  return result.raw();
}

ObjectPtr DartLibraryCalls::EnsureScheduleImmediate() {
  Zone* zone = Thread::Current()->zone();
  const Library& async_lib = Library::Handle(zone, Library::AsyncLibrary());
  ASSERT(!async_lib.IsNull());
  const Function& function =
      Function::Handle(zone, async_lib.LookupFunctionAllowPrivate(
                                 Symbols::_ensureScheduleImmediate()));
  ASSERT(!function.IsNull());
  const Object& result = Object::Handle(
      zone, DartEntry::InvokeFunction(function, Object::empty_array()));
  ASSERT(result.IsNull() || result.IsError());
  return result.raw();
}

ObjectPtr DartLibraryCalls::MapSetAt(const Instance& map,
                                     const Instance& key,
                                     const Instance& value) {
  const int kTypeArgsLen = 0;
  const int kNumArguments = 3;
  ArgumentsDescriptor args_desc(Array::Handle(
      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
  const Function& function = Function::Handle(
      Resolver::ResolveDynamic(map, Symbols::AssignIndexToken(), args_desc));
  ASSERT(!function.IsNull());
  const Array& args = Array::Handle(Array::New(kNumArguments));
  args.SetAt(0, map);
  args.SetAt(1, key);
  args.SetAt(2, value);
  const Object& result =
      Object::Handle(DartEntry::InvokeFunction(function, args));
  return result.raw();
}

}  // namespace dart
