code(exit_frame->LookupCode(), isolate_); const int offset = static_cast(exit_frame->pc() - code->InstructionStart()); int flags = 0; if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict; if (exit_frame->IsConstructor()) flags |= FrameArray::kIsConstructor; elements_ = FrameArray::AppendJSFrame(elements_, receiver, function, Handle::cast(code), offset, flags); } bool full() { return elements_->FrameCount() >= limit_; } Handle GetElements() { elements_->ShrinkToFit(isolate_); return elements_; } private: // Poison stack frames below the first strict mode frame. // The stack trace API should not expose receivers and function // objects on frames deeper than the top-most one with a strict mode // function. bool IsStrictFrame(Handle function) { if (!encountered_strict_function_) { encountered_strict_function_ = is_strict(function->shared()->language_mode()); } return encountered_strict_function_; } // Determines whether the given stack frame should be displayed in a stack // trace. bool IsVisibleInStackTrace(Handle function) { return ShouldIncludeFrame(function) && IsNotHidden(function) && IsInSameSecurityContext(function); } // This mechanism excludes a number of uninteresting frames from the stack // trace. This can be be the first frame (which will be a builtin-exit frame // for the error constructor builtin) or every frame until encountering a // user-specified function. bool ShouldIncludeFrame(Handle function) { switch (mode_) { case SKIP_NONE: return true; case SKIP_FIRST: if (!skip_next_frame_) return true; skip_next_frame_ = false; return false; case SKIP_UNTIL_SEEN: if (skip_next_frame_ && (*function == *caller_)) { skip_next_frame_ = false; return false; } return !skip_next_frame_; } UNREACHABLE(); } bool IsNotHidden(Handle function) { // Functions defined not in user scripts are not visible unless directly // exposed, in which case the native flag is set. // The --builtins-in-stack-traces command line flag allows including // internal call sites in the stack trace for debugging purposes. if (!FLAG_builtins_in_stack_traces && !function->shared()->IsUserJavaScript()) { return function->shared()->native(); } return true; } bool IsInSameSecurityContext(Handle function) { return isolate_->context()->HasSameSecurityTokenAs(function->context()); } // TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the // receiver in RegExp constructor frames. Handle TheHoleToUndefined(Isolate* isolate, Handle in) { return (in->IsTheHole(isolate)) ? Handle::cast(isolate->factory()->undefined_value()) : in; } Isolate* isolate_; const FrameSkipMode mode_; int limit_; const Handle caller_; bool skip_next_frame_ = true; bool encountered_strict_function_ = false; Handle elements_; }; bool GetStackTraceLimit(Isolate* isolate, int* result) { Handle error = isolate->error_function(); Handle key = isolate->factory()->stackTraceLimit_string(); Handle stack_trace_limit = JSReceiver::GetDataProperty(error, key); if (!stack_trace_limit->IsNumber()) return false; // Ensure that limit is not negative. *result = Max(FastD2IChecked(stack_trace_limit->Number()), 0); if (*result != FLAG_stack_trace_limit) { isolate->CountUsage(v8::Isolate::kErrorStackTraceLimit); } return true; } bool NoExtension(const v8::FunctionCallbackInfo&) { return false; } } // namespace Handle Isolate::CaptureSimpleStackTrace(Handle error_object, FrameSkipMode mode, Handle caller) { DisallowJavascriptExecution no_js(this); int limit; if (!GetStackTraceLimit(this, &limit)) return factory()->undefined_value(); FrameArrayBuilder builder(this, mode, limit, caller); for (StackFrameIterator iter(this); !iter.done() && !builder.full(); iter.Advance()) { StackFrame* frame = iter.frame(); switch (frame->type()) { case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION: case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH: case StackFrame::OPTIMIZED: case StackFrame::INTERPRETED: case StackFrame::BUILTIN: builder.AppendStandardFrame(JavaScriptFrame::cast(frame)); break; case StackFrame::BUILTIN_EXIT: // BuiltinExitFrames are not standard frames, so they do not have // Summarize(). However, they may have one JS frame worth showing. builder.AppendBuiltinExitFrame(BuiltinExitFrame::cast(frame)); break; case StackFrame::WASM_COMPILED: builder.AppendStandardFrame(WasmCompiledFrame::cast(frame)); break; case StackFrame::WASM_INTERPRETER_ENTRY: builder.AppendStandardFrame(WasmInterpreterEntryFrame::cast(frame)); break; default: break; } } // TODO(yangguo): Queue this structured stack trace for preprocessing on GC. return factory()->NewJSArrayWithElements(builder.GetElements()); } MaybeHandle Isolate::CaptureAndSetDetailedStackTrace( Handle error_object) { if (capture_stack_trace_for_uncaught_exceptions_) { // Capture stack trace for a detailed exception message. Handle key = factory()->detailed_stack_trace_symbol(); Handle stack_trace = CaptureCurrentStackTrace( stack_trace_for_uncaught_exceptions_frame_limit_, stack_trace_for_uncaught_exceptions_options_); RETURN_ON_EXCEPTION( this, JSReceiver::SetProperty(this, error_object, key, stack_trace, LanguageMode::kStrict), JSReceiver); } return error_object; } MaybeHandle Isolate::CaptureAndSetSimpleStackTrace( Handle error_object, FrameSkipMode mode, Handle caller) { // Capture stack trace for simple stack trace string formatting. Handle key = factory()->stack_trace_symbol(); Handle stack_trace = CaptureSimpleStackTrace(error_object, mode, caller); RETURN_ON_EXCEPTION( this, JSReceiver::SetProperty(this, error_object, key, stack_trace, LanguageMode::kStrict), JSReceiver); return error_object; } Handle Isolate::GetDetailedStackTrace( Handle error_object) { Handle key_detailed = factory()->detailed_stack_trace_symbol(); Handle stack_trace = JSReceiver::GetDataProperty(error_object, key_detailed); if (stack_trace->IsFixedArray()) return Handle::cast(stack_trace); return Handle(); } Address Isolate::GetAbstractPC(int* line, int* column) { JavaScriptFrameIterator it(this); if (it.done()) { *line = -1; *column = -1; return kNullAddress; } JavaScriptFrame* frame = it.frame(); DCHECK(!frame->is_builtin()); int position = frame->position(); Object* maybe_script = frame->function()->shared()->script(); if (maybe_script->IsScript()) { Handle 登录后可以享受更多权益 您还没有登录,登录后您可以: 收藏Android系统代码 收藏喜欢的文章 多个平台共享账号 去登录 首次使用?从这里 注册
您还没有登录,登录后您可以:
首次使用?从这里 注册