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 "lib/invocation_mirror.h" | 5 #include "lib/invocation_mirror.h" |
6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1204 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
1205 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1205 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
1206 GET_NON_NULL_NATIVE_ARGUMENT( | 1206 GET_NON_NULL_NATIVE_ARGUMENT( |
1207 String, function_name, arguments->NativeArgAt(2)); | 1207 String, function_name, arguments->NativeArgAt(2)); |
1208 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); | 1208 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); |
1209 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); | 1209 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
1210 | 1210 |
1211 const Array& args_descriptor_array = | 1211 const Array& args_descriptor_array = |
1212 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); | 1212 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
1213 | 1213 |
1214 String& ambiguity_error_msg = String::Handle(isolate); | |
1215 const Function& function = Function::Handle( | 1214 const Function& function = Function::Handle( |
1216 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); | 1215 library.LookupFunctionAllowPrivate(function_name)); |
1217 | |
1218 if (function.IsNull() && !ambiguity_error_msg.IsNull()) { | |
1219 ThrowMirroredCompilationError(ambiguity_error_msg); | |
1220 UNREACHABLE(); | |
1221 } | |
1222 | 1216 |
1223 ArgumentsDescriptor args_descriptor(args_descriptor_array); | 1217 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
1224 if (function.IsNull() || | 1218 if (function.IsNull() || |
1225 !function.AreValidArguments(args_descriptor, NULL) || | 1219 !function.AreValidArguments(args_descriptor, NULL) || |
1226 !function.is_visible()) { | 1220 !function.is_visible()) { |
1227 ThrowNoSuchMethod(Instance::null_instance(), | 1221 ThrowNoSuchMethod(Instance::null_instance(), |
1228 function_name, | 1222 function_name, |
1229 function, | 1223 function, |
1230 InvocationMirror::kTopLevel, | 1224 InvocationMirror::kTopLevel, |
1231 InvocationMirror::kMethod); | 1225 InvocationMirror::kMethod); |
(...skipping 14 matching lines...) Expand all Loading... |
1246 // Argument 0 is the mirror, which is unused by the native. It exists | 1240 // Argument 0 is the mirror, which is unused by the native. It exists |
1247 // because this native is an instance method in order to be polymorphic | 1241 // because this native is an instance method in order to be polymorphic |
1248 // with its cousins. | 1242 // with its cousins. |
1249 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1243 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
1250 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1244 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
1251 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); | 1245 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); |
1252 | 1246 |
1253 // To access a top-level we may need to use the Field or the | 1247 // To access a top-level we may need to use the Field or the |
1254 // getter Function. The getter function may either be in the | 1248 // getter Function. The getter function may either be in the |
1255 // library or in the field's owner class, depending. | 1249 // library or in the field's owner class, depending. |
1256 String& ambiguity_error_msg = String::Handle(isolate); | |
1257 const Field& field = Field::Handle( | 1250 const Field& field = Field::Handle( |
1258 library.LookupFieldAllowPrivate(getter_name, &ambiguity_error_msg)); | 1251 library.LookupFieldAllowPrivate(getter_name)); |
1259 Function& getter = Function::Handle(); | 1252 Function& getter = Function::Handle(); |
1260 if (field.IsNull() && ambiguity_error_msg.IsNull()) { | 1253 if (field.IsNull()) { |
1261 // No field found and no ambiguity error. Check for a getter in the lib. | 1254 // No field found and no ambiguity error. Check for a getter in the lib. |
1262 const String& internal_getter_name = | 1255 const String& internal_getter_name = |
1263 String::Handle(Field::GetterName(getter_name)); | 1256 String::Handle(Field::GetterName(getter_name)); |
1264 getter = library.LookupFunctionAllowPrivate(internal_getter_name, | 1257 getter = library.LookupFunctionAllowPrivate(internal_getter_name); |
1265 &ambiguity_error_msg); | |
1266 } else if (!field.IsNull() && FieldIsUninitialized(field)) { | 1258 } else if (!field.IsNull() && FieldIsUninitialized(field)) { |
1267 // A field was found. Check for a getter in the field's owner classs. | 1259 // A field was found. Check for a getter in the field's owner classs. |
1268 const Class& klass = Class::Handle(field.owner()); | 1260 const Class& klass = Class::Handle(field.owner()); |
1269 const String& internal_getter_name = | 1261 const String& internal_getter_name = |
1270 String::Handle(Field::GetterName(getter_name)); | 1262 String::Handle(Field::GetterName(getter_name)); |
1271 getter = klass.LookupStaticFunctionAllowPrivate(internal_getter_name); | 1263 getter = klass.LookupStaticFunctionAllowPrivate(internal_getter_name); |
1272 } | 1264 } |
1273 | 1265 |
1274 if (!getter.IsNull() && getter.is_visible()) { | 1266 if (!getter.IsNull() && getter.is_visible()) { |
1275 // Invoke the getter and return the result. | 1267 // Invoke the getter and return the result. |
1276 const Object& result = Object::Handle( | 1268 const Object& result = Object::Handle( |
1277 DartEntry::InvokeFunction(getter, Object::empty_array())); | 1269 DartEntry::InvokeFunction(getter, Object::empty_array())); |
1278 if (result.IsError()) { | 1270 if (result.IsError()) { |
1279 ThrowInvokeError(Error::Cast(result)); | 1271 ThrowInvokeError(Error::Cast(result)); |
1280 UNREACHABLE(); | 1272 UNREACHABLE(); |
1281 } | 1273 } |
1282 return result.raw(); | 1274 return result.raw(); |
1283 } | 1275 } |
1284 if (!field.IsNull()) { | 1276 if (!field.IsNull()) { |
1285 return field.value(); | 1277 return field.value(); |
1286 } | 1278 } |
1287 if (ambiguity_error_msg.IsNull()) { | 1279 ThrowNoSuchMethod(Instance::null_instance(), |
1288 ThrowNoSuchMethod(Instance::null_instance(), | 1280 getter_name, |
1289 getter_name, | 1281 getter, |
1290 getter, | 1282 InvocationMirror::kTopLevel, |
1291 InvocationMirror::kTopLevel, | 1283 InvocationMirror::kGetter); |
1292 InvocationMirror::kGetter); | |
1293 } else { | |
1294 ThrowMirroredCompilationError(ambiguity_error_msg); | |
1295 } | |
1296 UNREACHABLE(); | 1284 UNREACHABLE(); |
1297 return Instance::null(); | 1285 return Instance::null(); |
1298 } | 1286 } |
1299 | 1287 |
1300 | 1288 |
1301 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { | 1289 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { |
1302 // Argument 0 is the mirror, which is unused by the native. It exists | 1290 // Argument 0 is the mirror, which is unused by the native. It exists |
1303 // because this native is an instance method in order to be polymorphic | 1291 // because this native is an instance method in order to be polymorphic |
1304 // with its cousins. | 1292 // with its cousins. |
1305 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1293 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
1306 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1294 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
1307 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); | 1295 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); |
1308 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); | 1296 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); |
1309 | 1297 |
1310 // To access a top-level we may need to use the Field or the | 1298 // To access a top-level we may need to use the Field or the |
1311 // setter Function. The setter function may either be in the | 1299 // setter Function. The setter function may either be in the |
1312 // library or in the field's owner class, depending. | 1300 // library or in the field's owner class, depending. |
1313 String& ambiguity_error_msg = String::Handle(isolate); | |
1314 const Field& field = Field::Handle( | 1301 const Field& field = Field::Handle( |
1315 library.LookupFieldAllowPrivate(setter_name, &ambiguity_error_msg)); | 1302 library.LookupFieldAllowPrivate(setter_name)); |
1316 | 1303 |
1317 if (field.IsNull() && ambiguity_error_msg.IsNull()) { | 1304 if (field.IsNull()) { |
1318 const String& internal_setter_name = | 1305 const String& internal_setter_name = |
1319 String::Handle(Field::SetterName(setter_name)); | 1306 String::Handle(Field::SetterName(setter_name)); |
1320 const Function& setter = Function::Handle( | 1307 const Function& setter = Function::Handle( |
1321 library.LookupFunctionAllowPrivate(internal_setter_name, | 1308 library.LookupFunctionAllowPrivate(internal_setter_name)); |
1322 &ambiguity_error_msg)); | |
1323 if (setter.IsNull() || !setter.is_visible()) { | 1309 if (setter.IsNull() || !setter.is_visible()) { |
1324 if (ambiguity_error_msg.IsNull()) { | 1310 ThrowNoSuchMethod(Instance::null_instance(), |
1325 ThrowNoSuchMethod(Instance::null_instance(), | 1311 setter_name, |
1326 setter_name, | 1312 setter, |
1327 setter, | 1313 InvocationMirror::kTopLevel, |
1328 InvocationMirror::kTopLevel, | 1314 InvocationMirror::kSetter); |
1329 InvocationMirror::kSetter); | |
1330 } else { | |
1331 ThrowMirroredCompilationError(ambiguity_error_msg); | |
1332 } | |
1333 UNREACHABLE(); | 1315 UNREACHABLE(); |
1334 } | 1316 } |
1335 | 1317 |
1336 // Invoke the setter and return the result. | 1318 // Invoke the setter and return the result. |
1337 const int kNumArgs = 1; | 1319 const int kNumArgs = 1; |
1338 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1320 const Array& args = Array::Handle(Array::New(kNumArgs)); |
1339 args.SetAt(0, value); | 1321 args.SetAt(0, value); |
1340 const Object& result = Object::Handle( | 1322 const Object& result = Object::Handle( |
1341 DartEntry::InvokeFunction(setter, args)); | 1323 DartEntry::InvokeFunction(setter, args)); |
1342 if (result.IsError()) { | 1324 if (result.IsError()) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1444 } | 1426 } |
1445 | 1427 |
1446 | 1428 |
1447 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1429 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
1448 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1430 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
1449 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1431 const Field& field = Field::Handle(ref.GetFieldReferent()); |
1450 return field.type(); | 1432 return field.type(); |
1451 } | 1433 } |
1452 | 1434 |
1453 } // namespace dart | 1435 } // namespace dart |
OLD | NEW |