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

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/vm/dart_entry.h » ('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 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/vm/dart_entry.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698