mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 23:51:47 +00:00
54d56ca5d8
getField and setField as synchronous calls that accept isolate-local object as arguments. Originally reviewed as https://codereview.chromium.org/14044007/ Review URL: https://codereview.chromium.org//13942008 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@21591 260f80e4-7a28-3924-810f-c04153c831b5
1254 lines
36 KiB
C++
1254 lines
36 KiB
C++
// 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 "platform/json.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 bool IsSimpleValue(Dart_Handle object) {
|
|
return (Dart_IsNull(object) ||
|
|
Dart_IsNumber(object) ||
|
|
Dart_IsString(object) ||
|
|
Dart_IsBoolean(object));
|
|
}
|
|
|
|
|
|
static void FreeVMReference(Dart_Handle weak_ref, void* data) {
|
|
Dart_Handle perm_handle = reinterpret_cast<Dart_Handle>(data);
|
|
Dart_DeletePersistentHandle(perm_handle);
|
|
Dart_DeletePersistentHandle(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_Handle perm_handle = Dart_NewPersistentHandle(handle);
|
|
if (Dart_IsError(perm_handle)) {
|
|
return perm_handle;
|
|
}
|
|
|
|
// 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_Handle weak_ref =
|
|
Dart_NewWeakPersistentHandle(vm_ref, perm_handle_data, FreeVMReference);
|
|
if (Dart_IsError(weak_ref)) {
|
|
Dart_DeletePersistentHandle(perm_handle);
|
|
return weak_ref;
|
|
}
|
|
|
|
// Success.
|
|
return vm_ref;
|
|
}
|
|
|
|
|
|
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_Handle perm_handle = reinterpret_cast<Dart_Handle>(perm_handle_value);
|
|
ASSERT(!Dart_IsError(perm_handle));
|
|
return perm_handle;
|
|
}
|
|
|
|
|
|
static Dart_Handle UnwrapMirror(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 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_LibraryName(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_name;
|
|
if (Dart_IsNull(lib)) {
|
|
lib_name = Dart_Null();
|
|
} else {
|
|
lib_name = Dart_LibraryName(lib);
|
|
}
|
|
Dart_Handle args[] = { lib_name, 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?
|
|
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_key = Dart_LibraryName(lib);
|
|
Dart_Handle lib_mirror = CreateLibraryMirror(lib);
|
|
if (Dart_IsError(lib_mirror)) {
|
|
return lib_mirror;
|
|
}
|
|
// TODO(turnidge): Check for duplicate library names.
|
|
result = MapAdd(map, lib_key, 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(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
|