OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 1910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1921 info.SetSecondPassCallback(&SendAsyncTaskEventCancel); | 1921 info.SetSecondPassCallback(&SendAsyncTaskEventCancel); |
1922 } | 1922 } |
1923 | 1923 |
1924 // In an async function, reuse the existing stack related to the outer | 1924 // In an async function, reuse the existing stack related to the outer |
1925 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. | 1925 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. |
1926 // Promises with multiple reactions with one or more of them being async | 1926 // Promises with multiple reactions with one or more of them being async |
1927 // functions will not get a good stack trace, as async functions require | 1927 // functions will not get a good stack trace, as async functions require |
1928 // different stacks from direct Promise use, but we save and restore a | 1928 // different stacks from direct Promise use, but we save and restore a |
1929 // stack once for all reactions. | 1929 // stack once for all reactions. |
1930 // | 1930 // |
1931 // If this isn't a case of async function, we return false, otherwise | |
1932 // we set the correct id and return true. | |
1933 // | |
1934 // TODO(littledan): Improve this case. | 1931 // TODO(littledan): Improve this case. |
1935 int GetReferenceAsyncTaskId(Isolate* isolate, Handle<JSPromise> promise) { | 1932 int GetReferenceAsyncTaskId(Isolate* isolate, Handle<JSPromise> promise) { |
1936 Handle<Symbol> handled_by_symbol = | 1933 Handle<Symbol> handled_by_symbol = |
1937 isolate->factory()->promise_handled_by_symbol(); | 1934 isolate->factory()->promise_handled_by_symbol(); |
1938 Handle<Object> handled_by_promise = | 1935 Handle<Object> handled_by_promise = |
1939 JSObject::GetDataProperty(promise, handled_by_symbol); | 1936 JSObject::GetDataProperty(promise, handled_by_symbol); |
1940 if (!handled_by_promise->IsJSPromise()) { | 1937 if (!handled_by_promise->IsJSPromise()) { |
1941 return isolate->debug()->NextAsyncTaskId(promise); | 1938 return isolate->debug()->NextAsyncTaskId(promise); |
1942 } | 1939 } |
1943 Handle<JSPromise> handled_by_promise_js = | 1940 Handle<JSPromise> handled_by_promise_js = |
1944 Handle<JSPromise>::cast(handled_by_promise); | 1941 Handle<JSPromise>::cast(handled_by_promise); |
1945 Handle<Symbol> async_stack_id_symbol = | 1942 Handle<Symbol> async_stack_id_symbol = |
1946 isolate->factory()->promise_async_stack_id_symbol(); | 1943 isolate->factory()->promise_async_stack_id_symbol(); |
1947 Handle<Object> async_task_id = | 1944 Handle<Object> async_task_id = |
1948 JSObject::GetDataProperty(handled_by_promise_js, async_stack_id_symbol); | 1945 JSObject::GetDataProperty(handled_by_promise_js, async_stack_id_symbol); |
1949 if (!async_task_id->IsSmi()) { | 1946 if (!async_task_id->IsSmi()) { |
1950 return isolate->debug()->NextAsyncTaskId(promise); | 1947 return isolate->debug()->NextAsyncTaskId(promise); |
1951 } | 1948 } |
1952 return Handle<Smi>::cast(async_task_id)->value(); | 1949 return Handle<Smi>::cast(async_task_id)->value(); |
1953 } | 1950 } |
1951 | |
1952 bool IsPromiseAllOrRaceFrame(JavaScriptFrame* frame) { | |
1953 if (!frame->HasInlinedFrames()) { | |
Yang
2017/01/30 19:40:33
We can remove this check. GetFunctions should work
kozy
2017/02/15 01:00:54
Done.
| |
1954 return frame->function()->shared()->is_promise_all_or_race(); | |
1955 } | |
1956 List<SharedFunctionInfo*> raw_shareds; | |
1957 frame->GetFunctions(&raw_shareds); | |
1958 for (int i = 0; i < raw_shareds.length(); ++i) { | |
1959 if (raw_shareds[i]->is_promise_all_or_race()) return true; | |
1960 } | |
1961 return false; | |
1962 } | |
1963 | |
1954 } // namespace | 1964 } // namespace |
1955 | 1965 |
1966 bool Debug::IsBreakablePromiseCreated() { | |
1967 // Promise.all and Promise.race implementations use .then internally, | |
1968 // we don't need to break on these call. | |
1969 JavaScriptFrameIterator it(isolate_); | |
1970 while (!it.done()) { | |
1971 if (IsPromiseAllOrRaceFrame(it.frame())) return false; | |
1972 it.Advance(); | |
1973 } | |
1974 return true; | |
1975 } | |
1976 | |
1956 void Debug::RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise, | 1977 void Debug::RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise, |
1957 Handle<Object> parent) { | 1978 Handle<Object> parent) { |
1958 if (!debug_delegate_) return; | 1979 if (!debug_delegate_) return; |
1959 int id = GetReferenceAsyncTaskId(isolate_, promise); | 1980 int id = GetReferenceAsyncTaskId(isolate_, promise); |
1960 switch (type) { | 1981 switch (type) { |
1961 case PromiseHookType::kInit: | 1982 case PromiseHookType::kInit: |
1962 debug_delegate_->PromiseEventOccurred( | 1983 debug_delegate_->PromiseCreatedEvent( |
1963 debug::kDebugPromiseCreated, id, | 1984 id, |
1964 parent->IsJSPromise() ? GetReferenceAsyncTaskId( | 1985 parent->IsJSPromise() ? GetReferenceAsyncTaskId( |
1965 isolate_, Handle<JSPromise>::cast(parent)) | 1986 isolate_, Handle<JSPromise>::cast(parent)) |
1966 : 0); | 1987 : 0, |
1988 IsBreakablePromiseCreated()); | |
1967 return; | 1989 return; |
1968 case PromiseHookType::kResolve: | 1990 case PromiseHookType::kResolve: |
1969 // We can't use this hook because it's called before promise object will | 1991 // We can't use this hook because it's called before promise object will |
1970 // get resolved status. | 1992 // get resolved status. |
1971 return; | 1993 return; |
1972 case PromiseHookType::kBefore: | 1994 case PromiseHookType::kBefore: |
1973 OnAsyncTaskEvent(debug::kDebugWillHandle, id); | 1995 OnAsyncTaskEvent(debug::kDebugWillHandle, id); |
1974 return; | 1996 return; |
1975 case PromiseHookType::kAfter: | 1997 case PromiseHookType::kAfter: |
1976 OnAsyncTaskEvent(debug::kDebugDidHandle, id); | 1998 OnAsyncTaskEvent(debug::kDebugDidHandle, id); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2037 shared->set_debug_is_blackboxed(is_blackboxed); | 2059 shared->set_debug_is_blackboxed(is_blackboxed); |
2038 shared->set_computed_debug_is_blackboxed(true); | 2060 shared->set_computed_debug_is_blackboxed(true); |
2039 } | 2061 } |
2040 return shared->debug_is_blackboxed(); | 2062 return shared->debug_is_blackboxed(); |
2041 } | 2063 } |
2042 | 2064 |
2043 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { | 2065 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { |
2044 if (in_debug_scope() || ignore_events()) return; | 2066 if (in_debug_scope() || ignore_events()) return; |
2045 | 2067 |
2046 if (debug_delegate_) { | 2068 if (debug_delegate_) { |
2047 debug_delegate_->PromiseEventOccurred(type, id, 0); | 2069 debug_delegate_->PromiseEventOccurred(type, id); |
2048 if (!non_inspector_listener_exists()) return; | 2070 if (!non_inspector_listener_exists()) return; |
2049 } | 2071 } |
2050 | 2072 |
2051 HandleScope scope(isolate_); | 2073 HandleScope scope(isolate_); |
2052 DebugScope debug_scope(this); | 2074 DebugScope debug_scope(this); |
2053 if (debug_scope.failed()) return; | 2075 if (debug_scope.failed()) return; |
2054 | 2076 |
2055 // Create the script collected state object. | 2077 // Create the script collected state object. |
2056 Handle<Object> event_data; | 2078 Handle<Object> event_data; |
2057 // Bail out and don't call debugger if exception. | 2079 // Bail out and don't call debugger if exception. |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2428 return v8::Utils::ToLocal(callback_data_); | 2450 return v8::Utils::ToLocal(callback_data_); |
2429 } | 2451 } |
2430 | 2452 |
2431 | 2453 |
2432 v8::Isolate* EventDetailsImpl::GetIsolate() const { | 2454 v8::Isolate* EventDetailsImpl::GetIsolate() const { |
2433 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); | 2455 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); |
2434 } | 2456 } |
2435 | 2457 |
2436 } // namespace internal | 2458 } // namespace internal |
2437 } // namespace v8 | 2459 } // namespace v8 |
OLD | NEW |