| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "platform/v8_inspector/PromiseTracker.h" | |
| 6 | |
| 7 #include "platform/inspector_protocol/String16.h" | |
| 8 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" | |
| 9 #include "platform/v8_inspector/V8StackTraceImpl.h" | |
| 10 #include "platform/v8_inspector/public/V8DebuggerClient.h" | |
| 11 #include "wtf/PassOwnPtr.h" | |
| 12 | |
| 13 using namespace blink::protocol; | |
| 14 | |
| 15 namespace blink { | |
| 16 | |
| 17 class PromiseTracker::PromiseWrapper { | |
| 18 public: | |
| 19 PromiseWrapper(PromiseTracker* tracker, int id, v8::Local<v8::Object> promis
e) | |
| 20 : m_tracker(tracker) | |
| 21 , m_id(id) | |
| 22 , m_promise(tracker->m_isolate, promise) { } | |
| 23 | |
| 24 ~PromiseWrapper() | |
| 25 { | |
| 26 OwnPtr<Debugger::PromiseDetails> promiseDetails = Debugger::PromiseDetai
ls::create().setId(m_id).build(); | |
| 27 m_tracker->m_agent->didUpdatePromise(Debugger::PromiseUpdated::EventType
Enum::Gc, promiseDetails.release()); | |
| 28 } | |
| 29 | |
| 30 private: | |
| 31 friend class PromiseTracker; | |
| 32 | |
| 33 PromiseTracker* m_tracker; | |
| 34 int m_id; | |
| 35 v8::Global<v8::Object> m_promise; | |
| 36 }; | |
| 37 | |
| 38 PromiseTracker::PromiseTracker(V8DebuggerAgentImpl* agent, v8::Isolate* isolate) | |
| 39 : m_circularSequentialId(0) | |
| 40 , m_isEnabled(false) | |
| 41 , m_captureStacks(false) | |
| 42 , m_agent(agent) | |
| 43 , m_isolate(isolate) | |
| 44 { | |
| 45 clear(); | |
| 46 } | |
| 47 | |
| 48 PromiseTracker::~PromiseTracker() | |
| 49 { | |
| 50 } | |
| 51 | |
| 52 void PromiseTracker::setEnabled(bool enabled, bool captureStacks) | |
| 53 { | |
| 54 m_isEnabled = enabled; | |
| 55 m_captureStacks = captureStacks; | |
| 56 if (!enabled) | |
| 57 clear(); | |
| 58 } | |
| 59 | |
| 60 void PromiseTracker::clear() | |
| 61 { | |
| 62 v8::HandleScope scope(m_isolate); | |
| 63 m_promiseToId.Reset(m_isolate, v8::NativeWeakMap::New(m_isolate)); | |
| 64 m_idToPromise.clear(); | |
| 65 } | |
| 66 | |
| 67 int PromiseTracker::circularSequentialId() | |
| 68 { | |
| 69 ++m_circularSequentialId; | |
| 70 if (m_circularSequentialId <= 0) | |
| 71 m_circularSequentialId = 1; | |
| 72 return m_circularSequentialId; | |
| 73 } | |
| 74 | |
| 75 void PromiseTracker::weakCallback(const v8::WeakCallbackInfo<PromiseWrapper>& da
ta) | |
| 76 { | |
| 77 PromiseWrapper* wrapper = data.GetParameter(); | |
| 78 wrapper->m_tracker->m_idToPromise.remove(wrapper->m_id); | |
| 79 } | |
| 80 | |
| 81 void PromiseTracker::promiseCollected(int id) | |
| 82 { | |
| 83 } | |
| 84 | |
| 85 int PromiseTracker::promiseId(v8::Local<v8::Object> promise, bool* isNewPromise) | |
| 86 { | |
| 87 v8::HandleScope scope(m_isolate); | |
| 88 v8::Local<v8::NativeWeakMap> map = v8::Local<v8::NativeWeakMap>::New(m_isola
te, m_promiseToId); | |
| 89 v8::Local<v8::Value> value = map->Get(promise); | |
| 90 if (value->IsInt32()) { | |
| 91 *isNewPromise = false; | |
| 92 return value.As<v8::Int32>()->Value(); | |
| 93 } | |
| 94 *isNewPromise = true; | |
| 95 int id = circularSequentialId(); | |
| 96 map->Set(promise, v8::Int32::New(m_isolate, id)); | |
| 97 | |
| 98 OwnPtr<PromiseWrapper> wrapper = adoptPtr(new PromiseWrapper(this, id, promi
se)); | |
| 99 wrapper->m_promise.SetWeak(wrapper.get(), weakCallback, v8::WeakCallbackType
::kParameter); | |
| 100 m_idToPromise.set(id, wrapper.release()); | |
| 101 return id; | |
| 102 } | |
| 103 | |
| 104 void PromiseTracker::didReceiveV8PromiseEvent(v8::Local<v8::Context> context, v8
::Local<v8::Object> promise, v8::Local<v8::Value> parentPromise, int status) | |
| 105 { | |
| 106 ASSERT(isEnabled()); | |
| 107 ASSERT(!context.IsEmpty()); | |
| 108 | |
| 109 bool isNewPromise = false; | |
| 110 int id = promiseId(promise, &isNewPromise); | |
| 111 | |
| 112 blink::protocol::String16 eventType = isNewPromise ? Debugger::PromiseUpdate
d::EventTypeEnum::New : Debugger::PromiseUpdated::EventTypeEnum::Update; | |
| 113 | |
| 114 blink::protocol::String16 promiseStatus; | |
| 115 switch (status) { | |
| 116 case 0: | |
| 117 promiseStatus = Debugger::PromiseDetails::StatusEnum::Pending; | |
| 118 break; | |
| 119 case 1: | |
| 120 promiseStatus = Debugger::PromiseDetails::StatusEnum::Resolved; | |
| 121 break; | |
| 122 default: | |
| 123 promiseStatus = Debugger::PromiseDetails::StatusEnum::Rejected; | |
| 124 }; | |
| 125 OwnPtr<Debugger::PromiseDetails> promiseDetails = Debugger::PromiseDetails::
create().setId(id).setStatus(promiseStatus).build(); | |
| 126 | |
| 127 if (!parentPromise.IsEmpty() && parentPromise->IsObject()) { | |
| 128 v8::Local<v8::Object> handle = parentPromise->ToObject(context->GetIsola
te()); | |
| 129 bool parentIsNewPromise = false; | |
| 130 int parentPromiseId = promiseId(handle, &parentIsNewPromise); | |
| 131 promiseDetails->setParentId(parentPromiseId); | |
| 132 } else { | |
| 133 if (!status) { | |
| 134 if (isNewPromise) { | |
| 135 promiseDetails->setCreationTime(m_agent->debugger().client()->cu
rrentTimeMS()); | |
| 136 OwnPtr<V8StackTraceImpl> stack = V8StackTraceImpl::capture(m_age
nt, m_captureStacks ? V8StackTraceImpl::maxCallStackSizeToCapture : 1); | |
| 137 if (stack) | |
| 138 promiseDetails->setCreationStack(stack->buildInspectorObject
()); | |
| 139 } | |
| 140 } else { | |
| 141 promiseDetails->setSettlementTime(m_agent->debugger().client()->curr
entTimeMS()); | |
| 142 if (m_captureStacks) { | |
| 143 OwnPtr<V8StackTraceImpl> stack = V8StackTraceImpl::capture(m_age
nt, V8StackTrace::maxCallStackSizeToCapture); | |
| 144 if (stack) | |
| 145 promiseDetails->setSettlementStack(stack->buildInspectorObje
ct()); | |
| 146 } | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 m_agent->didUpdatePromise(eventType, promiseDetails.release()); | |
| 151 } | |
| 152 | |
| 153 v8::Local<v8::Object> PromiseTracker::promiseById(int promiseId) | |
| 154 { | |
| 155 ASSERT(isEnabled()); | |
| 156 PromiseWrapper* wrapper = m_idToPromise.get(promiseId); | |
| 157 return wrapper ? wrapper->m_promise.Get(m_isolate) : v8::Local<v8::Object>()
; | |
| 158 } | |
| 159 | |
| 160 } // namespace blink | |
| OLD | NEW |