Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: runtime/lib/mirrors.cc

Issue 18463003: Implement the invoke methods (invoke, getField, setField, newInstance, apply) as internal natives. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/vm/dart_entry.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "include/dart_api.h" 5 #include "include/dart_api.h"
6 #include "include/dart_debugger_api.h" 6 #include "include/dart_debugger_api.h"
7 #include "include/dart_mirrors_api.h" 7 #include "include/dart_mirrors_api.h"
8 #include "vm/dart_api_impl.h" 8 #include "vm/dart_api_impl.h"
9 #include "vm/dart_api_state.h" // TODO(11742): Remove with CreateMirrorRef. 9 #include "vm/dart_api_state.h" // TODO(11742): Remove with CreateMirrorRef.
10 #include "vm/bootstrap_natives.h" 10 #include "vm/bootstrap_natives.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/exceptions.h" 12 #include "vm/exceptions.h"
13 #include "vm/message.h" 13 #include "vm/message.h"
14 #include "vm/port.h" 14 #include "vm/port.h"
15 #include "vm/resolver.h" 15 #include "vm/resolver.h"
16 #include "vm/symbols.h"
16 17
17 namespace dart { 18 namespace dart {
18 19
19 inline Dart_Handle NewString(const char* str) { 20 inline Dart_Handle NewString(const char* str) {
20 return Dart_NewStringFromCString(str); 21 return Dart_NewStringFromCString(str);
21 } 22 }
22 23
23 24
24 DEFINE_NATIVE_ENTRY(Mirrors_isLocalPort, 1) { 25 DEFINE_NATIVE_ENTRY(Mirrors_isLocalPort, 1) {
25 GET_NON_NULL_NATIVE_ARGUMENT(Instance, port, arguments->NativeArgAt(0)); 26 GET_NON_NULL_NATIVE_ARGUMENT(Instance, port, arguments->NativeArgAt(0));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 return Dart_Invoke(map, NewString("[]="), ARRAY_SIZE(args), args); 62 return Dart_Invoke(map, NewString("[]="), ARRAY_SIZE(args), args);
62 } 63 }
63 64
64 65
65 static Dart_Handle MirrorLib() { 66 static Dart_Handle MirrorLib() {
66 Dart_Handle mirror_lib_name = NewString("dart:mirrors"); 67 Dart_Handle mirror_lib_name = NewString("dart:mirrors");
67 return Dart_LookupLibrary(mirror_lib_name); 68 return Dart_LookupLibrary(mirror_lib_name);
68 } 69 }
69 70
70 71
71 static Dart_Handle IsMirror(Dart_Handle object, bool* is_mirror) {
72 Dart_Handle cls_name = NewString("Mirror");
73 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
74 if (Dart_IsError(type)) {
75 return type;
76 }
77 Dart_Handle result = Dart_ObjectIsType(object, type, is_mirror);
78 if (Dart_IsError(result)) {
79 return result;
80 }
81 return Dart_True(); // Indicates success. Result is in is_mirror.
82 }
83
84 static Dart_Handle IsMethodMirror(Dart_Handle object, bool* is_mirror) { 72 static Dart_Handle IsMethodMirror(Dart_Handle object, bool* is_mirror) {
85 Dart_Handle cls_name = NewString("MethodMirror"); 73 Dart_Handle cls_name = NewString("MethodMirror");
86 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL); 74 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
87 if (Dart_IsError(type)) { 75 if (Dart_IsError(type)) {
88 return type; 76 return type;
89 } 77 }
90 Dart_Handle result = Dart_ObjectIsType(object, type, is_mirror); 78 Dart_Handle result = Dart_ObjectIsType(object, type, is_mirror);
91 if (Dart_IsError(result)) { 79 if (Dart_IsError(result)) {
92 return result; 80 return result;
93 } 81 }
94 return Dart_True(); // Indicates success. Result is in is_mirror. 82 return Dart_True(); // Indicates success. Result is in is_mirror.
95 } 83 }
96 84
97 static Dart_Handle IsVariableMirror(Dart_Handle object, bool* is_mirror) { 85 static Dart_Handle IsVariableMirror(Dart_Handle object, bool* is_mirror) {
98 Dart_Handle cls_name = NewString("VariableMirror"); 86 Dart_Handle cls_name = NewString("VariableMirror");
99 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL); 87 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
100 if (Dart_IsError(type)) { 88 if (Dart_IsError(type)) {
101 return type; 89 return type;
102 } 90 }
103 Dart_Handle result = Dart_ObjectIsType(object, type, is_mirror); 91 Dart_Handle result = Dart_ObjectIsType(object, type, is_mirror);
104 if (Dart_IsError(result)) { 92 if (Dart_IsError(result)) {
105 return result; 93 return result;
106 } 94 }
107 return Dart_True(); // Indicates success. Result is in is_mirror. 95 return Dart_True(); // Indicates success. Result is in is_mirror.
108 } 96 }
109 97
110 98
111 static bool IsSimpleValue(Dart_Handle object) {
112 return (Dart_IsNull(object) ||
113 Dart_IsNumber(object) ||
114 Dart_IsString(object) ||
115 Dart_IsBoolean(object));
116 }
117
118
119 static void FreeVMReference(Dart_WeakPersistentHandle weak_ref, void* data) { 99 static void FreeVMReference(Dart_WeakPersistentHandle weak_ref, void* data) {
120 Dart_PersistentHandle perm_handle = 100 Dart_PersistentHandle perm_handle =
121 reinterpret_cast<Dart_PersistentHandle>(data); 101 reinterpret_cast<Dart_PersistentHandle>(data);
122 Dart_DeletePersistentHandle(perm_handle); 102 Dart_DeletePersistentHandle(perm_handle);
123 Dart_DeleteWeakPersistentHandle(weak_ref); 103 Dart_DeleteWeakPersistentHandle(weak_ref);
124 } 104 }
125 105
126 106
127 static Dart_Handle CreateVMReference(Dart_Handle handle) { 107 static Dart_Handle CreateVMReference(Dart_Handle handle) {
128 // Create the VMReference object. 108 // Create the VMReference object.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 if (Dart_IsError(result)) { 255 if (Dart_IsError(result)) {
276 return result; 256 return result;
277 } 257 }
278 if (is_variable_mirror) { 258 if (is_variable_mirror) {
279 return UnwrapVariableMirror(mirror); 259 return UnwrapVariableMirror(mirror);
280 } 260 }
281 return UnwrapObjectMirror(mirror); 261 return UnwrapObjectMirror(mirror);
282 // will return nonsense if mirror is not an ObjectMirror 262 // will return nonsense if mirror is not an ObjectMirror
283 } 263 }
284 264
285 static Dart_Handle UnwrapArg(Dart_Handle arg) {
286 if (Dart_IsError(arg)) {
287 return arg;
288 }
289 bool is_mirror = false;
290 Dart_Handle result = IsMirror(arg, &is_mirror);
291 if (Dart_IsError(result)) {
292 return result;
293 }
294 if (is_mirror) {
295 return UnwrapMirror(arg);
296 } else {
297 // Simple value.
298 ASSERT(IsSimpleValue(arg));
299 return arg;
300 }
301 }
302
303 static Dart_Handle UnwrapArgList(Dart_Handle arg_list,
304 GrowableArray<Dart_Handle>* arg_array) {
305 intptr_t len = 0;
306 Dart_Handle result = Dart_ListLength(arg_list, &len);
307 if (Dart_IsError(result)) {
308 return result;
309 }
310 for (intptr_t i = 0; i < len; i++) {
311 Dart_Handle arg = Dart_ListGetAt(arg_list, i);
312 Dart_Handle unwrapped_arg = UnwrapArg(arg);
313 if (Dart_IsError(unwrapped_arg)) {
314 return unwrapped_arg;
315 }
316 arg_array->Add(unwrapped_arg);
317 }
318 return Dart_True();
319 }
320
321 static Dart_Handle UnpackLocalArgList(Dart_Handle arg_list,
322 GrowableArray<Dart_Handle>* arg_array) {
323 intptr_t len = 0;
324 Dart_Handle result = Dart_ListLength(arg_list, &len);
325 if (Dart_IsError(result)) {
326 return result;
327 }
328 for (intptr_t i = 0; i < len; i++) {
329 Dart_Handle arg = Dart_ListGetAt(arg_list, i);
330 if (Dart_IsError(arg)) {
331 return arg;
332 }
333 arg_array->Add(arg);
334 }
335 return Dart_True();
336 }
337 265
338 static Dart_Handle CreateLazyMirror(Dart_Handle target); 266 static Dart_Handle CreateLazyMirror(Dart_Handle target);
339 267
340 268
341 static Dart_Handle CreateParameterMirrorList(Dart_Handle func) { 269 static Dart_Handle CreateParameterMirrorList(Dart_Handle func) {
342 int64_t fixed_param_count; 270 int64_t fixed_param_count;
343 int64_t opt_param_count; 271 int64_t opt_param_count;
344 Dart_Handle result = Dart_FunctionParameterCounts(func, 272 Dart_Handle result = Dart_FunctionParameterCounts(func,
345 &fixed_param_count, 273 &fixed_param_count,
346 &opt_param_count); 274 &opt_param_count);
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 } 873 }
946 Dart_Handle lazy_lib_mirror = CreateLazyMirror(lib); 874 Dart_Handle lazy_lib_mirror = CreateLazyMirror(lib);
947 if (Dart_IsError(lazy_lib_mirror)) { 875 if (Dart_IsError(lazy_lib_mirror)) {
948 return lazy_lib_mirror; 876 return lazy_lib_mirror;
949 } 877 }
950 Dart_Handle member_map = CreateMemberMap(lib, lazy_lib_mirror); 878 Dart_Handle member_map = CreateMemberMap(lib, lazy_lib_mirror);
951 if (Dart_IsError(member_map)) { 879 if (Dart_IsError(member_map)) {
952 return member_map; 880 return member_map;
953 } 881 }
954 Dart_Handle args[] = { 882 Dart_Handle args[] = {
883 CreateMirrorReference(lib),
955 CreateVMReference(lib), 884 CreateVMReference(lib),
956 Dart_LibraryName(lib), 885 Dart_LibraryName(lib),
957 Dart_LibraryUrl(lib), 886 Dart_LibraryUrl(lib),
958 member_map, 887 member_map,
959 }; 888 };
960 Dart_Handle lib_mirror = Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); 889 Dart_Handle lib_mirror = Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
961 if (Dart_IsError(lib_mirror)) { 890 if (Dart_IsError(lib_mirror)) {
962 return lib_mirror; 891 return lib_mirror;
963 } 892 }
964 893
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 Dart_Handle args[] = { 1043 Dart_Handle args[] = {
1115 CreateVMReference(instance), 1044 CreateVMReference(instance),
1116 CreateLazyMirror(instance_cls), 1045 CreateLazyMirror(instance_cls),
1117 instance, 1046 instance,
1118 }; 1047 };
1119 return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); 1048 return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
1120 } 1049 }
1121 } 1050 }
1122 1051
1123 1052
1124 static Dart_Handle CreateMirroredError(Dart_Handle error) {
1125 ASSERT(Dart_IsError(error));
1126 if (Dart_IsUnhandledExceptionError(error)) {
1127 Dart_Handle exc = Dart_ErrorGetException(error);
1128 if (Dart_IsError(exc)) {
1129 return exc;
1130 }
1131 Dart_Handle exc_string = Dart_ToString(exc);
1132 if (Dart_IsError(exc_string)) {
1133 // Only propagate fatal errors from exc.toString(). Ignore the rest.
1134 if (Dart_IsFatalError(exc_string)) {
1135 return exc_string;
1136 }
1137 exc_string = Dart_Null();
1138 }
1139
1140 Dart_Handle stack = Dart_ErrorGetStacktrace(error);
1141 if (Dart_IsError(stack)) {
1142 return stack;
1143 }
1144 Dart_Handle cls_name = NewString("MirroredUncaughtExceptionError");
1145 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
1146 Dart_Handle args[] = {
1147 CreateInstanceMirror(exc),
1148 exc_string,
1149 stack,
1150 };
1151 Dart_Handle mirrored_exc =
1152 Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
1153 return Dart_NewUnhandledExceptionError(mirrored_exc);
1154 } else if (Dart_IsApiError(error) ||
1155 Dart_IsCompilationError(error)) {
1156 Dart_Handle cls_name = NewString("MirroredCompilationError");
1157 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
1158 Dart_Handle args[] = { NewString(Dart_GetError(error)) };
1159 Dart_Handle mirrored_exc =
1160 Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
1161 return Dart_NewUnhandledExceptionError(mirrored_exc);
1162 } else {
1163 ASSERT(Dart_IsFatalError(error));
1164 return error;
1165 }
1166 }
1167
1168
1169 void NATIVE_ENTRY_FUNCTION(Mirrors_makeLocalMirrorSystem)( 1053 void NATIVE_ENTRY_FUNCTION(Mirrors_makeLocalMirrorSystem)(
1170 Dart_NativeArguments args) { 1054 Dart_NativeArguments args) {
1171 Dart_EnterScope(); 1055 Dart_EnterScope();
1172 Dart_Handle mirrors = CreateMirrorSystem(); 1056 Dart_Handle mirrors = CreateMirrorSystem();
1173 if (Dart_IsError(mirrors)) { 1057 if (Dart_IsError(mirrors)) {
1174 Dart_PropagateError(mirrors); 1058 Dart_PropagateError(mirrors);
1175 } 1059 }
1176 Dart_SetReturnValue(args, mirrors); 1060 Dart_SetReturnValue(args, mirrors);
1177 Dart_ExitScope(); 1061 Dart_ExitScope();
1178 } 1062 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 Dart_Handle reflectee = UnwrapMirror(mirror); 1119 Dart_Handle reflectee = UnwrapMirror(mirror);
1236 Dart_Handle result = Dart_GetMetadata(reflectee); 1120 Dart_Handle result = Dart_GetMetadata(reflectee);
1237 if (Dart_IsError(result)) { 1121 if (Dart_IsError(result)) {
1238 Dart_PropagateError(result); 1122 Dart_PropagateError(result);
1239 } 1123 }
1240 ASSERT(Dart_IsList(result)); 1124 ASSERT(Dart_IsList(result));
1241 Dart_SetReturnValue(args, result); 1125 Dart_SetReturnValue(args, result);
1242 Dart_ExitScope(); 1126 Dart_ExitScope();
1243 } 1127 }
1244 1128
1245 void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_invoke)(
1246 Dart_NativeArguments args) {
1247 Dart_EnterScope();
1248 Dart_Handle mirror = Dart_GetNativeArgument(args, 0);
1249 Dart_Handle member_name = Dart_GetNativeArgument(args, 1);
1250 // The arguments are either simple values or instance mirrors.
1251 Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 2);
1252 Dart_Handle async = Dart_GetNativeArgument(args, 3);
1253
1254 Dart_Handle reflectee = UnwrapMirror(mirror);
1255 Dart_Handle result;
1256 GrowableArray<Dart_Handle> invoke_args;
1257 if (Dart_IdentityEquals(async, Dart_True())) {
1258 result = UnwrapArgList(positional_arguments, &invoke_args);
1259 } else {
1260 result = UnpackLocalArgList(positional_arguments, &invoke_args);
1261 }
1262 if (Dart_IsError(result)) {
1263 Dart_PropagateError(result);
1264 }
1265 result = Dart_Invoke(reflectee,
1266 member_name,
1267 invoke_args.length(),
1268 invoke_args.data());
1269 if (Dart_IsError(result)) {
1270 // Instead of propagating the error from an invoke directly, we
1271 // provide reflective access to the error.
1272 Dart_PropagateError(CreateMirroredError(result));
1273 }
1274
1275 Dart_Handle wrapped_result = CreateInstanceMirror(result);
1276 if (Dart_IsError(wrapped_result)) {
1277 Dart_PropagateError(wrapped_result);
1278 }
1279 Dart_SetReturnValue(args, wrapped_result);
1280 Dart_ExitScope();
1281 }
1282
1283
1284 void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_getField)(
1285 Dart_NativeArguments args) {
1286 Dart_EnterScope();
1287 Dart_Handle mirror = Dart_GetNativeArgument(args, 0);
1288 Dart_Handle fieldName = Dart_GetNativeArgument(args, 1);
1289
1290 Dart_Handle reflectee = UnwrapMirror(mirror);
1291 Dart_Handle result = Dart_GetField(reflectee, fieldName);
1292 if (Dart_IsError(result)) {
1293 // Instead of propagating the error from a GetField directly, we
1294 // provide reflective access to the error.
1295 Dart_PropagateError(CreateMirroredError(result));
1296 }
1297
1298 Dart_Handle wrapped_result = CreateInstanceMirror(result);
1299 if (Dart_IsError(wrapped_result)) {
1300 Dart_PropagateError(wrapped_result);
1301 }
1302 Dart_SetReturnValue(args, wrapped_result);
1303 Dart_ExitScope();
1304 }
1305
1306
1307 void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_setField)(
1308 Dart_NativeArguments args) {
1309 Dart_EnterScope();
1310 Dart_Handle mirror = Dart_GetNativeArgument(args, 0);
1311 Dart_Handle fieldName = Dart_GetNativeArgument(args, 1);
1312 Dart_Handle value = Dart_GetNativeArgument(args, 2);
1313 Dart_Handle async = Dart_GetNativeArgument(args, 3);
1314
1315 Dart_Handle reflectee = UnwrapMirror(mirror);
1316 Dart_Handle set_arg;
1317 if (Dart_IdentityEquals(async, Dart_True())) {
1318 set_arg = UnwrapArg(value);
1319 } else {
1320 set_arg = value;
1321 }
1322 if (Dart_IsError(set_arg)) {
1323 Dart_PropagateError(set_arg);
1324 }
1325 Dart_Handle result = Dart_SetField(reflectee, fieldName, set_arg);
1326 if (Dart_IsError(result)) {
1327 // Instead of propagating the error from a SetField directly, we
1328 // provide reflective access to the error.
1329 Dart_PropagateError(CreateMirroredError(result));
1330 }
1331
1332 Dart_Handle wrapped_result = CreateInstanceMirror(result);
1333 if (Dart_IsError(wrapped_result)) {
1334 Dart_PropagateError(wrapped_result);
1335 }
1336 Dart_SetReturnValue(args, wrapped_result);
1337 Dart_ExitScope();
1338 }
1339
1340
1341 void NATIVE_ENTRY_FUNCTION(LocalClosureMirrorImpl_apply)(
1342 Dart_NativeArguments args) {
1343 Dart_EnterScope();
1344 Dart_Handle mirror = Dart_GetNativeArgument(args, 0);
1345 // The arguments are either simple values or instance mirrors.
1346 Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 1);
1347 Dart_Handle async = Dart_GetNativeArgument(args, 2);
1348
1349 Dart_Handle reflectee = UnwrapMirror(mirror);
1350 GrowableArray<Dart_Handle> invoke_args;
1351 Dart_Handle result;
1352 if (Dart_IdentityEquals(async, Dart_True())) {
1353 result = UnwrapArgList(positional_arguments, &invoke_args);
1354 } else {
1355 result = UnpackLocalArgList(positional_arguments, &invoke_args);
1356 }
1357 if (Dart_IsError(result)) {
1358 Dart_PropagateError(result);
1359 }
1360 result =
1361 Dart_InvokeClosure(reflectee, invoke_args.length(), invoke_args.data());
1362 if (Dart_IsError(result)) {
1363 // Instead of propagating the error from an apply directly, we
1364 // provide reflective access to the error.
1365 Dart_PropagateError(CreateMirroredError(result));
1366 }
1367
1368 Dart_Handle wrapped_result = CreateInstanceMirror(result);
1369 if (Dart_IsError(wrapped_result)) {
1370 Dart_PropagateError(wrapped_result);
1371 }
1372 Dart_SetReturnValue(args, wrapped_result);
1373 Dart_ExitScope();
1374 }
1375
1376
1377 void NATIVE_ENTRY_FUNCTION(LocalClassMirrorImpl_invokeConstructor)(
1378 Dart_NativeArguments args) {
1379 Dart_EnterScope();
1380 Dart_Handle klass_mirror = Dart_GetNativeArgument(args, 0);
1381 Dart_Handle constructor_name = Dart_GetNativeArgument(args, 1);
1382 // The arguments are either simple values or instance mirrors.
1383 Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 2);
1384 Dart_Handle async = Dart_GetNativeArgument(args, 3);
1385
1386 Dart_Handle klass = UnwrapMirror(klass_mirror);
1387 GrowableArray<Dart_Handle> invoke_args;
1388 Dart_Handle result;
1389 if (Dart_IdentityEquals(async, Dart_True())) {
1390 result = UnwrapArgList(positional_arguments, &invoke_args);
1391 } else {
1392 result = UnpackLocalArgList(positional_arguments, &invoke_args);
1393 }
1394 if (Dart_IsError(result)) {
1395 Dart_PropagateError(result);
1396 }
1397 result = Dart_New(klass,
1398 constructor_name,
1399 invoke_args.length(),
1400 invoke_args.data());
1401 if (Dart_IsError(result)) {
1402 // Instead of propagating the error from an invoke directly, we
1403 // provide reflective access to the error.
1404 Dart_PropagateError(CreateMirroredError(result));
1405 }
1406
1407 Dart_Handle wrapped_result = CreateInstanceMirror(result);
1408 if (Dart_IsError(wrapped_result)) {
1409 Dart_PropagateError(wrapped_result);
1410 }
1411 Dart_SetReturnValue(args, wrapped_result);
1412 Dart_ExitScope();
1413 }
1414
1415 1129
1416 void HandleMirrorsMessage(Isolate* isolate, 1130 void HandleMirrorsMessage(Isolate* isolate,
1417 Dart_Port reply_port, 1131 Dart_Port reply_port,
1418 const Instance& message) { 1132 const Instance& message) {
1419 UNIMPLEMENTED(); 1133 UNIMPLEMENTED();
1420 } 1134 }
1421 1135
1422 1136
1137 // TODO(11742): This is transitional.
1138 static RawInstance* Reflect(const Instance& reflectee) {
1139 Isolate* isolate = Isolate::Current();
1140 DARTSCOPE(isolate);
1141 return Instance::RawCast(
1142 Api::UnwrapHandle(
1143 CreateInstanceMirror(
1144 Api::NewHandle(isolate, reflectee.raw()))));
1145 }
1146
1147
1148 static void ThrowMirroredUnhandledError(const Error& original_error) {
1149 const UnhandledException& unhandled_ex =
1150 UnhandledException::Cast(original_error);
1151 Instance& exc = Instance::Handle(unhandled_ex.exception());
1152 Instance& stack = Instance::Handle(unhandled_ex.stacktrace());
1153
1154 Object& exc_string_or_error =
1155 Object::Handle(DartLibraryCalls::ToString(exc));
1156 Instance& exc_string = Instance::Handle();
1157 if (exc_string_or_error.IsError()) {
1158 exc_string ^= Instance::null();
siva 2013/07/15 05:42:58 exc_string is already null why set it to Null agai
rmacnak 2013/07/15 19:53:23 There were more cases when this code dealt with un
1159 } else {
1160 exc_string ^= exc_string_or_error.raw();
1161 }
1162
1163 Instance& mirror_on_exc = Instance::Handle(Reflect(exc));
1164
1165 Array& args = Array::Handle(Array::New(3));
1166 args.SetAt(0, mirror_on_exc);
1167 args.SetAt(1, exc_string);
1168 args.SetAt(2, stack);
1169
1170 Exceptions::ThrowByType(Exceptions::kMirroredUncaughtExceptionError, args);
1171 UNREACHABLE();
1172 }
1173
1174
1175 static void ThrowMirroredCompilationError(const String& message) {
1176 Array& args = Array::Handle(Array::New(1));
1177 args.SetAt(0, message);
1178
1179 Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args);
1180 UNREACHABLE();
1181 }
1182
1183
1184 static void ThrowInvokeError(const Error& error) {
1185 if (error.IsUnhandledException()) {
1186 // An ordinary runtime error.
1187 ThrowMirroredUnhandledError(error);
1188 }
1189 if (error.IsLanguageError()) {
1190 // A compilation error that was delayed by lazy compilation.
1191 const LanguageError& compilation_error = LanguageError::Cast(error);
1192 String& message = String::Handle(compilation_error.message());
1193 ThrowMirroredCompilationError(message);
1194 }
1195 UNREACHABLE();
1196 }
1197
1198
1199 static RawFunction* ResolveConstructor(const char* current_func,
1200 const Class& cls,
1201 const String& class_name,
1202 const String& constr_name,
1203 int num_args) {
1204 // The constructor must be present in the interface.
1205 const Function& constructor =
1206 Function::Handle(cls.LookupFunctionAllowPrivate(constr_name));
1207 if (constructor.IsNull() ||
1208 (!constructor.IsConstructor() && !constructor.IsFactory())) {
1209 const String& lookup_class_name = String::Handle(cls.Name());
1210 if (!class_name.Equals(lookup_class_name)) {
1211 // When the class name used to build the constructor name is
1212 // different than the name of the class in which we are doing
1213 // the lookup, it can be confusing to the user to figure out
1214 // what's going on. Be a little more explicit for these error
1215 // messages.
1216 const String& message = String::Handle(
1217 String::NewFormatted(
1218 "%s: could not find factory '%s' in class '%s'.",
1219 current_func,
1220 constr_name.ToCString(),
1221 lookup_class_name.ToCString()));
1222 ThrowMirroredCompilationError(message);
1223 UNREACHABLE();
1224 } else {
1225 const String& message = String::Handle(
1226 String::NewFormatted("%s: could not find constructor '%s'.",
1227 current_func, constr_name.ToCString()));
1228 ThrowMirroredCompilationError(message);
1229 UNREACHABLE();
1230 }
1231 }
1232 int extra_args = (constructor.IsConstructor() ? 2 : 1);
1233 String& error_message = String::Handle();
1234 if (!constructor.AreValidArgumentCounts(num_args + extra_args,
1235 0,
1236 &error_message)) {
1237 const String& message = String::Handle(
1238 String::NewFormatted("%s: wrong argument count for "
1239 "constructor '%s': %s.",
1240 current_func,
1241 constr_name.ToCString(),
1242 error_message.ToCString()));
1243 ThrowMirroredCompilationError(message);
1244 UNREACHABLE();
1245 }
1246 return constructor.raw();
1247 }
1248
1249
1250 static bool FieldIsUninitialized(const Field& field) {
1251 ASSERT(!field.IsNull());
1252
1253 // Return getter method for uninitialized fields, rather than the
1254 // field object, since the value in the field object will not be
1255 // initialized until the first time the getter is invoked.
1256 const Instance& value = Instance::Handle(field.value());
1257 ASSERT(value.raw() != Object::transition_sentinel().raw());
1258 return value.raw() == Object::sentinel().raw();
1259 }
1260
1261
1423 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { 1262 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) {
1424 const MirrorReference& klass_ref = 1263 const MirrorReference& klass_ref =
1425 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); 1264 MirrorReference::CheckedHandle(arguments->NativeArgAt(0));
1426 Class& klass = Class::Handle(); 1265 Class& klass = Class::Handle();
1427 klass ^= klass_ref.referent(); 1266 klass ^= klass_ref.referent();
1428 return klass.Name(); 1267 return klass.Name();
1429 } 1268 }
1430 1269
1270
1271 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 4) {
1272 // Argument 0 is the mirror, which is unused by the native. It exists
1273 // because this native is an instance method in order to be polymorphic
1274 // with its cousins.
1275
1276 const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(1));
siva 2013/07/15 05:42:58 In the dart file you call this parameter reflectee
rmacnak 2013/07/15 19:53:23 Hm, calling it reflectee is more uniform, but ther
1277
1278 const String& function_name =
1279 String::CheckedHandle(arguments->NativeArgAt(2));
1280
1281 const Array& positional_args =
1282 Array::CheckedHandle(arguments->NativeArgAt(3));
1283 intptr_t number_of_arguments = positional_args.Length();
1284
1285
1286 const intptr_t num_receiver = 1; // 1 for instance methods
1287 const Array& args =
1288 Array::Handle(Array::New(number_of_arguments + num_receiver));
1289 Object& obj = Object::Handle();
1290 args.SetAt(0, receiver);
1291 for (int i = 0; i < number_of_arguments; i++) {
1292 obj = positional_args.At(i);
1293 args.SetAt((i + num_receiver), obj);
1294 }
1295
1296 // TODO(11771): This won't find private members.
1297 const Function& function = Function::Handle(
1298 Resolver::ResolveDynamic(receiver,
1299 function_name,
1300 (number_of_arguments + 1),
1301 Resolver::kIsQualified));
1302
1303 if (function.IsNull()) {
1304 const Array& args_descriptor =
1305 Array::Handle(ArgumentsDescriptor::New(args.Length()));
1306 obj = DartEntry::InvokeNoSuchMethod(receiver,
1307 function_name,
1308 args,
1309 args_descriptor);
1310 } else {
1311 obj = DartEntry::InvokeFunction(function, args);
1312 }
1313
1314 if (obj.IsError()) {
1315 ThrowInvokeError(Error::Cast(obj));
1316 UNREACHABLE();
1317 }
1318 return obj.raw();
1319 }
1320
1321
1322 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) {
1323 // Argument 0 is the mirror, which is unused by the native. It exists
1324 // because this native is an instance method in order to be polymorphic
1325 // with its cousins.
1326
1327 const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(1));
1328
1329 const String& getter_name =
1330 String::CheckedHandle(arguments->NativeArgAt(2));
1331
1332 // Every instance field has a getter Function. Try to find the
1333 // getter in any superclass and use that function to access the
1334 // field.
1335 // NB: We do not use Resolver::ResolveDynamic because we want to find private
1336 // members.
siva 2013/07/15 05:42:58 How come there isn't a similar check for a null re
rmacnak 2013/07/15 19:53:23 Null's class failed for field lookups, not functio
1337 Class& klass = Class::Handle(receiver.clazz());
1338 String& internal_getter_name = String::Handle(Field::GetterName(getter_name));
1339 Function& getter = Function::Handle();
1340 while (!klass.IsNull()) {
siva 2013/07/15 05:42:58 LookupInstanceField also?
rmacnak 2013/07/15 19:53:23 No. InstanceMirror_invokeGetter is the ideal case:
1341 getter = klass.LookupDynamicFunctionAllowPrivate(internal_getter_name);
1342 if (!getter.IsNull()) {
1343 break;
1344 }
1345 klass = klass.SuperClass();
1346 }
1347
1348 Object& result = Object::Handle();
1349
1350 // Invoke the getter or DNU and return the result.
siva 2013/07/15 05:42:58 DNU is not a standard abbreviation we use
rmacnak 2013/07/15 19:53:23 Smalltalkism, switched to noSuchMethod
1351 const int kNumArgs = 1;
1352 const Array& args = Array::Handle(Array::New(kNumArgs));
1353 args.SetAt(0, receiver);
1354
1355 if (getter.IsNull()) {
1356 const Array& args_descriptor =
1357 Array::Handle(ArgumentsDescriptor::New(args.Length()));
1358 result = DartEntry::InvokeNoSuchMethod(receiver,
1359 internal_getter_name,
1360 args,
1361 args_descriptor);
siva 2013/07/15 05:42:58 indentation.....
1362 } else {
1363 result = DartEntry::InvokeFunction(getter, args);
1364 }
1365
1366 if (result.IsError()) {
1367 ThrowInvokeError(Error::Cast(result));
1368 UNREACHABLE();
1369 }
1370 return result.raw();
1371 }
1372
1373
1374 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) {
1375 // Argument 0 is the mirror, which is unused by the native. It exists
1376 // because this native is an instance method in order to be polymorphic
1377 // with its cousins.
1378
1379 const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(1));
1380
1381 const String& setter_name =
1382 String::CheckedHandle(arguments->NativeArgAt(2));
1383
1384 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3));
1385
1386 String& internal_setter_name =
1387 String::Handle(Field::SetterName(setter_name));
1388 Function& setter = Function::Handle();
1389
1390 if (receiver.IsNull()) {
1391 // null's class doesn't handle lookups gracefully, fall through to the DNU
siva 2013/07/15 05:42:58 Ditto comment about DNU
1392 // case.
1393 } else {
1394 Class& klass = Class::Handle(receiver.clazz());
1395 Field& field = Field::Handle();
1396
1397 while (!klass.IsNull()) {
1398 field = klass.LookupInstanceField(setter_name);
1399 if (!field.IsNull() && field.is_final()) {
1400 const String& message = String::Handle(
1401 String::NewFormatted("%s: cannot set final field '%s'.",
1402 "InstanceMirror_invokeSetter",
1403 setter_name.ToCString()));
1404 ThrowMirroredCompilationError(message);
1405 UNREACHABLE();
1406 }
1407 setter = klass.LookupDynamicFunctionAllowPrivate(internal_setter_name);
1408 if (!setter.IsNull()) {
1409 break;
1410 }
1411 klass = klass.SuperClass();
1412 }
1413 }
1414
1415 Object& result = Object::Handle();
1416
1417 // Invoke the setter and return the result.
1418 const int kNumArgs = 2;
1419 const Array& args = Array::Handle(Array::New(kNumArgs));
1420 args.SetAt(0, receiver);
1421 args.SetAt(1, value);
1422 if (setter.IsNull()) {
1423 const Array& args_descriptor =
1424 Array::Handle(ArgumentsDescriptor::New(args.Length()));
1425 result = DartEntry::InvokeNoSuchMethod(receiver,
1426 internal_setter_name,
1427 args,
1428 args_descriptor);
1429 } else {
1430 result = DartEntry::InvokeFunction(setter, args);
1431 }
1432
1433 if (result.IsError()) {
1434 ThrowInvokeError(Error::Cast(result));
1435 UNREACHABLE();
1436 }
1437 return result.raw();
siva 2013/07/15 05:42:58 This pattern of InvokeNoSuchMethod or InvokeFuncti
rmacnak 2013/07/15 19:53:23 Extracted as ReflectivelyInvokeDynamicFunction. A
1438 }
1439
1440
1441 DEFINE_NATIVE_ENTRY(ClosureMirror_apply, 2) {
1442 const Instance& closure = Instance::CheckedHandle(arguments->NativeArgAt(0));
1443 ASSERT(!closure.IsNull() && closure.IsCallable(NULL, NULL));
1444
1445 const Array& positional_args =
1446 Array::CheckedHandle(arguments->NativeArgAt(1));
1447 intptr_t number_of_arguments = positional_args.Length();
1448
1449 // Set up arguments to include the closure as the first argument.
1450 const Array& args = Array::Handle(Array::New(number_of_arguments + 1));
1451 Object& obj = Object::Handle();
1452 args.SetAt(0, closure);
1453 for (int i = 0; i < number_of_arguments; i++) {
1454 obj = positional_args.At(i);
1455 args.SetAt(i + 1, obj);
1456 }
1457
1458 obj = DartEntry::InvokeClosure(args);
1459 if (obj.IsError()) {
1460 ThrowInvokeError(Error::Cast(obj));
1461 UNREACHABLE();
1462 }
1463 return obj.raw();
1464 }
1465
1466
1467 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) {
1468 // Argument 0 is the mirror, which is unused by the native. It exists
1469 // because this native is an instance method in order to be polymorphic
1470 // with its cousins.
1471
1472 const MirrorReference& klass_ref =
1473 MirrorReference::CheckedHandle(arguments->NativeArgAt(1));
1474 Class& klass = Class::Handle();
1475 klass ^= klass_ref.referent();
1476
1477 const String& function_name =
1478 String::CheckedHandle(arguments->NativeArgAt(2));
1479
1480 const Array& positional_args =
1481 Array::CheckedHandle(arguments->NativeArgAt(3));
1482 intptr_t number_of_arguments = positional_args.Length();
1483
1484 // TODO(11771): This won't find private members.
1485 const Function& function = Function::Handle(
1486 Resolver::ResolveStatic(klass,
1487 function_name,
1488 number_of_arguments,
1489 Object::empty_array(),
1490 Resolver::kIsQualified));
1491 if (function.IsNull()) {
1492 const String& klass_name = String::Handle(klass.Name());
1493 const String& message = String::Handle(
1494 String::NewFormatted("%s: did not find %d-arg static method '%s.%s'.",
1495 "ClassMirror_invoke",
1496 number_of_arguments,
1497 klass_name.ToCString(),
1498 function_name.ToCString()));
1499 ThrowMirroredCompilationError(message);
1500 UNREACHABLE();
1501 }
1502 Object& result = Object::Handle(DartEntry::InvokeFunction(function,
1503 positional_args));
1504 if (result.IsError()) {
1505 ThrowInvokeError(Error::Cast(result));
1506 UNREACHABLE();
1507 }
1508 return result.raw();
1509 }
1510
1511
1512 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) {
1513 // Argument 0 is the mirror, which is unused by the native. It exists
1514 // because this native is an instance method in order to be polymorphic
1515 // with its cousins.
1516
1517 const MirrorReference& klass_ref =
1518 MirrorReference::CheckedHandle(arguments->NativeArgAt(1));
1519 Class& klass = Class::Handle();
1520 klass ^= klass_ref.referent();
1521
1522 const String& getter_name =
1523 String::CheckedHandle(arguments->NativeArgAt(2));
1524
1525 const Field& field = Field::Handle(klass.LookupStaticField(getter_name));
1526 if (field.IsNull() || FieldIsUninitialized(field)) {
1527 const String& internal_getter_name = String::Handle(
1528 Field::GetterName(getter_name));
1529 const Function& getter = Function::Handle(
1530 klass.LookupStaticFunctionAllowPrivate(internal_getter_name));
1531
1532 if (getter.IsNull()) {
1533 const String& message = String::Handle(
1534 String::NewFormatted("%s: did not find static getter '%s'.",
1535 "ClassMirror_invokeGetter",
1536 getter_name.ToCString()));
1537 ThrowMirroredCompilationError(message);
1538 UNREACHABLE();
1539 }
1540
1541 // Invoke the getter and return the result.
1542 Object& result = Object::Handle(
1543 DartEntry::InvokeFunction(getter, Object::empty_array()));
1544 if (result.IsError()) {
1545 ThrowInvokeError(Error::Cast(result));
1546 UNREACHABLE();
1547 }
1548 return result.raw();
1549 }
1550 return field.value();
1551 }
1552
1553
1554 DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
1555 // Argument 0 is the mirror, which is unused by the native. It exists
1556 // because this native is an instance method in order to be polymorphic
1557 // with its cousins.
1558
1559 const MirrorReference& klass_ref =
1560 MirrorReference::CheckedHandle(arguments->NativeArgAt(1));
1561 Class& klass = Class::Handle();
1562 klass ^= klass_ref.referent();
1563
1564 const String& setter_name =
1565 String::CheckedHandle(arguments->NativeArgAt(2));
1566
1567 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3));
1568
1569 // Check for real fields and user-defined setters.
1570 const Field& field = Field::Handle(klass.LookupStaticField(setter_name));
1571 if (field.IsNull()) {
1572 const String& internal_setter_name = String::Handle(
1573 Field::SetterName(setter_name));
1574 const Function& setter = Function::Handle(
1575 klass.LookupStaticFunctionAllowPrivate(internal_setter_name));
1576
1577 if (setter.IsNull()) {
1578 const String& message = String::Handle(
1579 String::NewFormatted("%s: did not find static setter '%s'.",
1580 "ClassMirror_invokeSetter",
1581 setter_name.ToCString()));
1582 ThrowMirroredCompilationError(message);
1583 UNREACHABLE();
1584 }
1585
1586 // Invoke the getter and return the result.
siva 2013/07/15 05:42:58 Invoke the setter....
1587 const int kNumArgs = 1;
1588 const Array& args = Array::Handle(Array::New(kNumArgs));
1589 args.SetAt(0, value);
1590
1591 Object& result = Object::Handle(
1592 DartEntry::InvokeFunction(setter, args));
1593 if (result.IsError()) {
1594 ThrowInvokeError(Error::Cast(result));
1595 UNREACHABLE();
1596 }
1597 return result.raw();
1598 }
1599
1600 if (field.is_final()) {
1601 const String& message = String::Handle(
1602 String::NewFormatted("%s: cannot set final field '%s'.",
1603 "ClassMirror_invokeSetter",
1604 setter_name.ToCString()));
1605 ThrowMirroredCompilationError(message);
1606 UNREACHABLE();
1607 }
1608
1609 field.set_value(value);
1610 return value.raw();
1611 }
1612
1613
1614 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 3) {
1615 const MirrorReference& klass_ref =
1616 MirrorReference::CheckedHandle(arguments->NativeArgAt(0));
1617 Class& klass = Class::Handle();
1618 klass ^= klass_ref.referent();
1619
1620 const String& constructor_name =
1621 String::CheckedHandle(arguments->NativeArgAt(1));
1622
1623 const Array& positional_args =
1624 Array::CheckedHandle(arguments->NativeArgAt(2));
1625
1626 intptr_t number_of_arguments = positional_args.Length();
1627
1628 // By convention, the static function implementing a named constructor 'C'
1629 // for class 'A' is labeled 'A.C', and the static function implementing the
1630 // unnamed constructor for class 'A' is labeled 'A.'.
1631 // This convention prevents users from explicitly calling constructors.
1632 String& klass_name = String::Handle(klass.Name());
siva 2013/07/15 05:42:58 const String& klass_name = String::Handle(.....);
1633 String& internal_constructor_name =
1634 String::Handle(String::Concat(klass_name, Symbols::Dot()));
siva 2013/07/15 05:42:58 if (!constructor_name.IsNull()) {
rmacnak 2013/07/15 19:53:23 Attempting to pass null fails before the native, i
1635 internal_constructor_name =
1636 String::Concat(internal_constructor_name, constructor_name);
1637
1638 Function& constructor =
siva 2013/07/15 05:42:58 const Function& constructor =
1639 Function::Handle(ResolveConstructor("ClassMirror_invokeConstructor",
1640 klass,
1641 klass_name,
1642 internal_constructor_name,
1643 number_of_arguments));
1644
1645 Object& result =
siva 2013/07/15 05:42:58 const Object& result = ....
1646 Object::Handle(DartEntry::InvokeConstructor(klass,
1647 constructor,
1648 positional_args));
1649 if (result.IsError()) {
1650 ThrowInvokeError(Error::Cast(result));
1651 UNREACHABLE();
1652 }
1653 // Factories may return null.
1654 ASSERT(result.IsInstance() || result.IsNull());
1655 return result.raw();
1656 }
1657
1658
1659 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) {
1660 // Argument 0 is the mirror, which is unused by the native. It exists
1661 // because this native is an instance method in order to be polymorphic
1662 // with its cousins.
1663
1664 const MirrorReference& library_ref =
1665 MirrorReference::CheckedHandle(arguments->NativeArgAt(1));
1666 Library& library = Library::Handle();
1667 library ^= library_ref.referent();
1668
1669 const String& function_name =
1670 String::CheckedHandle(arguments->NativeArgAt(2));
1671
1672 const Array& positional_args =
1673 Array::CheckedHandle(arguments->NativeArgAt(3));
1674 intptr_t number_of_arguments = positional_args.Length();
1675
1676
1677 Function& function = Function::Handle();
1678 function = library.LookupFunctionAllowPrivate(function_name);
siva 2013/07/15 05:42:58 const Function& function = Function::Handle(.....)
1679
1680 if (function.IsNull()) {
1681 const String& message = String::Handle(
1682 String::NewFormatted("%s: did not find top-level function '%s'.",
1683 "LibraryMirror_invoke",
1684 function_name.ToCString()));
1685 ThrowMirroredCompilationError(message);
1686 UNREACHABLE();
1687 }
1688
1689 // LookupFunctionAllowPrivate does not check argument arity, so we
1690 // do it here.
1691 String& error_message = String::Handle();
1692 if (!function.AreValidArgumentCounts(number_of_arguments,
1693 /* num_named_args */ 0,
1694 &error_message)) {
1695 const String& message = String::Handle(
1696 String::NewFormatted("%s: wrong argument count for function '%s': %s.",
1697 "LibraryMirror_invoke",
1698 function_name.ToCString(),
1699 error_message.ToCString()));
1700 ThrowMirroredCompilationError(message);
1701 UNREACHABLE();
1702 }
1703
1704 Object& result = Object::Handle(DartEntry::InvokeFunction(function,
1705 positional_args));
siva 2013/07/15 05:42:58 const Object& result = .....
1706 if (result.IsError()) {
1707 ThrowInvokeError(Error::Cast(result));
1708 UNREACHABLE();
1709 }
1710 return result.raw();
1711 }
1712
1713
1714 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) {
1715 // Argument 0 is the mirror, which is unused by the native. It exists
1716 // because this native is an instance method in order to be polymorphic
1717 // with its cousins.
1718
1719 const MirrorReference& library_ref =
1720 MirrorReference::CheckedHandle(arguments->NativeArgAt(1));
1721 Library& library = Library::Handle();
1722 library ^= library_ref.referent();
1723
1724 const String& getter_name =
1725 String::CheckedHandle(arguments->NativeArgAt(2));
1726
1727 // To access a top-level we may need to use the Field or the
1728 // getter Function. The getter function may either be in the
1729 // library or in the field's owner class, depending.
1730 Field& field = Field::Handle(library.LookupFieldAllowPrivate(getter_name));
1731 Function& getter = Function::Handle();
1732 if (field.IsNull()) {
1733 // No field found. Check for a getter in the lib.
1734 const String& internal_getter_name =
1735 String::Handle(Field::GetterName(getter_name));
1736 getter = library.LookupFunctionAllowPrivate(internal_getter_name);
1737 } else if (FieldIsUninitialized(field)) {
1738 // A field was found. Check for a getter in the field's owner classs.
1739 const Class& klass = Class::Handle(field.owner());
1740 const String& internal_getter_name =
1741 String::Handle(Field::GetterName(getter_name));
1742 getter = klass.LookupStaticFunctionAllowPrivate(internal_getter_name);
1743 }
1744
1745 if (!getter.IsNull()) {
1746 // Invoke the getter and return the result.
1747 Object& result = Object::Handle(
1748 DartEntry::InvokeFunction(getter, Object::empty_array()));
1749 if (result.IsError()) {
1750 ThrowInvokeError(Error::Cast(result));
1751 UNREACHABLE();
1752 }
1753 return result.raw();
1754 } else if (!field.IsNull()) {
1755 return field.value();
1756 } else {
1757 const String& message = String::Handle(
1758 String::NewFormatted("%s: did not find top-level variable '%s'.",
1759 "LibraryMirror_invokeGetter",
1760 getter_name.ToCString()));
1761 ThrowMirroredCompilationError(message);
1762 UNREACHABLE();
1763 return Instance::null();
1764 }
1765 }
1766
1767
1768 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) {
1769 // Argument 0 is the mirror, which is unused by the native. It exists
1770 // because this native is an instance method in order to be polymorphic
1771 // with its cousins.
1772
1773 const MirrorReference& library_ref =
1774 MirrorReference::CheckedHandle(arguments->NativeArgAt(1));
1775 Library& library = Library::Handle();
1776 library ^= library_ref.referent();
1777
1778 const String& setter_name =
1779 String::CheckedHandle(arguments->NativeArgAt(2));
1780
1781 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3));
1782
1783 // To access a top-level we may need to use the Field or the
1784 // setter Function. The setter function may either be in the
1785 // library or in the field's owner class, depending.
1786 Field& field = Field::Handle(library.LookupFieldAllowPrivate(setter_name));
1787
1788 if (field.IsNull()) {
1789 const String& internal_setter_name =
1790 String::Handle(Field::SetterName(setter_name));
1791 const Function& setter = Function::Handle(
1792 library.LookupFunctionAllowPrivate(internal_setter_name));
1793
1794 if (setter.IsNull()) {
1795 const String& message = String::Handle(
1796 String::NewFormatted("%s: did not find top-level variable '%s'.",
1797 "LibraryMirror_invokeSetter",
1798 setter_name.ToCString()));
1799 ThrowMirroredCompilationError(message);
1800 UNREACHABLE();
1801 }
1802
1803 // Invoke the setter and return the result.
1804 const int kNumArgs = 1;
1805 const Array& args = Array::Handle(Array::New(kNumArgs));
1806 args.SetAt(0, value);
1807 Object& result = Object::Handle(
1808 DartEntry::InvokeFunction(setter, args));
1809 if (result.IsError()) {
1810 ThrowInvokeError(Error::Cast(result));
1811 UNREACHABLE();
1812 }
1813 return result.raw();
1814 }
1815
1816 if (field.is_final()) {
1817 const String& message = String::Handle(
1818 String::NewFormatted("%s: cannot set final top-level variable '%s'.",
1819 "LibraryMirror_invokeSetter",
1820 setter_name.ToCString()));
1821 ThrowMirroredCompilationError(message);
1822 UNREACHABLE();
1823 }
1824
1825 field.set_value(value);
1826 return value.raw();
1827 }
1828
1829
1431 DEFINE_NATIVE_ENTRY(MethodMirror_name, 1) { 1830 DEFINE_NATIVE_ENTRY(MethodMirror_name, 1) {
1432 const MirrorReference& func_ref = 1831 const MirrorReference& func_ref =
1433 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); 1832 MirrorReference::CheckedHandle(arguments->NativeArgAt(0));
1434 Function& func = Function::Handle(); 1833 Function& func = Function::Handle();
1435 func ^= func_ref.referent(); 1834 func ^= func_ref.referent();
1436 return func.UserVisibleName(); 1835 return func.UserVisibleName();
1437 } 1836 }
1438 1837
1439 } // namespace dart 1838 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/vm/dart_entry.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698