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 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
945 } | 946 } |
946 Dart_Handle lazy_lib_mirror = CreateLazyMirror(lib); | 947 Dart_Handle lazy_lib_mirror = CreateLazyMirror(lib); |
947 if (Dart_IsError(lazy_lib_mirror)) { | 948 if (Dart_IsError(lazy_lib_mirror)) { |
948 return lazy_lib_mirror; | 949 return lazy_lib_mirror; |
949 } | 950 } |
950 Dart_Handle member_map = CreateMemberMap(lib, lazy_lib_mirror); | 951 Dart_Handle member_map = CreateMemberMap(lib, lazy_lib_mirror); |
951 if (Dart_IsError(member_map)) { | 952 if (Dart_IsError(member_map)) { |
952 return member_map; | 953 return member_map; |
953 } | 954 } |
954 Dart_Handle args[] = { | 955 Dart_Handle args[] = { |
956 CreateMirrorReference(lib), | |
955 CreateVMReference(lib), | 957 CreateVMReference(lib), |
956 Dart_LibraryName(lib), | 958 Dart_LibraryName(lib), |
957 Dart_LibraryUrl(lib), | 959 Dart_LibraryUrl(lib), |
958 member_map, | 960 member_map, |
959 }; | 961 }; |
960 Dart_Handle lib_mirror = Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); | 962 Dart_Handle lib_mirror = Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); |
961 if (Dart_IsError(lib_mirror)) { | 963 if (Dart_IsError(lib_mirror)) { |
962 return lib_mirror; | 964 return lib_mirror; |
963 } | 965 } |
964 | 966 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1114 Dart_Handle args[] = { | 1116 Dart_Handle args[] = { |
1115 CreateVMReference(instance), | 1117 CreateVMReference(instance), |
1116 CreateLazyMirror(instance_cls), | 1118 CreateLazyMirror(instance_cls), |
1117 instance, | 1119 instance, |
1118 }; | 1120 }; |
1119 return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); | 1121 return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); |
1120 } | 1122 } |
1121 } | 1123 } |
1122 | 1124 |
1123 | 1125 |
1124 static Dart_Handle CreateMirroredError(Dart_Handle error) { | 1126 static Dart_Handle CreateHandledMirroredError(Dart_Handle error) { |
1125 ASSERT(Dart_IsError(error)); | 1127 ASSERT(Dart_IsError(error)); |
1126 if (Dart_IsUnhandledExceptionError(error)) { | 1128 if (Dart_IsUnhandledExceptionError(error)) { |
1127 Dart_Handle exc = Dart_ErrorGetException(error); | 1129 Dart_Handle exc = Dart_ErrorGetException(error); |
1128 if (Dart_IsError(exc)) { | 1130 if (Dart_IsError(exc)) { |
1129 return exc; | 1131 return exc; |
1130 } | 1132 } |
1131 Dart_Handle exc_string = Dart_ToString(exc); | 1133 Dart_Handle exc_string = Dart_ToString(exc); |
1132 if (Dart_IsError(exc_string)) { | 1134 if (Dart_IsError(exc_string)) { |
1133 // Only propagate fatal errors from exc.toString(). Ignore the rest. | 1135 // Only propagate fatal errors from exc.toString(). Ignore the rest. |
1134 if (Dart_IsFatalError(exc_string)) { | 1136 if (Dart_IsFatalError(exc_string)) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1235 Dart_Handle reflectee = UnwrapMirror(mirror); | 1237 Dart_Handle reflectee = UnwrapMirror(mirror); |
1236 Dart_Handle result = Dart_GetMetadata(reflectee); | 1238 Dart_Handle result = Dart_GetMetadata(reflectee); |
1237 if (Dart_IsError(result)) { | 1239 if (Dart_IsError(result)) { |
1238 Dart_PropagateError(result); | 1240 Dart_PropagateError(result); |
1239 } | 1241 } |
1240 ASSERT(Dart_IsList(result)); | 1242 ASSERT(Dart_IsList(result)); |
1241 Dart_SetReturnValue(args, result); | 1243 Dart_SetReturnValue(args, result); |
1242 Dart_ExitScope(); | 1244 Dart_ExitScope(); |
1243 } | 1245 } |
1244 | 1246 |
1245 void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_invoke)( | 1247 |
1248 void NATIVE_ENTRY_FUNCTION(LocalClosureMirrorImpl_apply)( | |
1246 Dart_NativeArguments args) { | 1249 Dart_NativeArguments args) { |
1247 Dart_EnterScope(); | 1250 Dart_EnterScope(); |
1248 Dart_Handle mirror = Dart_GetNativeArgument(args, 0); | 1251 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. | 1252 // The arguments are either simple values or instance mirrors. |
1251 Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 2); | 1253 Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 1); |
1252 Dart_Handle async = Dart_GetNativeArgument(args, 3); | 1254 Dart_Handle async = Dart_GetNativeArgument(args, 2); |
1253 | 1255 |
1254 Dart_Handle reflectee = UnwrapMirror(mirror); | 1256 Dart_Handle reflectee = UnwrapMirror(mirror); |
1257 GrowableArray<Dart_Handle> invoke_args; | |
1255 Dart_Handle result; | 1258 Dart_Handle result; |
1256 GrowableArray<Dart_Handle> invoke_args; | |
1257 if (Dart_IdentityEquals(async, Dart_True())) { | 1259 if (Dart_IdentityEquals(async, Dart_True())) { |
1258 result = UnwrapArgList(positional_arguments, &invoke_args); | 1260 result = UnwrapArgList(positional_arguments, &invoke_args); |
1259 } else { | 1261 } else { |
1260 result = UnpackLocalArgList(positional_arguments, &invoke_args); | 1262 result = UnpackLocalArgList(positional_arguments, &invoke_args); |
1261 } | 1263 } |
1262 if (Dart_IsError(result)) { | 1264 if (Dart_IsError(result)) { |
1263 Dart_PropagateError(result); | 1265 Dart_PropagateError(result); |
1264 } | 1266 } |
1265 result = Dart_Invoke(reflectee, | 1267 result = |
1266 member_name, | 1268 Dart_InvokeClosure(reflectee, invoke_args.length(), invoke_args.data()); |
1267 invoke_args.length(), | |
1268 invoke_args.data()); | |
1269 if (Dart_IsError(result)) { | 1269 if (Dart_IsError(result)) { |
1270 // Instead of propagating the error from an invoke directly, we | 1270 // Instead of propagating the error from an apply directly, we |
1271 // provide reflective access to the error. | 1271 // provide reflective access to the error. |
1272 Dart_PropagateError(CreateMirroredError(result)); | 1272 Dart_PropagateError(CreateHandledMirroredError(result)); |
1273 } | 1273 } |
1274 | 1274 |
1275 Dart_Handle wrapped_result = CreateInstanceMirror(result); | 1275 Dart_Handle wrapped_result = CreateInstanceMirror(result); |
1276 if (Dart_IsError(wrapped_result)) { | 1276 if (Dart_IsError(wrapped_result)) { |
1277 Dart_PropagateError(wrapped_result); | 1277 Dart_PropagateError(wrapped_result); |
1278 } | 1278 } |
1279 Dart_SetReturnValue(args, wrapped_result); | 1279 Dart_SetReturnValue(args, wrapped_result); |
1280 Dart_ExitScope(); | 1280 Dart_ExitScope(); |
1281 } | 1281 } |
1282 | 1282 |
1283 | 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 | |
1416 void HandleMirrorsMessage(Isolate* isolate, | 1284 void HandleMirrorsMessage(Isolate* isolate, |
1417 Dart_Port reply_port, | 1285 Dart_Port reply_port, |
1418 const Instance& message) { | 1286 const Instance& message) { |
1419 UNIMPLEMENTED(); | 1287 UNIMPLEMENTED(); |
1420 } | 1288 } |
1421 | 1289 |
1422 | 1290 |
1291 // TODO(11742): This is transitional. | |
1292 static RawInstance* Reflect(const Instance& reflectee) { | |
1293 Isolate* isolate = Isolate::Current(); | |
1294 DARTSCOPE(isolate); | |
1295 return Instance::RawCast( | |
1296 Api::UnwrapHandle( | |
1297 CreateInstanceMirror( | |
1298 Api::NewHandle(isolate, reflectee.raw())))); | |
1299 } | |
1300 | |
1301 | |
1302 // This is based on the embedding API, but direct use of the cid outside of | |
1303 // object.h/.c is questionable. | |
1304 static bool IsApiError(const Object& object) { | |
1305 return object.GetClassId() == kApiErrorCid; | |
1306 } | |
1307 static bool IsCompilationError(const Object& object) { | |
1308 return object.GetClassId() == kLanguageErrorCid; | |
1309 } | |
1310 | |
1311 | |
1312 static RawError* CreateMirroredError(const Error& error) { | |
siva
2013/07/11 23:50:59
Why can't this just be
void ThrowMirroredError(con
rmacnak
2013/07/12 00:04:09
Good point.
| |
1313 if (error.IsUnhandledException()) { | |
1314 const UnhandledException& unhandled_ex = UnhandledException::Cast(error); | |
1315 Instance& exc = Instance::Handle(unhandled_ex.exception()); | |
1316 Instance& stack = Instance::Handle(unhandled_ex.stacktrace()); | |
1317 | |
1318 Object& exc_string_or_error = | |
1319 Object::Handle(DartLibraryCalls::ToString(exc)); | |
1320 Instance& exc_string = Instance::Handle(); | |
1321 if (exc_string_or_error.IsError()) { | |
1322 exc_string ^= Instance::null(); | |
1323 } else { | |
1324 exc_string ^= exc_string_or_error.raw(); | |
1325 } | |
1326 | |
1327 Instance& mirror_on_exc = Instance::Handle(Reflect(exc)); | |
1328 | |
1329 Array& args = Array::Handle(Array::New(3)); | |
1330 args.SetAt(0, mirror_on_exc); | |
1331 args.SetAt(1, exc_string); | |
1332 args.SetAt(2, stack); | |
1333 | |
1334 Instance& mirrored_exc = Instance::CheckedHandle( | |
1335 DartLibraryCalls::ExceptionCreate( | |
1336 Library::Handle(Library::MirrorsLibrary()), | |
1337 String::Handle(String::New("MirroredUncaughtExceptionError")), | |
1338 Symbols::Dot(), // The unnamed constructor. | |
1339 args)); | |
1340 | |
1341 return UnhandledException::New(mirrored_exc, stack); | |
siva
2013/07/11 23:50:59
Here you would call:
Exceptions::ThrowByType(kMirr
| |
1342 } else if (IsApiError(error) || | |
1343 IsCompilationError(error)) { | |
1344 String& message = String::Handle(); | |
1345 if (IsApiError(error)) { | |
1346 message ^= ApiError::Cast(error).message(); | |
1347 } else { | |
1348 message ^= LanguageError::Cast(error).message(); | |
1349 } | |
1350 | |
1351 Array& args = Array::Handle(Array::New(1)); | |
1352 args.SetAt(0, message); | |
1353 | |
1354 Instance& mirrored_exc = Instance::CheckedHandle( | |
1355 DartLibraryCalls::ExceptionCreate( | |
1356 Library::Handle(Library::MirrorsLibrary()), | |
1357 String::Handle(String::New("MirroredCompilationError")), | |
1358 Symbols::Dot(), // The unnamed constructor. | |
1359 args)); | |
1360 | |
1361 const Instance& stack = Instance::Handle(); | |
1362 return UnhandledException::New(mirrored_exc, stack); | |
siva
2013/07/11 23:50:59
Here you would call
Exceptions::ThrowByType(kMirro
| |
1363 } else { | |
1364 UNREACHABLE(); | |
1365 return Error::null(); | |
1366 } | |
1367 } | |
1368 | |
1369 | |
1370 static RawObject* ResolveConstructor(const char* current_func, | |
1371 const Class& cls, | |
1372 const String& class_name, | |
1373 const String& constr_name, | |
1374 int num_args) { | |
1375 // The constructor must be present in the interface. | |
1376 const Function& constructor = | |
1377 Function::Handle(cls.LookupFunctionAllowPrivate(constr_name)); | |
1378 if (constructor.IsNull() || | |
1379 (!constructor.IsConstructor() && !constructor.IsFactory())) { | |
1380 const String& lookup_class_name = String::Handle(cls.Name()); | |
1381 if (!class_name.Equals(lookup_class_name)) { | |
1382 // When the class name used to build the constructor name is | |
1383 // different than the name of the class in which we are doing | |
1384 // the lookup, it can be confusing to the user to figure out | |
1385 // what's going on. Be a little more explicit for these error | |
1386 // messages. | |
1387 const String& message = String::Handle( | |
1388 String::NewFormatted( | |
1389 "%s: could not find factory '%s' in class '%s'.", | |
1390 current_func, | |
1391 constr_name.ToCString(), | |
1392 lookup_class_name.ToCString())); | |
1393 return ApiError::New(message); | |
1394 } else { | |
1395 const String& message = String::Handle( | |
1396 String::NewFormatted("%s: could not find constructor '%s'.", | |
1397 current_func, constr_name.ToCString())); | |
1398 return ApiError::New(message); | |
1399 } | |
1400 } | |
1401 int extra_args = (constructor.IsConstructor() ? 2 : 1); | |
1402 String& error_message = String::Handle(); | |
1403 if (!constructor.AreValidArgumentCounts(num_args + extra_args, | |
1404 0, | |
1405 &error_message)) { | |
1406 const String& message = String::Handle( | |
1407 String::NewFormatted("%s: wrong argument count for " | |
1408 "constructor '%s': %s.", | |
1409 current_func, | |
1410 constr_name.ToCString(), | |
1411 error_message.ToCString())); | |
1412 return ApiError::New(message); | |
1413 } | |
1414 return constructor.raw(); | |
1415 } | |
1416 | |
1417 | |
1418 static bool FieldIsUninitialized(const Field& field) { | |
1419 ASSERT(!field.IsNull()); | |
1420 | |
1421 // Return getter method for uninitialized fields, rather than the | |
1422 // field object, since the value in the field object will not be | |
1423 // initialized until the first time the getter is invoked. | |
1424 const Instance& value = Instance::Handle(field.value()); | |
1425 ASSERT(value.raw() != Object::transition_sentinel().raw()); | |
1426 return value.raw() == Object::sentinel().raw(); | |
1427 } | |
1428 | |
1429 | |
1423 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { | 1430 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { |
1424 const MirrorReference& klass_ref = | 1431 const MirrorReference& klass_ref = |
1425 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | 1432 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); |
1426 Class& klass = Class::Handle(); | 1433 Class& klass = Class::Handle(); |
1427 klass ^= klass_ref.referent(); | 1434 klass ^= klass_ref.referent(); |
1428 return klass.Name(); | 1435 return klass.Name(); |
1429 } | 1436 } |
1430 | 1437 |
1438 | |
1439 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 4) { | |
siva
2013/07/11 23:50:59
Argument 0 is not used at all in these methods, sh
rmacnak
2013/07/12 00:04:09
Argument 0 is the mirror. These natives are polymo
| |
1440 const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(1)); | |
1441 | |
1442 const String& function_name = | |
1443 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1444 | |
1445 const Array& positional_args = | |
1446 Array::CheckedHandle(arguments->NativeArgAt(3)); | |
1447 intptr_t number_of_arguments = positional_args.Length(); | |
1448 | |
1449 | |
1450 intptr_t num_receiver = 1; // 1 for instance methods | |
1451 const Array& args = | |
1452 Array::Handle(Array::New(number_of_arguments + num_receiver)); | |
1453 Object& arg = Object::Handle(); | |
1454 for (int i = 0; i < number_of_arguments; i++) { | |
1455 arg = positional_args.At(i); | |
1456 args.SetAt((i + num_receiver), arg); | |
1457 } | |
1458 args.SetAt(0, receiver); | |
1459 | |
1460 // TODO(11771): This won't find private members. | |
1461 const Function& function = Function::Handle( | |
1462 Resolver::ResolveDynamic(receiver, | |
1463 function_name, | |
1464 (number_of_arguments + 1), | |
1465 Resolver::kIsQualified)); | |
1466 | |
1467 Object& result = Object::Handle(); | |
siva
2013/07/11 23:50:59
Can you share the 'arg' handle above and the 'resu
| |
1468 | |
1469 if (function.IsNull()) { | |
1470 const Array& args_descriptor = | |
1471 Array::Handle(ArgumentsDescriptor::New(args.Length())); | |
1472 result = DartEntry::InvokeNoSuchMethod(receiver, | |
1473 function_name, | |
1474 args, | |
1475 args_descriptor); | |
1476 } else { | |
1477 result = DartEntry::InvokeFunction(function, args); | |
1478 } | |
1479 | |
1480 if (result.IsError()) { | |
1481 Error& mirrored_error = | |
1482 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1483 Exceptions::PropagateError(mirrored_error); | |
1484 UNREACHABLE(); | |
siva
2013/07/11 23:50:59
ThrowMirroredError(Error::Cast(result));
| |
1485 } | |
1486 return result.raw(); | |
1487 } | |
1488 | |
1489 | |
1490 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) { | |
1491 const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(1)); | |
1492 | |
1493 const String& getter_name = | |
1494 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1495 | |
1496 // Every instance field has a getter Function. Try to find the | |
1497 // getter in any superclass and use that function to access the | |
1498 // field. | |
1499 // NB: We do not use Resolver::ResolveDynamic because we want to find private | |
1500 // members. | |
1501 Class& klass = Class::Handle(receiver.clazz()); | |
1502 String& internal_getter_name = String::Handle(Field::GetterName(getter_name)); | |
1503 Function& getter = Function::Handle(); | |
1504 while (!klass.IsNull()) { | |
1505 getter = klass.LookupDynamicFunctionAllowPrivate(internal_getter_name); | |
1506 if (!getter.IsNull()) { | |
1507 break; | |
1508 } | |
1509 klass = klass.SuperClass(); | |
1510 } | |
1511 | |
1512 Object& result = Object::Handle(); | |
1513 | |
1514 // Invoke the getter or DNU and return the result. | |
1515 const int kNumArgs = 1; | |
1516 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
1517 args.SetAt(0, receiver); | |
1518 | |
1519 if (getter.IsNull()) { | |
1520 const Array& args_descriptor = | |
1521 Array::Handle(ArgumentsDescriptor::New(args.Length())); | |
1522 result = DartEntry::InvokeNoSuchMethod(receiver, | |
1523 internal_getter_name, | |
1524 args, | |
1525 args_descriptor); | |
1526 } else { | |
1527 result = DartEntry::InvokeFunction(getter, args); | |
1528 } | |
1529 | |
1530 if (result.IsError()) { | |
1531 Error& mirrored_error = | |
1532 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1533 Exceptions::PropagateError(mirrored_error); | |
1534 UNREACHABLE(); | |
1535 } | |
1536 return result.raw(); | |
1537 } | |
1538 | |
1539 | |
1540 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { | |
1541 const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(1)); | |
1542 | |
1543 const String& setter_name = | |
1544 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1545 | |
1546 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3)); | |
1547 | |
1548 String& internal_setter_name = | |
1549 String::Handle(Field::SetterName(setter_name)); | |
1550 Function& setter = Function::Handle(); | |
1551 | |
1552 if (receiver.IsNull()) { | |
1553 // null's class doesn't handle lookups gracefully, fall through to the DNU | |
1554 // case. | |
1555 } else { | |
1556 Class& klass = Class::Handle(receiver.clazz()); | |
1557 Field& field = Field::Handle(); | |
1558 | |
1559 while (!klass.IsNull()) { | |
1560 field = klass.LookupInstanceField(setter_name); | |
1561 if (!field.IsNull() && field.is_final()) { | |
1562 const String& message = String::Handle( | |
1563 String::NewFormatted("%s: cannot set final field '%s'.", | |
1564 "InstanceMirror_invokeSetter", | |
1565 setter_name.ToCString())); | |
1566 Error& error = Error::Handle(ApiError::New(message)); | |
1567 error = CreateMirroredError(error); | |
1568 Exceptions::PropagateError(error); | |
1569 UNREACHABLE(); | |
siva
2013/07/11 23:50:59
Instead of this elaborate scheme of first creating
| |
1570 } | |
1571 setter = klass.LookupDynamicFunctionAllowPrivate(internal_setter_name); | |
1572 if (!setter.IsNull()) { | |
1573 break; | |
1574 } | |
1575 klass = klass.SuperClass(); | |
1576 } | |
1577 } | |
1578 | |
1579 Object& result = Object::Handle(); | |
1580 | |
1581 // Invoke the setter and return the result. | |
1582 const int kNumArgs = 2; | |
1583 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
1584 args.SetAt(0, receiver); | |
1585 args.SetAt(1, value); | |
1586 if (setter.IsNull()) { | |
1587 const Array& args_descriptor = | |
1588 Array::Handle(ArgumentsDescriptor::New(args.Length())); | |
1589 result = DartEntry::InvokeNoSuchMethod(receiver, | |
1590 internal_setter_name, | |
1591 args, | |
1592 args_descriptor); | |
1593 } else { | |
1594 result = DartEntry::InvokeFunction(setter, args); | |
1595 } | |
1596 | |
1597 if (result.IsError()) { | |
1598 Error& mirrored_error = | |
1599 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1600 Exceptions::PropagateError(mirrored_error); | |
1601 UNREACHABLE(); | |
1602 } | |
1603 return result.raw(); | |
1604 } | |
1605 | |
1606 | |
1607 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) { | |
siva
2013/07/11 23:50:59
Argument 0 is not used at all here, maybe this sho
| |
1608 const MirrorReference& klass_ref = | |
1609 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
1610 Class& klass = Class::Handle(); | |
1611 klass ^= klass_ref.referent(); | |
1612 | |
1613 const String& function_name = | |
1614 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1615 | |
1616 const Array& positional_args = | |
1617 Array::CheckedHandle(arguments->NativeArgAt(3)); | |
1618 intptr_t number_of_arguments = positional_args.Length(); | |
1619 | |
1620 // TODO(11771): This won't find private members. | |
1621 const Function& function = Function::Handle( | |
1622 Resolver::ResolveStatic(klass, | |
1623 function_name, | |
1624 number_of_arguments, | |
1625 Object::empty_array(), | |
1626 Resolver::kIsQualified)); | |
1627 if (function.IsNull()) { | |
1628 const String& klass_name = String::Handle(klass.Name()); | |
1629 const String& message = String::Handle( | |
1630 String::NewFormatted("%s: did not find %d-arg static method '%s.%s'.", | |
1631 "ClassMirror_invoke", | |
1632 number_of_arguments, | |
1633 klass_name.ToCString(), | |
1634 function_name.ToCString())); | |
1635 Error& error = Error::Handle(ApiError::New(message)); | |
1636 error = CreateMirroredError(error); | |
1637 Exceptions::PropagateError(error); | |
siva
2013/07/11 23:50:59
Instead of this elaborate scheme of first creating
| |
1638 UNREACHABLE(); | |
1639 } | |
1640 Object& result = Object::Handle(DartEntry::InvokeFunction(function, | |
1641 positional_args)); | |
1642 if (result.IsError()) { | |
1643 Error& mirrored_error = | |
1644 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1645 Exceptions::PropagateError(mirrored_error); | |
1646 UNREACHABLE(); | |
1647 } | |
1648 return result.raw(); | |
1649 } | |
1650 | |
1651 | |
1652 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { | |
1653 const MirrorReference& klass_ref = | |
1654 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
1655 Class& klass = Class::Handle(); | |
1656 klass ^= klass_ref.referent(); | |
1657 | |
1658 const String& getter_name = | |
1659 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1660 | |
1661 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); | |
1662 if (field.IsNull() || FieldIsUninitialized(field)) { | |
1663 const String& internal_getter_name = String::Handle( | |
1664 Field::GetterName(getter_name)); | |
1665 const Function& getter = Function::Handle( | |
1666 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); | |
1667 | |
1668 if (getter.IsNull()) { | |
1669 const String& message = String::Handle( | |
1670 String::NewFormatted("%s: did not find static getter '%s'.", | |
1671 "ClassMirror_invokeGetter", | |
1672 getter_name.ToCString())); | |
1673 Error& error = Error::Handle(ApiError::New(message)); | |
1674 error = CreateMirroredError(error); | |
1675 Exceptions::PropagateError(error); | |
1676 UNREACHABLE(); | |
1677 } | |
1678 | |
1679 // Invoke the getter and return the result. | |
1680 Object& result = Object::Handle( | |
1681 DartEntry::InvokeFunction(getter, Object::empty_array())); | |
1682 if (result.IsError()) { | |
1683 Error& mirrored_error = | |
1684 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1685 Exceptions::PropagateError(mirrored_error); | |
1686 UNREACHABLE(); | |
1687 } | |
1688 return result.raw(); | |
1689 } | |
1690 return field.value(); | |
1691 } | |
1692 | |
1693 | |
1694 DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) { | |
1695 const MirrorReference& klass_ref = | |
1696 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
1697 Class& klass = Class::Handle(); | |
1698 klass ^= klass_ref.referent(); | |
1699 | |
1700 const String& setter_name = | |
1701 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1702 | |
1703 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3)); | |
1704 | |
1705 // Check for real fields and user-defined setters | |
1706 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | |
1707 if (field.IsNull()) { | |
1708 const String& internal_setter_name = String::Handle( | |
1709 Field::SetterName(setter_name)); | |
1710 const Function& setter = Function::Handle( | |
1711 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); | |
1712 | |
1713 if (setter.IsNull()) { | |
1714 const String& message = String::Handle( | |
1715 String::NewFormatted("%s: did not find static setter '%s'.", | |
1716 "ClassMirror_invokeSetter", | |
1717 setter_name.ToCString())); | |
1718 Error& error = Error::Handle(ApiError::New(message)); | |
1719 error = CreateMirroredError(error); | |
1720 Exceptions::PropagateError(error); | |
1721 UNREACHABLE(); | |
1722 } | |
1723 | |
1724 // Invoke the getter and return the result. | |
1725 const int kNumArgs = 1; | |
1726 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
1727 args.SetAt(0, value); | |
1728 | |
1729 Object& result = Object::Handle( | |
1730 DartEntry::InvokeFunction(setter, args)); | |
1731 if (result.IsError()) { | |
1732 Error& mirrored_error = | |
1733 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1734 Exceptions::PropagateError(mirrored_error); | |
1735 UNREACHABLE(); | |
1736 } | |
1737 return result.raw(); | |
1738 } | |
1739 | |
1740 if (field.is_final()) { | |
1741 const String& message = String::Handle( | |
1742 String::NewFormatted("%s: cannot set final field '%s'.", | |
1743 "ClassMirror_invokeSetter", | |
1744 setter_name.ToCString())); | |
1745 Error& error = Error::Handle(ApiError::New(message)); | |
1746 error = CreateMirroredError(error); | |
1747 Exceptions::PropagateError(error); | |
1748 UNREACHABLE(); | |
1749 } | |
1750 | |
1751 field.set_value(value); | |
1752 return value.raw(); | |
1753 } | |
1754 | |
1755 | |
1756 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 3) { | |
1757 const MirrorReference& klass_ref = | |
1758 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | |
1759 Class& klass = Class::Handle(); | |
1760 klass ^= klass_ref.referent(); | |
1761 | |
1762 const String& constructor_name = | |
1763 String::CheckedHandle(arguments->NativeArgAt(1)); | |
1764 | |
1765 const Array& positional_args = | |
1766 Array::CheckedHandle(arguments->NativeArgAt(2)); | |
1767 | |
1768 intptr_t number_of_arguments = positional_args.Length(); | |
1769 | |
1770 // By convention, the static function implementing a named constructor 'C' | |
1771 // for class 'A' is labeled 'A.C', and the static function implementing the | |
1772 // unnamed constructor for class 'A' is labeled 'A.'. | |
1773 // This convention prevents users from explicitly calling constructors. | |
1774 String& klass_name = String::Handle(klass.Name()); | |
1775 String& internal_constructor_name = | |
1776 String::Handle(String::Concat(klass_name, Symbols::Dot())); | |
1777 internal_constructor_name = | |
1778 String::Concat(internal_constructor_name, constructor_name); | |
1779 | |
1780 Object& constructor = Object::Handle(); | |
1781 constructor = ResolveConstructor("ClassMirror_invokeConstructor", | |
1782 klass, | |
1783 klass_name, | |
1784 internal_constructor_name, | |
1785 number_of_arguments); | |
1786 if (constructor.IsError()) { | |
1787 Exceptions::PropagateError(Error::Cast(constructor)); | |
1788 UNREACHABLE(); | |
1789 } | |
1790 ASSERT(constructor.IsFunction()); | |
1791 | |
1792 Object& result = | |
1793 Object::Handle(DartEntry::InvokeConstructor(klass, | |
1794 Function::Cast(constructor), | |
1795 positional_args)); | |
1796 if (result.IsError()) { | |
1797 Error& mirrored_error = | |
1798 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1799 Exceptions::PropagateError(mirrored_error); | |
1800 UNREACHABLE(); | |
1801 } | |
1802 // Factories may return null. | |
1803 ASSERT(result.IsInstance() || result.IsNull()); | |
1804 return result.raw(); | |
1805 } | |
1806 | |
1807 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) { | |
1808 const MirrorReference& library_ref = | |
1809 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
1810 Library& library = Library::Handle(); | |
1811 library ^= library_ref.referent(); | |
1812 | |
1813 const String& function_name = | |
1814 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1815 | |
1816 const Array& positional_args = | |
1817 Array::CheckedHandle(arguments->NativeArgAt(3)); | |
1818 intptr_t number_of_arguments = positional_args.Length(); | |
1819 | |
1820 | |
1821 Function& function = Function::Handle(); | |
1822 function = library.LookupFunctionAllowPrivate(function_name); | |
1823 | |
1824 if (function.IsNull()) { | |
1825 const String& message = String::Handle( | |
1826 String::NewFormatted("%s: did not find top-level function '%s'.", | |
1827 "LibraryMirror_invoke", | |
1828 function_name.ToCString())); | |
1829 Error& error = Error::Handle(ApiError::New(message)); | |
1830 error = CreateMirroredError(error); | |
1831 Exceptions::PropagateError(error); | |
1832 UNREACHABLE(); | |
1833 } | |
1834 | |
1835 // LookupFunctionAllowPrivate does not check argument arity, so we | |
1836 // do it here. | |
1837 String& error_message = String::Handle(); | |
1838 if (!function.AreValidArgumentCounts(number_of_arguments, | |
1839 /* num_named_args */ 0, | |
1840 &error_message)) { | |
1841 const String& message = String::Handle( | |
1842 String::NewFormatted("%s: wrong argument count for function '%s': %s.", | |
1843 "LibraryMirror_invoke", | |
1844 function_name.ToCString(), | |
1845 error_message.ToCString())); | |
1846 Error& error = Error::Handle(ApiError::New(message)); | |
1847 error = CreateMirroredError(error); | |
1848 Exceptions::PropagateError(error); | |
1849 UNREACHABLE(); | |
1850 } | |
1851 | |
1852 Object& result = Object::Handle(DartEntry::InvokeFunction(function, | |
1853 positional_args)); | |
1854 if (result.IsError()) { | |
1855 Error& mirrored_error = | |
1856 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1857 Exceptions::PropagateError(mirrored_error); | |
1858 UNREACHABLE(); | |
1859 } | |
1860 return result.raw(); | |
1861 } | |
1862 | |
1863 | |
1864 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) { | |
1865 const MirrorReference& library_ref = | |
1866 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
1867 Library& library = Library::Handle(); | |
1868 library ^= library_ref.referent(); | |
1869 | |
1870 const String& getter_name = | |
1871 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1872 | |
1873 // To access a top-level we may need to use the Field or the | |
1874 // getter Function. The getter function may either be in the | |
1875 // library or in the field's owner class, depending. | |
1876 Field& field = Field::Handle(library.LookupFieldAllowPrivate(getter_name)); | |
1877 Function& getter = Function::Handle(); | |
1878 if (field.IsNull()) { | |
1879 // No field found. Check for a getter in the lib. | |
1880 const String& internal_getter_name = | |
1881 String::Handle(Field::GetterName(getter_name)); | |
1882 getter = library.LookupFunctionAllowPrivate(internal_getter_name); | |
1883 } else if (FieldIsUninitialized(field)) { | |
1884 // A field was found. Check for a getter in the field's owner classs. | |
1885 const Class& klass = Class::Handle(field.owner()); | |
1886 const String& internal_getter_name = | |
1887 String::Handle(Field::GetterName(getter_name)); | |
1888 getter = klass.LookupStaticFunctionAllowPrivate(internal_getter_name); | |
1889 } | |
1890 | |
1891 if (!getter.IsNull()) { | |
1892 // Invoke the getter and return the result. | |
1893 Object& result = Object::Handle( | |
1894 DartEntry::InvokeFunction(getter, Object::empty_array())); | |
1895 if (result.IsError()) { | |
1896 Error& mirrored_error = | |
1897 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1898 Exceptions::PropagateError(mirrored_error); | |
1899 UNREACHABLE(); | |
1900 } | |
1901 return result.raw(); | |
1902 } else if (!field.IsNull()) { | |
1903 return field.value(); | |
1904 } else { | |
1905 const String& message = String::Handle( | |
1906 String::NewFormatted("%s: did not find top-level variable '%s'.", | |
1907 "LibraryMirror_invokeGetter", | |
1908 getter_name.ToCString())); | |
1909 Error& error = Error::Handle(ApiError::New(message)); | |
1910 error = CreateMirroredError(error); | |
1911 Exceptions::PropagateError(error); | |
1912 UNREACHABLE(); | |
1913 return Instance::null(); | |
1914 } | |
1915 } | |
1916 | |
1917 | |
1918 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { | |
1919 const MirrorReference& library_ref = | |
1920 MirrorReference::CheckedHandle(arguments->NativeArgAt(1)); | |
1921 Library& library = Library::Handle(); | |
1922 library ^= library_ref.referent(); | |
1923 | |
1924 const String& setter_name = | |
1925 String::CheckedHandle(arguments->NativeArgAt(2)); | |
1926 | |
1927 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(3)); | |
1928 | |
1929 // To access a top-level we may need to use the Field or the | |
1930 // setter Function. The setter function may either be in the | |
1931 // library or in the field's owner class, depending. | |
1932 Field& field = Field::Handle(library.LookupFieldAllowPrivate(setter_name)); | |
1933 | |
1934 if (field.IsNull()) { | |
1935 const String& internal_setter_name = | |
1936 String::Handle(Field::SetterName(setter_name)); | |
1937 const Function& setter = Function::Handle( | |
1938 library.LookupFunctionAllowPrivate(internal_setter_name)); | |
1939 | |
1940 if (setter.IsNull()) { | |
1941 const String& message = String::Handle( | |
1942 String::NewFormatted("%s: did not find top-level variable '%s'.", | |
1943 "LibraryMirror_invokeSetter", | |
1944 setter_name.ToCString())); | |
1945 Error& error = Error::Handle(ApiError::New(message)); | |
1946 error = CreateMirroredError(error); | |
1947 Exceptions::PropagateError(error); | |
1948 UNREACHABLE(); | |
1949 } | |
1950 | |
1951 // Invoke the setter and return the result. | |
1952 const int kNumArgs = 1; | |
1953 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
1954 args.SetAt(0, value); | |
1955 Object& result = Object::Handle( | |
1956 DartEntry::InvokeFunction(setter, args)); | |
1957 if (result.IsError()) { | |
1958 Error& mirrored_error = | |
1959 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
1960 Exceptions::PropagateError(mirrored_error); | |
1961 UNREACHABLE(); | |
1962 } | |
1963 return result.raw(); | |
1964 } | |
1965 | |
1966 if (field.is_final()) { | |
1967 const String& message = String::Handle( | |
1968 String::NewFormatted("%s: cannot set final top-level variable '%s'.", | |
1969 "LibraryMirror_invokeSetter", | |
1970 setter_name.ToCString())); | |
1971 Error& error = Error::Handle(ApiError::New(message)); | |
1972 error = CreateMirroredError(error); | |
1973 Exceptions::PropagateError(error); | |
1974 UNREACHABLE(); | |
1975 } | |
1976 | |
1977 field.set_value(value); | |
1978 return value.raw(); | |
1979 } | |
1980 | |
1981 | |
1431 DEFINE_NATIVE_ENTRY(MethodMirror_name, 1) { | 1982 DEFINE_NATIVE_ENTRY(MethodMirror_name, 1) { |
1432 const MirrorReference& func_ref = | 1983 const MirrorReference& func_ref = |
1433 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | 1984 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); |
1434 Function& func = Function::Handle(); | 1985 Function& func = Function::Handle(); |
1435 func ^= func_ref.referent(); | 1986 func ^= func_ref.referent(); |
1436 return func.UserVisibleName(); | 1987 return func.UserVisibleName(); |
1437 } | 1988 } |
1438 | 1989 |
1439 } // namespace dart | 1990 } // namespace dart |
OLD | NEW |