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/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
8 #include "vm/code_generator.h" | 8 #include "vm/code_generator.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 | 129 |
130 RawObject* DartEntry::InvokeClosure(const Array& arguments) { | 130 RawObject* DartEntry::InvokeClosure(const Array& arguments) { |
131 const Array& arguments_descriptor = | 131 const Array& arguments_descriptor = |
132 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); | 132 Array::Handle(ArgumentsDescriptor::New(arguments.Length())); |
133 return InvokeClosure(arguments, arguments_descriptor); | 133 return InvokeClosure(arguments, arguments_descriptor); |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 RawObject* DartEntry::InvokeClosure(const Array& arguments, | 137 RawObject* DartEntry::InvokeClosure(const Array& arguments, |
138 const Array& arguments_descriptor) { | 138 const Array& arguments_descriptor) { |
139 Instance& instance = Instance::Handle(); | 139 Thread* thread = Thread::Current(); |
| 140 Zone* zone = thread->zone(); |
| 141 Instance& instance = Instance::Handle(zone); |
140 instance ^= arguments.At(0); | 142 instance ^= arguments.At(0); |
141 // Get the entrypoint corresponding to the closure function or to the call | 143 // Get the entrypoint corresponding to the closure function or to the call |
142 // method of the instance. This will result in a compilation of the function | 144 // method of the instance. This will result in a compilation of the function |
143 // if it is not already compiled. | 145 // if it is not already compiled. |
144 Function& function = Function::Handle(); | 146 Function& function = Function::Handle(zone); |
145 if (instance.IsCallable(&function)) { | 147 if (instance.IsCallable(&function)) { |
146 // Only invoke the function if its arguments are compatible. | 148 // Only invoke the function if its arguments are compatible. |
147 const ArgumentsDescriptor args_desc(arguments_descriptor); | 149 const ArgumentsDescriptor args_desc(arguments_descriptor); |
148 if (function.AreValidArgumentCounts(args_desc.Count(), | 150 if (function.AreValidArgumentCounts(args_desc.Count(), |
149 args_desc.NamedCount(), | 151 args_desc.NamedCount(), |
150 NULL)) { | 152 NULL)) { |
151 // The closure or non-closure object (receiver) is passed as implicit | 153 // The closure or non-closure object (receiver) is passed as implicit |
152 // first argument. It is already included in the arguments array. | 154 // first argument. It is already included in the arguments array. |
153 return InvokeFunction(function, arguments, arguments_descriptor); | 155 return InvokeFunction(function, arguments, arguments_descriptor); |
154 } | 156 } |
155 } | 157 } |
156 | 158 |
157 // There is no compatible 'call' method, see if there's a getter. | 159 // There is no compatible 'call' method, see if there's a getter. |
158 if (instance.IsClosure()) { | 160 if (instance.IsClosure()) { |
159 // Special case: closures are implemented with a call getter instead of a | 161 // Special case: closures are implemented with a call getter instead of a |
160 // call method. If the arguments didn't match, go to noSuchMethod instead | 162 // call method. If the arguments didn't match, go to noSuchMethod instead |
161 // of infinitely recursing on the getter. | 163 // of infinitely recursing on the getter. |
162 } else { | 164 } else { |
163 const String& getter_name = String::Handle(Symbols::New("get:call")); | 165 const String& getter_name = Symbols::GetCall(); |
164 Class& cls = Class::Handle(instance.clazz()); | 166 Class& cls = Class::Handle(zone, instance.clazz()); |
165 while (!cls.IsNull()) { | 167 while (!cls.IsNull()) { |
166 function ^= cls.LookupDynamicFunction(getter_name); | 168 function ^= cls.LookupDynamicFunction(getter_name); |
167 if (!function.IsNull()) { | 169 if (!function.IsNull()) { |
168 Thread* thread = Thread::Current(); | |
169 Isolate* isolate = thread->isolate(); | 170 Isolate* isolate = thread->isolate(); |
170 volatile uword c_stack_pos = Thread::GetCurrentStackPointer(); | 171 volatile uword c_stack_pos = Thread::GetCurrentStackPointer(); |
171 volatile uword c_stack_limit = OSThread::Current()->stack_base() - | 172 volatile uword c_stack_limit = OSThread::Current()->stack_base() - |
172 OSThread::GetSpecifiedStackSize(); | 173 OSThread::GetSpecifiedStackSize(); |
173 #if !defined(USING_SIMULATOR) | 174 #if !defined(USING_SIMULATOR) |
174 ASSERT(c_stack_limit == thread->saved_stack_limit()); | 175 ASSERT(c_stack_limit == thread->saved_stack_limit()); |
175 #endif | 176 #endif |
176 | 177 |
177 if (c_stack_pos < c_stack_limit) { | 178 if (c_stack_pos < c_stack_limit) { |
178 const Instance& exception = | 179 const Instance& exception = |
179 Instance::Handle(isolate->object_store()->stack_overflow()); | 180 Instance::Handle(zone, isolate->object_store()->stack_overflow()); |
180 return UnhandledException::New(exception, Stacktrace::Handle()); | 181 return UnhandledException::New(exception, Stacktrace::Handle(zone)); |
181 } | 182 } |
182 | 183 |
183 const Array& getter_arguments = Array::Handle(Array::New(1)); | 184 const Array& getter_arguments = Array::Handle(zone, Array::New(1)); |
184 getter_arguments.SetAt(0, instance); | 185 getter_arguments.SetAt(0, instance); |
185 const Object& getter_result = | 186 const Object& getter_result = |
186 Object::Handle(DartEntry::InvokeFunction(function, | 187 Object::Handle(zone, DartEntry::InvokeFunction(function, |
187 getter_arguments)); | 188 getter_arguments)); |
188 if (getter_result.IsError()) { | 189 if (getter_result.IsError()) { |
189 return getter_result.raw(); | 190 return getter_result.raw(); |
190 } | 191 } |
191 ASSERT(getter_result.IsNull() || getter_result.IsInstance()); | 192 ASSERT(getter_result.IsNull() || getter_result.IsInstance()); |
192 | 193 |
193 arguments.SetAt(0, getter_result); | 194 arguments.SetAt(0, getter_result); |
194 // This otherwise unnecessary handle is used to prevent clang from | 195 // This otherwise unnecessary handle is used to prevent clang from |
195 // doing tail call elimination, which would make the stack overflow | 196 // doing tail call elimination, which would make the stack overflow |
196 // check above ineffective. | 197 // check above ineffective. |
197 Object& result = Object::Handle(InvokeClosure(arguments, | 198 Object& result = Object::Handle(zone, |
198 arguments_descriptor)); | 199 InvokeClosure(arguments, arguments_descriptor)); |
199 return result.raw(); | 200 return result.raw(); |
200 } | 201 } |
201 cls = cls.SuperClass(); | 202 cls = cls.SuperClass(); |
202 } | 203 } |
203 } | 204 } |
204 | 205 |
205 // No compatible method or getter so invoke noSuchMethod. | 206 // No compatible method or getter so invoke noSuchMethod. |
206 return InvokeNoSuchMethod(instance, | 207 return InvokeNoSuchMethod(instance, |
207 Symbols::Call(), | 208 Symbols::Call(), |
208 arguments, | 209 arguments, |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 const Array& args = Array::Handle(Array::New(kNumArguments)); | 595 const Array& args = Array::Handle(Array::New(kNumArguments)); |
595 args.SetAt(0, map); | 596 args.SetAt(0, map); |
596 args.SetAt(1, key); | 597 args.SetAt(1, key); |
597 args.SetAt(2, value); | 598 args.SetAt(2, value); |
598 const Object& result = Object::Handle(DartEntry::InvokeFunction(function, | 599 const Object& result = Object::Handle(DartEntry::InvokeFunction(function, |
599 args)); | 600 args)); |
600 return result.raw(); | 601 return result.raw(); |
601 } | 602 } |
602 | 603 |
603 } // namespace dart | 604 } // namespace dart |
OLD | NEW |