Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 the V8 project 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 "src/debug/debug-interface.h" | |
| 6 | |
| 7 #include "src/debug/debug.h" | |
| 8 #include "src/factory.h" | |
| 9 #include "src/isolate-inl.h" | |
| 10 #include "src/vm-state-inl.h" | |
| 11 | |
| 12 namespace v8 { | |
| 13 | |
| 14 namespace i = internal; | |
| 15 | |
| 16 static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) { | |
| 17 if (isolate->has_scheduled_exception()) { | |
| 18 return isolate->scheduled_exception() == | |
| 19 isolate->heap()->termination_exception(); | |
| 20 } | |
| 21 return false; | |
| 22 } | |
| 23 | |
| 24 #define ENTER_V8(isolate) i::VMState<v8::OTHER> __state__((isolate)) | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 class InternalEscapableScope : public v8::EscapableHandleScope { | |
| 29 public: | |
| 30 explicit inline InternalEscapableScope(i::Isolate* isolate) | |
| 31 : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {} | |
| 32 }; | |
| 33 | |
| 34 class CallDepthScope { | |
|
Yang
2016/10/17 09:53:25
This and some other parts are duplicates of what's
kozy
2016/10/17 14:38:06
Done.
| |
| 35 public: | |
| 36 explicit CallDepthScope(i::Isolate* isolate, Local<Context> context) | |
| 37 : isolate_(isolate), context_(context), escaped_(false) { | |
| 38 // TODO(dcarney): remove this when blink stops crashing. | |
| 39 DCHECK(!isolate_->external_caught_exception()); | |
| 40 isolate_->IncrementJsCallsFromApiCounter(); | |
| 41 isolate_->handle_scope_implementer()->IncrementCallDepth(); | |
| 42 if (!context.IsEmpty()) { | |
| 43 i::Handle<i::Context> env = Utils::OpenHandle(*context); | |
| 44 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer(); | |
| 45 if (isolate->context() != nullptr && | |
| 46 isolate->context()->native_context() == env->native_context() && | |
| 47 impl->LastEnteredContextWas(env)) { | |
| 48 context_ = Local<Context>(); | |
| 49 } else { | |
| 50 context_->Enter(); | |
| 51 } | |
| 52 } | |
| 53 } | |
| 54 ~CallDepthScope() { | |
| 55 if (!context_.IsEmpty()) context_->Exit(); | |
| 56 if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth(); | |
| 57 } | |
| 58 | |
| 59 void Escape() { | |
| 60 DCHECK(!escaped_); | |
| 61 escaped_ = true; | |
| 62 auto handle_scope_implementer = isolate_->handle_scope_implementer(); | |
| 63 handle_scope_implementer->DecrementCallDepth(); | |
| 64 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); | |
| 65 isolate_->OptionalRescheduleException(call_depth_is_zero); | |
| 66 } | |
| 67 | |
| 68 private: | |
| 69 i::Isolate* const isolate_; | |
| 70 Local<Context> context_; | |
| 71 bool escaped_; | |
| 72 }; | |
| 73 | |
| 74 } // namespace | |
| 75 | |
| 76 bool DebugInterface::SetDebugEventListener(Isolate* isolate, EventCallback that, | |
| 77 Local<Value> data) { | |
| 78 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | |
| 79 ENTER_V8(i_isolate); | |
| 80 i::HandleScope scope(i_isolate); | |
| 81 i::Handle<i::Object> foreign = i_isolate->factory()->undefined_value(); | |
| 82 if (that != NULL) { | |
| 83 foreign = i_isolate->factory()->NewForeign(FUNCTION_ADDR(that)); | |
| 84 } | |
| 85 i_isolate->debug()->SetEventListener(foreign, Utils::OpenHandle(*data, true)); | |
| 86 return true; | |
| 87 } | |
| 88 | |
| 89 Local<Context> DebugInterface::GetDebugContext(Isolate* isolate) { | |
| 90 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | |
| 91 ENTER_V8(i_isolate); | |
| 92 return Utils::ToLocal(i_isolate->debug()->GetDebugContext()); | |
| 93 } | |
| 94 | |
| 95 MaybeLocal<Value> DebugInterface::Call(Local<Context> context, | |
| 96 v8::Local<v8::Function> fun, | |
| 97 v8::Local<v8::Value> data) { | |
| 98 auto isolate = context.IsEmpty() | |
| 99 ? i::Isolate::Current() | |
| 100 : reinterpret_cast<i::Isolate*>(context->GetIsolate()); | |
| 101 if (IsExecutionTerminatingCheck(isolate)) { | |
| 102 return MaybeLocal<Value>(); | |
| 103 } | |
| 104 InternalEscapableScope handle_scope(isolate); | |
| 105 CallDepthScope call_depth_scope(isolate, context); | |
| 106 ENTER_V8(isolate); | |
| 107 bool has_pending_exception = false; | |
| 108 i::Handle<i::Object> data_obj; | |
| 109 if (data.IsEmpty()) { | |
| 110 data_obj = isolate->factory()->undefined_value(); | |
| 111 } else { | |
| 112 data_obj = Utils::OpenHandle(*data); | |
| 113 } | |
| 114 Local<Value> result; | |
| 115 has_pending_exception = !ToLocal<Value>( | |
| 116 isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj), &result); | |
| 117 if (has_pending_exception) { | |
| 118 call_depth_scope.Escape(); | |
| 119 return result; | |
| 120 } | |
| 121 return handle_scope.Escape(result); | |
| 122 } | |
| 123 | |
| 124 void DebugInterface::SetLiveEditEnabled(Isolate* isolate, bool enable) { | |
| 125 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); | |
| 126 internal_isolate->debug()->set_live_edit_enabled(enable); | |
| 127 } | |
| 128 | |
| 129 void DebugInterface::DebugBreak(Isolate* isolate) { | |
| 130 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak(); | |
| 131 } | |
| 132 | |
| 133 void DebugInterface::CancelDebugBreak(Isolate* isolate) { | |
| 134 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); | |
| 135 internal_isolate->stack_guard()->ClearDebugBreak(); | |
| 136 } | |
| 137 | |
| 138 MaybeLocal<Array> DebugInterface::GetInternalProperties(Isolate* v8_isolate, | |
| 139 Local<Value> value) { | |
| 140 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); | |
| 141 ENTER_V8(isolate); | |
| 142 i::Handle<i::Object> val = Utils::OpenHandle(*value); | |
| 143 i::Handle<i::JSArray> result; | |
| 144 if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result)) | |
| 145 return MaybeLocal<Array>(); | |
| 146 return Utils::ToLocal(result); | |
| 147 } | |
| 148 | |
| 149 } // namespace v8 | |
| OLD | NEW |