Introduce v8::Exception::GetStackTrace API method.

This will be needed to get a stack trace from a DOMException.

API=v8::Exception::GetStackTrace
R=yangguo@chromium.org
LOG=Y

Review URL: https://codereview.chromium.org/655243002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24655 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
aandrey@chromium.org 2014-10-16 10:42:08 +00:00
parent 0840abf37b
commit b96b570628
3 changed files with 58 additions and 0 deletions

View File

@ -4164,6 +4164,8 @@ class V8_EXPORT Exception {
static Local<Value> SyntaxError(Handle<String> message);
static Local<Value> TypeError(Handle<String> message);
static Local<Value> Error(Handle<String> message);
static Local<StackTrace> GetStackTrace(Handle<Value> exception);
};

View File

@ -6926,6 +6926,21 @@ DEFINE_ERROR(Error)
#undef DEFINE_ERROR
Local<StackTrace> Exception::GetStackTrace(Handle<Value> exception) {
i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
if (!obj->IsJSObject()) return Local<StackTrace>();
i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
i::Isolate* isolate = js_obj->GetIsolate();
ENTER_V8(isolate);
i::Handle<i::Name> key = isolate->factory()->detailed_stack_trace_symbol();
i::Handle<i::Object> property = i::JSObject::GetDataProperty(js_obj, key);
if (property->IsJSArray()) {
return Utils::StackTraceToLocal(i::Handle<i::JSArray>::cast(property));
}
return Local<StackTrace>();
}
// --- D e b u g S u p p o r t ---
bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {

View File

@ -8504,6 +8504,47 @@ THREADED_TEST(ErrorConstruction) {
}
static void ThrowV8Exception(const v8::FunctionCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
v8::Handle<String> foo = v8_str("foo");
v8::Handle<String> message = v8_str("message");
v8::Handle<Value> error = v8::Exception::Error(foo);
CHECK(error->IsObject());
CHECK(error.As<v8::Object>()->Get(message)->Equals(foo));
info.GetIsolate()->ThrowException(error);
info.GetReturnValue().SetUndefined();
}
THREADED_TEST(ExceptionGetStackTrace) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
Local<v8::FunctionTemplate> fun =
v8::FunctionTemplate::New(context->GetIsolate(), ThrowV8Exception);
v8::Local<v8::Object> global = context->Global();
global->Set(v8_str("throwV8Exception"), fun->GetFunction());
TryCatch try_catch;
CompileRun("function f1() { throwV8Exception(); }; f1();");
CHECK(try_catch.HasCaught());
v8::Handle<v8::Value> error = try_catch.Exception();
v8::Handle<String> foo = v8_str("foo");
v8::Handle<String> message = v8_str("message");
CHECK(error->IsObject());
CHECK(error.As<v8::Object>()->Get(message)->Equals(foo));
v8::Handle<v8::StackTrace> stackTrace = v8::Exception::GetStackTrace(error);
CHECK(!stackTrace.IsEmpty());
CHECK_EQ(2, stackTrace->GetFrameCount());
v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
}
static void YGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();