OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "vm/service.h" | 5 #include "vm/service.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "platform/globals.h" | 9 #include "platform/globals.h" |
10 | 10 |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 HANDLESCOPE(T); | 806 HANDLESCOPE(T); |
807 JSONStream js; | 807 JSONStream js; |
808 js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), id, method_name, | 808 js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), id, method_name, |
809 parameter_keys, parameter_values); | 809 parameter_keys, parameter_values); |
810 js.PrintError(kExtensionError, "Error in extension `%s`: %s", js.method(), | 810 js.PrintError(kExtensionError, "Error in extension `%s`: %s", js.method(), |
811 error.ToErrorCString()); | 811 error.ToErrorCString()); |
812 js.PostReply(); | 812 js.PostReply(); |
813 } | 813 } |
814 | 814 |
815 | 815 |
816 void Service::InvokeMethod(Isolate* I, | 816 RawError* Service::InvokeMethod(Isolate* I, |
817 const Array& msg, | 817 const Array& msg, |
818 bool parameters_are_dart_objects) { | 818 bool parameters_are_dart_objects) { |
819 Thread* T = Thread::Current(); | 819 Thread* T = Thread::Current(); |
820 ASSERT(I == T->isolate()); | 820 ASSERT(I == T->isolate()); |
821 ASSERT(I != NULL); | 821 ASSERT(I != NULL); |
822 ASSERT(T->execution_state() == Thread::kThreadInVM); | 822 ASSERT(T->execution_state() == Thread::kThreadInVM); |
823 ASSERT(!msg.IsNull()); | 823 ASSERT(!msg.IsNull()); |
824 ASSERT(msg.Length() == 6); | 824 ASSERT(msg.Length() == 6); |
825 | 825 |
826 { | 826 { |
827 StackZone zone(T); | 827 StackZone zone(T); |
828 HANDLESCOPE(T); | 828 HANDLESCOPE(T); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 // Change the default ring's policy. | 870 // Change the default ring's policy. |
871 RingServiceIdZone* zone = | 871 RingServiceIdZone* zone = |
872 reinterpret_cast<RingServiceIdZone*>(js.id_zone()); | 872 reinterpret_cast<RingServiceIdZone*>(js.id_zone()); |
873 zone->set_policy(ObjectIdRing::kReuseId); | 873 zone->set_policy(ObjectIdRing::kReuseId); |
874 } else { | 874 } else { |
875 // TODO(johnmccutchan): Support creating, deleting, and selecting | 875 // TODO(johnmccutchan): Support creating, deleting, and selecting |
876 // custom service id zones. | 876 // custom service id zones. |
877 // For now, always return an error. | 877 // For now, always return an error. |
878 PrintInvalidParamError(&js, "_idZone"); | 878 PrintInvalidParamError(&js, "_idZone"); |
879 js.PostReply(); | 879 js.PostReply(); |
880 return; | 880 return T->get_and_clear_sticky_error(); |
881 } | 881 } |
882 } | 882 } |
883 const char* c_method_name = method_name.ToCString(); | 883 const char* c_method_name = method_name.ToCString(); |
884 | 884 |
885 const ServiceMethodDescriptor* method = FindMethod(c_method_name); | 885 const ServiceMethodDescriptor* method = FindMethod(c_method_name); |
886 if (method != NULL) { | 886 if (method != NULL) { |
887 if (!ValidateParameters(method->parameters, &js)) { | 887 if (!ValidateParameters(method->parameters, &js)) { |
888 js.PostReply(); | 888 js.PostReply(); |
889 return; | 889 return T->get_and_clear_sticky_error(); |
890 } | 890 } |
891 if (method->entry(T, &js)) { | 891 if (method->entry(T, &js)) { |
892 js.PostReply(); | 892 js.PostReply(); |
893 } else { | 893 } else { |
894 // NOTE(turnidge): All message handlers currently return true, | 894 // NOTE(turnidge): All message handlers currently return true, |
895 // so this case shouldn't be reached, at present. | 895 // so this case shouldn't be reached, at present. |
896 UNIMPLEMENTED(); | 896 UNIMPLEMENTED(); |
897 } | 897 } |
898 return; | 898 return T->get_and_clear_sticky_error(); |
899 } | 899 } |
900 | 900 |
901 EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(c_method_name); | 901 EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(c_method_name); |
902 if (handler == NULL) { | 902 if (handler == NULL) { |
903 handler = FindRootEmbedderHandler(c_method_name); | 903 handler = FindRootEmbedderHandler(c_method_name); |
904 } | 904 } |
905 | 905 |
906 if (handler != NULL) { | 906 if (handler != NULL) { |
907 EmbedderHandleMessage(handler, &js); | 907 EmbedderHandleMessage(handler, &js); |
908 return; | 908 return T->get_and_clear_sticky_error(); |
909 } | 909 } |
910 | 910 |
911 const Instance& extension_handler = | 911 const Instance& extension_handler = |
912 Instance::Handle(Z, I->LookupServiceExtensionHandler(method_name)); | 912 Instance::Handle(Z, I->LookupServiceExtensionHandler(method_name)); |
913 if (!extension_handler.IsNull()) { | 913 if (!extension_handler.IsNull()) { |
914 ScheduleExtensionHandler(extension_handler, method_name, param_keys, | 914 ScheduleExtensionHandler(extension_handler, method_name, param_keys, |
915 param_values, reply_port, seq); | 915 param_values, reply_port, seq); |
916 // Schedule was successful. Extension code will post a reply | 916 // Schedule was successful. Extension code will post a reply |
917 // asynchronously. | 917 // asynchronously. |
918 return; | 918 return T->get_and_clear_sticky_error(); |
919 } | 919 } |
920 | 920 |
921 PrintUnrecognizedMethodError(&js); | 921 PrintUnrecognizedMethodError(&js); |
922 js.PostReply(); | 922 js.PostReply(); |
923 return; | 923 return T->get_and_clear_sticky_error(); |
924 } | 924 } |
925 } | 925 } |
926 | 926 |
927 | 927 |
928 void Service::HandleRootMessage(const Array& msg_instance) { | 928 RawError* Service::HandleRootMessage(const Array& msg_instance) { |
929 Isolate* isolate = Isolate::Current(); | 929 Isolate* isolate = Isolate::Current(); |
930 InvokeMethod(isolate, msg_instance); | 930 return InvokeMethod(isolate, msg_instance); |
931 } | 931 } |
932 | 932 |
933 | 933 |
934 void Service::HandleObjectRootMessage(const Array& msg_instance) { | 934 RawError* Service::HandleObjectRootMessage(const Array& msg_instance) { |
935 Isolate* isolate = Isolate::Current(); | 935 Isolate* isolate = Isolate::Current(); |
936 InvokeMethod(isolate, msg_instance, true); | 936 return InvokeMethod(isolate, msg_instance, true); |
937 } | 937 } |
938 | 938 |
939 | 939 |
940 void Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) { | 940 RawError* Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) { |
941 ASSERT(isolate != NULL); | 941 ASSERT(isolate != NULL); |
942 InvokeMethod(isolate, msg); | 942 const Error& error = Error::Handle(InvokeMethod(isolate, msg)); |
943 MaybePause(isolate); | 943 return MaybePause(isolate, error); |
944 } | 944 } |
945 | 945 |
946 | 946 |
947 static void Finalizer(void* isolate_callback_data, | 947 static void Finalizer(void* isolate_callback_data, |
948 Dart_WeakPersistentHandle handle, | 948 Dart_WeakPersistentHandle handle, |
949 void* buffer) { | 949 void* buffer) { |
950 free(buffer); | 950 free(buffer); |
951 } | 951 } |
952 | 952 |
953 | 953 |
(...skipping 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2531 } | 2531 } |
2532 | 2532 |
2533 | 2533 |
2534 void Service::CheckForPause(Isolate* isolate, JSONStream* stream) { | 2534 void Service::CheckForPause(Isolate* isolate, JSONStream* stream) { |
2535 // Should we pause? | 2535 // Should we pause? |
2536 isolate->set_should_pause_post_service_request( | 2536 isolate->set_should_pause_post_service_request( |
2537 BoolParameter::Parse(stream->LookupParam("pause"), false)); | 2537 BoolParameter::Parse(stream->LookupParam("pause"), false)); |
2538 } | 2538 } |
2539 | 2539 |
2540 | 2540 |
2541 void Service::MaybePause(Isolate* isolate) { | 2541 RawError* Service::MaybePause(Isolate* isolate, const Error& error) { |
2542 // Don't pause twice. | 2542 // Don't pause twice. |
2543 if (!isolate->IsPaused()) { | 2543 if (!isolate->IsPaused()) { |
2544 if (isolate->should_pause_post_service_request()) { | 2544 if (isolate->should_pause_post_service_request()) { |
2545 isolate->set_should_pause_post_service_request(false); | 2545 isolate->set_should_pause_post_service_request(false); |
2546 isolate->PausePostRequest(); | 2546 // Before pausing, restore the sticky error. The debugger will return it |
| 2547 // from PausePostRequest. |
| 2548 Thread::Current()->set_sticky_error(error); |
| 2549 return isolate->PausePostRequest(); |
2547 } | 2550 } |
2548 } | 2551 } |
| 2552 return error.raw(); |
2549 } | 2553 } |
2550 | 2554 |
2551 | 2555 |
2552 static bool AddBreakpointCommon(Thread* thread, | 2556 static bool AddBreakpointCommon(Thread* thread, |
2553 JSONStream* js, | 2557 JSONStream* js, |
2554 const String& script_uri) { | 2558 const String& script_uri) { |
2555 if (!thread->isolate()->compilation_allowed()) { | 2559 if (!thread->isolate()->compilation_allowed()) { |
2556 js->PrintError( | 2560 js->PrintError( |
2557 kFeatureDisabled, | 2561 kFeatureDisabled, |
2558 "Cannot use breakpoints when running a precompiled program."); | 2562 "Cannot use breakpoints when running a precompiled program."); |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3854 } | 3858 } |
3855 } | 3859 } |
3856 | 3860 |
3857 | 3861 |
3858 static bool GetVM(Thread* thread, JSONStream* js) { | 3862 static bool GetVM(Thread* thread, JSONStream* js) { |
3859 Service::PrintJSONForVM(js, false); | 3863 Service::PrintJSONForVM(js, false); |
3860 return true; | 3864 return true; |
3861 } | 3865 } |
3862 | 3866 |
3863 | 3867 |
3864 static const MethodParameter* restart_vm_params[] = { | |
3865 NO_ISOLATE_PARAMETER, NULL, | |
3866 }; | |
3867 | |
3868 | |
3869 static bool RestartVM(Thread* thread, JSONStream* js) { | |
3870 Isolate::KillAllIsolates(Isolate::kVMRestartMsg); | |
3871 PrintSuccess(js); | |
3872 return true; | |
3873 } | |
3874 | |
3875 | |
3876 static const char* exception_pause_mode_names[] = { | 3868 static const char* exception_pause_mode_names[] = { |
3877 "All", "None", "Unhandled", NULL, | 3869 "All", "None", "Unhandled", NULL, |
3878 }; | 3870 }; |
3879 | 3871 |
3880 | 3872 |
3881 static Dart_ExceptionPauseInfo exception_pause_mode_values[] = { | 3873 static Dart_ExceptionPauseInfo exception_pause_mode_values[] = { |
3882 kPauseOnAllExceptions, kNoPauseOnExceptions, kPauseOnUnhandledExceptions, | 3874 kPauseOnAllExceptions, kNoPauseOnExceptions, kPauseOnUnhandledExceptions, |
3883 kInvalidExceptionPauseInfo, | 3875 kInvalidExceptionPauseInfo, |
3884 }; | 3876 }; |
3885 | 3877 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4135 { "_getVMMetricList", GetVMMetricList, | 4127 { "_getVMMetricList", GetVMMetricList, |
4136 get_vm_metric_list_params }, | 4128 get_vm_metric_list_params }, |
4137 { "_getVMTimeline", GetVMTimeline, | 4129 { "_getVMTimeline", GetVMTimeline, |
4138 get_vm_timeline_params }, | 4130 get_vm_timeline_params }, |
4139 { "_getVMTimelineFlags", GetVMTimelineFlags, | 4131 { "_getVMTimelineFlags", GetVMTimelineFlags, |
4140 get_vm_timeline_flags_params }, | 4132 get_vm_timeline_flags_params }, |
4141 { "pause", Pause, | 4133 { "pause", Pause, |
4142 pause_params }, | 4134 pause_params }, |
4143 { "removeBreakpoint", RemoveBreakpoint, | 4135 { "removeBreakpoint", RemoveBreakpoint, |
4144 remove_breakpoint_params }, | 4136 remove_breakpoint_params }, |
4145 { "_restartVM", RestartVM, | |
4146 restart_vm_params }, | |
4147 { "reloadSources", ReloadSources, | 4137 { "reloadSources", ReloadSources, |
4148 reload_sources_params }, | 4138 reload_sources_params }, |
4149 { "_reloadSources", ReloadSources, | 4139 { "_reloadSources", ReloadSources, |
4150 reload_sources_params }, | 4140 reload_sources_params }, |
4151 { "resume", Resume, | 4141 { "resume", Resume, |
4152 resume_params }, | 4142 resume_params }, |
4153 { "_requestHeapSnapshot", RequestHeapSnapshot, | 4143 { "_requestHeapSnapshot", RequestHeapSnapshot, |
4154 request_heap_snapshot_params }, | 4144 request_heap_snapshot_params }, |
4155 { "setExceptionPauseMode", SetExceptionPauseMode, | 4145 { "setExceptionPauseMode", SetExceptionPauseMode, |
4156 set_exception_pause_mode_params }, | 4146 set_exception_pause_mode_params }, |
(...skipping 19 matching lines...) Expand all Loading... |
4176 if (strcmp(method_name, method.name) == 0) { | 4166 if (strcmp(method_name, method.name) == 0) { |
4177 return &method; | 4167 return &method; |
4178 } | 4168 } |
4179 } | 4169 } |
4180 return NULL; | 4170 return NULL; |
4181 } | 4171 } |
4182 | 4172 |
4183 #endif // !PRODUCT | 4173 #endif // !PRODUCT |
4184 | 4174 |
4185 } // namespace dart | 4175 } // namespace dart |
OLD | NEW |