Chromium Code Reviews| Index: runtime/lib/isolate.cc |
| =================================================================== |
| --- runtime/lib/isolate.cc (revision 16063) |
| +++ runtime/lib/isolate.cc (working copy) |
| @@ -202,11 +202,12 @@ |
| class SpawnState { |
| public: |
| - explicit SpawnState(const Function& func) |
| + 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
|
| : isolate_(NULL), |
| script_url_(NULL), |
| library_url_(NULL), |
| - function_name_(NULL) { |
| + function_name_(NULL), |
| + exception_callback_name_(NULL) { |
| script_url_ = strdup(GetRootScriptUri(Isolate::Current())); |
| const Class& cls = Class::Handle(func.Owner()); |
| ASSERT(cls.IsTopLevel()); |
| @@ -216,6 +217,12 @@ |
| const String& func_name = String::Handle(func.name()); |
| function_name_ = strdup(func_name.ToCString()); |
| + if (!callback_func.IsNull()) { |
| + const String& callback_name = String::Handle(callback_func.name()); |
| + exception_callback_name_ = strdup(callback_name.ToCString()); |
| + } else { |
| + exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
| + } |
| } |
| explicit SpawnState(const char* script_url) |
| @@ -225,12 +232,16 @@ |
| script_url_ = strdup(script_url); |
| library_url_ = NULL; |
| function_name_ = strdup("main"); |
| + exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
| } |
| ~SpawnState() { |
| free(script_url_); |
| free(library_url_); |
| free(function_name_); |
| + if (exception_callback_name_ != NULL) { |
|
siva
2012/12/13 18:30:38
Can exception_callback_name_ be NULL?
|
| + free(exception_callback_name_); |
| + } |
| } |
| Isolate* isolate() const { return isolate_; } |
| @@ -238,6 +249,7 @@ |
| char* script_url() const { return script_url_; } |
| char* library_url() const { return library_url_; } |
| char* function_name() const { return function_name_; } |
| + char* exception_callback_name() const { return exception_callback_name_; } |
| RawObject* ResolveFunction() { |
| // Resolve the library. |
| @@ -278,6 +290,7 @@ |
| char* script_url_; |
| char* library_url_; |
| char* function_name_; |
| + char* exception_callback_name_; |
| }; |
| @@ -320,6 +333,15 @@ |
| *error = strdup(errobj.ToErrorCString()); |
| resolve_error = true; |
| } |
| + |
| + if (!resolve_error) { |
| + StackZone zone(child_isolate); |
| + HandleScope handle_scope(child_isolate); |
|
siva
2012/12/13 18:30:38
Do we need a new zone and handle scope for the cod
|
| + RawString* raw_name = String::New(state->exception_callback_name()); |
| + const String& callback_name = String::Handle(child_isolate, raw_name); |
| + child_isolate->object_store()-> |
| + set_unhandled_exception_handler(callback_name); |
| + } |
| } |
| if (resolve_error) { |
| Dart::ShutdownIsolate(); |
| @@ -344,8 +366,8 @@ |
| // Error is in sticky error already. |
| return false; |
| } |
| + |
| Object& result = Object::Handle(); |
| - |
| result = state->ResolveFunction(); |
| delete state; |
| state = NULL; |
| @@ -397,7 +419,7 @@ |
| } |
| -DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) { |
| +DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 2) { |
| GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); |
| bool throw_exception = false; |
| Function& func = Function::Handle(); |
| @@ -417,12 +439,33 @@ |
| ThrowIllegalArgException(msg); |
| } |
| + GET_NATIVE_ARGUMENT(Instance, callback, arguments->NativeArgAt(1)); |
| + Function& callback_func = Function::Handle(); |
| + if (callback.IsNull()) { |
| + callback_func = Function::null(); |
| + } else if (callback.IsClosure()) { |
| + callback_func ^= Closure::function(callback); |
| + const Class& cls = Class::Handle(callback_func.Owner()); |
| + if (!callback_func.IsClosureFunction() || !callback_func.is_static() || |
| + !cls.IsTopLevel()) { |
| + throw_exception = true; |
| + } |
| + } else { |
| + throw_exception = true; |
| + } |
| + if (throw_exception) { |
| + const String& msg = String::Handle(String::New( |
| + "spawnFunction expects to be passed either a unhandled exception " |
| + "callback to a top-level static function, or null")); |
| + ThrowIllegalArgException(msg); |
| + } |
| + |
| #if defined(DEBUG) |
| const Context& ctx = Context::Handle(Closure::context(closure)); |
| ASSERT(ctx.num_variables() == 0); |
| #endif |
| - return Spawn(arguments, new SpawnState(func)); |
| + return Spawn(arguments, new SpawnState(func, callback_func)); |
| } |