| 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 "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" |
| 6 | 6 |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.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/native_entry.h" | 10 #include "vm/native_entry.h" |
| 11 #include "vm/object_store.h" | 11 #include "vm/object_store.h" |
| 12 #include "vm/resolver.h" | 12 #include "vm/resolver.h" |
| 13 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 // TODO(regis): Factorize this static helper copied from code_generator.cc. | |
| 18 static RawObject* InvokeNoSuchMethod(const Instance& receiver, | |
| 19 const String& target_name, | |
| 20 const Array& arguments_descriptor, | |
| 21 const Array& arguments) { | |
| 22 // Allocate an InvocationMirror object. | |
| 23 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | |
| 24 const String& invocation_mirror_name = | |
| 25 String::Handle(Symbols::InvocationMirror()); | |
| 26 Class& invocation_mirror_class = | |
| 27 Class::Handle(core_lib.LookupClassAllowPrivate(invocation_mirror_name)); | |
| 28 ASSERT(!invocation_mirror_class.IsNull()); | |
| 29 const String& allocation_function_name = | |
| 30 String::Handle(Symbols::AllocateInvocationMirror()); | |
| 31 const Function& allocation_function = Function::Handle( | |
| 32 Resolver::ResolveStaticByName(invocation_mirror_class, | |
| 33 allocation_function_name, | |
| 34 Resolver::kIsQualified)); | |
| 35 ASSERT(!allocation_function.IsNull()); | |
| 36 const int kNumAllocationArgs = 3; | |
| 37 const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs)); | |
| 38 allocation_args.SetAt(0, target_name); | |
| 39 allocation_args.SetAt(1, arguments_descriptor); | |
| 40 allocation_args.SetAt(2, arguments); | |
| 41 const Object& invocation_mirror = | |
| 42 Object::Handle(DartEntry::InvokeStatic(allocation_function, | |
| 43 allocation_args)); | |
| 44 | |
| 45 const String& function_name = String::Handle(Symbols::NoSuchMethod()); | |
| 46 const int kNumInvokeArgs = 2; | |
| 47 const int kNumNamedInvokeArgs = 0; | |
| 48 const Function& function = Function::Handle( | |
| 49 Resolver::ResolveDynamic(receiver, | |
| 50 function_name, | |
| 51 kNumInvokeArgs, | |
| 52 kNumNamedInvokeArgs)); | |
| 53 ASSERT(!function.IsNull()); | |
| 54 const Array& invoke_arguments = Array::Handle(Array::New(kNumInvokeArgs)); | |
| 55 invoke_arguments.SetAt(0, receiver); | |
| 56 invoke_arguments.SetAt(1, invocation_mirror); | |
| 57 const Object& result = | |
| 58 Object::Handle(DartEntry::InvokeDynamic(function, invoke_arguments)); | |
| 59 if (result.IsError()) { | |
| 60 Exceptions::PropagateError(Error::Cast(result)); | |
| 61 } | |
| 62 return result.raw(); | |
| 63 } | |
| 64 | |
| 65 | |
| 66 DEFINE_NATIVE_ENTRY(InvocationMirror_invoke, 4) { | 17 DEFINE_NATIVE_ENTRY(InvocationMirror_invoke, 4) { |
| 67 const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 18 const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(0)); |
| 68 const String& fun_name = String::CheckedHandle(arguments->NativeArgAt(1)); | 19 const String& fun_name = String::CheckedHandle(arguments->NativeArgAt(1)); |
| 69 const Array& fun_args_desc = Array::CheckedHandle(arguments->NativeArgAt(2)); | 20 const Array& fun_args_desc = Array::CheckedHandle(arguments->NativeArgAt(2)); |
| 70 const Array& fun_arguments = Array::CheckedHandle(arguments->NativeArgAt(3)); | 21 const Array& fun_arguments = Array::CheckedHandle(arguments->NativeArgAt(3)); |
| 71 | 22 |
| 72 // Allocate a fixed-length array duplicating the original function arguments | 23 // Allocate a fixed-length array duplicating the original function arguments |
| 73 // and replace the receiver. | 24 // and replace the receiver. |
| 74 const int num_arguments = fun_arguments.Length(); | 25 const int num_arguments = fun_arguments.Length(); |
| 75 const Array& invoke_arguments = Array::Handle(Array::New(num_arguments)); | 26 const Array& invoke_arguments = Array::Handle(Array::New(num_arguments)); |
| 76 invoke_arguments.SetAt(0, receiver); | 27 invoke_arguments.SetAt(0, receiver); |
| 77 Object& arg = Object::Handle(); | 28 Object& arg = Object::Handle(); |
| 78 for (int i = 1; i < num_arguments; i++) { | 29 for (int i = 1; i < num_arguments; i++) { |
| 79 arg = fun_arguments.At(i); | 30 arg = fun_arguments.At(i); |
| 80 invoke_arguments.SetAt(i, arg); | 31 invoke_arguments.SetAt(i, arg); |
| 81 } | 32 } |
| 82 // Resolve dynamic function given by name. | 33 // Resolve dynamic function given by name. |
| 83 const ArgumentsDescriptor args_desc(fun_args_desc); | 34 const ArgumentsDescriptor args_desc(fun_args_desc); |
| 84 const Function& function = Function::Handle( | 35 const Function& function = Function::Handle( |
| 85 Resolver::ResolveDynamic(receiver, | 36 Resolver::ResolveDynamic(receiver, |
| 86 fun_name, | 37 fun_name, |
| 87 args_desc.Count(), | 38 args_desc.Count(), |
| 88 args_desc.NamedCount())); | 39 args_desc.NamedCount())); |
| 40 Object& result = Object::Handle(); |
| 89 if (function.IsNull()) { | 41 if (function.IsNull()) { |
| 90 return InvokeNoSuchMethod(receiver, | 42 result = DartEntry::InvokeNoSuchMethod(receiver, |
| 91 fun_name, | 43 fun_name, |
| 92 fun_args_desc, | 44 invoke_arguments, |
| 93 invoke_arguments); | 45 fun_args_desc); |
| 46 } else { |
| 47 result = DartEntry::InvokeDynamic(function, |
| 48 invoke_arguments, |
| 49 fun_args_desc); |
| 94 } | 50 } |
| 95 ASSERT(!function.IsNull()); | |
| 96 const Object& result = | |
| 97 Object::Handle(DartEntry::InvokeDynamic(function, | |
| 98 invoke_arguments, | |
| 99 fun_args_desc)); | |
| 100 if (result.IsError()) { | 51 if (result.IsError()) { |
| 101 Exceptions::PropagateError(Error::Cast(result)); | 52 Exceptions::PropagateError(Error::Cast(result)); |
| 102 } | 53 } |
| 103 return result.raw(); | 54 return result.raw(); |
| 104 } | 55 } |
| 105 | 56 |
| 106 } // namespace dart | 57 } // namespace dart |
| OLD | NEW |