Chromium Code Reviews| 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 String& exc_string = String::Handle(); | |
| 1157 // Ignore any errors that might occur in toString. | |
| 1158 if (exc_string_or_error.IsString()) { | |
| 1159 exc_string ^= exc_string_or_error.raw(); | |
| 1160 } | |
| 1161 | |
| 1162 Instance& mirror_on_exc = Instance::Handle(Reflect(exc)); | |
| 1163 | |
| 1164 Array& args = Array::Handle(Array::New(3)); | |
| 1165 args.SetAt(0, mirror_on_exc); | |
| 1166 args.SetAt(1, exc_string); | |
| 1167 args.SetAt(2, stack); | |
| 1168 | |
| 1169 Exceptions::ThrowByType(Exceptions::kMirroredUncaughtExceptionError, args); | |
| 1170 UNREACHABLE(); | |
| 1171 } | |
| 1172 | |
| 1173 | |
| 1174 static void ThrowMirroredCompilationError(const String& message) { | |
| 1175 Array& args = Array::Handle(Array::New(1)); | |
| 1176 args.SetAt(0, message); | |
| 1177 | |
| 1178 Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args); | |
| 1179 UNREACHABLE(); | |
| 1180 } | |
| 1181 | |
| 1182 | |
| 1183 static void ThrowInvokeError(const Error& error) { | |
| 1184 if (error.IsUnhandledException()) { | |
| 1185 // An ordinary runtime error. | |
| 1186 ThrowMirroredUnhandledError(error); | |
| 1187 } | |
| 1188 if (error.IsLanguageError()) { | |
| 1189 // A compilation error that was delayed by lazy compilation. | |
| 1190 const LanguageError& compilation_error = LanguageError::Cast(error); | |
| 1191 String& message = String::Handle(compilation_error.message()); | |
| 1192 ThrowMirroredCompilationError(message); | |
| 1193 } | |
| 1194 UNREACHABLE(); | |
| 1195 } | |
| 1196 | |
| 1197 | |
| 1198 static RawFunction* ResolveConstructor(const char* current_func, | |
| 1199 const Class& cls, | |
| 1200 const String& class_name, | |
| 1201 const String& constr_name, | |
| 1202 int num_args) { | |
| 1203 // The constructor must be present in the interface. | |
| 1204 const Function& constructor = | |
| 1205 Function::Handle(cls.LookupFunctionAllowPrivate(constr_name)); | |
| 1206 if (constructor.IsNull() || | |
| 1207 (!constructor.IsConstructor() && !constructor.IsFactory())) { | |
| 1208 const String& lookup_class_name = String::Handle(cls.Name()); | |
| 1209 if (!class_name.Equals(lookup_class_name)) { | |
| 1210 // When the class name used to build the constructor name is | |
| 1211 // different than the name of the class in which we are doing | |
| 1212 // the lookup, it can be confusing to the user to figure out | |
| 1213 // what's going on. Be a little more explicit for these error | |
| 1214 // messages. | |
| 1215 const String& message = String::Handle( | |
| 1216 String::NewFormatted( | |
| 1217 "%s: could not find factory '%s' in class '%s'.", | |
| 1218 current_func, | |
| 1219 constr_name.ToCString(), | |
| 1220 lookup_class_name.ToCString())); | |
| 1221 ThrowMirroredCompilationError(message); | |
| 1222 UNREACHABLE(); | |
| 1223 } else { | |
| 1224 const String& message = String::Handle( | |
| 1225 String::NewFormatted("%s: could not find constructor '%s'.", | |
| 1226 current_func, constr_name.ToCString())); | |
| 1227 ThrowMirroredCompilationError(message); | |
| 1228 UNREACHABLE(); | |
| 1229 } | |
| 1230 } | |
| 1231 int extra_args = (constructor.IsConstructor() ? 2 : 1); | |
| 1232 String& error_message = String::Handle(); | |
| 1233 if (!constructor.AreValidArgumentCounts(num_args + extra_args, | |
| 1234 0, | |
| 1235 &error_message)) { | |
| 1236 const String& message = String::Handle( | |
| 1237 String::NewFormatted("%s: wrong argument count for " | |
| 1238 "constructor '%s': %s.", | |
| 1239 current_func, | |
| 1240 constr_name.ToCString(), | |
| 1241 error_message.ToCString())); | |
| 1242 ThrowMirroredCompilationError(message); | |
| 1243 UNREACHABLE(); | |
| 1244 } | |
| 1245 return constructor.raw(); | |
| 1246 } | |
| 1247 | |
| 1248 | |
| 1249 static bool FieldIsUninitialized(const Field& field) { | |
| 1250 ASSERT(!field.IsNull()); | |
| 1251 | |
| 1252 // Return getter method for uninitialized fields, rather than the | |
| 1253 // field object, since the value in the field object will not be | |
| 1254 // initialized until the first time the getter is invoked. | |
| 1255 const Instance& value = Instance::Handle(field.value()); | |
| 1256 ASSERT(value.raw() != Object::transition_sentinel().raw()); | |
| 1257 return value.raw() == Object::sentinel().raw(); | |
| 1258 } | |
| 1259 | |
| 1260 | |
| 1423 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { | 1261 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { |
| 1424 const MirrorReference& klass_ref = | 1262 const MirrorReference& klass_ref = |
| 1425 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | 1263 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); |
| 1426 Class& klass = Class::Handle(); | 1264 Class& klass = Class::Handle(); |
| 1427 klass ^= klass_ref.referent(); | 1265 klass ^= klass_ref.referent(); |
| 1428 return klass.Name(); | 1266 return klass.Name(); |
| 1429 } | 1267 } |
| 1430 | 1268 |
| 1269 | |
| 1270 // Invoke the function, or noSuchMethod if it is null. Propagate any unhandled | |
| 1271 // exceptions. Wrap and propagate any compilation errors. | |
| 1272 static RawObject* ReflectivelyInvokeDynamicFunction(const Instance& receiver, | |
| 1273 const Function& function, | |
| 1274 const String& target_name, | |
| 1275 const Array& arguments) { | |
| 1276 // Note "arguments" is already the internal arguments with the receiver as | |
| 1277 // the first element. | |
| 1278 Object& result = Object::Handle(); | |
| 1279 if (function.IsNull()) { | |
| 1280 const Array& arguments_descriptor = | |
| 1281 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); | |
| 1282 result = DartEntry::InvokeNoSuchMethod(receiver, | |
| 1283 target_name, | |
| 1284 arguments, | |
| 1285 arguments_descriptor); | |
| 1286 } else { | |
| 1287 result = DartEntry::InvokeFunction(function, arguments); | |
| 1288 } | |
| 1289 | |
| 1290 if (result.IsError()) { | |
| 1291 ThrowInvokeError(Error::Cast(result)); | |
| 1292 UNREACHABLE(); | |
| 1293 } | |
| 1294 return result.raw(); | |
| 1295 } | |
| 1296 | |
| 1297 | |
| 1298 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 4) { | |
| 1299 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1300 // because this native is an instance method in order to be polymorphic | |
| 1301 // with its cousins. | |
| 1302 | |
| 1303 const Instance& reflectee = | |
| 1304 Instance::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1305 | |
| 1306 const String& function_name = | |
| 1307 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1308 | |
| 1309 const Array& positional_args = | |
| 1310 Array::CheckedHandle(arguments->NativeArgAt(3)); | |
| 1311 intptr_t number_of_arguments = positional_args.Length(); | |
| 1312 | |
| 1313 | |
| 1314 const intptr_t num_receiver = 1; // 1 for instance methods | |
| 1315 const Array& args = | |
| 1316 Array::Handle(Array::New(number_of_arguments + num_receiver)); | |
| 1317 Object& arg = Object::Handle(); | |
| 1318 args.SetAt(0, reflectee); | |
| 1319 for (int i = 0; i < number_of_arguments; i++) { | |
| 1320 arg = positional_args.At(i); | |
| 1321 args.SetAt((i + num_receiver), arg); | |
|
Florian Schneider
2013/07/16 09:39:56
Please don't over-parenthesize. I don't think ther
| |
| 1322 } | |
| 1323 | |
| 1324 // TODO(11771): This won't find private members. | |
| 1325 const Function& function = Function::Handle( | |
| 1326 Resolver::ResolveDynamic(reflectee, | |
| 1327 function_name, | |
| 1328 (number_of_arguments + 1), | |
|
Florian Schneider
2013/07/16 09:39:56
Please don't over-parenthesize. I don't think ther
| |
| 1329 Resolver::kIsQualified)); | |
|
Florian Schneider
2013/07/16 09:39:56
This is an enum where the function expects an int.
| |
| 1330 | |
| 1331 return ReflectivelyInvokeDynamicFunction(reflectee, | |
| 1332 function, | |
| 1333 function_name, | |
| 1334 args); | |
| 1335 } | |
| 1336 | |
| 1337 | |
| 1338 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) { | |
| 1339 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1340 // because this native is an instance method in order to be polymorphic | |
| 1341 // with its cousins. | |
| 1342 | |
| 1343 const Instance& reflectee = | |
| 1344 Instance::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1345 | |
| 1346 const String& getter_name = | |
| 1347 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1348 | |
| 1349 // Every instance field has a getter Function. Try to find the | |
| 1350 // getter in any superclass and use that function to access the | |
| 1351 // field. | |
| 1352 // NB: We do not use Resolver::ResolveDynamic because we want to find private | |
| 1353 // members. | |
| 1354 Class& klass = Class::Handle(reflectee.clazz()); | |
| 1355 String& internal_getter_name = String::Handle(Field::GetterName(getter_name)); | |
| 1356 Function& getter = Function::Handle(); | |
| 1357 while (!klass.IsNull()) { | |
| 1358 getter = klass.LookupDynamicFunctionAllowPrivate(internal_getter_name); | |
| 1359 if (!getter.IsNull()) { | |
| 1360 break; | |
| 1361 } | |
| 1362 klass = klass.SuperClass(); | |
| 1363 } | |
| 1364 | |
| 1365 const int kNumArgs = 1; | |
| 1366 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
| 1367 args.SetAt(0, reflectee); | |
| 1368 | |
| 1369 return ReflectivelyInvokeDynamicFunction(reflectee, | |
| 1370 getter, | |
| 1371 internal_getter_name, | |
| 1372 args); | |
| 1373 } | |
| 1374 | |
| 1375 | |
| 1376 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { | |
| 1377 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1378 // because this native is an instance method in order to be polymorphic | |
| 1379 // with its cousins. | |
| 1380 | |
| 1381 const Instance& reflectee = | |
| 1382 Instance::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1383 | |
| 1384 const String& setter_name = | |
| 1385 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1386 | |
| 1387 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3)); | |
| 1388 | |
| 1389 String& internal_setter_name = | |
| 1390 String::Handle(Field::SetterName(setter_name)); | |
| 1391 Function& setter = Function::Handle(); | |
| 1392 | |
| 1393 Class& klass = Class::Handle(reflectee.clazz()); | |
| 1394 Field& field = Field::Handle(); | |
| 1395 | |
| 1396 while (!klass.IsNull()) { | |
| 1397 field = klass.LookupInstanceField(setter_name); | |
| 1398 if (!field.IsNull() && field.is_final()) { | |
| 1399 const String& message = String::Handle( | |
| 1400 String::NewFormatted("%s: cannot set final field '%s'.", | |
| 1401 "InstanceMirror_invokeSetter", | |
| 1402 setter_name.ToCString())); | |
| 1403 ThrowMirroredCompilationError(message); | |
| 1404 UNREACHABLE(); | |
| 1405 } | |
| 1406 setter = klass.LookupDynamicFunctionAllowPrivate(internal_setter_name); | |
| 1407 if (!setter.IsNull()) { | |
| 1408 break; | |
| 1409 } | |
| 1410 klass = klass.SuperClass(); | |
| 1411 } | |
| 1412 | |
| 1413 // Invoke the setter and return the result. | |
| 1414 const int kNumArgs = 2; | |
| 1415 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
| 1416 args.SetAt(0, reflectee); | |
| 1417 args.SetAt(1, value); | |
| 1418 | |
| 1419 return ReflectivelyInvokeDynamicFunction(reflectee, | |
| 1420 setter, | |
| 1421 internal_setter_name, | |
| 1422 args); | |
| 1423 } | |
| 1424 | |
| 1425 | |
| 1426 DEFINE_NATIVE_ENTRY(ClosureMirror_apply, 2) { | |
| 1427 const Instance& closure = Instance::CheckedHandle(arguments->NativeArgAt(0)); | |
| 1428 ASSERT(!closure.IsNull() && closure.IsCallable(NULL, NULL)); | |
| 1429 | |
| 1430 const Array& positional_args = | |
| 1431 Array::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1432 intptr_t number_of_arguments = positional_args.Length(); | |
| 1433 | |
| 1434 // Set up arguments to include the closure as the first argument. | |
| 1435 const Array& args = Array::Handle(Array::New(number_of_arguments + 1)); | |
| 1436 Object& obj = Object::Handle(); | |
| 1437 args.SetAt(0, closure); | |
| 1438 for (int i = 0; i < number_of_arguments; i++) { | |
| 1439 obj = positional_args.At(i); | |
| 1440 args.SetAt(i + 1, obj); | |
| 1441 } | |
| 1442 | |
| 1443 obj = DartEntry::InvokeClosure(args); | |
| 1444 if (obj.IsError()) { | |
| 1445 ThrowInvokeError(Error::Cast(obj)); | |
| 1446 UNREACHABLE(); | |
| 1447 } | |
| 1448 return obj.raw(); | |
| 1449 } | |
| 1450 | |
| 1451 | |
| 1452 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) { | |
| 1453 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1454 // because this native is an instance method in order to be polymorphic | |
| 1455 // with its cousins. | |
| 1456 | |
| 1457 const MirrorReference& klass_ref = | |
| 1458 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1459 Class& klass = Class::Handle(); | |
| 1460 klass ^= klass_ref.referent(); | |
| 1461 | |
| 1462 const String& function_name = | |
| 1463 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1464 | |
| 1465 const Array& positional_args = | |
| 1466 Array::CheckedHandle(arguments->NativeArgAt(3)); | |
| 1467 intptr_t number_of_arguments = positional_args.Length(); | |
| 1468 | |
| 1469 // TODO(11771): This won't find private members. | |
| 1470 const Function& function = Function::Handle( | |
| 1471 Resolver::ResolveStatic(klass, | |
| 1472 function_name, | |
| 1473 number_of_arguments, | |
| 1474 Object::empty_array(), | |
| 1475 Resolver::kIsQualified)); | |
| 1476 if (function.IsNull()) { | |
| 1477 const String& klass_name = String::Handle(klass.Name()); | |
| 1478 const String& message = String::Handle( | |
| 1479 String::NewFormatted("%s: did not find %d-arg static method '%s.%s'.", | |
| 1480 "ClassMirror_invoke", | |
| 1481 number_of_arguments, | |
| 1482 klass_name.ToCString(), | |
| 1483 function_name.ToCString())); | |
| 1484 ThrowMirroredCompilationError(message); | |
| 1485 UNREACHABLE(); | |
| 1486 } | |
| 1487 Object& result = Object::Handle(DartEntry::InvokeFunction(function, | |
| 1488 positional_args)); | |
| 1489 if (result.IsError()) { | |
| 1490 ThrowInvokeError(Error::Cast(result)); | |
| 1491 UNREACHABLE(); | |
| 1492 } | |
| 1493 return result.raw(); | |
| 1494 } | |
| 1495 | |
| 1496 | |
| 1497 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { | |
| 1498 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1499 // because this native is an instance method in order to be polymorphic | |
| 1500 // with its cousins. | |
| 1501 | |
| 1502 const MirrorReference& klass_ref = | |
| 1503 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1504 Class& klass = Class::Handle(); | |
| 1505 klass ^= klass_ref.referent(); | |
| 1506 | |
| 1507 const String& getter_name = | |
| 1508 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1509 | |
| 1510 // Note static fields do not have implicit getters. | |
| 1511 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); | |
| 1512 if (field.IsNull() || FieldIsUninitialized(field)) { | |
| 1513 const String& internal_getter_name = String::Handle( | |
| 1514 Field::GetterName(getter_name)); | |
| 1515 const Function& getter = Function::Handle( | |
| 1516 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); | |
| 1517 | |
| 1518 if (getter.IsNull()) { | |
| 1519 const String& message = String::Handle( | |
| 1520 String::NewFormatted("%s: did not find static getter '%s'.", | |
| 1521 "ClassMirror_invokeGetter", | |
| 1522 getter_name.ToCString())); | |
| 1523 ThrowMirroredCompilationError(message); | |
| 1524 UNREACHABLE(); | |
| 1525 } | |
| 1526 | |
| 1527 // Invoke the getter and return the result. | |
| 1528 Object& result = Object::Handle( | |
| 1529 DartEntry::InvokeFunction(getter, Object::empty_array())); | |
| 1530 if (result.IsError()) { | |
| 1531 ThrowInvokeError(Error::Cast(result)); | |
| 1532 UNREACHABLE(); | |
| 1533 } | |
| 1534 return result.raw(); | |
| 1535 } | |
| 1536 return field.value(); | |
| 1537 } | |
| 1538 | |
| 1539 | |
| 1540 DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) { | |
| 1541 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1542 // because this native is an instance method in order to be polymorphic | |
| 1543 // with its cousins. | |
| 1544 | |
| 1545 const MirrorReference& klass_ref = | |
| 1546 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1547 Class& klass = Class::Handle(); | |
| 1548 klass ^= klass_ref.referent(); | |
| 1549 | |
| 1550 const String& setter_name = | |
| 1551 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1552 | |
| 1553 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3)); | |
| 1554 | |
| 1555 // Check for real fields and user-defined setters. | |
| 1556 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | |
| 1557 if (field.IsNull()) { | |
| 1558 const String& internal_setter_name = String::Handle( | |
| 1559 Field::SetterName(setter_name)); | |
| 1560 const Function& setter = Function::Handle( | |
| 1561 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); | |
| 1562 | |
| 1563 if (setter.IsNull()) { | |
| 1564 const String& message = String::Handle( | |
| 1565 String::NewFormatted("%s: did not find static setter '%s'.", | |
| 1566 "ClassMirror_invokeSetter", | |
| 1567 setter_name.ToCString())); | |
| 1568 ThrowMirroredCompilationError(message); | |
| 1569 UNREACHABLE(); | |
| 1570 } | |
| 1571 | |
| 1572 // Invoke the setter and return the result. | |
| 1573 const int kNumArgs = 1; | |
| 1574 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
| 1575 args.SetAt(0, value); | |
| 1576 | |
| 1577 Object& result = Object::Handle( | |
| 1578 DartEntry::InvokeFunction(setter, args)); | |
| 1579 if (result.IsError()) { | |
| 1580 ThrowInvokeError(Error::Cast(result)); | |
| 1581 UNREACHABLE(); | |
| 1582 } | |
| 1583 return result.raw(); | |
| 1584 } | |
| 1585 | |
| 1586 if (field.is_final()) { | |
| 1587 const String& message = String::Handle( | |
| 1588 String::NewFormatted("%s: cannot set final field '%s'.", | |
| 1589 "ClassMirror_invokeSetter", | |
| 1590 setter_name.ToCString())); | |
| 1591 ThrowMirroredCompilationError(message); | |
| 1592 UNREACHABLE(); | |
| 1593 } | |
| 1594 | |
| 1595 field.set_value(value); | |
| 1596 return value.raw(); | |
| 1597 } | |
| 1598 | |
| 1599 | |
| 1600 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 3) { | |
| 1601 const MirrorReference& klass_ref = | |
| 1602 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | |
| 1603 Class& klass = Class::Handle(); | |
| 1604 klass ^= klass_ref.referent(); | |
| 1605 | |
| 1606 const String& constructor_name = | |
| 1607 String::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1608 | |
| 1609 const Array& positional_args = | |
| 1610 Array::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1611 | |
| 1612 intptr_t number_of_arguments = positional_args.Length(); | |
| 1613 | |
| 1614 // By convention, the static function implementing a named constructor 'C' | |
| 1615 // for class 'A' is labeled 'A.C', and the static function implementing the | |
| 1616 // unnamed constructor for class 'A' is labeled 'A.'. | |
| 1617 // This convention prevents users from explicitly calling constructors. | |
| 1618 const String& klass_name = String::Handle(klass.Name()); | |
| 1619 String& internal_constructor_name = | |
| 1620 String::Handle(String::Concat(klass_name, Symbols::Dot())); | |
| 1621 if (!constructor_name.IsNull()) { | |
| 1622 internal_constructor_name = | |
| 1623 String::Concat(internal_constructor_name, constructor_name); | |
| 1624 } | |
| 1625 | |
| 1626 const Function& constructor = | |
| 1627 Function::Handle(ResolveConstructor("ClassMirror_invokeConstructor", | |
| 1628 klass, | |
| 1629 klass_name, | |
| 1630 internal_constructor_name, | |
| 1631 number_of_arguments)); | |
| 1632 | |
| 1633 const Object& result = | |
| 1634 Object::Handle(DartEntry::InvokeConstructor(klass, | |
| 1635 constructor, | |
| 1636 positional_args)); | |
| 1637 if (result.IsError()) { | |
| 1638 ThrowInvokeError(Error::Cast(result)); | |
| 1639 UNREACHABLE(); | |
| 1640 } | |
| 1641 // Factories may return null. | |
| 1642 ASSERT(result.IsInstance() || result.IsNull()); | |
| 1643 return result.raw(); | |
| 1644 } | |
| 1645 | |
| 1646 | |
| 1647 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) { | |
| 1648 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1649 // because this native is an instance method in order to be polymorphic | |
| 1650 // with its cousins. | |
| 1651 | |
| 1652 const MirrorReference& library_ref = | |
| 1653 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1654 Library& library = Library::Handle(); | |
| 1655 library ^= library_ref.referent(); | |
| 1656 | |
| 1657 const String& function_name = | |
| 1658 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1659 | |
| 1660 const Array& positional_args = | |
| 1661 Array::CheckedHandle(arguments->NativeArgAt(3)); | |
| 1662 intptr_t number_of_arguments = positional_args.Length(); | |
| 1663 | |
| 1664 | |
| 1665 const Function& function = Function::Handle( | |
| 1666 library.LookupFunctionAllowPrivate(function_name)); | |
| 1667 | |
| 1668 if (function.IsNull()) { | |
| 1669 const String& message = String::Handle( | |
| 1670 String::NewFormatted("%s: did not find top-level function '%s'.", | |
| 1671 "LibraryMirror_invoke", | |
| 1672 function_name.ToCString())); | |
| 1673 ThrowMirroredCompilationError(message); | |
| 1674 UNREACHABLE(); | |
| 1675 } | |
| 1676 | |
| 1677 // LookupFunctionAllowPrivate does not check argument arity, so we | |
| 1678 // do it here. | |
| 1679 String& error_message = String::Handle(); | |
| 1680 if (!function.AreValidArgumentCounts(number_of_arguments, | |
| 1681 /* num_named_args */ 0, | |
| 1682 &error_message)) { | |
| 1683 const String& message = String::Handle( | |
| 1684 String::NewFormatted("%s: wrong argument count for function '%s': %s.", | |
| 1685 "LibraryMirror_invoke", | |
| 1686 function_name.ToCString(), | |
| 1687 error_message.ToCString())); | |
| 1688 ThrowMirroredCompilationError(message); | |
| 1689 UNREACHABLE(); | |
| 1690 } | |
| 1691 | |
| 1692 const Object& result = Object::Handle( | |
| 1693 DartEntry::InvokeFunction(function, positional_args)); | |
| 1694 if (result.IsError()) { | |
| 1695 ThrowInvokeError(Error::Cast(result)); | |
| 1696 UNREACHABLE(); | |
| 1697 } | |
| 1698 return result.raw(); | |
| 1699 } | |
| 1700 | |
| 1701 | |
| 1702 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) { | |
| 1703 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1704 // because this native is an instance method in order to be polymorphic | |
| 1705 // with its cousins. | |
| 1706 | |
| 1707 const MirrorReference& library_ref = | |
| 1708 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1709 Library& library = Library::Handle(); | |
| 1710 library ^= library_ref.referent(); | |
| 1711 | |
| 1712 const String& getter_name = | |
| 1713 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1714 | |
| 1715 // To access a top-level we may need to use the Field or the | |
| 1716 // getter Function. The getter function may either be in the | |
| 1717 // library or in the field's owner class, depending. | |
| 1718 const Field& field = | |
| 1719 Field::Handle(library.LookupFieldAllowPrivate(getter_name)); | |
| 1720 Function& getter = Function::Handle(); | |
| 1721 if (field.IsNull()) { | |
| 1722 // No field found. Check for a getter in the lib. | |
| 1723 const String& internal_getter_name = | |
| 1724 String::Handle(Field::GetterName(getter_name)); | |
| 1725 getter = library.LookupFunctionAllowPrivate(internal_getter_name); | |
| 1726 } else if (FieldIsUninitialized(field)) { | |
| 1727 // A field was found. Check for a getter in the field's owner classs. | |
| 1728 const Class& klass = Class::Handle(field.owner()); | |
| 1729 const String& internal_getter_name = | |
| 1730 String::Handle(Field::GetterName(getter_name)); | |
| 1731 getter = klass.LookupStaticFunctionAllowPrivate(internal_getter_name); | |
| 1732 } | |
| 1733 | |
| 1734 if (!getter.IsNull()) { | |
| 1735 // Invoke the getter and return the result. | |
| 1736 const Object& result = Object::Handle( | |
| 1737 DartEntry::InvokeFunction(getter, Object::empty_array())); | |
| 1738 if (result.IsError()) { | |
| 1739 ThrowInvokeError(Error::Cast(result)); | |
| 1740 UNREACHABLE(); | |
| 1741 } | |
| 1742 return result.raw(); | |
| 1743 } else if (!field.IsNull()) { | |
| 1744 return field.value(); | |
| 1745 } else { | |
| 1746 const String& message = String::Handle( | |
| 1747 String::NewFormatted("%s: did not find top-level variable '%s'.", | |
| 1748 "LibraryMirror_invokeGetter", | |
| 1749 getter_name.ToCString())); | |
| 1750 ThrowMirroredCompilationError(message); | |
| 1751 UNREACHABLE(); | |
| 1752 return Instance::null(); | |
| 1753 } | |
| 1754 } | |
| 1755 | |
| 1756 | |
| 1757 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { | |
| 1758 // Argument 0 is the mirror, which is unused by the native. It exists | |
| 1759 // because this native is an instance method in order to be polymorphic | |
| 1760 // with its cousins. | |
| 1761 | |
| 1762 const MirrorReference& library_ref = | |
| 1763 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1764 Library& library = Library::Handle(); | |
| 1765 library ^= library_ref.referent(); | |
| 1766 | |
| 1767 const String& setter_name = | |
| 1768 String::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1769 | |
| 1770 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3)); | |
| 1771 | |
| 1772 // To access a top-level we may need to use the Field or the | |
| 1773 // setter Function. The setter function may either be in the | |
| 1774 // library or in the field's owner class, depending. | |
| 1775 const Field& field = | |
| 1776 Field::Handle(library.LookupFieldAllowPrivate(setter_name)); | |
| 1777 | |
| 1778 if (field.IsNull()) { | |
| 1779 const String& internal_setter_name = | |
| 1780 String::Handle(Field::SetterName(setter_name)); | |
| 1781 const Function& setter = Function::Handle( | |
| 1782 library.LookupFunctionAllowPrivate(internal_setter_name)); | |
| 1783 | |
| 1784 if (setter.IsNull()) { | |
| 1785 const String& message = String::Handle( | |
| 1786 String::NewFormatted("%s: did not find top-level variable '%s'.", | |
| 1787 "LibraryMirror_invokeSetter", | |
| 1788 setter_name.ToCString())); | |
| 1789 ThrowMirroredCompilationError(message); | |
| 1790 UNREACHABLE(); | |
| 1791 } | |
| 1792 | |
| 1793 // Invoke the setter and return the result. | |
| 1794 const int kNumArgs = 1; | |
| 1795 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
| 1796 args.SetAt(0, value); | |
| 1797 const Object& result = Object::Handle( | |
| 1798 DartEntry::InvokeFunction(setter, args)); | |
| 1799 if (result.IsError()) { | |
| 1800 ThrowInvokeError(Error::Cast(result)); | |
| 1801 UNREACHABLE(); | |
| 1802 } | |
| 1803 return result.raw(); | |
| 1804 } | |
| 1805 | |
| 1806 if (field.is_final()) { | |
| 1807 const String& message = String::Handle( | |
| 1808 String::NewFormatted("%s: cannot set final top-level variable '%s'.", | |
| 1809 "LibraryMirror_invokeSetter", | |
| 1810 setter_name.ToCString())); | |
| 1811 ThrowMirroredCompilationError(message); | |
| 1812 UNREACHABLE(); | |
| 1813 } | |
| 1814 | |
| 1815 field.set_value(value); | |
| 1816 return value.raw(); | |
| 1817 } | |
| 1818 | |
| 1819 | |
| 1431 DEFINE_NATIVE_ENTRY(MethodMirror_name, 1) { | 1820 DEFINE_NATIVE_ENTRY(MethodMirror_name, 1) { |
| 1432 const MirrorReference& func_ref = | 1821 const MirrorReference& func_ref = |
| 1433 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | 1822 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); |
| 1434 Function& func = Function::Handle(); | 1823 Function& func = Function::Handle(); |
| 1435 func ^= func_ref.referent(); | 1824 func ^= func_ref.referent(); |
| 1436 return func.UserVisibleName(); | 1825 return func.UserVisibleName(); |
| 1437 } | 1826 } |
| 1438 | 1827 |
| 1439 } // namespace dart | 1828 } // namespace dart |
| OLD | NEW |