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 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1116 Dart_Handle args[] = { | 1117 Dart_Handle args[] = { |
| 1117 CreateVMReference(instance), | 1118 CreateVMReference(instance), |
| 1118 CreateLazyMirror(instance_cls), | 1119 CreateLazyMirror(instance_cls), |
| 1119 instance, | 1120 instance, |
| 1120 }; | 1121 }; |
| 1121 return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); | 1122 return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); |
| 1122 } | 1123 } |
| 1123 } | 1124 } |
| 1124 | 1125 |
| 1125 | 1126 |
| 1126 static Dart_Handle CreateMirroredError(Dart_Handle error) { | 1127 static Dart_Handle CreateHandledMirroredError(Dart_Handle error) { |
| 1127 ASSERT(Dart_IsError(error)); | 1128 ASSERT(Dart_IsError(error)); |
| 1128 if (Dart_IsUnhandledExceptionError(error)) { | 1129 if (Dart_IsUnhandledExceptionError(error)) { |
| 1129 Dart_Handle exc = Dart_ErrorGetException(error); | 1130 Dart_Handle exc = Dart_ErrorGetException(error); |
| 1130 if (Dart_IsError(exc)) { | 1131 if (Dart_IsError(exc)) { |
| 1131 return exc; | 1132 return exc; |
| 1132 } | 1133 } |
| 1133 Dart_Handle exc_string = Dart_ToString(exc); | 1134 Dart_Handle exc_string = Dart_ToString(exc); |
| 1134 if (Dart_IsError(exc_string)) { | 1135 if (Dart_IsError(exc_string)) { |
| 1135 // Only propagate fatal errors from exc.toString(). Ignore the rest. | 1136 // Only propagate fatal errors from exc.toString(). Ignore the rest. |
| 1136 if (Dart_IsFatalError(exc_string)) { | 1137 if (Dart_IsFatalError(exc_string)) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1264 if (Dart_IsError(result)) { | 1265 if (Dart_IsError(result)) { |
| 1265 Dart_PropagateError(result); | 1266 Dart_PropagateError(result); |
| 1266 } | 1267 } |
| 1267 result = Dart_Invoke(reflectee, | 1268 result = Dart_Invoke(reflectee, |
| 1268 member_name, | 1269 member_name, |
| 1269 invoke_args.length(), | 1270 invoke_args.length(), |
| 1270 invoke_args.data()); | 1271 invoke_args.data()); |
| 1271 if (Dart_IsError(result)) { | 1272 if (Dart_IsError(result)) { |
| 1272 // Instead of propagating the error from an invoke directly, we | 1273 // Instead of propagating the error from an invoke directly, we |
| 1273 // provide reflective access to the error. | 1274 // provide reflective access to the error. |
| 1274 Dart_PropagateError(CreateMirroredError(result)); | 1275 Dart_PropagateError(CreateHandledMirroredError(result)); |
| 1275 } | 1276 } |
| 1276 | 1277 |
| 1277 Dart_Handle wrapped_result = CreateInstanceMirror(result); | 1278 Dart_Handle wrapped_result = CreateInstanceMirror(result); |
| 1278 if (Dart_IsError(wrapped_result)) { | 1279 if (Dart_IsError(wrapped_result)) { |
| 1279 Dart_PropagateError(wrapped_result); | 1280 Dart_PropagateError(wrapped_result); |
| 1280 } | 1281 } |
| 1281 Dart_SetReturnValue(args, wrapped_result); | 1282 Dart_SetReturnValue(args, wrapped_result); |
| 1282 Dart_ExitScope(); | 1283 Dart_ExitScope(); |
| 1283 } | 1284 } |
| 1284 | 1285 |
| 1285 | 1286 |
| 1286 void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_getField)( | 1287 void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_getField)( |
| 1287 Dart_NativeArguments args) { | 1288 Dart_NativeArguments args) { |
| 1288 Dart_EnterScope(); | 1289 Dart_EnterScope(); |
| 1289 Dart_Handle mirror = Dart_GetNativeArgument(args, 0); | 1290 Dart_Handle mirror = Dart_GetNativeArgument(args, 0); |
| 1290 Dart_Handle fieldName = Dart_GetNativeArgument(args, 1); | 1291 Dart_Handle fieldName = Dart_GetNativeArgument(args, 1); |
| 1291 | 1292 |
| 1292 Dart_Handle reflectee = UnwrapMirror(mirror); | 1293 Dart_Handle reflectee = UnwrapMirror(mirror); |
| 1293 Dart_Handle result = Dart_GetField(reflectee, fieldName); | 1294 Dart_Handle result = Dart_GetField(reflectee, fieldName); |
| 1294 if (Dart_IsError(result)) { | 1295 if (Dart_IsError(result)) { |
| 1295 // Instead of propagating the error from a GetField directly, we | 1296 // Instead of propagating the error from a GetField directly, we |
| 1296 // provide reflective access to the error. | 1297 // provide reflective access to the error. |
| 1297 Dart_PropagateError(CreateMirroredError(result)); | 1298 Dart_PropagateError(CreateHandledMirroredError(result)); |
| 1298 } | 1299 } |
| 1299 | 1300 |
| 1300 Dart_Handle wrapped_result = CreateInstanceMirror(result); | 1301 Dart_Handle wrapped_result = CreateInstanceMirror(result); |
| 1301 if (Dart_IsError(wrapped_result)) { | 1302 if (Dart_IsError(wrapped_result)) { |
| 1302 Dart_PropagateError(wrapped_result); | 1303 Dart_PropagateError(wrapped_result); |
| 1303 } | 1304 } |
| 1304 Dart_SetReturnValue(args, wrapped_result); | 1305 Dart_SetReturnValue(args, wrapped_result); |
| 1305 Dart_ExitScope(); | 1306 Dart_ExitScope(); |
| 1306 } | 1307 } |
| 1307 | 1308 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1321 } else { | 1322 } else { |
| 1322 set_arg = value; | 1323 set_arg = value; |
| 1323 } | 1324 } |
| 1324 if (Dart_IsError(set_arg)) { | 1325 if (Dart_IsError(set_arg)) { |
| 1325 Dart_PropagateError(set_arg); | 1326 Dart_PropagateError(set_arg); |
| 1326 } | 1327 } |
| 1327 Dart_Handle result = Dart_SetField(reflectee, fieldName, set_arg); | 1328 Dart_Handle result = Dart_SetField(reflectee, fieldName, set_arg); |
| 1328 if (Dart_IsError(result)) { | 1329 if (Dart_IsError(result)) { |
| 1329 // Instead of propagating the error from a SetField directly, we | 1330 // Instead of propagating the error from a SetField directly, we |
| 1330 // provide reflective access to the error. | 1331 // provide reflective access to the error. |
| 1331 Dart_PropagateError(CreateMirroredError(result)); | 1332 Dart_PropagateError(CreateHandledMirroredError(result)); |
| 1332 } | 1333 } |
| 1333 | 1334 |
| 1334 Dart_Handle wrapped_result = CreateInstanceMirror(result); | 1335 Dart_Handle wrapped_result = CreateInstanceMirror(result); |
| 1335 if (Dart_IsError(wrapped_result)) { | 1336 if (Dart_IsError(wrapped_result)) { |
| 1336 Dart_PropagateError(wrapped_result); | 1337 Dart_PropagateError(wrapped_result); |
| 1337 } | 1338 } |
| 1338 Dart_SetReturnValue(args, wrapped_result); | 1339 Dart_SetReturnValue(args, wrapped_result); |
| 1339 Dart_ExitScope(); | 1340 Dart_ExitScope(); |
| 1340 } | 1341 } |
| 1341 | 1342 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1357 result = UnpackLocalArgList(positional_arguments, &invoke_args); | 1358 result = UnpackLocalArgList(positional_arguments, &invoke_args); |
| 1358 } | 1359 } |
| 1359 if (Dart_IsError(result)) { | 1360 if (Dart_IsError(result)) { |
| 1360 Dart_PropagateError(result); | 1361 Dart_PropagateError(result); |
| 1361 } | 1362 } |
| 1362 result = | 1363 result = |
| 1363 Dart_InvokeClosure(reflectee, invoke_args.length(), invoke_args.data()); | 1364 Dart_InvokeClosure(reflectee, invoke_args.length(), invoke_args.data()); |
| 1364 if (Dart_IsError(result)) { | 1365 if (Dart_IsError(result)) { |
| 1365 // Instead of propagating the error from an apply directly, we | 1366 // Instead of propagating the error from an apply directly, we |
| 1366 // provide reflective access to the error. | 1367 // provide reflective access to the error. |
| 1367 Dart_PropagateError(CreateMirroredError(result)); | 1368 Dart_PropagateError(CreateHandledMirroredError(result)); |
| 1368 } | 1369 } |
| 1369 | 1370 |
| 1370 Dart_Handle wrapped_result = CreateInstanceMirror(result); | 1371 Dart_Handle wrapped_result = CreateInstanceMirror(result); |
| 1371 if (Dart_IsError(wrapped_result)) { | 1372 if (Dart_IsError(wrapped_result)) { |
| 1372 Dart_PropagateError(wrapped_result); | 1373 Dart_PropagateError(wrapped_result); |
| 1373 } | 1374 } |
| 1374 Dart_SetReturnValue(args, wrapped_result); | 1375 Dart_SetReturnValue(args, wrapped_result); |
| 1375 Dart_ExitScope(); | 1376 Dart_ExitScope(); |
| 1376 } | 1377 } |
| 1377 | 1378 |
| 1378 | 1379 |
| 1379 void NATIVE_ENTRY_FUNCTION(LocalClassMirrorImpl_invokeConstructor)( | |
| 1380 Dart_NativeArguments args) { | |
| 1381 Dart_EnterScope(); | |
| 1382 Dart_Handle klass_mirror = Dart_GetNativeArgument(args, 0); | |
| 1383 Dart_Handle constructor_name = Dart_GetNativeArgument(args, 1); | |
| 1384 // The arguments are either simple values or instance mirrors. | |
| 1385 Dart_Handle positional_arguments = Dart_GetNativeArgument(args, 2); | |
| 1386 Dart_Handle async = Dart_GetNativeArgument(args, 3); | |
| 1387 | |
| 1388 Dart_Handle klass = UnwrapMirror(klass_mirror); | |
| 1389 GrowableArray<Dart_Handle> invoke_args; | |
| 1390 Dart_Handle result; | |
| 1391 if (Dart_IdentityEquals(async, Dart_True())) { | |
| 1392 result = UnwrapArgList(positional_arguments, &invoke_args); | |
| 1393 } else { | |
| 1394 result = UnpackLocalArgList(positional_arguments, &invoke_args); | |
| 1395 } | |
| 1396 if (Dart_IsError(result)) { | |
| 1397 Dart_PropagateError(result); | |
| 1398 } | |
| 1399 result = Dart_New(klass, | |
| 1400 constructor_name, | |
| 1401 invoke_args.length(), | |
| 1402 invoke_args.data()); | |
| 1403 if (Dart_IsError(result)) { | |
| 1404 // Instead of propagating the error from an invoke directly, we | |
| 1405 // provide reflective access to the error. | |
| 1406 Dart_PropagateError(CreateMirroredError(result)); | |
| 1407 } | |
| 1408 | |
| 1409 Dart_Handle wrapped_result = CreateInstanceMirror(result); | |
| 1410 if (Dart_IsError(wrapped_result)) { | |
| 1411 Dart_PropagateError(wrapped_result); | |
| 1412 } | |
| 1413 Dart_SetReturnValue(args, wrapped_result); | |
| 1414 Dart_ExitScope(); | |
| 1415 } | |
| 1416 | |
| 1417 | |
| 1418 void HandleMirrorsMessage(Isolate* isolate, | 1380 void HandleMirrorsMessage(Isolate* isolate, |
| 1419 Dart_Port reply_port, | 1381 Dart_Port reply_port, |
| 1420 const Instance& message) { | 1382 const Instance& message) { |
| 1421 UNIMPLEMENTED(); | 1383 UNIMPLEMENTED(); |
| 1422 } | 1384 } |
| 1423 | 1385 |
| 1424 | 1386 |
| 1387 // TODO(11742): This is transitional. | |
| 1388 static RawInstance* Reflect(const Instance& reflectee) { | |
| 1389 Isolate* isolate = Isolate::Current(); | |
| 1390 DARTSCOPE(isolate); | |
| 1391 return Instance::RawCast( | |
| 1392 Api::UnwrapHandle( | |
| 1393 CreateInstanceMirror( | |
| 1394 Api::NewHandle(isolate, reflectee.raw())))); | |
| 1395 } | |
|
siva
2013/07/11 22:53:37
This seems kind of hacky, I realize it is a tempor
rmacnak
2013/07/11 23:59:23
The intention is that there will be no plain VM co
| |
| 1396 | |
| 1397 | |
| 1398 // This is based on the embedding API, but direct use of the cid outside of | |
| 1399 // object.h/.c is questionable. | |
|
rmacnak
2013/07/09 21:04:54
Questionable
| |
| 1400 static bool IsApiError(const Object& object) { | |
| 1401 return object.GetClassId() == kApiErrorCid; | |
| 1402 } | |
| 1403 static bool IsCompilationError(const Object& object) { | |
| 1404 return object.GetClassId() == kLanguageErrorCid; | |
| 1405 } | |
|
siva
2013/07/11 22:53:37
We already have a bunch of IsXXXClassId(index) met
rmacnak
2013/07/11 23:59:23
Now I see that CompilationError is an alias for La
| |
| 1406 | |
| 1407 | |
| 1408 static RawError* CreateMirroredError(const Error& error) { | |
| 1409 if (error.IsUnhandledException()) { | |
| 1410 const UnhandledException& unhandled_ex = UnhandledException::Cast(error); | |
| 1411 Instance& exc = Instance::Handle(unhandled_ex.exception()); | |
| 1412 Instance& stack = Instance::Handle(unhandled_ex.stacktrace()); | |
| 1413 | |
| 1414 Object& exc_string_or_error = | |
| 1415 Object::Handle(DartLibraryCalls::ToString(exc)); | |
| 1416 Instance& exc_string = Instance::Handle(); | |
| 1417 if (exc_string_or_error.IsError()) { | |
| 1418 exc_string ^= Instance::null(); | |
| 1419 } else { | |
| 1420 exc_string ^= exc_string_or_error.raw(); | |
| 1421 } | |
| 1422 | |
| 1423 Instance& mirror_on_exc = Instance::Handle(Reflect(exc)); | |
| 1424 | |
| 1425 Array& args = Array::Handle(Array::New(3)); | |
| 1426 args.SetAt(0, mirror_on_exc); | |
| 1427 args.SetAt(1, exc_string); | |
| 1428 args.SetAt(2, stack); | |
| 1429 | |
| 1430 Instance& mirrored_exc = Instance::CheckedHandle( | |
| 1431 DartLibraryCalls::ExceptionCreate( | |
| 1432 Library::Handle(Library::MirrorsLibrary()), | |
| 1433 String::Handle(String::New("MirroredUncaughtExceptionError")), | |
|
siva
2013/07/11 22:53:37
You probably want to add MirroredUncaughtException
| |
| 1434 Symbols::Dot(), // The unnamed constructor. | |
| 1435 args)); | |
| 1436 | |
| 1437 return UnhandledException::New(mirrored_exc, stack); | |
| 1438 } else if (IsApiError(error) || | |
| 1439 IsCompilationError(error)) { | |
| 1440 String& message = String::Handle(); | |
| 1441 if (IsApiError(error)) { | |
| 1442 message ^= ApiError::Cast(error).message(); | |
| 1443 } else { | |
| 1444 message ^= LanguageError::Cast(error).message(); | |
| 1445 } | |
|
siva
2013/07/11 22:53:37
Once you have all VM code there would be no ApiErr
| |
| 1446 | |
| 1447 Array& args = Array::Handle(Array::New(1)); | |
| 1448 args.SetAt(0, message); | |
| 1449 | |
| 1450 Instance& mirrored_exc = Instance::CheckedHandle( | |
| 1451 DartLibraryCalls::ExceptionCreate( | |
| 1452 Library::Handle(Library::MirrorsLibrary()), | |
| 1453 String::Handle(String::New("MirroredCompilationError")), | |
|
siva
2013/07/11 22:53:37
Ditto comment about adding MirroredCompilationErro
| |
| 1454 Symbols::Dot(), // The unnamed constructor. | |
| 1455 args)); | |
| 1456 | |
| 1457 const Instance& stack = Instance::Handle(); | |
|
siva
2013/07/11 22:53:37
shadowing local variables like this is not a good
rmacnak
2013/07/11 23:59:23
It's not shadowing. They are in "sibling" scopes.
| |
| 1458 return UnhandledException::New(mirrored_exc, stack); | |
| 1459 } else { | |
| 1460 UNREACHABLE(); | |
| 1461 return Error::null(); | |
| 1462 } | |
| 1463 } | |
| 1464 | |
| 1465 | |
| 1466 static RawObject* ResolveConstructor(const char* current_func, | |
|
rmacnak
2013/07/09 21:04:54
This is the same as the embedding API's version. I
| |
| 1467 const Class& cls, | |
| 1468 const String& class_name, | |
| 1469 const String& constr_name, | |
| 1470 int num_args) { | |
| 1471 // The constructor must be present in the interface. | |
| 1472 const Function& constructor = | |
| 1473 Function::Handle(cls.LookupFunctionAllowPrivate(constr_name)); | |
| 1474 if (constructor.IsNull() || | |
| 1475 (!constructor.IsConstructor() && !constructor.IsFactory())) { | |
| 1476 const String& lookup_class_name = String::Handle(cls.Name()); | |
| 1477 if (!class_name.Equals(lookup_class_name)) { | |
| 1478 // When the class name used to build the constructor name is | |
| 1479 // different than the name of the class in which we are doing | |
| 1480 // the lookup, it can be confusing to the user to figure out | |
| 1481 // what's going on. Be a little more explicit for these error | |
| 1482 // messages. | |
| 1483 const String& message = String::Handle( | |
| 1484 String::NewFormatted( | |
| 1485 "%s: could not find factory '%s' in class '%s'.", | |
| 1486 current_func, | |
| 1487 constr_name.ToCString(), | |
| 1488 lookup_class_name.ToCString())); | |
| 1489 return ApiError::New(message); | |
| 1490 } else { | |
| 1491 const String& message = String::Handle( | |
| 1492 String::NewFormatted("%s: could not find constructor '%s'.", | |
| 1493 current_func, constr_name.ToCString())); | |
| 1494 return ApiError::New(message); | |
| 1495 } | |
| 1496 } | |
| 1497 int extra_args = (constructor.IsConstructor() ? 2 : 1); | |
| 1498 String& error_message = String::Handle(); | |
| 1499 if (!constructor.AreValidArgumentCounts(num_args + extra_args, | |
| 1500 0, | |
| 1501 &error_message)) { | |
| 1502 const String& message = String::Handle( | |
| 1503 String::NewFormatted("%s: wrong argument count for " | |
| 1504 "constructor '%s': %s.", | |
| 1505 current_func, | |
| 1506 constr_name.ToCString(), | |
| 1507 error_message.ToCString())); | |
| 1508 return ApiError::New(message); | |
| 1509 } | |
| 1510 return constructor.raw(); | |
| 1511 } | |
| 1512 | |
| 1513 | |
| 1425 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { | 1514 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { |
| 1426 const MirrorReference& klass_ref = | 1515 const MirrorReference& klass_ref = |
| 1427 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | 1516 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); |
| 1428 Class& klass = Class::Handle(); | 1517 Class& klass = Class::Handle(); |
| 1429 klass ^= klass_ref.referent(); | 1518 klass ^= klass_ref.referent(); |
| 1430 return klass.Name(); | 1519 return klass.Name(); |
| 1431 } | 1520 } |
| 1432 | 1521 |
| 1522 | |
| 1523 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 3) { | |
| 1524 const MirrorReference& klass_ref = | |
| 1525 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | |
| 1526 Class& klass = Class::Handle(); | |
| 1527 klass ^= klass_ref.referent(); | |
| 1528 | |
| 1529 const String& function_name = | |
| 1530 String::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1531 | |
| 1532 const Array& positional_args = | |
| 1533 Array::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1534 intptr_t number_of_arguments = positional_args.Length(); | |
| 1535 | |
| 1536 | |
|
siva
2013/07/11 22:53:37
extra blank line?
| |
| 1537 intptr_t num_receiver = 0; // 1 for instance methods | |
| 1538 const Array& args = | |
| 1539 Array::Handle(Array::New(number_of_arguments + num_receiver)); | |
| 1540 Object& arg = Object::Handle(); | |
| 1541 for (int i = 0; i < number_of_arguments; i++) { | |
| 1542 arg = positional_args.At(i); | |
| 1543 args.SetAt((i + num_receiver), arg); | |
| 1544 } | |
| 1545 | |
| 1546 const Function& function = Function::Handle( | |
| 1547 Resolver::ResolveStatic(klass, | |
| 1548 function_name, | |
| 1549 number_of_arguments, | |
| 1550 Object::empty_array(), | |
| 1551 Resolver::kIsQualified)); | |
| 1552 if (function.IsNull()) { | |
| 1553 const String& klass_name = String::Handle(isolate, klass.Name()); | |
| 1554 const String& message = String::Handle( | |
| 1555 String::NewFormatted("%s: did not find %d-arg static method '%s.%s'.", | |
| 1556 "ClassMirror_invoke", | |
| 1557 number_of_arguments, | |
| 1558 klass_name.ToCString(), | |
| 1559 function_name.ToCString())); | |
| 1560 const ApiError& error = ApiError::Handle(ApiError::New(message)); | |
| 1561 | |
| 1562 Exceptions::PropagateError(error); | |
|
siva
2013/07/11 22:53:37
Why are we creating an ApiError and propagating it
rmacnak
2013/07/11 23:59:23
Right. These ApiErrors (wrapped in MirroredCompila
| |
| 1563 UNREACHABLE(); | |
| 1564 } | |
| 1565 Object& result = Object::Handle(DartEntry::InvokeFunction(function, args)); | |
| 1566 if (result.IsError()) { | |
| 1567 Error& mirrored_error = | |
| 1568 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
| 1569 Exceptions::PropagateError(mirrored_error); | |
| 1570 UNREACHABLE(); | |
| 1571 } | |
| 1572 return result.raw(); | |
| 1573 } | |
| 1574 | |
| 1575 | |
| 1576 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 2) { | |
| 1577 const MirrorReference& klass_ref = | |
| 1578 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | |
| 1579 Class& klass = Class::Handle(); | |
| 1580 klass ^= klass_ref.referent(); | |
| 1581 | |
| 1582 const String& getter_name = | |
| 1583 String::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1584 | |
| 1585 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); | |
| 1586 if (field.IsNull()) { | |
| 1587 const String& internal_getter_name = String::Handle( | |
| 1588 Field::GetterName(getter_name)); | |
| 1589 const Function& getter = Function::Handle( | |
| 1590 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); | |
| 1591 | |
| 1592 if (getter.IsNull()) { | |
| 1593 const String& message = String::Handle( | |
| 1594 String::NewFormatted("%s: did not find static getter '%s'.", | |
| 1595 "ClassMirror_invokeGetter", | |
| 1596 getter_name.ToCString())); | |
| 1597 const ApiError& error = ApiError::Handle(ApiError::New(message)); | |
| 1598 Exceptions::PropagateError(error); | |
|
siva
2013/07/11 22:53:37
Ditto question about ApiError
| |
| 1599 UNREACHABLE(); | |
| 1600 } | |
| 1601 | |
| 1602 // Invoke the getter and return the result. | |
| 1603 Object& result = Object::Handle( | |
| 1604 DartEntry::InvokeFunction(getter, Object::empty_array())); | |
| 1605 if (result.IsError()) { | |
| 1606 Error& mirrored_error = | |
| 1607 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
| 1608 Exceptions::PropagateError(mirrored_error); | |
| 1609 UNREACHABLE(); | |
| 1610 } | |
| 1611 return result.raw(); | |
| 1612 } | |
| 1613 return field.value(); | |
| 1614 } | |
| 1615 | |
| 1616 | |
| 1617 DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 3) { | |
| 1618 const MirrorReference& klass_ref = | |
| 1619 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | |
| 1620 Class& klass = Class::Handle(); | |
| 1621 klass ^= klass_ref.referent(); | |
| 1622 | |
| 1623 const String& setter_name = | |
| 1624 String::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1625 | |
| 1626 const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1627 | |
| 1628 // Check for real fields and user-defined setters | |
|
siva
2013/07/11 22:53:37
missing '.' at end of comment.
| |
| 1629 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | |
| 1630 if (field.IsNull()) { | |
| 1631 const String& internal_setter_name = String::Handle( | |
| 1632 Field::SetterName(setter_name)); | |
| 1633 const Function& setter = Function::Handle( | |
| 1634 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); | |
| 1635 | |
| 1636 if (setter.IsNull()) { | |
| 1637 const String& message = String::Handle( | |
| 1638 String::NewFormatted("%s: did not find static setter '%s'.", | |
| 1639 "ClassMirror_invokeSetter", | |
| 1640 setter_name.ToCString())); | |
| 1641 const ApiError& error = ApiError::Handle(ApiError::New(message)); | |
| 1642 Exceptions::PropagateError(error); | |
| 1643 UNREACHABLE(); | |
| 1644 } | |
| 1645 | |
| 1646 // Invoke the getter and return the result. | |
| 1647 const int kNumArgs = 1; | |
| 1648 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); | |
| 1649 args.SetAt(0, value); | |
| 1650 | |
| 1651 Object& result = Object::Handle( | |
| 1652 DartEntry::InvokeFunction(setter, args)); | |
| 1653 if (result.IsError()) { | |
| 1654 Error& mirrored_error = | |
| 1655 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
| 1656 Exceptions::PropagateError(mirrored_error); | |
| 1657 UNREACHABLE(); | |
| 1658 } | |
| 1659 return result.raw(); | |
| 1660 } | |
| 1661 | |
| 1662 if (field.is_final()) { | |
| 1663 const String& message = String::Handle( | |
| 1664 String::NewFormatted("%s: cannot set final field '%s'.", | |
| 1665 "ClassMirror_invokeSetter", | |
| 1666 setter_name.ToCString())); | |
| 1667 const ApiError& error = ApiError::Handle(ApiError::New(message)); | |
| 1668 Exceptions::PropagateError(error); | |
| 1669 UNREACHABLE(); | |
| 1670 } | |
| 1671 | |
| 1672 field.set_value(value); | |
| 1673 return value.raw(); | |
| 1674 } | |
| 1675 | |
| 1676 | |
| 1677 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 3) { | |
| 1678 const MirrorReference& klass_ref = | |
| 1679 MirrorReference::CheckedHandle(arguments->NativeArgAt(0)); | |
| 1680 Class& klass = Class::Handle(); | |
| 1681 klass ^= klass_ref.referent(); | |
| 1682 | |
| 1683 const String& constructor_name = | |
| 1684 String::CheckedHandle(arguments->NativeArgAt(1)); | |
| 1685 | |
| 1686 const Array& positional_args = | |
| 1687 Array::CheckedHandle(arguments->NativeArgAt(2)); | |
| 1688 | |
| 1689 intptr_t number_of_arguments = positional_args.Length(); | |
| 1690 | |
| 1691 // By convention, the static function implementing a named constructor 'C' | |
| 1692 // for class 'A' is labeled 'A.C', and the static function implementing the | |
| 1693 // unnamed constructor for class 'A' is labeled 'A.'. | |
| 1694 // This convention prevents users from explicitly calling constructors. | |
| 1695 String& klass_name = String::Handle(klass.Name()); | |
| 1696 String& internal_constructor_name = | |
| 1697 String::Handle(String::Concat(klass_name, Symbols::Dot())); | |
| 1698 internal_constructor_name = | |
| 1699 String::Concat(internal_constructor_name, constructor_name); | |
| 1700 | |
| 1701 Object& constructor = Object::Handle(); | |
| 1702 constructor = ResolveConstructor("ClassMirror_invokeConstructor", | |
| 1703 klass, | |
| 1704 klass_name, | |
| 1705 internal_constructor_name, | |
| 1706 number_of_arguments); | |
| 1707 if (constructor.IsError()) { | |
| 1708 Exceptions::PropagateError(Error::Cast(constructor)); | |
| 1709 UNREACHABLE(); | |
| 1710 } | |
| 1711 ASSERT(constructor.IsFunction()); | |
| 1712 | |
| 1713 Object& result = | |
| 1714 Object::Handle(DartEntry::InvokeConstructor(klass, | |
| 1715 Function::Cast(constructor), | |
| 1716 positional_args)); | |
| 1717 if (result.IsError()) { | |
| 1718 Error& mirrored_error = | |
| 1719 Error::Handle(CreateMirroredError(Error::Cast(result))); | |
| 1720 Exceptions::PropagateError(mirrored_error); | |
| 1721 UNREACHABLE(); | |
| 1722 } | |
| 1723 // Factories may return null. | |
| 1724 ASSERT(result.IsInstance() || result.IsNull()); | |
| 1725 return result.raw(); | |
| 1726 } | |
| 1727 | |
| 1433 } // namespace dart | 1728 } // namespace dart |
| OLD | NEW |