Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 *error = zone->PrintToString("Unable to canonicalize uri '%s': " | 195 *error = zone->PrintToString("Unable to canonicalize uri '%s': " |
| 196 "library tag handler returned wrong type", | 196 "library tag handler returned wrong type", |
| 197 uri.ToCString()); | 197 uri.ToCString()); |
| 198 return false; | 198 return false; |
| 199 } | 199 } |
| 200 } | 200 } |
| 201 | 201 |
| 202 | 202 |
| 203 class SpawnState { | 203 class SpawnState { |
| 204 public: | 204 public: |
| 205 explicit SpawnState(const Function& func) | 205 SpawnState(const Function& func, const Function& callback_func) |
| 206 : isolate_(NULL), | 206 : isolate_(NULL), |
| 207 script_url_(NULL), | 207 script_url_(NULL), |
| 208 library_url_(NULL), | 208 library_url_(NULL), |
| 209 function_name_(NULL) { | 209 function_name_(NULL), |
| 210 exception_callback_name_(NULL) { | |
| 210 script_url_ = strdup(GetRootScriptUri(Isolate::Current())); | 211 script_url_ = strdup(GetRootScriptUri(Isolate::Current())); |
| 211 const Class& cls = Class::Handle(func.Owner()); | 212 const Class& cls = Class::Handle(func.Owner()); |
| 212 ASSERT(cls.IsTopLevel()); | 213 ASSERT(cls.IsTopLevel()); |
| 213 const Library& lib = Library::Handle(cls.library()); | 214 const Library& lib = Library::Handle(cls.library()); |
| 214 const String& lib_url = String::Handle(lib.url()); | 215 const String& lib_url = String::Handle(lib.url()); |
| 215 library_url_ = strdup(lib_url.ToCString()); | 216 library_url_ = strdup(lib_url.ToCString()); |
| 216 | 217 |
| 217 const String& func_name = String::Handle(func.name()); | 218 const String& func_name = String::Handle(func.name()); |
| 218 function_name_ = strdup(func_name.ToCString()); | 219 function_name_ = strdup(func_name.ToCString()); |
| 220 if (!callback_func.IsNull()) { | |
| 221 const String& callback_name = String::Handle(callback_func.name()); | |
| 222 exception_callback_name_ = strdup(callback_name.ToCString()); | |
| 223 } else { | |
| 224 exception_callback_name_ = strdup("_unhandledExceptionCallback"); | |
| 225 } | |
| 219 } | 226 } |
| 220 | 227 |
| 221 explicit SpawnState(const char* script_url) | 228 explicit SpawnState(const char* script_url) |
| 222 : isolate_(NULL), | 229 : isolate_(NULL), |
| 223 library_url_(NULL), | 230 library_url_(NULL), |
| 224 function_name_(NULL) { | 231 function_name_(NULL), |
| 232 exception_callback_name_(NULL) { | |
| 225 script_url_ = strdup(script_url); | 233 script_url_ = strdup(script_url); |
| 226 library_url_ = NULL; | 234 library_url_ = NULL; |
| 227 function_name_ = strdup("main"); | 235 function_name_ = strdup("main"); |
| 236 exception_callback_name_ = strdup("_unhandledExceptionCallback"); | |
| 228 } | 237 } |
| 229 | 238 |
| 230 ~SpawnState() { | 239 ~SpawnState() { |
| 231 free(script_url_); | 240 free(script_url_); |
| 232 free(library_url_); | 241 free(library_url_); |
| 233 free(function_name_); | 242 free(function_name_); |
| 243 free(exception_callback_name_); | |
| 234 } | 244 } |
| 235 | 245 |
| 236 Isolate* isolate() const { return isolate_; } | 246 Isolate* isolate() const { return isolate_; } |
| 237 void set_isolate(Isolate* value) { isolate_ = value; } | 247 void set_isolate(Isolate* value) { isolate_ = value; } |
| 238 char* script_url() const { return script_url_; } | 248 char* script_url() const { return script_url_; } |
| 239 char* library_url() const { return library_url_; } | 249 char* library_url() const { return library_url_; } |
| 240 char* function_name() const { return function_name_; } | 250 char* function_name() const { return function_name_; } |
| 251 char* exception_callback_name() const { return exception_callback_name_; } | |
| 241 | 252 |
| 242 RawObject* ResolveFunction() { | 253 RawObject* ResolveFunction() { |
| 243 // Resolve the library. | 254 // Resolve the library. |
| 244 Library& lib = Library::Handle(); | 255 Library& lib = Library::Handle(); |
| 245 if (library_url()) { | 256 if (library_url()) { |
| 246 const String& lib_url = String::Handle(String::New(library_url())); | 257 const String& lib_url = String::Handle(String::New(library_url())); |
| 247 lib = Library::LookupLibrary(lib_url); | 258 lib = Library::LookupLibrary(lib_url); |
| 248 if (lib.IsNull() || lib.IsError()) { | 259 if (lib.IsNull() || lib.IsError()) { |
| 249 const String& msg = String::Handle(String::NewFormatted( | 260 const String& msg = String::Handle(String::NewFormatted( |
| 250 "Unable to find library '%s'.", library_url())); | 261 "Unable to find library '%s'.", library_url())); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 271 void Cleanup() { | 282 void Cleanup() { |
| 272 SwitchIsolateScope switch_scope(isolate()); | 283 SwitchIsolateScope switch_scope(isolate()); |
| 273 Dart::ShutdownIsolate(); | 284 Dart::ShutdownIsolate(); |
| 274 } | 285 } |
| 275 | 286 |
| 276 private: | 287 private: |
| 277 Isolate* isolate_; | 288 Isolate* isolate_; |
| 278 char* script_url_; | 289 char* script_url_; |
| 279 char* library_url_; | 290 char* library_url_; |
| 280 char* function_name_; | 291 char* function_name_; |
| 292 char* exception_callback_name_; | |
| 281 }; | 293 }; |
| 282 | 294 |
| 283 | 295 |
| 284 static bool CreateIsolate(SpawnState* state, char** error) { | 296 static bool CreateIsolate(SpawnState* state, char** error) { |
| 285 Isolate* parent_isolate = Isolate::Current(); | 297 Isolate* parent_isolate = Isolate::Current(); |
| 286 | 298 |
| 287 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); | 299 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); |
| 288 if (callback == NULL) { | 300 if (callback == NULL) { |
| 289 *error = strdup("Null callback specified for isolate creation\n"); | 301 *error = strdup("Null callback specified for isolate creation\n"); |
| 290 Isolate::SetCurrent(parent_isolate); | 302 Isolate::SetCurrent(parent_isolate); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 312 bool resolve_error = false; | 324 bool resolve_error = false; |
| 313 { | 325 { |
| 314 StackZone zone(child_isolate); | 326 StackZone zone(child_isolate); |
| 315 HandleScope handle_scope(child_isolate); | 327 HandleScope handle_scope(child_isolate); |
| 316 const Object& result = Object::Handle(state->ResolveFunction()); | 328 const Object& result = Object::Handle(state->ResolveFunction()); |
| 317 if (result.IsError()) { | 329 if (result.IsError()) { |
| 318 Error& errobj = Error::Handle(); | 330 Error& errobj = Error::Handle(); |
| 319 errobj ^= result.raw(); | 331 errobj ^= result.raw(); |
| 320 *error = strdup(errobj.ToErrorCString()); | 332 *error = strdup(errobj.ToErrorCString()); |
| 321 resolve_error = true; | 333 resolve_error = true; |
| 334 } else { | |
| 335 const String& callback_name = | |
| 336 String::Handle(child_isolate, | |
| 337 String::New(state->exception_callback_name())); | |
| 338 child_isolate->object_store()-> | |
| 339 set_unhandled_exception_handler(callback_name); | |
| 322 } | 340 } |
| 323 } | 341 } |
| 324 if (resolve_error) { | 342 if (resolve_error) { |
| 325 Dart::ShutdownIsolate(); | 343 Dart::ShutdownIsolate(); |
| 326 Isolate::SetCurrent(parent_isolate); | 344 Isolate::SetCurrent(parent_isolate); |
| 327 return false; | 345 return false; |
| 328 } | 346 } |
| 329 | 347 |
| 330 Isolate::SetCurrent(parent_isolate); | 348 Isolate::SetCurrent(parent_isolate); |
| 331 return true; | 349 return true; |
| 332 } | 350 } |
| 333 | 351 |
| 334 | 352 |
| 335 static bool RunIsolate(uword parameter) { | 353 static bool RunIsolate(uword parameter) { |
| 336 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 354 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 337 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data()); | 355 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data()); |
| 338 isolate->set_spawn_data(0); | 356 isolate->set_spawn_data(0); |
| 339 { | 357 { |
| 340 StartIsolateScope start_scope(isolate); | 358 StartIsolateScope start_scope(isolate); |
| 341 StackZone zone(isolate); | 359 StackZone zone(isolate); |
| 342 HandleScope handle_scope(isolate); | 360 HandleScope handle_scope(isolate); |
| 343 if (!ClassFinalizer::FinalizePendingClasses()) { | 361 if (!ClassFinalizer::FinalizePendingClasses()) { |
| 344 // Error is in sticky error already. | 362 // Error is in sticky error already. |
| 345 return false; | 363 return false; |
| 346 } | 364 } |
| 365 | |
| 347 Object& result = Object::Handle(); | 366 Object& result = Object::Handle(); |
| 348 | |
| 349 result = state->ResolveFunction(); | 367 result = state->ResolveFunction(); |
| 350 delete state; | 368 delete state; |
| 351 state = NULL; | 369 state = NULL; |
| 352 if (result.IsError()) { | 370 if (result.IsError()) { |
| 353 StoreError(isolate, result); | 371 StoreError(isolate, result); |
| 354 return false; | 372 return false; |
| 355 } | 373 } |
| 356 ASSERT(result.IsFunction()); | 374 ASSERT(result.IsFunction()); |
| 357 Function& func = Function::Handle(isolate); | 375 Function& func = Function::Handle(isolate); |
| 358 func ^= result.raw(); | 376 func ^= result.raw(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 // Start the new isolate. | 408 // Start the new isolate. |
| 391 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); | 409 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); |
| 392 state->isolate()->message_handler()->Run( | 410 state->isolate()->message_handler()->Run( |
| 393 Dart::thread_pool(), RunIsolate, ShutdownIsolate, | 411 Dart::thread_pool(), RunIsolate, ShutdownIsolate, |
| 394 reinterpret_cast<uword>(state->isolate())); | 412 reinterpret_cast<uword>(state->isolate())); |
| 395 | 413 |
| 396 return port.raw(); | 414 return port.raw(); |
| 397 } | 415 } |
| 398 | 416 |
| 399 | 417 |
| 400 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) { | 418 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 2) { |
| 401 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); | 419 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); |
| 402 bool throw_exception = false; | 420 bool throw_exception = false; |
| 403 Function& func = Function::Handle(); | 421 Function& func = Function::Handle(); |
| 404 if (closure.IsClosure()) { | 422 if (closure.IsClosure()) { |
| 405 func ^= Closure::function(closure); | 423 func ^= Closure::function(closure); |
| 406 const Class& cls = Class::Handle(func.Owner()); | 424 const Class& cls = Class::Handle(func.Owner()); |
| 407 if (!func.IsClosureFunction() || !func.is_static() || !cls.IsTopLevel()) { | 425 if (!func.IsClosureFunction() || !func.is_static() || !cls.IsTopLevel()) { |
| 408 throw_exception = true; | 426 throw_exception = true; |
| 409 } | 427 } |
| 410 } else { | 428 } else { |
| 411 throw_exception = true; | 429 throw_exception = true; |
| 412 } | 430 } |
| 413 if (throw_exception) { | 431 if (throw_exception) { |
| 414 const String& msg = String::Handle(String::New( | 432 const String& msg = String::Handle(String::New( |
| 415 "spawnFunction expects to be passed a closure to a top-level static " | 433 "spawnFunction expects to be passed a closure to a top-level static " |
| 416 "function")); | 434 "function")); |
| 417 ThrowIllegalArgException(msg); | 435 ThrowIllegalArgException(msg); |
| 418 } | 436 } |
| 419 | 437 |
| 438 GET_NATIVE_ARGUMENT(Instance, callback, arguments->NativeArgAt(1)); | |
| 439 Function& callback_func = Function::Handle(); | |
| 440 if (callback.IsClosure()) { | |
| 441 callback_func ^= Closure::function(callback); | |
| 442 const Class& cls = Class::Handle(callback_func.Owner()); | |
| 443 if (!callback_func.IsClosureFunction() || !callback_func.is_static() || | |
| 444 !cls.IsTopLevel()) { | |
| 445 throw_exception = true; | |
| 446 } | |
| 447 } else if (!callback.IsNull()) { | |
| 448 throw_exception = true; | |
| 449 } | |
| 450 if (throw_exception) { | |
| 451 const String& msg = String::Handle(String::New( | |
| 452 "spawnFunction expects to be passed either a unhandled exception " | |
| 453 "callback to a top-level static function, or null")); | |
| 454 ThrowIllegalArgException(msg); | |
| 455 } | |
| 456 | |
| 420 #if defined(DEBUG) | 457 #if defined(DEBUG) |
| 421 const Context& ctx = Context::Handle(Closure::context(closure)); | 458 const Context& ctx = Context::Handle(Closure::context(closure)); |
| 422 ASSERT(ctx.num_variables() == 0); | 459 ASSERT(ctx.num_variables() == 0); |
| 460 ASSERT(callback_func.IsFunction() || callback_func.IsNull()); | |
|
siva
2012/12/14 06:28:36
I actually meant something like:
#if defined(DEBU
Tom Ball
2012/12/14 21:22:44
Done.
| |
| 423 #endif | 461 #endif |
| 424 | 462 |
| 425 return Spawn(arguments, new SpawnState(func)); | 463 return Spawn(arguments, new SpawnState(func, callback_func)); |
| 426 } | 464 } |
| 427 | 465 |
| 428 | 466 |
| 429 DEFINE_NATIVE_ENTRY(isolate_spawnUri, 1) { | 467 DEFINE_NATIVE_ENTRY(isolate_spawnUri, 1) { |
| 430 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0)); | 468 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0)); |
| 431 | 469 |
| 432 // Canonicalize the uri with respect to the current isolate. | 470 // Canonicalize the uri with respect to the current isolate. |
| 433 char* error = NULL; | 471 char* error = NULL; |
| 434 char* canonical_uri = NULL; | 472 char* canonical_uri = NULL; |
| 435 const Library& root_lib = | 473 const Library& root_lib = |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 447 | 485 |
| 448 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { | 486 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { |
| 449 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); | 487 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); |
| 450 if (port.IsError()) { | 488 if (port.IsError()) { |
| 451 Exceptions::PropagateError(Error::Cast(port)); | 489 Exceptions::PropagateError(Error::Cast(port)); |
| 452 } | 490 } |
| 453 return port.raw(); | 491 return port.raw(); |
| 454 } | 492 } |
| 455 | 493 |
| 456 } // namespace dart | 494 } // namespace dart |
| OLD | NEW |