OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/dart_entry.h" | 5 #include "vm/dart_entry.h" |
6 | 6 |
7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
10 #include "vm/resolver.h" | 10 #include "vm/resolver.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 const Code& code = Code::Handle(function.CurrentCode()); | 74 const Code& code = Code::Handle(function.CurrentCode()); |
75 ASSERT(!code.IsNull()); | 75 ASSERT(!code.IsNull()); |
76 const Array& arg_descriptor = | 76 const Array& arg_descriptor = |
77 Array::Handle(ArgumentsDescriptor::New(arguments.length(), | 77 Array::Handle(ArgumentsDescriptor::New(arguments.length(), |
78 optional_arguments_names)); | 78 optional_arguments_names)); |
79 return entrypoint(code.EntryPoint(), arg_descriptor, arguments.data(), | 79 return entrypoint(code.EntryPoint(), arg_descriptor, arguments.data(), |
80 context); | 80 context); |
81 } | 81 } |
82 | 82 |
83 | 83 |
| 84 // TODO(regis): Pass arguments as an Array including the receiver. |
84 RawObject* DartEntry::InvokeClosure( | 85 RawObject* DartEntry::InvokeClosure( |
85 const Instance& closure, | 86 const Instance& instance, |
86 const GrowableArray<const Object*>& arguments, | 87 const GrowableArray<const Object*>& arguments, |
87 const Array& optional_arguments_names) { | 88 const Array& optional_arguments_names) { |
88 // Get the entrypoint corresponding to the closure specified, this | 89 // Get the entrypoint corresponding to the closure function or to the call |
89 // will result in a compilation of the closure if it is not already | 90 // method of the instance. This will result in a compilation of the function |
90 // compiled. | 91 // if it is not already compiled. |
91 ASSERT(Class::Handle(closure.clazz()).signature_function() != Object::null()); | 92 Function& function = Function::Handle(); |
92 const Function& function = Function::Handle(Closure::function(closure)); | 93 Context& context = Context::Handle(); |
93 const Context& context = Context::Handle(Closure::context(closure)); | 94 if (!instance.IsCallable(&function, &context)) { |
| 95 // Set up arguments to include the receiver as the first argument. |
| 96 const int num_arguments = arguments.length() + 1; |
| 97 const Array& args = Array::Handle(Array::New(num_arguments)); |
| 98 args.SetAt(0, instance); |
| 99 for (int i = 1; i < num_arguments; i++) { |
| 100 args.SetAt(i, *arguments[i - 1]); |
| 101 } |
| 102 const String& call_symbol = String::Handle(Symbols::Call()); |
| 103 const Object& null_object = Object::Handle(); |
| 104 GrowableArray<const Object*> dart_arguments(5); |
| 105 dart_arguments.Add(&instance); |
| 106 dart_arguments.Add(&call_symbol); |
| 107 dart_arguments.Add(&args); // Including instance. |
| 108 dart_arguments.Add(&null_object); // TODO(regis): Provide names. |
| 109 // If a function "call" with different arguments exists, it will have been |
| 110 // invoked above, so no need to handle this case here. |
| 111 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); |
| 112 UNREACHABLE(); |
| 113 return Object::null(); |
| 114 } |
94 ASSERT(!function.IsNull()); | 115 ASSERT(!function.IsNull()); |
95 if (!function.HasCode()) { | 116 if (!function.HasCode()) { |
96 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 117 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
97 if (!error.IsNull()) { | 118 if (!error.IsNull()) { |
98 return error.raw(); | 119 return error.raw(); |
99 } | 120 } |
100 } | 121 } |
101 // Set up arguments to include the closure as the first argument. | 122 // Set up arguments to include the receiver as the first argument. |
102 const int num_arguments = arguments.length() + 1; | 123 const int num_arguments = arguments.length() + 1; |
103 GrowableArray<const Object*> args(num_arguments); | 124 GrowableArray<const Object*> args(num_arguments); |
104 const Object& arg0 = Object::ZoneHandle(closure.raw()); | 125 const Object& arg0 = Object::ZoneHandle(instance.raw()); |
105 args.Add(&arg0); | 126 args.Add(&arg0); |
106 for (int i = 1; i < num_arguments; i++) { | 127 for (int i = 1; i < num_arguments; i++) { |
107 args.Add(arguments[i - 1]); | 128 args.Add(arguments[i - 1]); |
108 } | 129 } |
109 // Now call the invoke stub which will invoke the closure. | 130 // Now call the invoke stub which will invoke the closure. |
110 invokestub entrypoint = reinterpret_cast<invokestub>( | 131 invokestub entrypoint = reinterpret_cast<invokestub>( |
111 StubCode::InvokeDartCodeEntryPoint()); | 132 StubCode::InvokeDartCodeEntryPoint()); |
112 ASSERT(context.isolate() == Isolate::Current()); | 133 ASSERT(context.isolate() == Isolate::Current()); |
113 const Code& code = Code::Handle(function.CurrentCode()); | 134 const Code& code = Code::Handle(function.CurrentCode()); |
114 ASSERT(!code.IsNull()); | 135 ASSERT(!code.IsNull()); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 const String& func_name = String::Handle(Field::GetterName(field_name)); | 381 const String& func_name = String::Handle(Field::GetterName(field_name)); |
361 const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name)); | 382 const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name)); |
362 ASSERT(!func.IsNull()); | 383 ASSERT(!func.IsNull()); |
363 GrowableArray<const Object*> arguments; | 384 GrowableArray<const Object*> arguments; |
364 const Array& kNoArgumentNames = Array::Handle(); | 385 const Array& kNoArgumentNames = Array::Handle(); |
365 return DartEntry::InvokeDynamic(port, func, arguments, kNoArgumentNames); | 386 return DartEntry::InvokeDynamic(port, func, arguments, kNoArgumentNames); |
366 } | 387 } |
367 | 388 |
368 | 389 |
369 } // namespace dart | 390 } // namespace dart |
OLD | NEW |