// Copyright (c) 2012, 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 "include/dart_api.h"
#include "include/dart_debugger_api.h"
#include "include/dart_mirrors_api.h"
#include "vm/dart_api_impl.h"
#include "vm/bootstrap_natives.h"
#include "vm/dart_entry.h"
#include "vm/exceptions.h"
#include "vm/message.h"
#include "vm/port.h"
#include "vm/resolver.h"

namespace dart {

inline Dart_Handle NewString(const char* str) {
  return Dart_NewStringFromCString(str);
}


DEFINE_NATIVE_ENTRY(Mirrors_isLocalPort, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(Instance, port, arguments->NativeArgAt(0));

  // Get the port id from the SendPort instance.
  const Object& id_obj = Object::Handle(DartLibraryCalls::PortGetId(port));
  if (id_obj.IsError()) {
    Exceptions::PropagateError(Error::Cast(id_obj));
    UNREACHABLE();
  }
  ASSERT(id_obj.IsSmi() || id_obj.IsMint());
  Integer& id = Integer::Handle();
  id ^= id_obj.raw();
  Dart_Port port_id = static_cast<Dart_Port>(id.AsInt64Value());
  return Bool::Get(PortMap::IsLocalPort(port_id));
}


// TODO(turnidge): Add Map support to the dart embedding api instead
// of implementing it here.
static Dart_Handle CoreLib() {
  Dart_Handle core_lib_name = NewString("dart:core");
  return Dart_LookupLibrary(core_lib_name);
}


static Dart_Handle MapNew() {
  // TODO(turnidge): Switch to an order-preserving map type.
  Dart_Handle cls = Dart_GetClass(CoreLib(), NewString("Map"));
  if (Dart_IsError(cls)) {
    return cls;
  }
  return Dart_New(cls, Dart_Null(), 0, NULL);
}


static Dart_Handle MapAdd(Dart_Handle map, Dart_Handle key, Dart_Handle value) {
  Dart_Handle args[] = { key, value };
  return Dart_Invoke(map, NewString("[]="), ARRAY_SIZE(args), args);
}


static Dart_Handle MirrorLib() {
  Dart_Handle mirror_lib_name = NewString("dart:mirrors");
  return Dart_LookupLibrary(mirror_lib_name);
}


static Dart_Handle IsMirror(Dart_Handle object, bool* is_mirror) {
  Dart_Handle cls_name = NewString("Mirror");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }
  Dart_Handle result = Dart_ObjectIsType(object, cls, is_mirror);
  if (Dart_IsError(result)) {
    return result;
  }
  return Dart_True();  // Indicates success.  Result is in is_mirror.
}

static Dart_Handle IsMethodMirror(Dart_Handle object, bool* is_mirror) {
  Dart_Handle cls_name = NewString("MethodMirror");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }
  Dart_Handle result = Dart_ObjectIsType(object, cls, is_mirror);
  if (Dart_IsError(result)) {
    return result;
  }
  return Dart_True();  // Indicates success.  Result is in is_mirror.
}

static Dart_Handle IsVariableMirror(Dart_Handle object, bool* is_mirror) {
  Dart_Handle cls_name = NewString("VariableMirror");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }
  Dart_Handle result = Dart_ObjectIsType(object, cls, is_mirror);
  if (Dart_IsError(result)) {
    return result;
  }
  return Dart_True();  // Indicates success.  Result is in is_mirror.
}


static bool IsSimpleValue(Dart_Handle object) {
  return (Dart_IsNull(object) ||
          Dart_IsNumber(object) ||
          Dart_IsString(object) ||
          Dart_IsBoolean(object));
}


static void FreeVMReference(Dart_WeakPersistentHandle weak_ref, void* data) {
  Dart_PersistentHandle perm_handle =
      reinterpret_cast<Dart_PersistentHandle>(data);
  Dart_DeletePersistentHandle(perm_handle);
  Dart_DeleteWeakPersistentHandle(weak_ref);
}


static Dart_Handle CreateVMReference(Dart_Handle handle) {
  // Create the VMReference object.
  Dart_Handle cls_name = NewString("VMReference");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }
  Dart_Handle vm_ref =  Dart_New(cls, Dart_Null(), 0, NULL);
  if (Dart_IsError(vm_ref)) {
    return vm_ref;
  }

  // Allocate a persistent handle.
  Dart_PersistentHandle perm_handle = Dart_NewPersistentHandle(handle);
  ASSERT(perm_handle != NULL);

  // Store the persistent handle in the VMReference.
  intptr_t perm_handle_value = reinterpret_cast<intptr_t>(perm_handle);
  Dart_Handle result =
      Dart_SetNativeInstanceField(vm_ref, 0, perm_handle_value);
  if (Dart_IsError(result)) {
    Dart_DeletePersistentHandle(perm_handle);
    return result;
  }

  // Create a weak reference.  We use the callback to be informed when
  // the VMReference is collected, so we can release the persistent
  // handle.
  void* perm_handle_data = reinterpret_cast<void*>(perm_handle);
  Dart_WeakPersistentHandle weak_ref =
      Dart_NewWeakPersistentHandle(vm_ref, perm_handle_data, FreeVMReference);
  ASSERT(weak_ref != NULL);

  // Success.
  return vm_ref;
}

static Dart_Handle StringFromSymbol(Dart_Handle symbol) {
  Dart_Handle result = Dart_Invoke(MirrorLib(), NewString("_n"), 1, &symbol);
  return result;
}


static Dart_Handle UnwrapVMReference(Dart_Handle vm_ref) {
  // Retrieve the persistent handle from the VMReference
  intptr_t perm_handle_value = 0;
  Dart_Handle result =
      Dart_GetNativeInstanceField(vm_ref, 0, &perm_handle_value);
  if (Dart_IsError(result)) {
    return result;
  }
  Dart_PersistentHandle perm_handle =
      reinterpret_cast<Dart_PersistentHandle>(perm_handle_value);
  ASSERT(perm_handle != NULL);
  Dart_Handle handle = Dart_HandleFromPersistent(perm_handle);
  ASSERT(handle != NULL);
  ASSERT(!Dart_IsError(handle));
  return handle;
}

static Dart_Handle UnwrapMirror(Dart_Handle mirror);

static Dart_Handle UnwrapObjectMirror(Dart_Handle mirror) {
  Dart_Handle field_name = NewString("_reference");
  Dart_Handle vm_ref = Dart_GetField(mirror, field_name);
  if (Dart_IsError(vm_ref)) {
    return vm_ref;
  }
  return UnwrapVMReference(vm_ref);
}


static Dart_Handle UnwrapMethodMirror(Dart_Handle methodMirror) {
  Dart_Handle namefield_name = NewString("simpleName");
  Dart_Handle name_ref = Dart_GetField(methodMirror, namefield_name);
  if (Dart_IsError(name_ref)) {
    return name_ref;
  }
  Dart_Handle ownerfield_name = NewString("_owner");
  Dart_Handle owner_mirror = Dart_GetField(methodMirror, ownerfield_name);
  if (Dart_IsError(owner_mirror)) {
    return owner_mirror;
  }
  Dart_Handle owner = UnwrapMirror(owner_mirror);
  if (Dart_IsError(owner)) {
    return owner;
  }
  Dart_Handle func = Dart_LookupFunction(owner, StringFromSymbol(name_ref));
  if (Dart_IsError(func)) {
    return func;
  }
  ASSERT(!Dart_IsNull(func));
  return func;
}

static Dart_Handle UnwrapVariableMirror(Dart_Handle variableMirror) {
  Dart_Handle namefield_name = NewString("simpleName");
  Dart_Handle name_ref = Dart_GetField(variableMirror, namefield_name);
  if (Dart_IsError(name_ref)) {
    return name_ref;
  }
  Dart_Handle ownerfield_name = NewString("_owner");
  Dart_Handle owner_mirror = Dart_GetField(variableMirror, ownerfield_name);
  ASSERT(!Dart_IsNull(owner_mirror));
  if (Dart_IsError(owner_mirror)) {
    return owner_mirror;
  }
  Dart_Handle owner = UnwrapMirror(owner_mirror);
  if (Dart_IsError(owner)) {
    return owner;
  }
  Dart_Handle variable =
  Dart_LookupVariable(owner, StringFromSymbol(name_ref));
  if (Dart_IsError(variable)) {
    return variable;
  }
  ASSERT(!Dart_IsNull(variable));
  return variable;
}

static Dart_Handle UnwrapMirror(Dart_Handle mirror) {
  // Caveat Emptor:
  // only works for ObjectMirrors, VariableMirrors and MethodMirrors
  // and their subtypes
  bool is_method_mirror = false;
  Dart_Handle result = IsMethodMirror(mirror, &is_method_mirror);
  if (Dart_IsError(result)) {
    return result;
  }
  if (is_method_mirror) {
    return UnwrapMethodMirror(mirror);
  }
  bool is_variable_mirror = false;
  result = IsVariableMirror(mirror, &is_variable_mirror);
  if (Dart_IsError(result)) {
    return result;
  }
  if (is_variable_mirror) {
    return UnwrapVariableMirror(mirror);
  }
  return UnwrapObjectMirror(mirror);
  // will return nonsense if mirror is not an ObjectMirror
}

static Dart_Handle UnwrapArg(Dart_Handle arg) {
    if (Dart_IsError(arg)) {
      return arg;
    }
    bool is_mirror = false;
    Dart_Handle result = IsMirror(arg, &is_mirror);
    if (Dart_IsError(result)) {
      return result;
    }
    if (is_mirror) {
      return UnwrapMirror(arg);
    } else {
      // Simple value.
      ASSERT(IsSimpleValue(arg));
      return arg;
    }
}

static Dart_Handle UnwrapArgList(Dart_Handle arg_list,
                                 GrowableArray<Dart_Handle>* arg_array) {
  intptr_t len = 0;
  Dart_Handle result = Dart_ListLength(arg_list, &len);
  if (Dart_IsError(result)) {
    return result;
  }
  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle arg = Dart_ListGetAt(arg_list, i);
    Dart_Handle unwrapped_arg = UnwrapArg(arg);
    if (Dart_IsError(unwrapped_arg)) {
      return unwrapped_arg;
    }
    arg_array->Add(unwrapped_arg);
  }
  return Dart_True();
}

static Dart_Handle UnpackLocalArgList(Dart_Handle arg_list,
                                      GrowableArray<Dart_Handle>* arg_array) {
  intptr_t len = 0;
  Dart_Handle result = Dart_ListLength(arg_list, &len);
  if (Dart_IsError(result)) {
    return result;
  }
  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle arg = Dart_ListGetAt(arg_list, i);
    if (Dart_IsError(arg)) {
      return arg;
    }
    arg_array->Add(arg);
  }
  return Dart_True();
}

static Dart_Handle CreateLazyMirror(Dart_Handle target);


static Dart_Handle CreateParameterMirrorList(Dart_Handle func) {
  int64_t fixed_param_count;
  int64_t opt_param_count;
  Dart_Handle result = Dart_FunctionParameterCounts(func,
                                                    &fixed_param_count,
                                                    &opt_param_count);
  if (Dart_IsError(result)) {
    return result;
  }

  int64_t param_count = fixed_param_count + opt_param_count;
  Dart_Handle parameter_list = Dart_NewList(param_count);
  if (Dart_IsError(parameter_list)) {
    return result;
  }

  Dart_Handle param_cls_name = NewString("_LocalParameterMirrorImpl");
  Dart_Handle param_cls = Dart_GetClass(MirrorLib(), param_cls_name);
  if (Dart_IsError(param_cls)) {
    return param_cls;
  }

  for (int64_t i = 0; i < param_count; i++) {
    Dart_Handle param_type = Dart_FunctionParameterType(func, i);
    if (Dart_IsError(param_type)) {
      return param_type;
    }
    Dart_Handle args[] = {
      CreateLazyMirror(param_type),
      Dart_NewBoolean(i >= fixed_param_count),  // optional param?
    };
    Dart_Handle param =
        Dart_New(param_cls, Dart_Null(), ARRAY_SIZE(args), args);
    if (Dart_IsError(param)) {
      return param;
    }
    result = Dart_ListSetAt(parameter_list, i, param);
    if (Dart_IsError(result)) {
      return result;
    }
  }
  return parameter_list;
}


static Dart_Handle CreateLazyMirror(Dart_Handle target) {
  if (Dart_IsNull(target) || Dart_IsError(target)) {
    return target;
  }

  if (Dart_IsLibrary(target)) {
    Dart_Handle cls_name = NewString("_LazyLibraryMirror");
    Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
    Dart_Handle args[] = { Dart_LibraryUrl(target) };
    return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  }

  if (Dart_IsClass(target)) {
    if (Dart_ClassIsFunctionType(target)) {
      Dart_Handle cls_name = NewString("_LazyFunctionTypeMirror");
      Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);

      Dart_Handle sig = Dart_ClassGetFunctionTypeSignature(target);
      Dart_Handle return_type = Dart_FunctionReturnType(sig);
      if (Dart_IsError(return_type)) {
        return return_type;
      }

      Dart_Handle args[] = {
        CreateLazyMirror(return_type),
        CreateParameterMirrorList(sig),
      };
      return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
    } else {
      Dart_Handle cls_name = NewString("_LazyTypeMirror");
      Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
      Dart_Handle lib = Dart_ClassGetLibrary(target);
      Dart_Handle lib_url;
      if (Dart_IsNull(lib)) {
        lib_url = Dart_Null();
      } else {
        lib_url = Dart_LibraryUrl(lib);
      }
      Dart_Handle args[] = { lib_url, Dart_ClassName(target) };
      return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
    }
  }

  if (Dart_IsTypeVariable(target)) {
    Dart_Handle var_name = Dart_TypeVariableName(target);
    Dart_Handle owner = Dart_TypeVariableOwner(target);
    Dart_Handle owner_mirror = CreateLazyMirror(owner);

    Dart_Handle cls_name = NewString("_LazyTypeVariableMirror");
    Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);

    Dart_Handle args[] = { var_name, owner_mirror };
    return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  }

  UNREACHABLE();
  return Dart_Null();
}


static Dart_Handle CreateImplementsList(Dart_Handle intf) {
  intptr_t len = 0;
  Dart_Handle result = Dart_ClassGetInterfaceCount(intf, &len);
  if (Dart_IsError(result)) {
    return result;
  }

  Dart_Handle mirror_list = Dart_NewList(len);
  if (Dart_IsError(mirror_list)) {
    return mirror_list;
  }

  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle interface = Dart_ClassGetInterfaceAt(intf, i);
    if (Dart_IsError(interface)) {
      return interface;
    }
    Dart_Handle mirror = CreateLazyMirror(interface);
    if (Dart_IsError(mirror)) {
      return mirror;
    }
    Dart_Handle result = Dart_ListSetAt(mirror_list, i, mirror);
    if (Dart_IsError(result)) {
      return result;
    }
  }
  return mirror_list;
}


static Dart_Handle CreateTypeVariableMirror(Dart_Handle type_var,
                                            Dart_Handle type_var_name,
                                            Dart_Handle owner_mirror) {
  ASSERT(Dart_IsTypeVariable(type_var));
  Dart_Handle cls_name = NewString("_LocalTypeVariableMirrorImpl");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }

  Dart_Handle upper_bound = Dart_TypeVariableUpperBound(type_var);
  if (Dart_IsError(upper_bound)) {
    return upper_bound;
  }

  Dart_Handle args[] = {
    type_var_name,
    owner_mirror,
    CreateLazyMirror(upper_bound),
  };
  Dart_Handle mirror = Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  return mirror;
}


static Dart_Handle CreateTypeVariableMap(Dart_Handle owner,
                                         Dart_Handle owner_mirror) {
  ASSERT(Dart_IsClass(owner));
  // TODO(turnidge): This should be an immutable map.
  Dart_Handle map = MapNew();
  if (Dart_IsError(map)) {
    return map;
  }

  Dart_Handle names = Dart_GetTypeVariableNames(owner);
  if (Dart_IsError(names)) {
    return names;
  }
  intptr_t len;
  Dart_Handle result = Dart_ListLength(names, &len);
  if (Dart_IsError(result)) {
    return result;
  }
  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle type_var_name = Dart_ListGetAt(names, i);
    Dart_Handle type_var = Dart_LookupTypeVariable(owner, type_var_name);
    if (Dart_IsError(type_var)) {
      return type_var;
    }
    ASSERT(!Dart_IsNull(type_var));
    Dart_Handle type_var_mirror =
        CreateTypeVariableMirror(type_var, type_var_name, owner_mirror);
    if (Dart_IsError(type_var_mirror)) {
      return type_var_mirror;
    }
    result = MapAdd(map, type_var_name, type_var_mirror);
    if (Dart_IsError(result)) {
      return result;
    }
  }
  return map;
}


static Dart_Handle CreateTypedefMirror(Dart_Handle cls,
                                       Dart_Handle cls_name,
                                       Dart_Handle owner,
                                       Dart_Handle owner_mirror) {
  Dart_Handle mirror_cls_name = NewString("_LocalTypedefMirrorImpl");
  Dart_Handle mirror_cls = Dart_GetClass(MirrorLib(), mirror_cls_name);
  if (Dart_IsError(mirror_cls)) {
    return mirror_cls;
  }

  Dart_Handle referent = Dart_ClassGetTypedefReferent(cls);
  if (Dart_IsError(referent)) {
    return referent;
  }

  Dart_Handle args[] = {
    cls_name,
    owner_mirror,
    CreateLazyMirror(referent),
  };
  Dart_Handle mirror =
      Dart_New(mirror_cls, Dart_Null(), ARRAY_SIZE(args), args);
  return mirror;
}


static Dart_Handle CreateMemberMap(Dart_Handle owner, Dart_Handle owner_mirror);
static Dart_Handle CreateConstructorMap(Dart_Handle owner,
                                        Dart_Handle owner_mirror);


static Dart_Handle CreateClassMirror(Dart_Handle intf,
                                     Dart_Handle intf_name,
                                     Dart_Handle lib,
                                     Dart_Handle lib_mirror) {
  ASSERT(Dart_IsClass(intf));
  if (Dart_ClassIsTypedef(intf)) {
    // This class is actually a typedef.  Represent it specially in
    // reflection.
    return CreateTypedefMirror(intf, intf_name, lib, lib_mirror);
  }

  Dart_Handle cls_name = NewString("_LocalClassMirrorImpl");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }

  // TODO(turnidge): Why am I getting Null when I expect Object?
  // TODO(gbracha): this is probably the root of bug 7868
  Dart_Handle super_class = Dart_GetSuperclass(intf);
  if (Dart_IsNull(super_class)) {
    super_class = Dart_GetClass(CoreLib(), NewString("Object"));
  }
  // TODO(turnidge): Simplify code, now that default classes have been removed.
  Dart_Handle default_class = Dart_Null();

  Dart_Handle intf_mirror = CreateLazyMirror(intf);
  if (Dart_IsError(intf_mirror)) {
    return intf_mirror;
  }
  Dart_Handle member_map = CreateMemberMap(intf, intf_mirror);
  if (Dart_IsError(member_map)) {
    return member_map;
  }
  Dart_Handle constructor_map = CreateConstructorMap(intf, intf_mirror);
  if (Dart_IsError(constructor_map)) {
    return constructor_map;
  }
  Dart_Handle type_var_map = CreateTypeVariableMap(intf, intf_mirror);
  if (Dart_IsError(type_var_map)) {
    return type_var_map;
  }

  Dart_Handle args[] = {
    CreateVMReference(intf),
    intf_name,
    Dart_NewBoolean(Dart_IsClass(intf)),
    lib_mirror,
    CreateLazyMirror(super_class),
    CreateImplementsList(intf),
    CreateLazyMirror(default_class),
    member_map,
    constructor_map,
    type_var_map,
  };
  Dart_Handle mirror = Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  return mirror;
}


static Dart_Handle CreateMethodMirror(Dart_Handle func,
                                      Dart_Handle func_name,
                                      Dart_Handle owner_mirror) {
  ASSERT(Dart_IsFunction(func));
  Dart_Handle mirror_cls_name = NewString("_LocalMethodMirrorImpl");
  Dart_Handle mirror_cls = Dart_GetClass(MirrorLib(), mirror_cls_name);
  if (Dart_IsError(mirror_cls)) {
    return mirror_cls;
  }

  bool is_static = false;
  bool is_abstract = false;
  bool is_getter = false;
  bool is_setter = false;
  bool is_constructor = false;

  Dart_Handle result = Dart_FunctionIsStatic(func, &is_static);
  if (Dart_IsError(result)) {
    return result;
  }
  result = Dart_FunctionIsAbstract(func, &is_abstract);
  if (Dart_IsError(result)) {
    return result;
  }
  result = Dart_FunctionIsGetter(func, &is_getter);
  if (Dart_IsError(result)) {
    return result;
  }
  result = Dart_FunctionIsSetter(func, &is_setter);
  if (Dart_IsError(result)) {
    return result;
  }
  result = Dart_FunctionIsConstructor(func, &is_constructor);
  if (Dart_IsError(result)) {
    return result;
  }

  Dart_Handle return_type = Dart_FunctionReturnType(func);
  if (Dart_IsError(return_type)) {
    return return_type;
  }

  int64_t fixed_param_count;
  int64_t opt_param_count;
  result = Dart_FunctionParameterCounts(func,
                                        &fixed_param_count,
                                        &opt_param_count);
  if (Dart_IsError(result)) {
    return result;
  }

  // TODO(turnidge): Implement constructor kinds (arguments 7 - 10).
  Dart_Handle args[] = {
    func_name,
    owner_mirror,
    CreateParameterMirrorList(func),
    CreateLazyMirror(return_type),
    Dart_NewBoolean(is_static),
    Dart_NewBoolean(is_abstract),
    Dart_NewBoolean(is_getter),
    Dart_NewBoolean(is_setter),
    Dart_NewBoolean(is_constructor),
    Dart_False(),
    Dart_False(),
    Dart_False(),
    Dart_False(),
  };
  Dart_Handle mirror =
      Dart_New(mirror_cls, Dart_Null(), ARRAY_SIZE(args), args);
  return mirror;
}


static Dart_Handle CreateVariableMirror(Dart_Handle var,
                                        Dart_Handle var_name,
                                        Dart_Handle lib_mirror) {
  ASSERT(Dart_IsVariable(var));
  Dart_Handle cls_name = NewString("_LocalVariableMirrorImpl");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }

  bool is_static = false;
  bool is_final = false;

  Dart_Handle result = Dart_VariableIsStatic(var, &is_static);
  if (Dart_IsError(result)) {
    return result;
  }
  result = Dart_VariableIsFinal(var, &is_final);
  if (Dart_IsError(result)) {
    return result;
  }

  Dart_Handle type = Dart_VariableType(var);
  if (Dart_IsError(type)) {
    return type;
  }

  Dart_Handle args[] = {
    var_name,
    lib_mirror,
    CreateLazyMirror(type),
    Dart_NewBoolean(is_static),
    Dart_NewBoolean(is_final),
  };
  Dart_Handle mirror = Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  return mirror;
}


static Dart_Handle AddMemberClasses(Dart_Handle map,
                                    Dart_Handle owner,
                                    Dart_Handle owner_mirror) {
  ASSERT(Dart_IsLibrary(owner));
  Dart_Handle result;
  Dart_Handle names = Dart_LibraryGetClassNames(owner);
  if (Dart_IsError(names)) {
    return names;
  }
  intptr_t len;
  result = Dart_ListLength(names, &len);
  if (Dart_IsError(result)) {
    return result;
  }
  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle intf_name = Dart_ListGetAt(names, i);
    Dart_Handle intf = Dart_GetClass(owner, intf_name);
    if (Dart_IsError(intf)) {
      return intf;
    }
    Dart_Handle intf_mirror =
        CreateClassMirror(intf, intf_name, owner, owner_mirror);
    if (Dart_IsError(intf_mirror)) {
      return intf_mirror;
    }
    result = MapAdd(map, intf_name, intf_mirror);
    if (Dart_IsError(result)) {
      return result;
    }
  }
  return Dart_True();
}


static Dart_Handle AddMemberFunctions(Dart_Handle map,
                                      Dart_Handle owner,
                                      Dart_Handle owner_mirror) {
  Dart_Handle result;
  Dart_Handle names = Dart_GetFunctionNames(owner);
  if (Dart_IsError(names)) {
    return names;
  }
  intptr_t len;
  result = Dart_ListLength(names, &len);
  if (Dart_IsError(result)) {
    return result;
  }
  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle func_name = Dart_ListGetAt(names, i);
    Dart_Handle func = Dart_LookupFunction(owner, func_name);
    if (Dart_IsError(func)) {
      return func;
    }
    ASSERT(!Dart_IsNull(func));

    bool is_constructor = false;
    result = Dart_FunctionIsConstructor(func, &is_constructor);
    if (Dart_IsError(result)) {
      return result;
    }
    if (is_constructor) {
      // Skip constructors.
      continue;
    }

    Dart_Handle func_mirror = CreateMethodMirror(func, func_name, owner_mirror);
    if (Dart_IsError(func_mirror)) {
      return func_mirror;
    }
    result = MapAdd(map, func_name, func_mirror);
    if (Dart_IsError(result)) {
      return result;
    }
  }
  return Dart_True();
}


static Dart_Handle AddConstructors(Dart_Handle map,
                                   Dart_Handle owner,
                                   Dart_Handle owner_mirror) {
  Dart_Handle result;
  Dart_Handle names = Dart_GetFunctionNames(owner);
  if (Dart_IsError(names)) {
    return names;
  }
  intptr_t len;
  result = Dart_ListLength(names, &len);
  if (Dart_IsError(result)) {
    return result;
  }
  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle func_name = Dart_ListGetAt(names, i);
    Dart_Handle func = Dart_LookupFunction(owner, func_name);
    if (Dart_IsError(func)) {
      return func;
    }
    ASSERT(!Dart_IsNull(func));

    bool is_constructor = false;
    result = Dart_FunctionIsConstructor(func, &is_constructor);
    if (Dart_IsError(result)) {
      return result;
    }
    if (!is_constructor) {
      // Skip non-constructors.
      continue;
    }

    Dart_Handle func_mirror = CreateMethodMirror(func, func_name, owner_mirror);
    if (Dart_IsError(func_mirror)) {
      return func_mirror;
    }
    result = MapAdd(map, func_name, func_mirror);
    if (Dart_IsError(result)) {
      return result;
    }
  }
  return Dart_True();
}


static Dart_Handle AddMemberVariables(Dart_Handle map,
                                      Dart_Handle owner,
                                      Dart_Handle owner_mirror) {
  Dart_Handle result;
  Dart_Handle names = Dart_GetVariableNames(owner);
  if (Dart_IsError(names)) {
    return names;
  }
  intptr_t len;
  result = Dart_ListLength(names, &len);
  if (Dart_IsError(result)) {
    return result;
  }
  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle var_name = Dart_ListGetAt(names, i);
    Dart_Handle var = Dart_LookupVariable(owner, var_name);
    if (Dart_IsError(var)) {
      return var;
    }
    ASSERT(!Dart_IsNull(var));
    Dart_Handle var_mirror = CreateVariableMirror(var, var_name, owner_mirror);
    if (Dart_IsError(var_mirror)) {
      return var_mirror;
    }
    result = MapAdd(map, var_name, var_mirror);
    if (Dart_IsError(result)) {
      return result;
    }
  }
  return Dart_True();
}


static Dart_Handle CreateMemberMap(Dart_Handle owner,
                                   Dart_Handle owner_mirror) {
  // TODO(turnidge): This should be an immutable map.
  if (Dart_IsError(owner_mirror)) {
    return owner_mirror;
  }
  Dart_Handle result;
  Dart_Handle map = MapNew();
  if (Dart_IsLibrary(owner)) {
    result = AddMemberClasses(map, owner, owner_mirror);
    if (Dart_IsError(result)) {
      return result;
    }
  }
  result = AddMemberFunctions(map, owner, owner_mirror);
  if (Dart_IsError(result)) {
    return result;
  }
  result = AddMemberVariables(map, owner, owner_mirror);
  if (Dart_IsError(result)) {
    return result;
  }
  return map;
}


static Dart_Handle CreateConstructorMap(Dart_Handle owner,
                                        Dart_Handle owner_mirror) {
  // TODO(turnidge): This should be an immutable map.
  if (Dart_IsError(owner_mirror)) {
    return owner_mirror;
  }
  Dart_Handle result;
  Dart_Handle map = MapNew();
  result = AddConstructors(map, owner, owner_mirror);
  if (Dart_IsError(result)) {
    return result;
  }
  return map;
}


static Dart_Handle CreateLibraryMirror(Dart_Handle lib) {
  Dart_Handle cls_name = NewString("_LocalLibraryMirrorImpl");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }
  Dart_Handle lazy_lib_mirror = CreateLazyMirror(lib);
  if (Dart_IsError(lazy_lib_mirror)) {
    return lazy_lib_mirror;
  }
  Dart_Handle member_map = CreateMemberMap(lib, lazy_lib_mirror);
  if (Dart_IsError(member_map)) {
    return member_map;
  }
  Dart_Handle args[] = {
    CreateVMReference(lib),
    Dart_LibraryName(lib),
    Dart_LibraryUrl(lib),
    member_map,
  };
  Dart_Handle lib_mirror = Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  if (Dart_IsError(lib_mirror)) {
    return lib_mirror;
  }

  return lib_mirror;
}


static Dart_Handle CreateLibrariesMap() {
  // TODO(turnidge): This should be an immutable map.
  Dart_Handle map = MapNew();

  Dart_Handle lib_ids = Dart_GetLibraryIds();
  if (Dart_IsError(lib_ids)) {
    return lib_ids;
  }
  intptr_t len;
  Dart_Handle result = Dart_ListLength(lib_ids, &len);
  if (Dart_IsError(result)) {
    return result;
  }
  for (intptr_t i = 0; i < len; i++) {
    Dart_Handle lib_id = Dart_ListGetAt(lib_ids, i);
    int64_t id64;
    Dart_IntegerToInt64(lib_id, &id64);
    Dart_Handle lib_url = Dart_GetLibraryURL(id64);
    if (Dart_IsError(lib_url)) {
      return lib_url;
    }
    Dart_Handle lib = Dart_LookupLibrary(lib_url);
    if (Dart_IsError(lib)) {
      return lib;
    }
    Dart_Handle lib_mirror = CreateLibraryMirror(lib);
    if (Dart_IsError(lib_mirror)) {
      return lib_mirror;
    }
    result = MapAdd(map, lib_url, lib_mirror);
  }
  return map;
}


static Dart_Handle CreateIsolateMirror() {
  Dart_Handle cls_name = NewString("_LocalIsolateMirrorImpl");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }
  Dart_Handle args[] = {
    Dart_DebugName(),
    CreateLazyMirror(Dart_RootLibrary()),
  };
  return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
}


static Dart_Handle CreateMirrorSystem() {
  Dart_Handle cls_name = NewString("_LocalMirrorSystemImpl");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }

  Dart_Handle libraries = CreateLibrariesMap();
  if (Dart_IsError(libraries)) {
    return libraries;
  }

  Dart_Handle args[] = {
    libraries,
    CreateIsolateMirror(),
  };
  Dart_Handle mirror = Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  if (Dart_IsError(mirror)) {
    return mirror;
  }

  return mirror;
}


static Dart_Handle CreateNullMirror() {
  Dart_Handle cls_name = NewString("_LocalInstanceMirrorImpl");
  Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
  if (Dart_IsError(cls)) {
    return cls;
  }

  // TODO(turnidge): This is wrong.  The Null class is distinct from object.
  Dart_Handle object_class = Dart_GetClass(CoreLib(), NewString("Object"));

  Dart_Handle args[] = {
    CreateVMReference(Dart_Null()),
    CreateLazyMirror(object_class),
    Dart_Null(),
  };
  Dart_Handle mirror = Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  return mirror;
}


static Dart_Handle CreateInstanceMirror(Dart_Handle instance) {
  if (Dart_IsNull(instance)) {
    return CreateNullMirror();
  }
  ASSERT(Dart_IsInstance(instance));

  Dart_Handle instance_cls = Dart_InstanceGetClass(instance);
  if (Dart_IsError(instance_cls)) {
    return instance_cls;
  }

  if (Dart_IsClosure(instance)) {
    Dart_Handle cls_name = NewString("_LocalClosureMirrorImpl");
    Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
    if (Dart_IsError(cls)) {
      return cls;
    }
    // We set the function field of ClosureMirrors outside of the constructor
    // to break the mutual recursion.
    Dart_Handle func = Dart_ClosureFunction(instance);
    if (Dart_IsError(func)) {
      return func;
    }

    // TODO(turnidge): Why not use the real function name here?
    Dart_Handle func_name = NewString("call");
    Dart_Handle func_owner = Dart_FunctionOwner(func);
    if (Dart_IsError(func_owner)) {
      return func_owner;
    }

    // TODO(turnidge): Pass the function owner here.  This will require
    // us to support functions in CreateLazyMirror.
    Dart_Handle func_mirror =
        CreateMethodMirror(func, func_name, Dart_Null());
    if (Dart_IsError(func_mirror)) {
      return func_mirror;
    }
    Dart_Handle args[] = {
      CreateVMReference(instance),
      CreateLazyMirror(instance_cls),
      instance,
      func_mirror,
    };
    return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);

  } else {
    Dart_Handle cls_name = NewString("_LocalInstanceMirrorImpl");
    Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
    if (Dart_IsError(cls)) {
      return cls;
    }
    Dart_Handle args[] = {
      CreateVMReference(instance),
      CreateLazyMirror(instance_cls),
      instance,
    };
    return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
  }
}


static Dart_Handle CreateMirroredError(Dart_Handle error) {
  ASSERT(Dart_IsError(error));
  if (Dart_IsUnhandledExceptionError(error)) {
    Dart_Handle exc = Dart_ErrorGetException(error);
    if (Dart_IsError(exc)) {
      return exc;
    }
    Dart_Handle exc_string = Dart_ToString(exc);
    if (Dart_IsError(exc_string)) {
      // Only propagate fatal errors from exc.toString().  Ignore the rest.
      if (Dart_IsFatalError(exc_string)) {
        return exc_string;
      }
      exc_string = Dart_Null();
    }

    Dart_Handle stack = Dart_ErrorGetStacktrace(error);
    if (Dart_IsError(stack)) {
      return stack;
    }
    Dart_Handle cls_name = NewString("MirroredUncaughtExceptionError");
    Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
    Dart_Handle args[] = {
      CreateInstanceMirror(exc),
      exc_string,
      stack,
    };
    Dart_Handle mirrored_exc =
        Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
    return Dart_NewUnhandledExceptionError(mirrored_exc);
  } else if (Dart_IsApiError(error) ||
             Dart_IsCompilationError(error)) {
    Dart_Handle cls_name = NewString("MirroredCompilationError");
    Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
    Dart_Handle args[] = { NewString(Dart_GetError(error)) };
    Dart_Handle mirrored_exc =
        Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
    return Dart_NewUnhandledExceptionError(mirrored_exc);
  } else {
    ASSERT(Dart_IsFatalError(error));
    return error;
  }
}


void NATIVE_ENTRY_FUNCTION(Mirrors_makeLocalMirrorSystem)(
    Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle mirrors = CreateMirrorSystem();
  if (Dart_IsError(mirrors)) {
    Dart_PropagateError(mirrors);
  }
  Dart_SetReturnValue(args, mirrors);
  Dart_ExitScope();
}


void NATIVE_ENTRY_FUNCTION(Mirrors_makeLocalInstanceMirror)(
    Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle reflectee = Dart_GetNativeArgument(args, 0);
  Dart_Handle mirror = CreateInstanceMirror(reflectee);
  if (Dart_IsError(mirror)) {
    Dart_PropagateError(mirror);
  }
  Dart_SetReturnValue(args, mirror);
  Dart_ExitScope();
}


void NATIVE_ENTRY_FUNCTION(Mirrors_makeLocalClassMirror)(
    Dart_NativeArguments args) {
  Dart_EnterScope();
  Isolate* isolate = Isolate::Current();
  Dart_Handle key = Dart_GetNativeArgument(args, 0);
  if (Dart_IsError(key)) {
    Dart_PropagateError(key);
  }
  const Type& type = Api::UnwrapTypeHandle(isolate, key);
  const Class& cls = Class::Handle(type.type_class());
  Dart_Handle cls_handle = Api::NewHandle(isolate, cls.raw());
  if (Dart_IsError(cls_handle)) {
    Dart_PropagateError(cls_handle);
  }
  Dart_Handle name_handle = Api::NewHandle(isolate, cls.Name());
  if (Dart_IsError(name_handle)) {
    Dart_PropagateError(name_handle);
  }
  Dart_Handle lib_handle = Api::NewHandle(isolate, cls.library());
  if (Dart_IsError(lib_handle)) {
    Dart_PropagateError(lib_handle);
  }
  Dart_Handle lib_mirror = CreateLibraryMirror(lib_handle);
  if (Dart_IsError(lib_mirror)) {
    Dart_PropagateError(lib_mirror);
  }
  Dart_Handle result = CreateClassMirror(cls_handle,
                                         name_handle,
                                         lib_handle,
                                         lib_mirror);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  Dart_SetReturnValue(args, result);
  Dart_ExitScope();
}

void NATIVE_ENTRY_FUNCTION(Mirrors_metadata)(Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle mirror = Dart_GetNativeArgument(args, 0);

  Dart_Handle reflectee = UnwrapMirror(mirror);
  Dart_Handle result = Dart_GetMetadata(reflectee);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  ASSERT(Dart_IsList(result));
  Dart_SetReturnValue(args, result);
  Dart_ExitScope();
}

void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_invoke)(
    Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle mirror = Dart_GetNativeArgument(args, 0);
  Dart_Handle member_name = Dart_GetNativeArgument(args, 1);
  // The arguments are either simple values or instance mirrors.
  Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 2);
  Dart_Handle async = Dart_GetNativeArgument(args, 3);

  Dart_Handle reflectee = UnwrapMirror(mirror);
  Dart_Handle result;
  GrowableArray<Dart_Handle> invoke_args;
  if (Dart_IdentityEquals(async, Dart_True())) {
    result = UnwrapArgList(positional_arguments, &invoke_args);
  } else {
    result = UnpackLocalArgList(positional_arguments, &invoke_args);
  }
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  result = Dart_Invoke(reflectee,
                       member_name,
                       invoke_args.length(),
                       invoke_args.data());
  if (Dart_IsError(result)) {
    // Instead of propagating the error from an invoke directly, we
    // provide reflective access to the error.
    Dart_PropagateError(CreateMirroredError(result));
  }

  Dart_Handle wrapped_result = CreateInstanceMirror(result);
  if (Dart_IsError(wrapped_result)) {
    Dart_PropagateError(wrapped_result);
  }
  Dart_SetReturnValue(args, wrapped_result);
  Dart_ExitScope();
}


void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_getField)(
    Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle mirror = Dart_GetNativeArgument(args, 0);
  Dart_Handle fieldName = Dart_GetNativeArgument(args, 1);

  Dart_Handle reflectee = UnwrapMirror(mirror);
  Dart_Handle result = Dart_GetField(reflectee, fieldName);
  if (Dart_IsError(result)) {
    // Instead of propagating the error from a GetField directly, we
    // provide reflective access to the error.
    Dart_PropagateError(CreateMirroredError(result));
  }

  Dart_Handle wrapped_result = CreateInstanceMirror(result);
  if (Dart_IsError(wrapped_result)) {
    Dart_PropagateError(wrapped_result);
  }
  Dart_SetReturnValue(args, wrapped_result);
  Dart_ExitScope();
}


void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_setField)(
    Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle mirror = Dart_GetNativeArgument(args, 0);
  Dart_Handle fieldName = Dart_GetNativeArgument(args, 1);
  Dart_Handle value = Dart_GetNativeArgument(args, 2);
  Dart_Handle async = Dart_GetNativeArgument(args, 3);

  Dart_Handle reflectee = UnwrapMirror(mirror);
  Dart_Handle set_arg;
  if (Dart_IdentityEquals(async, Dart_True())) {
    set_arg = UnwrapArg(value);
  } else {
    set_arg = value;
  }
  if (Dart_IsError(set_arg)) {
    Dart_PropagateError(set_arg);
  }
  Dart_Handle result = Dart_SetField(reflectee, fieldName, set_arg);
  if (Dart_IsError(result)) {
    // Instead of propagating the error from a SetField directly, we
    // provide reflective access to the error.
    Dart_PropagateError(CreateMirroredError(result));
  }

  Dart_Handle wrapped_result = CreateInstanceMirror(result);
  if (Dart_IsError(wrapped_result)) {
    Dart_PropagateError(wrapped_result);
  }
  Dart_SetReturnValue(args, wrapped_result);
  Dart_ExitScope();
}


void NATIVE_ENTRY_FUNCTION(LocalClosureMirrorImpl_apply)(
    Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle mirror = Dart_GetNativeArgument(args, 0);
  // The arguments are either simple values or instance mirrors.
  Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 1);
  Dart_Handle async = Dart_GetNativeArgument(args, 2);

  Dart_Handle reflectee = UnwrapMirror(mirror);
  GrowableArray<Dart_Handle> invoke_args;
  Dart_Handle result;
  if (Dart_IdentityEquals(async, Dart_True())) {
    result = UnwrapArgList(positional_arguments, &invoke_args);
  } else {
    result = UnpackLocalArgList(positional_arguments, &invoke_args);
  }
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  result =
      Dart_InvokeClosure(reflectee, invoke_args.length(), invoke_args.data());
  if (Dart_IsError(result)) {
    // Instead of propagating the error from an apply directly, we
    // provide reflective access to the error.
    Dart_PropagateError(CreateMirroredError(result));
  }

  Dart_Handle wrapped_result = CreateInstanceMirror(result);
  if (Dart_IsError(wrapped_result)) {
    Dart_PropagateError(wrapped_result);
  }
  Dart_SetReturnValue(args, wrapped_result);
  Dart_ExitScope();
}


void NATIVE_ENTRY_FUNCTION(LocalClassMirrorImpl_invokeConstructor)(
    Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle klass_mirror = Dart_GetNativeArgument(args, 0);
  Dart_Handle constructor_name = Dart_GetNativeArgument(args, 1);
  // The arguments are either simple values or instance mirrors.
  Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 2);
  Dart_Handle async = Dart_GetNativeArgument(args, 3);

  Dart_Handle klass = UnwrapMirror(klass_mirror);
  GrowableArray<Dart_Handle> invoke_args;
  Dart_Handle result;
  if (Dart_IdentityEquals(async, Dart_True())) {
    result = UnwrapArgList(positional_arguments, &invoke_args);
  } else {
    result = UnpackLocalArgList(positional_arguments, &invoke_args);
  }
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  result = Dart_New(klass,
                    constructor_name,
                    invoke_args.length(),
                    invoke_args.data());
  if (Dart_IsError(result)) {
    // Instead of propagating the error from an invoke directly, we
    // provide reflective access to the error.
    Dart_PropagateError(CreateMirroredError(result));
  }

  Dart_Handle wrapped_result = CreateInstanceMirror(result);
  if (Dart_IsError(wrapped_result)) {
    Dart_PropagateError(wrapped_result);
  }
  Dart_SetReturnValue(args, wrapped_result);
  Dart_ExitScope();
}

void HandleMirrorsMessage(Isolate* isolate,
                          Dart_Port reply_port,
                          const Instance& message) {
  UNIMPLEMENTED();
}

}  // namespace dart
