���� JFIF �� � ( %"1"%)+...383,7(-.-
![]() Server : Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.20 System : Linux st2.domain.com 3.10.0-1127.10.1.el7.x86_64 #1 SMP Wed Jun 3 14:28:03 UTC 2020 x86_64 User : apache ( 48) PHP Version : 7.4.20 Disable Function : NONE Directory : /home/real/node-v13.0.1/deps/v8/src/debug/ |
// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/debug/debug-stack-trace-iterator.h" #include "src/api/api-inl.h" #include "src/debug/debug-evaluate.h" #include "src/debug/debug-scope-iterator.h" #include "src/debug/debug.h" #include "src/debug/liveedit.h" #include "src/execution/frames-inl.h" #include "src/execution/isolate.h" namespace v8 { std::unique_ptr<debug::StackTraceIterator> debug::StackTraceIterator::Create( v8::Isolate* isolate, int index) { return std::unique_ptr<debug::StackTraceIterator>( new internal::DebugStackTraceIterator( reinterpret_cast<internal::Isolate*>(isolate), index)); } namespace internal { DebugStackTraceIterator::DebugStackTraceIterator(Isolate* isolate, int index) : isolate_(isolate), iterator_(isolate, isolate->debug()->break_frame_id()), is_top_frame_(true) { if (iterator_.done()) return; std::vector<FrameSummary> frames; iterator_.frame()->Summarize(&frames); inlined_frame_index_ = static_cast<int>(frames.size()); Advance(); for (; !Done() && index > 0; --index) Advance(); } DebugStackTraceIterator::~DebugStackTraceIterator() = default; bool DebugStackTraceIterator::Done() const { return iterator_.done(); } void DebugStackTraceIterator::Advance() { while (true) { --inlined_frame_index_; for (; inlined_frame_index_ >= 0; --inlined_frame_index_) { // Omit functions from native and extension scripts. if (FrameSummary::Get(iterator_.frame(), inlined_frame_index_) .is_subject_to_debugging()) { break; } is_top_frame_ = false; } if (inlined_frame_index_ >= 0) { frame_inspector_.reset(new FrameInspector( iterator_.frame(), inlined_frame_index_, isolate_)); break; } is_top_frame_ = false; frame_inspector_.reset(); iterator_.Advance(); if (iterator_.done()) break; std::vector<FrameSummary> frames; iterator_.frame()->Summarize(&frames); inlined_frame_index_ = static_cast<int>(frames.size()); } } int DebugStackTraceIterator::GetContextId() const { DCHECK(!Done()); Handle<Object> context = frame_inspector_->GetContext(); if (context->IsContext()) { Object value = Context::cast(*context).native_context().debug_context_id(); if (value.IsSmi()) return Smi::ToInt(value); } return 0; } v8::MaybeLocal<v8::Value> DebugStackTraceIterator::GetReceiver() const { DCHECK(!Done()); if (frame_inspector_->IsJavaScript() && frame_inspector_->GetFunction()->shared().kind() == kArrowFunction) { // FrameInspector is not able to get receiver for arrow function. // So let's try to fetch it using same logic as is used to retrieve 'this' // during DebugEvaluate::Local. Handle<JSFunction> function = frame_inspector_->GetFunction(); Handle<Context> context(function->context(), isolate_); // Arrow function defined in top level function without references to // variables may have NativeContext as context. if (!context->IsFunctionContext()) return v8::MaybeLocal<v8::Value>(); ScopeIterator scope_iterator(isolate_, frame_inspector_.get(), ScopeIterator::COLLECT_NON_LOCALS); // We lookup this variable in function context only when it is used in arrow // function otherwise V8 can optimize it out. if (!scope_iterator.GetNonLocals()->Has(isolate_, isolate_->factory()->this_string())) return v8::MaybeLocal<v8::Value>(); DisallowHeapAllocation no_gc; VariableMode mode; InitializationFlag flag; MaybeAssignedFlag maybe_assigned_flag; int slot_index = ScopeInfo::ContextSlotIndex( context->scope_info(), ReadOnlyRoots(isolate_->heap()).this_string(), &mode, &flag, &maybe_assigned_flag); if (slot_index < 0) return v8::MaybeLocal<v8::Value>(); Handle<Object> value = handle(context->get(slot_index), isolate_); if (value->IsTheHole(isolate_)) return v8::MaybeLocal<v8::Value>(); return Utils::ToLocal(value); } Handle<Object> value = frame_inspector_->GetReceiver(); if (value.is_null() || (value->IsSmi() || !value->IsTheHole(isolate_))) { return Utils::ToLocal(value); } return v8::MaybeLocal<v8::Value>(); } v8::Local<v8::Value> DebugStackTraceIterator::GetReturnValue() const { DCHECK(!Done()); if (frame_inspector_ && frame_inspector_->IsWasm()) { return v8::Local<v8::Value>(); } bool is_optimized = iterator_.frame()->is_optimized(); if (is_optimized || !is_top_frame_ || !isolate_->debug()->IsBreakAtReturn(iterator_.javascript_frame())) { return v8::Local<v8::Value>(); } return Utils::ToLocal(isolate_->debug()->return_value_handle()); } v8::Local<v8::String> DebugStackTraceIterator::GetFunctionDebugName() const { DCHECK(!Done()); return Utils::ToLocal(frame_inspector_->GetFunctionName()); } v8::Local<v8::debug::Script> DebugStackTraceIterator::GetScript() const { DCHECK(!Done()); Handle<Object> value = frame_inspector_->GetScript(); if (!value->IsScript()) return v8::Local<v8::debug::Script>(); return ToApiHandle<debug::Script>(Handle<Script>::cast(value)); } debug::Location DebugStackTraceIterator::GetSourceLocation() const { DCHECK(!Done()); v8::Local<v8::debug::Script> script = GetScript(); if (script.IsEmpty()) return v8::debug::Location(); return script->GetSourceLocation(frame_inspector_->GetSourcePosition()); } v8::Local<v8::Function> DebugStackTraceIterator::GetFunction() const { DCHECK(!Done()); if (!frame_inspector_->IsJavaScript()) return v8::Local<v8::Function>(); return Utils::ToLocal(frame_inspector_->GetFunction()); } std::unique_ptr<v8::debug::ScopeIterator> DebugStackTraceIterator::GetScopeIterator() const { DCHECK(!Done()); StandardFrame* frame = iterator_.frame(); if (frame->is_wasm_interpreter_entry()) { return std::unique_ptr<v8::debug::ScopeIterator>(new DebugWasmScopeIterator( isolate_, iterator_.frame(), inlined_frame_index_)); } return std::unique_ptr<v8::debug::ScopeIterator>( new DebugScopeIterator(isolate_, frame_inspector_.get())); } bool DebugStackTraceIterator::Restart() { DCHECK(!Done()); if (iterator_.is_wasm()) return false; return LiveEdit::RestartFrame(iterator_.javascript_frame()); } v8::MaybeLocal<v8::Value> DebugStackTraceIterator::Evaluate( v8::Local<v8::String> source, bool throw_on_side_effect) { DCHECK(!Done()); Handle<Object> value; i::SafeForInterruptsScope safe_for_interrupt_scope(isolate_); if (!DebugEvaluate::Local(isolate_, iterator_.frame()->id(), inlined_frame_index_, Utils::OpenHandle(*source), throw_on_side_effect) .ToHandle(&value)) { isolate_->OptionalRescheduleException(false); return v8::MaybeLocal<v8::Value>(); } return Utils::ToLocal(value); } } // namespace internal } // namespace v8