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