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

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

Issue 13452007: Add new Dart API call Dart_MakeIsolateRunnable(). This would allow an (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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
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 24 matching lines...) Expand all
35 intptr_t port_id_; 35 intptr_t port_id_;
36 }; 36 };
37 37
38 38
39 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { 39 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
40 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); 40 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
41 return reinterpret_cast<uint8_t*>(new_ptr); 41 return reinterpret_cast<uint8_t*>(new_ptr);
42 } 42 }
43 43
44 44
45 static void StoreError(Isolate* isolate, const Object& obj) {
46 ASSERT(obj.IsError());
47 isolate->object_store()->set_sticky_error(Error::Cast(obj));
48 }
49
50
51 // TODO(turnidge): Move to DartLibraryCalls. 45 // TODO(turnidge): Move to DartLibraryCalls.
52 static RawObject* ReceivePortCreate(intptr_t port_id) { 46 static RawObject* ReceivePortCreate(intptr_t port_id) {
53 Isolate* isolate = Isolate::Current(); 47 Isolate* isolate = Isolate::Current();
54 Function& func = 48 Function& func =
55 Function::Handle(isolate, 49 Function::Handle(isolate,
56 isolate->object_store()->receive_port_create_function()); 50 isolate->object_store()->receive_port_create_function());
57 const int kNumArguments = 1; 51 const int kNumArguments = 1;
58 if (func.IsNull()) { 52 if (func.IsNull()) {
59 Library& isolate_lib = Library::Handle(Library::IsolateLibrary()); 53 Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
60 ASSERT(!isolate_lib.IsNull()); 54 ASSERT(!isolate_lib.IsNull());
(...skipping 14 matching lines...) Expand all
75 args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id))); 69 args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id)));
76 const Object& result = 70 const Object& result =
77 Object::Handle(isolate, DartEntry::InvokeFunction(func, args)); 71 Object::Handle(isolate, DartEntry::InvokeFunction(func, args));
78 if (!result.IsError()) { 72 if (!result.IsError()) {
79 PortMap::SetLive(port_id); 73 PortMap::SetLive(port_id);
80 } 74 }
81 return result.raw(); 75 return result.raw();
82 } 76 }
83 77
84 78
85 static void ShutdownIsolate(uword parameter) {
86 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
87 {
88 // Print the error if there is one. This may execute dart code to
89 // print the exception object, so we need to use a StartIsolateScope.
90 StartIsolateScope start_scope(isolate);
91 StackZone zone(isolate);
92 HandleScope handle_scope(isolate);
93 Error& error = Error::Handle();
94 error = isolate->object_store()->sticky_error();
95 if (!error.IsNull()) {
96 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
97 }
98 }
99 {
100 // Shut the isolate down.
101 SwitchIsolateScope switch_scope(isolate);
102 Dart::ShutdownIsolate();
103 }
104 }
105
106
107 static char* GetRootScriptUri(Isolate* isolate) {
108 const Library& library =
109 Library::Handle(isolate->object_store()->root_library());
110 ASSERT(!library.IsNull());
111 const String& script_name = String::Handle(library.url());
112 return isolate->current_zone()->MakeCopyOfString(script_name.ToCString());
113 }
114
115
116 DEFINE_NATIVE_ENTRY(ReceivePortImpl_factory, 1) { 79 DEFINE_NATIVE_ENTRY(ReceivePortImpl_factory, 1) {
117 ASSERT(AbstractTypeArguments::CheckedHandle( 80 ASSERT(AbstractTypeArguments::CheckedHandle(
118 arguments->NativeArgAt(0)).IsNull()); 81 arguments->NativeArgAt(0)).IsNull());
119 intptr_t port_id = 82 intptr_t port_id =
120 PortMap::CreatePort(arguments->isolate()->message_handler()); 83 PortMap::CreatePort(arguments->isolate()->message_handler());
121 const Object& port = Object::Handle(ReceivePortCreate(port_id)); 84 const Object& port = Object::Handle(ReceivePortCreate(port_id));
122 if (port.IsError()) { 85 if (port.IsError()) {
123 Exceptions::PropagateError(Error::Cast(port)); 86 Exceptions::PropagateError(Error::Cast(port));
124 } 87 }
125 return port.raw(); 88 return port.raw();
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 Dart_ExitScope(); 158 Dart_ExitScope();
196 } else { 159 } else {
197 *error = zone->PrintToString( 160 *error = zone->PrintToString(
198 "Unable to canonicalize uri '%s': no library tag handler found.", 161 "Unable to canonicalize uri '%s': no library tag handler found.",
199 uri.ToCString()); 162 uri.ToCString());
200 } 163 }
201 return retval; 164 return retval;
202 } 165 }
203 166
204 167
205 class SpawnState { 168 static bool CreateIsolate(IsolateSpawnState* state, char** error) {
206 public:
207 SpawnState(const Function& func, const Function& callback_func)
208 : isolate_(NULL),
209 script_url_(NULL),
210 library_url_(NULL),
211 function_name_(NULL),
212 exception_callback_name_(NULL) {
213 script_url_ = strdup(GetRootScriptUri(Isolate::Current()));
214 const Class& cls = Class::Handle(func.Owner());
215 ASSERT(cls.IsTopLevel());
216 const Library& lib = Library::Handle(cls.library());
217 const String& lib_url = String::Handle(lib.url());
218 library_url_ = strdup(lib_url.ToCString());
219
220 const String& func_name = String::Handle(func.name());
221 function_name_ = strdup(func_name.ToCString());
222 if (!callback_func.IsNull()) {
223 const String& callback_name = String::Handle(callback_func.name());
224 exception_callback_name_ = strdup(callback_name.ToCString());
225 } else {
226 exception_callback_name_ = strdup("_unhandledExceptionCallback");
227 }
228 }
229
230 explicit SpawnState(const char* script_url)
231 : isolate_(NULL),
232 library_url_(NULL),
233 function_name_(NULL),
234 exception_callback_name_(NULL) {
235 script_url_ = strdup(script_url);
236 library_url_ = NULL;
237 function_name_ = strdup("main");
238 exception_callback_name_ = strdup("_unhandledExceptionCallback");
239 }
240
241 ~SpawnState() {
242 free(script_url_);
243 free(library_url_);
244 free(function_name_);
245 free(exception_callback_name_);
246 }
247
248 Isolate* isolate() const { return isolate_; }
249 void set_isolate(Isolate* value) { isolate_ = value; }
250 char* script_url() const { return script_url_; }
251 char* library_url() const { return library_url_; }
252 char* function_name() const { return function_name_; }
253 char* exception_callback_name() const { return exception_callback_name_; }
254
255 RawObject* ResolveFunction() {
256 // Resolve the library.
257 Library& lib = Library::Handle();
258 if (library_url()) {
259 const String& lib_url = String::Handle(String::New(library_url()));
260 lib = Library::LookupLibrary(lib_url);
261 if (lib.IsNull() || lib.IsError()) {
262 const String& msg = String::Handle(String::NewFormatted(
263 "Unable to find library '%s'.", library_url()));
264 return LanguageError::New(msg);
265 }
266 } else {
267 lib = isolate()->object_store()->root_library();
268 }
269 ASSERT(!lib.IsNull());
270
271 // Resolve the function.
272 const String& func_name =
273 String::Handle(String::New(function_name()));
274 const Function& func = Function::Handle(lib.LookupLocalFunction(func_name));
275 if (func.IsNull()) {
276 const String& msg = String::Handle(String::NewFormatted(
277 "Unable to resolve function '%s' in library '%s'.",
278 function_name(), (library_url() ? library_url() : script_url())));
279 return LanguageError::New(msg);
280 }
281 return func.raw();
282 }
283
284 void Cleanup() {
285 SwitchIsolateScope switch_scope(isolate());
286 Dart::ShutdownIsolate();
287 }
288
289 private:
290 Isolate* isolate_;
291 char* script_url_;
292 char* library_url_;
293 char* function_name_;
294 char* exception_callback_name_;
295 };
296
297
298 static bool CreateIsolate(SpawnState* state, char** error) {
299 Isolate* parent_isolate = Isolate::Current(); 169 Isolate* parent_isolate = Isolate::Current();
300 170
301 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); 171 Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
302 if (callback == NULL) { 172 if (callback == NULL) {
303 *error = strdup("Null callback specified for isolate creation\n"); 173 *error = strdup("Null callback specified for isolate creation\n");
304 Isolate::SetCurrent(parent_isolate); 174 Isolate::SetCurrent(parent_isolate);
305 return false; 175 return false;
306 } 176 }
307 177
308 void* init_data = parent_isolate->init_callback_data(); 178 void* init_data = parent_isolate->init_callback_data();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 child_isolate->object_store()-> 210 child_isolate->object_store()->
341 set_unhandled_exception_handler(callback_name); 211 set_unhandled_exception_handler(callback_name);
342 } 212 }
343 } 213 }
344 if (resolve_error) { 214 if (resolve_error) {
345 Dart::ShutdownIsolate(); 215 Dart::ShutdownIsolate();
346 Isolate::SetCurrent(parent_isolate); 216 Isolate::SetCurrent(parent_isolate);
347 return false; 217 return false;
348 } 218 }
349 219
220 child_isolate->set_spawn_data(reinterpret_cast<uword>(state));
350 Isolate::SetCurrent(parent_isolate); 221 Isolate::SetCurrent(parent_isolate);
351 return true; 222 return true;
352 } 223 }
353 224
354 225
355 static bool RunIsolate(uword parameter) { 226 static RawObject* Spawn(NativeArguments* arguments, IsolateSpawnState* state) {
356 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
357 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data());
358 isolate->set_spawn_data(0);
359 {
360 StartIsolateScope start_scope(isolate);
361 StackZone zone(isolate);
362 HandleScope handle_scope(isolate);
363 if (!ClassFinalizer::FinalizePendingClasses()) {
364 // Error is in sticky error already.
365 return false;
366 }
367
368 Object& result = Object::Handle();
369 result = state->ResolveFunction();
370 delete state;
371 state = NULL;
372 if (result.IsError()) {
373 StoreError(isolate, result);
374 return false;
375 }
376 ASSERT(result.IsFunction());
377 Function& func = Function::Handle(isolate);
378 func ^= result.raw();
379 result = DartEntry::InvokeFunction(func, Object::empty_array());
380 if (result.IsError()) {
381 StoreError(isolate, result);
382 return false;
383 }
384 }
385 return true;
386 }
387
388
389 static RawObject* Spawn(NativeArguments* arguments, SpawnState* state) {
390 // Create a new isolate. 227 // Create a new isolate.
391 char* error = NULL; 228 char* error = NULL;
392 if (!CreateIsolate(state, &error)) { 229 if (!CreateIsolate(state, &error)) {
393 delete state; 230 delete state;
394 const String& msg = String::Handle(String::New(error)); 231 const String& msg = String::Handle(String::New(error));
395 free(error); 232 free(error);
396 ThrowIsolateSpawnException(msg); 233 ThrowIsolateSpawnException(msg);
397 } 234 }
398 235
399 // Try to create a SendPort for the new isolate. 236 // Try to create a SendPort for the new isolate.
400 const Object& port = Object::Handle( 237 const Object& port = Object::Handle(
401 DartLibraryCalls::NewSendPort(state->isolate()->main_port())); 238 DartLibraryCalls::NewSendPort(state->isolate()->main_port()));
402 if (port.IsError()) { 239 if (port.IsError()) {
403 state->Cleanup(); 240 state->Cleanup();
404 delete state; 241 delete state;
405 Exceptions::PropagateError(Error::Cast(port)); 242 Exceptions::PropagateError(Error::Cast(port));
406 } 243 }
407 244
408 // Start the new isolate. 245 // Start the new isolate if it is already marked as runnable.
409 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); 246 if (state->isolate()->is_runnable()) {
410 state->isolate()->message_handler()->Run( 247 state->isolate()->Run();
411 Dart::thread_pool(), RunIsolate, ShutdownIsolate, 248 }
412 reinterpret_cast<uword>(state->isolate()));
413 249
414 return port.raw(); 250 return port.raw();
415 } 251 }
416 252
417 253
418 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 2) { 254 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 2) {
419 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); 255 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
420 bool throw_exception = false; 256 bool throw_exception = false;
421 Function& func = Function::Handle(); 257 Function& func = Function::Handle();
422 if (closure.IsClosure()) { 258 if (closure.IsClosure()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 #if defined(DEBUG) 293 #if defined(DEBUG)
458 Context& ctx = Context::Handle(); 294 Context& ctx = Context::Handle();
459 ctx = Closure::context(closure); 295 ctx = Closure::context(closure);
460 ASSERT(ctx.num_variables() == 0); 296 ASSERT(ctx.num_variables() == 0);
461 if (!callback.IsNull()) { 297 if (!callback.IsNull()) {
462 ctx = Closure::context(callback); 298 ctx = Closure::context(callback);
463 ASSERT(ctx.num_variables() == 0); 299 ASSERT(ctx.num_variables() == 0);
464 } 300 }
465 #endif 301 #endif
466 302
467 return Spawn(arguments, new SpawnState(func, callback_func)); 303 return Spawn(arguments, new IsolateSpawnState(func, callback_func));
468 } 304 }
469 305
470 306
471 DEFINE_NATIVE_ENTRY(isolate_spawnUri, 1) { 307 DEFINE_NATIVE_ENTRY(isolate_spawnUri, 1) {
472 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0)); 308 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0));
473 309
474 // Canonicalize the uri with respect to the current isolate. 310 // Canonicalize the uri with respect to the current isolate.
475 char* error = NULL; 311 char* error = NULL;
476 char* canonical_uri = NULL; 312 char* canonical_uri = NULL;
477 const Library& root_lib = 313 const Library& root_lib =
478 Library::Handle(arguments->isolate()->object_store()->root_library()); 314 Library::Handle(arguments->isolate()->object_store()->root_library());
479 if (!CanonicalizeUri(arguments->isolate(), root_lib, uri, 315 if (!CanonicalizeUri(arguments->isolate(), root_lib, uri,
480 &canonical_uri, &error)) { 316 &canonical_uri, &error)) {
481 const String& msg = String::Handle(String::New(error)); 317 const String& msg = String::Handle(String::New(error));
482 ThrowIsolateSpawnException(msg); 318 ThrowIsolateSpawnException(msg);
483 } 319 }
484 320
485 return Spawn(arguments, new SpawnState(canonical_uri)); 321 return Spawn(arguments, new IsolateSpawnState(canonical_uri));
486 } 322 }
487 323
488 324
489 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { 325 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) {
490 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); 326 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port()));
491 if (port.IsError()) { 327 if (port.IsError()) {
492 Exceptions::PropagateError(Error::Cast(port)); 328 Exceptions::PropagateError(Error::Cast(port));
493 } 329 }
494 return port.raw(); 330 return port.raw();
495 } 331 }
496 332
497 } // namespace dart 333 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698