Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(666)

Unified Diff: src/isolate.cc

Issue 2142933003: Move Error methods to C++ (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Handle exception in GetProperty Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/isolate.h ('k') | src/js/messages.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index 13627ad968b26e07249d4c489bbbf3910a2a3e02..5c7423288ffdf3a36087c8d0e562b79e80f8b9c5 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -329,12 +329,34 @@ static Handle<FixedArray> MaybeGrow(Isolate* isolate,
}
class StackTraceHelper {
+ private:
+ enum FrameSkipMode {
+ SKIP_FIRST,
+ SKIP_UNTIL_SEEN,
+ SKIP_NONE,
+ };
+
public:
StackTraceHelper(Isolate* isolate, Handle<Object> caller)
: isolate_(isolate), caller_(caller) {
- // If the caller parameter is a function we skip frames until we're
- // under it before starting to collect.
- seen_caller_ = !caller->IsJSFunction();
+ // The caller parameter can be used to skip a specific set of frames in the
+ // stack trace. It can be:
+ // * null, when called from a standard error constructor. We unconditionally
+ // skip the top frame, which is always a builtin-exit frame for the error
+ // constructor builtin.
+ // * a JSFunction, when called by the user from Error.captureStackTrace().
+ // We skip each frame until encountering the caller function.
+ // * For any other value, all frames are included in the trace.
+ if (caller_.is_null()) {
+ mode_ = SKIP_FIRST;
+ skip_next_frame_ = true;
+ } else if (caller_->IsJSFunction()) {
+ mode_ = SKIP_UNTIL_SEEN;
+ skip_next_frame_ = true;
+ } else {
+ mode_ = SKIP_NONE;
+ skip_next_frame_ = false;
+ }
encountered_strict_function_ = false;
sloppy_frames_ = 0;
}
@@ -356,26 +378,34 @@ class StackTraceHelper {
// Determines whether the given stack frame should be displayed in a stack
// trace.
bool IsVisibleInStackTrace(JSFunction* fun) {
- return IsAfterCaller(fun) && IsNotInNativeScript(fun) &&
+ return ShouldIncludeFrame(fun) && IsNotInNativeScript(fun) &&
IsInSameSecurityContext(fun);
}
int sloppy_frames() const { return sloppy_frames_; }
private:
- // The caller is the error constructor that asked
- // for the stack trace to be collected. The first time a construct
- // call to this function is encountered it is skipped. The seen_caller
- // in/out parameter is used to remember if the caller has been seen
- // yet.
- bool IsAfterCaller(JSFunction* fun) {
- if ((fun == *caller_) && !(seen_caller_)) {
- seen_caller_ = true;
- return false;
+ // 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(JSFunction* fun) {
+ 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_ && (fun == *caller_)) {
+ skip_next_frame_ = false;
+ return false;
+ }
+ return !skip_next_frame_;
}
- // Skip all frames until we've seen the caller.
- if (!seen_caller_) return false;
- return true;
+ UNREACHABLE();
+ return false;
}
bool IsNotInNativeScript(JSFunction* fun) {
@@ -394,9 +424,11 @@ class StackTraceHelper {
}
Isolate* isolate_;
+
+ FrameSkipMode mode_;
Handle<Object> caller_;
+ bool skip_next_frame_;
- bool seen_caller_;
int sloppy_frames_;
bool encountered_strict_function_;
};
@@ -531,8 +563,9 @@ MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace(
Handle<JSArray> stack_trace = CaptureCurrentStackTrace(
stack_trace_for_uncaught_exceptions_frame_limit_,
stack_trace_for_uncaught_exceptions_options_);
+ // TODO(jgruber): Set back to STRICT once we have eagerly formatted traces.
RETURN_ON_EXCEPTION(
- this, JSReceiver::SetProperty(error_object, key, stack_trace, STRICT),
+ this, JSReceiver::SetProperty(error_object, key, stack_trace, SLOPPY),
JSReceiver);
}
return error_object;
@@ -543,8 +576,9 @@ MaybeHandle<JSReceiver> Isolate::CaptureAndSetSimpleStackTrace(
// Capture stack trace for simple stack trace string formatting.
Handle<Name> key = factory()->stack_trace_symbol();
Handle<Object> stack_trace = CaptureSimpleStackTrace(error_object, caller);
+ // TODO(jgruber): Set back to STRICT once we have eagerly formatted traces.
RETURN_ON_EXCEPTION(
- this, JSReceiver::SetProperty(error_object, key, stack_trace, STRICT),
+ this, JSReceiver::SetProperty(error_object, key, stack_trace, SLOPPY),
JSReceiver);
return error_object;
}
« no previous file with comments | « src/isolate.h ('k') | src/js/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698