| 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/longjump.h" |
| 9 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
| 10 #include "vm/resolver.h" | 11 #include "vm/resolver.h" |
| 11 #include "vm/stub_code.h" | 12 #include "vm/stub_code.h" |
| 12 | 13 |
| 13 namespace dart { | 14 namespace dart { |
| 14 | 15 |
| 15 RawObject* DartEntry::InvokeDynamic( | 16 RawInstance* DartEntry::InvokeDynamic( |
| 16 const Instance& receiver, | 17 const Instance& receiver, |
| 17 const Function& function, | 18 const Function& function, |
| 18 const GrowableArray<const Object*>& arguments, | 19 const GrowableArray<const Object*>& arguments, |
| 19 const Array& optional_arguments_names) { | 20 const Array& optional_arguments_names) { |
| 20 // Get the entrypoint corresponding to the function specified, this | 21 // Get the entrypoint corresponding to the function specified, this |
| 21 // will result in a compilation of the function if it is not already | 22 // will result in a compilation of the function if it is not already |
| 22 // compiled. | 23 // compiled. |
| 23 if (!function.HasCode()) { | 24 if (!function.HasCode()) { |
| 24 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 25 Compiler::CompileFunction(function); |
| 25 if (!error.IsNull()) { | |
| 26 return error.raw(); | |
| 27 } | |
| 28 } | 26 } |
| 29 const Code& code = Code::Handle(function.code()); | 27 const Code& code = Code::Handle(function.code()); |
| 30 ASSERT(!code.IsNull()); | 28 ASSERT(!code.IsNull()); |
| 31 const Instructions& instrs = Instructions::Handle(code.instructions()); | 29 const Instructions& instrs = Instructions::Handle(code.instructions()); |
| 32 ASSERT(!instrs.IsNull()); | 30 ASSERT(!instrs.IsNull()); |
| 33 | 31 |
| 34 // Set up arguments to include the receiver as the first argument. | 32 // Set up arguments to include the receiver as the first argument. |
| 35 const int num_arguments = arguments.length() + 1; | 33 const int num_arguments = arguments.length() + 1; |
| 36 GrowableArray<const Object*> args(num_arguments); | 34 GrowableArray<const Object*> args(num_arguments); |
| 37 const Object& arg0 = Object::ZoneHandle(receiver.raw()); | 35 const Object& arg0 = Object::ZoneHandle(receiver.raw()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 48 ASSERT(context.isolate() == Isolate::Current()); | 46 ASSERT(context.isolate() == Isolate::Current()); |
| 49 return entrypoint( | 47 return entrypoint( |
| 50 instrs.EntryPoint(), | 48 instrs.EntryPoint(), |
| 51 CodeGenerator::ArgumentsDescriptor(num_arguments, | 49 CodeGenerator::ArgumentsDescriptor(num_arguments, |
| 52 optional_arguments_names), | 50 optional_arguments_names), |
| 53 args.data(), | 51 args.data(), |
| 54 context); | 52 context); |
| 55 } | 53 } |
| 56 | 54 |
| 57 | 55 |
| 58 RawObject* DartEntry::InvokeStatic( | 56 RawInstance* DartEntry::InvokeStatic( |
| 59 const Function& function, | 57 const Function& function, |
| 60 const GrowableArray<const Object*>& arguments, | 58 const GrowableArray<const Object*>& arguments, |
| 61 const Array& optional_arguments_names) { | 59 const Array& optional_arguments_names) { |
| 62 // Get the entrypoint corresponding to the function specified, this | 60 // Get the entrypoint corresponding to the function specified, this |
| 63 // will result in a compilation of the function if it is not already | 61 // will result in a compilation of the function if it is not already |
| 64 // compiled. | 62 // compiled. |
| 65 ASSERT(!function.IsNull()); | 63 ASSERT(!function.IsNull()); |
| 66 if (!function.HasCode()) { | 64 if (!function.HasCode()) { |
| 67 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 65 Compiler::CompileFunction(function); |
| 68 if (!error.IsNull()) { | |
| 69 return error.raw(); | |
| 70 } | |
| 71 } | 66 } |
| 72 const Code& code = Code::Handle(function.code()); | 67 const Code& code = Code::Handle(function.code()); |
| 73 ASSERT(!code.IsNull()); | 68 ASSERT(!code.IsNull()); |
| 74 const Instructions& instrs = Instructions::Handle(code.instructions()); | 69 const Instructions& instrs = Instructions::Handle(code.instructions()); |
| 75 ASSERT(!instrs.IsNull()); | 70 ASSERT(!instrs.IsNull()); |
| 76 | 71 |
| 77 // Now Call the invoke stub which will invoke the dart function. | 72 // Now Call the invoke stub which will invoke the dart function. |
| 78 invokestub entrypoint = reinterpret_cast<invokestub>( | 73 invokestub entrypoint = reinterpret_cast<invokestub>( |
| 79 StubCode::InvokeDartCodeEntryPoint()); | 74 StubCode::InvokeDartCodeEntryPoint()); |
| 80 const Context& context = | 75 const Context& context = |
| 81 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context()); | 76 Context::ZoneHandle(Isolate::Current()->object_store()->empty_context()); |
| 82 ASSERT(context.isolate() == Isolate::Current()); | 77 ASSERT(context.isolate() == Isolate::Current()); |
| 83 return entrypoint( | 78 return entrypoint( |
| 84 instrs.EntryPoint(), | 79 instrs.EntryPoint(), |
| 85 CodeGenerator::ArgumentsDescriptor(arguments.length(), | 80 CodeGenerator::ArgumentsDescriptor(arguments.length(), |
| 86 optional_arguments_names), | 81 optional_arguments_names), |
| 87 arguments.data(), | 82 arguments.data(), |
| 88 context); | 83 context); |
| 89 } | 84 } |
| 90 | 85 |
| 91 | 86 |
| 92 RawObject* DartEntry::InvokeClosure( | 87 RawInstance* DartEntry::InvokeClosure( |
| 93 const Closure& closure, | 88 const Closure& closure, |
| 94 const GrowableArray<const Object*>& arguments, | 89 const GrowableArray<const Object*>& arguments, |
| 95 const Array& optional_arguments_names) { | 90 const Array& optional_arguments_names) { |
| 96 // Get the entrypoint corresponding to the closure specified, this | 91 // Get the entrypoint corresponding to the closure specified, this |
| 97 // will result in a compilation of the closure if it is not already | 92 // will result in a compilation of the closure if it is not already |
| 98 // compiled. | 93 // compiled. |
| 99 ASSERT(Class::Handle(closure.clazz()).signature_function() != Object::null()); | 94 ASSERT(Class::Handle(closure.clazz()).signature_function() != Object::null()); |
| 100 const Function& function = Function::Handle(closure.function()); | 95 const Function& function = Function::Handle(closure.function()); |
| 101 const Context& context = Context::Handle(closure.context()); | 96 const Context& context = Context::Handle(closure.context()); |
| 102 ASSERT(!function.IsNull()); | 97 ASSERT(!function.IsNull()); |
| 103 if (!function.HasCode()) { | 98 if (!function.HasCode()) { |
| 104 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 99 Compiler::CompileFunction(function); |
| 105 if (!error.IsNull()) { | |
| 106 return error.raw(); | |
| 107 } | |
| 108 } | 100 } |
| 109 const Code& code = Code::Handle(function.code()); | 101 const Code& code = Code::Handle(function.code()); |
| 110 ASSERT(!code.IsNull()); | 102 ASSERT(!code.IsNull()); |
| 111 const Instructions& instrs = Instructions::Handle(code.instructions()); | 103 const Instructions& instrs = Instructions::Handle(code.instructions()); |
| 112 ASSERT(!instrs.IsNull()); | 104 ASSERT(!instrs.IsNull()); |
| 113 | 105 |
| 114 // Now Call the invoke stub which will invoke the closure. | 106 // Now Call the invoke stub which will invoke the closure. |
| 115 invokestub entrypoint = reinterpret_cast<invokestub>( | 107 invokestub entrypoint = reinterpret_cast<invokestub>( |
| 116 StubCode::InvokeDartCodeEntryPoint()); | 108 StubCode::InvokeDartCodeEntryPoint()); |
| 117 ASSERT(context.isolate() == Isolate::Current()); | 109 ASSERT(context.isolate() == Isolate::Current()); |
| 118 return entrypoint( | 110 return entrypoint( |
| 119 instrs.EntryPoint(), | 111 instrs.EntryPoint(), |
| 120 CodeGenerator::ArgumentsDescriptor(arguments.length(), | 112 CodeGenerator::ArgumentsDescriptor(arguments.length(), |
| 121 optional_arguments_names), | 113 optional_arguments_names), |
| 122 arguments.data(), | 114 arguments.data(), |
| 123 context); | 115 context); |
| 124 } | 116 } |
| 125 | 117 |
| 126 | 118 |
| 127 RawObject* DartLibraryCalls::ExceptionCreate( | 119 RawInstance* DartLibraryCalls::ExceptionCreate( |
| 128 const String& class_name, | 120 const String& class_name, |
| 129 const GrowableArray<const Object*>& arguments) { | 121 const GrowableArray<const Object*>& arguments) { |
| 130 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 122 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 131 const Class& cls = Class::Handle(core_lib.LookupClass(class_name)); | 123 const Class& cls = Class::Handle(core_lib.LookupClass(class_name)); |
| 132 ASSERT(!cls.IsNull()); | 124 ASSERT(!cls.IsNull()); |
| 133 // For now, we only support a non-parameterized or raw type. | 125 // For now, we only support a non-parameterized or raw type. |
| 134 const Instance& exception_object = Instance::Handle(Instance::New(cls)); | 126 const Instance& exception_object = Instance::Handle(Instance::New(cls)); |
| 135 GrowableArray<const Object*> constructor_arguments(arguments.length() + 2); | 127 GrowableArray<const Object*> constructor_arguments(arguments.length() + 2); |
| 136 constructor_arguments.Add(&exception_object); | 128 constructor_arguments.Add(&exception_object); |
| 137 constructor_arguments.Add(&Smi::Handle(Smi::New(Function::kCtorPhaseAll))); | 129 constructor_arguments.Add(&Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
| 138 constructor_arguments.AddArray(arguments); | 130 constructor_arguments.AddArray(arguments); |
| 139 | 131 |
| 140 const String& period = String::Handle(String::New(".")); | 132 const String& period = String::Handle(String::New(".")); |
| 141 String& constructor_name = String::Handle(String::Concat(class_name, period)); | 133 String& constructor_name = String::Handle(String::Concat(class_name, period)); |
| 142 Function& constructor = | 134 Function& constructor = |
| 143 Function::Handle(cls.LookupConstructor(constructor_name)); | 135 Function::Handle(cls.LookupConstructor(constructor_name)); |
| 144 ASSERT(!constructor.IsNull()); | 136 ASSERT(!constructor.IsNull()); |
| 145 const Array& kNoArgumentNames = Array::Handle(); | 137 const Array& kNoArgumentNames = Array::Handle(); |
| 146 const Object& retval = Object::Handle( | 138 DartEntry::InvokeStatic(constructor, constructor_arguments, kNoArgumentNames); |
| 147 DartEntry::InvokeStatic(constructor, constructor_arguments, | |
| 148 kNoArgumentNames)); | |
| 149 ASSERT(retval.IsNull() || retval.IsError()); | |
| 150 if (retval.IsError()) { | |
| 151 return retval.raw(); | |
| 152 } | |
| 153 return exception_object.raw(); | 139 return exception_object.raw(); |
| 154 } | 140 } |
| 155 | 141 |
| 156 | 142 |
| 157 RawObject* DartLibraryCalls::ToString(const Instance& receiver) { | 143 RawInstance* DartLibraryCalls::ToString(const Instance& receiver) { |
| 158 const String& function_name = | 144 const String& function_name = |
| 159 String::Handle(String::NewSymbol("toString")); | 145 String::Handle(String::NewSymbol("toString")); |
| 160 GrowableArray<const Object*> arguments; | 146 GrowableArray<const Object*> arguments; |
| 161 const int kNumArguments = 1; // Receiver. | 147 const int kNumArguments = 1; // Receiver. |
| 162 const int kNumNamedArguments = 0; // None. | 148 const int kNumNamedArguments = 0; // None. |
| 163 const Array& kNoArgumentNames = Array::Handle(); | 149 const Array& kNoArgumentNames = Array::Handle(); |
| 164 const Function& function = Function::Handle( | 150 const Function& function = Function::Handle( |
| 165 Resolver::ResolveDynamic(receiver, | 151 Resolver::ResolveDynamic(receiver, |
| 166 function_name, | 152 function_name, |
| 167 kNumArguments, | 153 kNumArguments, |
| 168 kNumNamedArguments)); | 154 kNumNamedArguments)); |
| 169 ASSERT(!function.IsNull()); | 155 ASSERT(!function.IsNull()); |
| 170 const Object& result = Object::Handle( | 156 const Instance& result = Instance::Handle( |
| 171 DartEntry::InvokeDynamic(receiver, | 157 DartEntry::InvokeDynamic(receiver, |
| 172 function, | 158 function, |
| 173 arguments, | 159 arguments, |
| 174 kNoArgumentNames)); | 160 kNoArgumentNames)); |
| 175 ASSERT(result.IsInstance() || result.IsError()); | 161 // Object's 'toString' threw an exception, let the caller handle it. |
| 162 ASSERT(result.IsString() || result.IsUnhandledException()); |
| 176 return result.raw(); | 163 return result.raw(); |
| 177 } | 164 } |
| 178 | 165 |
| 179 | 166 |
| 180 RawObject* DartLibraryCalls::Equals(const Instance& left, | 167 RawInstance* DartLibraryCalls::Equals(const Instance& left, |
| 181 const Instance& right) { | 168 const Instance& right) { |
| 182 const String& function_name = | 169 const String& function_name = |
| 183 String::Handle(String::NewSymbol("==")); | 170 String::Handle(String::NewSymbol("==")); |
| 184 GrowableArray<const Object*> arguments; | 171 GrowableArray<const Object*> arguments; |
| 185 arguments.Add(&right); | 172 arguments.Add(&right); |
| 186 const int kNumArguments = 2; | 173 const int kNumArguments = 2; |
| 187 const int kNumNamedArguments = 0; | 174 const int kNumNamedArguments = 0; |
| 188 const Array& kNoArgumentNames = Array::Handle(); | 175 const Array& kNoArgumentNames = Array::Handle(); |
| 189 const Function& function = Function::Handle( | 176 const Function& function = Function::Handle( |
| 190 Resolver::ResolveDynamic(left, | 177 Resolver::ResolveDynamic(left, |
| 191 function_name, | 178 function_name, |
| 192 kNumArguments, | 179 kNumArguments, |
| 193 kNumNamedArguments)); | 180 kNumNamedArguments)); |
| 194 ASSERT(!function.IsNull()); | 181 ASSERT(!function.IsNull()); |
| 195 const Object& result = Object::Handle( | 182 const Instance& result = Instance::Handle( |
| 196 DartEntry::InvokeDynamic(left, function, arguments, kNoArgumentNames)); | 183 DartEntry::InvokeDynamic(left, function, arguments, kNoArgumentNames)); |
| 197 ASSERT(result.IsInstance() || result.IsError()); | 184 // Object's '==' threw an exception, let the caller handle it. |
| 185 ASSERT(result.IsBool() || result.IsUnhandledException()); |
| 198 return result.raw(); | 186 return result.raw(); |
| 199 } | 187 } |
| 200 | 188 |
| 201 | 189 |
| 202 RawObject* DartLibraryCalls::HandleMessage(Dart_Port dest_port_id, | 190 RawObject* DartLibraryCalls::HandleMessage(Dart_Port dest_port_id, |
| 203 Dart_Port reply_port_id, | 191 Dart_Port reply_port_id, |
| 204 const Instance& message) { | 192 const Instance& message) { |
| 205 const String& class_name = | 193 const String& class_name = |
| 206 String::Handle(String::NewSymbol("ReceivePortImpl")); | 194 String::Handle(String::NewSymbol("ReceivePortImpl")); |
| 207 const String& function_name = | 195 const String& function_name = |
| 208 String::Handle(String::NewSymbol("_handleMessage")); | 196 String::Handle(String::NewSymbol("_handleMessage")); |
| 209 const int kNumArguments = 3; | 197 const int kNumArguments = 3; |
| 210 const Array& kNoArgumentNames = Array::Handle(); | 198 const Array& kNoArgumentNames = Array::Handle(); |
| 211 const Function& function = Function::Handle( | 199 const Function& function = Function::Handle( |
| 212 Resolver::ResolveStatic(Library::Handle(Library::CoreLibrary()), | 200 Resolver::ResolveStatic(Library::Handle(Library::CoreLibrary()), |
| 213 class_name, | 201 class_name, |
| 214 function_name, | 202 function_name, |
| 215 kNumArguments, | 203 kNumArguments, |
| 216 kNoArgumentNames, | 204 kNoArgumentNames, |
| 217 Resolver::kIsQualified)); | 205 Resolver::kIsQualified)); |
| 218 GrowableArray<const Object*> arguments(kNumArguments); | 206 GrowableArray<const Object*> arguments(kNumArguments); |
| 219 arguments.Add(&Integer::Handle(Integer::New(dest_port_id))); | 207 arguments.Add(&Integer::Handle(Integer::New(dest_port_id))); |
| 220 arguments.Add(&Integer::Handle(Integer::New(reply_port_id))); | 208 arguments.Add(&Integer::Handle(Integer::New(reply_port_id))); |
| 221 arguments.Add(&message); | 209 arguments.Add(&message); |
| 222 const Object& result = Object::Handle( | 210 const Object& result = Object::Handle( |
| 223 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); | 211 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); |
| 224 ASSERT(result.IsNull() || result.IsError()); | 212 ASSERT(result.IsNull() || result.IsUnhandledException()); |
| 225 return result.raw(); | 213 return result.raw(); |
| 226 } | 214 } |
| 227 | 215 |
| 228 } // namespace dart | 216 } // namespace dart |
| OLD | NEW |