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

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

Issue 18463003: Implement the invoke methods (invoke, getField, setField, newInstance, apply) as internal natives. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/lib/mirrors_impl.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "include/dart_api.h" 5 #include "include/dart_api.h"
6 #include "include/dart_debugger_api.h" 6 #include "include/dart_debugger_api.h"
7 #include "include/dart_mirrors_api.h" 7 #include "include/dart_mirrors_api.h"
8 #include "vm/dart_api_impl.h" 8 #include "vm/dart_api_impl.h"
9 #include "vm/dart_api_state.h" // TODO(11742): Remove with CreateMirrorRef. 9 #include "vm/dart_api_state.h" // TODO(11742): Remove with CreateMirrorRef.
10 #include "vm/bootstrap_natives.h" 10 #include "vm/bootstrap_natives.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/exceptions.h" 12 #include "vm/exceptions.h"
13 #include "vm/message.h" 13 #include "vm/message.h"
14 #include "vm/port.h" 14 #include "vm/port.h"
15 #include "vm/resolver.h" 15 #include "vm/resolver.h"
16 #include "vm/symbols.h"
16 17
17 namespace dart { 18 namespace dart {
18 19
19 inline Dart_Handle NewString(const char* str) { 20 inline Dart_Handle NewString(const char* str) {
20 return Dart_NewStringFromCString(str); 21 return Dart_NewStringFromCString(str);
21 } 22 }
22 23
23 24
24 DEFINE_NATIVE_ENTRY(Mirrors_isLocalPort, 1) { 25 DEFINE_NATIVE_ENTRY(Mirrors_isLocalPort, 1) {
25 GET_NON_NULL_NATIVE_ARGUMENT(Instance, port, arguments->NativeArgAt(0)); 26 GET_NON_NULL_NATIVE_ARGUMENT(Instance, port, arguments->NativeArgAt(0));
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/lib/mirrors_impl.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698