Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(926)

Side by Side Diff: runtime/lib/isolate.cc

Issue 10837070: Remove old isolate API and update all code in the repository to use (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/isolate/isolate_compiler.dart ('k') | runtime/lib/isolate.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "platform/assert.h" 5 #include "platform/assert.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.h" 8 #include "vm/dart.h"
9 #include "vm/dart_api_impl.h" 9 #include "vm/dart_api_impl.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 53
54 static void StoreError(Isolate* isolate, const Object& obj) { 54 static void StoreError(Isolate* isolate, const Object& obj) {
55 ASSERT(obj.IsError()); 55 ASSERT(obj.IsError());
56 Error& error = Error::Handle(); 56 Error& error = Error::Handle();
57 error ^= obj.raw(); 57 error ^= obj.raw();
58 isolate->object_store()->set_sticky_error(error); 58 isolate->object_store()->set_sticky_error(error);
59 } 59 }
60 60
61 61
62 static void ThrowErrorException(Exceptions::ExceptionType type,
63 const char* error_msg,
64 const char* library_url,
65 const char* class_name) {
66 String& str = String::Handle();
67 String& name = String::Handle();
68 str ^= String::New(error_msg);
69 name ^= Symbols::New(library_url);
70 str ^= String::Concat(str, name);
71 name ^= String::New(":");
72 str ^= String::Concat(str, name);
73 name ^= Symbols::New(class_name);
74 str ^= String::Concat(str, name);
75 GrowableArray<const Object*> arguments(1);
76 arguments.Add(&str);
77 Exceptions::ThrowByType(type, arguments);
78 }
79
80
81 // TODO(turnidge): Move to DartLibraryCalls. 62 // TODO(turnidge): Move to DartLibraryCalls.
82 RawObject* ReceivePortCreate(intptr_t port_id) { 63 RawObject* ReceivePortCreate(intptr_t port_id) {
83 Library& isolate_lib = Library::Handle(Library::IsolateLibrary()); 64 Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
84 ASSERT(!isolate_lib.IsNull()); 65 ASSERT(!isolate_lib.IsNull());
85 const String& public_class_name = 66 const String& public_class_name =
86 String::Handle(Symbols::New("_ReceivePortImpl")); 67 String::Handle(Symbols::New("_ReceivePortImpl"));
87 const String& class_name = 68 const String& class_name =
88 String::Handle(isolate_lib.PrivateName(public_class_name)); 69 String::Handle(isolate_lib.PrivateName(public_class_name));
89 const String& function_name = 70 const String& function_name =
90 String::Handle(Symbols::New("_get_or_create")); 71 String::Handle(Symbols::New("_get_or_create"));
(...skipping 10 matching lines...) Expand all
101 arguments.Add(&Integer::Handle(Integer::New(port_id))); 82 arguments.Add(&Integer::Handle(Integer::New(port_id)));
102 const Object& result = Object::Handle( 83 const Object& result = Object::Handle(
103 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); 84 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames));
104 if (!result.IsError()) { 85 if (!result.IsError()) {
105 PortMap::SetLive(port_id); 86 PortMap::SetLive(port_id);
106 } 87 }
107 return result.raw(); 88 return result.raw();
108 } 89 }
109 90
110 91
111 static bool RunIsolate(uword parameter) {
112 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
113 IsolateStartData* data =
114 reinterpret_cast<IsolateStartData*>(isolate->spawn_data());
115 isolate->set_spawn_data(NULL);
116 char* library_url = data->library_url_;
117 char* class_name = data->class_name_;
118 intptr_t port_id = data->port_id_;
119 delete data;
120
121 {
122 StartIsolateScope start_scope(isolate);
123 Zone zone(isolate);
124 HandleScope handle_scope(isolate);
125 ASSERT(ClassFinalizer::AllClassesFinalized());
126 // Lookup the target class by name, create an instance and call the run
127 // method.
128 const String& lib_name = String::Handle(Symbols::New(library_url));
129 free(library_url);
130 const Library& lib = Library::Handle(Library::LookupLibrary(lib_name));
131 ASSERT(!lib.IsNull());
132 const String& cls_name = String::Handle(Symbols::New(class_name));
133 free(class_name);
134 const Class& target_class = Class::Handle(lib.LookupClass(cls_name));
135 // TODO(iposva): Deserialize or call the constructor after allocating.
136 // For now, we only support a non-parameterized or raw target class.
137 const Instance& target = Instance::Handle(Instance::New(target_class));
138 Object& result = Object::Handle();
139
140 // Invoke the default constructor.
141 const String& period = String::Handle(String::New("."));
142 String& constructor_name = String::Handle(String::Concat(cls_name, period));
143 const Function& default_constructor =
144 Function::Handle(target_class.LookupConstructor(constructor_name));
145 if (!default_constructor.IsNull()) {
146 GrowableArray<const Object*> arguments(1);
147 arguments.Add(&target);
148 arguments.Add(&Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
149 const Array& kNoArgumentNames = Array::Handle();
150 result = DartEntry::InvokeStatic(default_constructor,
151 arguments,
152 kNoArgumentNames);
153 if (result.IsError()) {
154 StoreError(isolate, result);
155 return false;
156 }
157 ASSERT(result.IsNull());
158 }
159
160 // Invoke the "_run" method.
161 const Function& target_function = Function::Handle(Resolver::ResolveDynamic(
162 target, String::Handle(Symbols::New("_run")), 2, 0));
163 // TODO(iposva): Proper error checking here.
164 ASSERT(!target_function.IsNull());
165 // TODO(iposva): Allocate the proper port number here.
166 const Object& local_port = Object::Handle(ReceivePortCreate(port_id));
167 if (local_port.IsError()) {
168 StoreError(isolate, local_port);
169 return false;
170 }
171 GrowableArray<const Object*> arguments(1);
172 arguments.Add(&local_port);
173 const Array& kNoArgumentNames = Array::Handle();
174 result = DartEntry::InvokeDynamic(target,
175 target_function,
176 arguments,
177 kNoArgumentNames);
178 if (result.IsError()) {
179 StoreError(isolate, result);
180 return false;
181 }
182 ASSERT(result.IsNull());
183 }
184 return true;
185 }
186
187
188 static void ShutdownIsolate(uword parameter) { 92 static void ShutdownIsolate(uword parameter) {
189 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); 93 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
190 { 94 {
191 // Print the error if there is one. This may execute dart code to 95 // Print the error if there is one. This may execute dart code to
192 // print the exception object, so we need to use a StartIsolateScope. 96 // print the exception object, so we need to use a StartIsolateScope.
193 StartIsolateScope start_scope(isolate); 97 StartIsolateScope start_scope(isolate);
194 Zone zone(isolate); 98 Zone zone(isolate);
195 HandleScope handle_scope(isolate); 99 HandleScope handle_scope(isolate);
196 Error& error = Error::Handle(); 100 Error& error = Error::Handle();
197 error = isolate->object_store()->sticky_error(); 101 error = isolate->object_store()->sticky_error();
198 if (!error.IsNull()) { 102 if (!error.IsNull()) {
199 OS::PrintErr("%s\n", error.ToErrorCString()); 103 OS::PrintErr("%s\n", error.ToErrorCString());
200 exit(255); 104 exit(255);
201 } 105 }
202 } 106 }
203 { 107 {
204 // Shut the isolate down. 108 // Shut the isolate down.
205 SwitchIsolateScope switch_scope(isolate); 109 SwitchIsolateScope switch_scope(isolate);
206 Dart::ShutdownIsolate(); 110 Dart::ShutdownIsolate();
207 } 111 }
208 } 112 }
209 113
210 114
211 static bool CheckArguments(const char* library_url, const char* class_name) {
212 Isolate* isolate = Isolate::Current();
213 Zone zone(isolate);
214 HandleScope handle_scope(isolate);
215 String& name = String::Handle();
216 if (!ClassFinalizer::FinalizePendingClasses()) {
217 return false;
218 }
219 // Lookup the target class by name, create an instance and call the run
220 // method.
221 name ^= Symbols::New(library_url);
222 const Library& lib = Library::Handle(Library::LookupLibrary(name));
223 if (lib.IsNull()) {
224 const String& error_str = String::Handle(
225 String::New("Error starting Isolate, library not loaded : "));
226 const Error& error = Error::Handle(LanguageError::New(error_str));
227 Isolate::Current()->object_store()->set_sticky_error(error);
228 return false;
229 }
230 name ^= Symbols::New(class_name);
231 const Class& target_class = Class::Handle(lib.LookupClass(name));
232 if (target_class.IsNull()) {
233 const String& error_str = String::Handle(
234 String::New("Error starting Isolate, class not loaded : "));
235 const Error& error = Error::Handle(LanguageError::New(error_str));
236 Isolate::Current()->object_store()->set_sticky_error(error);
237 return false;
238 }
239 return true; // No errors.
240 }
241
242
243 static char* GetRootScriptUri(Isolate* isolate) { 115 static char* GetRootScriptUri(Isolate* isolate) {
244 const Library& library = 116 const Library& library =
245 Library::Handle(isolate->object_store()->root_library()); 117 Library::Handle(isolate->object_store()->root_library());
246 ASSERT(!library.IsNull()); 118 ASSERT(!library.IsNull());
247 const String& script_name = String::Handle(library.url()); 119 const String& script_name = String::Handle(library.url());
248 return isolate->current_zone()->MakeCopyOfString(script_name.ToCString()); 120 return isolate->current_zone()->MakeCopyOfString(script_name.ToCString());
249 } 121 }
250 122
251 123
252 static char* BuildMainName(const char* class_name) {
253 intptr_t len = OS::SNPrint(NULL, 0, "%s.main", class_name) + 1;
254 char* chars = reinterpret_cast<char*>(
255 Isolate::Current()->current_zone()->Allocate(len));
256 OS::SNPrint(chars, len, "%s.main", class_name);
257 return chars;
258 }
259
260
261 DEFINE_NATIVE_ENTRY(IsolateNatives_start, 2) {
262 Isolate* preserved_isolate = Isolate::Current();
263 GET_NATIVE_ARGUMENT(Instance, runnable, arguments->At(0));
264 // arguments->At(1) unused.
265 const Class& runnable_class = Class::Handle(runnable.clazz());
266 const char* class_name = String::Handle(runnable_class.Name()).ToCString();
267 const Library& library = Library::Handle(runnable_class.library());
268 ASSERT(!library.IsNull());
269 const char* library_url = String::Handle(library.url()).ToCString();
270 intptr_t port_id = 0;
271 LongJump jump;
272 bool init_successful = true;
273 Isolate* spawned_isolate = NULL;
274 void* callback_data = preserved_isolate->init_callback_data();
275 char* error = NULL;
276 Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
277 const char* root_script_uri = GetRootScriptUri(preserved_isolate);
278 const char* main = BuildMainName(class_name);
279 if (callback == NULL) {
280 error = strdup("Null callback specified for isolate creation\n");
281 } else if (callback(root_script_uri, main, callback_data, &error)) {
282 spawned_isolate = Isolate::Current();
283 ASSERT(spawned_isolate != NULL);
284 // Check arguments to see if the specified library and classes are
285 // loaded, this check will throw an exception if they are not loaded.
286 if (init_successful && CheckArguments(library_url, class_name)) {
287 port_id = spawned_isolate->main_port();
288 spawned_isolate->set_spawn_data(
289 reinterpret_cast<uword>(
290 new IsolateStartData(strdup(library_url),
291 strdup(class_name),
292 port_id)));
293 Isolate::SetCurrent(NULL);
294 spawned_isolate->message_handler()->Run(
295 Dart::thread_pool(), RunIsolate, ShutdownIsolate,
296 reinterpret_cast<uword>(spawned_isolate));
297 } else {
298 // Error spawning the isolate, maybe due to initialization errors or
299 // errors while loading the application into spawned isolate, shut
300 // it down and report error.
301 // Make sure to grab the error message out of the isolate before it has
302 // been shutdown and to allocate it in the preserved isolates zone.
303 {
304 Zone zone(spawned_isolate);
305 HandleScope scope(spawned_isolate);
306 const Error& err_obj = Error::Handle(
307 spawned_isolate->object_store()->sticky_error());
308 error = strdup(err_obj.ToErrorCString());
309 }
310 Dart::ShutdownIsolate();
311 spawned_isolate = NULL;
312 }
313 }
314
315 // Switch back to the original isolate and return.
316 Isolate::SetCurrent(preserved_isolate);
317 if (spawned_isolate == NULL) {
318 // Unable to spawn isolate correctly, throw exception.
319 ThrowErrorException(Exceptions::kIllegalArgument,
320 error,
321 library_url,
322 class_name);
323 }
324
325 // TODO(turnidge): Move this code up before we launch the new
326 // thread. That way we won't have a thread hanging around that we
327 // can't talk to.
328 const Object& port = Object::Handle(DartLibraryCalls::NewSendPort(port_id));
329 if (port.IsError()) {
330 Exceptions::PropagateError(Error::Cast(port));
331 }
332 arguments->SetReturn(port);
333 }
334
335
336 DEFINE_NATIVE_ENTRY(ReceivePortImpl_factory, 1) { 124 DEFINE_NATIVE_ENTRY(ReceivePortImpl_factory, 1) {
337 ASSERT(AbstractTypeArguments::CheckedHandle(arguments->At(0)).IsNull()); 125 ASSERT(AbstractTypeArguments::CheckedHandle(arguments->At(0)).IsNull());
338 intptr_t port_id = 126 intptr_t port_id =
339 PortMap::CreatePort(arguments->isolate()->message_handler()); 127 PortMap::CreatePort(arguments->isolate()->message_handler());
340 const Object& port = Object::Handle(ReceivePortCreate(port_id)); 128 const Object& port = Object::Handle(ReceivePortCreate(port_id));
341 if (port.IsError()) { 129 if (port.IsError()) {
342 Exceptions::PropagateError(Error::Cast(port)); 130 Exceptions::PropagateError(Error::Cast(port));
343 } 131 }
344 arguments->SetReturn(port); 132 arguments->SetReturn(port);
345 } 133 }
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 char* script_url_; 281 char* script_url_;
494 char* library_url_; 282 char* library_url_;
495 char* function_name_; 283 char* function_name_;
496 }; 284 };
497 285
498 286
499 static bool CreateIsolate(SpawnState* state, char** error) { 287 static bool CreateIsolate(SpawnState* state, char** error) {
500 Isolate* parent_isolate = Isolate::Current(); 288 Isolate* parent_isolate = Isolate::Current();
501 289
502 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); 290 Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
503 ASSERT(callback != NULL); 291 if (callback == NULL) {
292 *error = strdup("Null callback specified for isolate creation\n");
293 Isolate::SetCurrent(parent_isolate);
294 return false;
295 }
296
504 void* init_data = parent_isolate->init_callback_data(); 297 void* init_data = parent_isolate->init_callback_data();
505 bool retval = (callback)(state->script_url(), 298 bool retval = (callback)(state->script_url(),
506 state->function_name(), 299 state->function_name(),
507 init_data, 300 init_data,
508 error); 301 error);
509 if (!retval) { 302 if (!retval) {
510 Isolate::SetCurrent(parent_isolate); 303 Isolate::SetCurrent(parent_isolate);
511 return false; 304 return false;
512 } 305 }
513 306
(...skipping 21 matching lines...) Expand all
535 Dart::ShutdownIsolate(); 328 Dart::ShutdownIsolate();
536 Isolate::SetCurrent(parent_isolate); 329 Isolate::SetCurrent(parent_isolate);
537 return false; 330 return false;
538 } 331 }
539 332
540 Isolate::SetCurrent(parent_isolate); 333 Isolate::SetCurrent(parent_isolate);
541 return true; 334 return true;
542 } 335 }
543 336
544 337
545 static bool RunIsolate2(uword parameter) { 338 static bool RunIsolate(uword parameter) {
546 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); 339 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
547 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data()); 340 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data());
548 isolate->set_spawn_data(NULL); 341 isolate->set_spawn_data(NULL);
549 { 342 {
550 StartIsolateScope start_scope(isolate); 343 StartIsolateScope start_scope(isolate);
551 Zone zone(isolate); 344 Zone zone(isolate);
552 HandleScope handle_scope(isolate); 345 HandleScope handle_scope(isolate);
553 if (!ClassFinalizer::FinalizePendingClasses()) { 346 if (!ClassFinalizer::FinalizePendingClasses()) {
554 // Error is in sticky error already. 347 // Error is in sticky error already.
555 return false; 348 return false;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 DartLibraryCalls::NewSendPort(state->isolate()->main_port())); 386 DartLibraryCalls::NewSendPort(state->isolate()->main_port()));
594 if (port.IsError()) { 387 if (port.IsError()) {
595 state->Cleanup(); 388 state->Cleanup();
596 delete state; 389 delete state;
597 Exceptions::PropagateError(Error::Cast(port)); 390 Exceptions::PropagateError(Error::Cast(port));
598 } 391 }
599 392
600 // Start the new isolate. 393 // Start the new isolate.
601 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); 394 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state));
602 state->isolate()->message_handler()->Run( 395 state->isolate()->message_handler()->Run(
603 Dart::thread_pool(), RunIsolate2, ShutdownIsolate, 396 Dart::thread_pool(), RunIsolate, ShutdownIsolate,
604 reinterpret_cast<uword>(state->isolate())); 397 reinterpret_cast<uword>(state->isolate()));
605 398
606 arguments->SetReturn(port); 399 arguments->SetReturn(port);
607 } 400 }
608 401
609 402
610 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) { 403 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) {
611 GET_NATIVE_ARGUMENT(Closure, closure, arguments->At(0)); 404 GET_NATIVE_ARGUMENT(Closure, closure, arguments->At(0));
612 const Function& func = Function::Handle(closure.function()); 405 const Function& func = Function::Handle(closure.function());
613 const Class& cls = Class::Handle(func.owner()); 406 const Class& cls = Class::Handle(func.owner());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 441
649 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { 442 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) {
650 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); 443 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port()));
651 if (port.IsError()) { 444 if (port.IsError()) {
652 Exceptions::PropagateError(Error::Cast(port)); 445 Exceptions::PropagateError(Error::Cast(port));
653 } 446 }
654 arguments->SetReturn(port); 447 arguments->SetReturn(port);
655 } 448 }
656 449
657 } // namespace dart 450 } // namespace dart
OLDNEW
« no previous file with comments | « lib/isolate/isolate_compiler.dart ('k') | runtime/lib/isolate.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698