OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |