From 1379f4efebb7672478906059449dd6b60fc4806c Mon Sep 17 00:00:00 2001 From: "yurys@chromium.org" Date: Fri, 30 Aug 2013 14:54:59 +0000 Subject: [PATCH] Add scriptId to StackTrace frames. BUG=v8:2865 R=verwaest@chromium.org, yurys@chromium.org Review URL: https://codereview.chromium.org/23536007 Patch from Vsevolod Vlasov . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16459 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 10 ++++++++++ src/api.cc | 16 ++++++++++++++++ src/isolate.cc | 15 +++++++++++++-- test/cctest/test-api.cc | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/include/v8.h b/include/v8.h index cfc1de6..c94e510 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1157,6 +1157,7 @@ class V8_EXPORT Message { static const int kNoLineNumberInfo = 0; static const int kNoColumnInfo = 0; + static const int kNoScriptIdInfo = 0; }; @@ -1179,6 +1180,7 @@ class V8_EXPORT StackTrace { kIsEval = 1 << 4, kIsConstructor = 1 << 5, kScriptNameOrSourceURL = 1 << 6, + kScriptId = 1 << 7, kOverview = kLineNumber | kColumnOffset | kScriptName | kFunctionName, kDetailed = kOverview | kIsEval | kIsConstructor | kScriptNameOrSourceURL }; @@ -1234,6 +1236,14 @@ class V8_EXPORT StackFrame { int GetColumn() const; /** + * Returns the id of the script for the function for this StackFrame. + * This method will return Message::kNoScriptIdInfo if it is unable to + * retrieve the script id, or if kScriptId was not passed as an option when + * capturing the StackTrace. + */ + int GetScriptId() const; + + /** * Returns the name of the resource that contains the script for the * function for this StackFrame. */ diff --git a/src/api.cc b/src/api.cc index 937e7c4..3e1f9fe 100644 --- a/src/api.cc +++ b/src/api.cc @@ -2356,6 +2356,22 @@ int StackFrame::GetColumn() const { } +int StackFrame::GetScriptId() const { + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); + if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptId()")) { + return Message::kNoScriptIdInfo; + } + ENTER_V8(isolate); + i::HandleScope scope(isolate); + i::Handle self = Utils::OpenHandle(this); + i::Handle scriptId = GetProperty(self, "scriptId"); + if (!scriptId->IsSmi()) { + return Message::kNoScriptIdInfo; + } + return i::Smi::cast(*scriptId)->value(); +} + + Local StackFrame::GetScriptName() const { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) { diff --git a/src/isolate.cc b/src/isolate.cc index d0b6d46..0e7b6d5 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -734,7 +734,9 @@ Handle Isolate::CaptureCurrentStackTrace( factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("column")); Handle line_key = factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("lineNumber")); - Handle script_key = + Handle script_id_key = + factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("scriptId")); + Handle script_name_key = factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("scriptName")); Handle script_name_or_source_url_key = factory()->InternalizeOneByteString( @@ -790,11 +792,20 @@ Handle Isolate::CaptureCurrentStackTrace( Handle(Smi::FromInt(line_number + 1), this), NONE)); } + if (options & StackTrace::kScriptId) { + Handle script_id(script->id(), this); + CHECK_NOT_EMPTY_HANDLE(this, + JSObject::SetLocalPropertyIgnoreAttributes( + stack_frame, script_id_key, script_id, + NONE)); + } + if (options & StackTrace::kScriptName) { Handle script_name(script->name(), this); CHECK_NOT_EMPTY_HANDLE(this, JSObject::SetLocalPropertyIgnoreAttributes( - stack_frame, script_key, script_name, NONE)); + stack_frame, script_name_key, script_name, + NONE)); } if (options & StackTrace::kScriptNameOrSourceURL) { diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index ccf1cbd..91f377a 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -16665,6 +16665,42 @@ TEST(SourceURLInStackTrace) { } +static int scriptIdInStack[2]; + +void AnalyzeScriptIdInStack( + const v8::FunctionCallbackInfo& args) { + v8::HandleScope scope(args.GetIsolate()); + v8::Handle stackTrace = + v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kScriptId); + CHECK_EQ(2, stackTrace->GetFrameCount()); + for (int i = 0; i < 2; i++) { + scriptIdInStack[i] = stackTrace->GetFrame(i)->GetScriptId(); + } +} + + +TEST(ScriptIdInStackTrace) { + v8::HandleScope scope(v8::Isolate::GetCurrent()); + Local templ = ObjectTemplate::New(); + templ->Set(v8_str("AnalyzeScriptIdInStack"), + v8::FunctionTemplate::New(AnalyzeScriptIdInStack)); + LocalContext context(0, templ); + + v8::Handle scriptSource = v8::String::New( + "function foo() {\n" + " AnalyzeScriptIdInStack();" + "}\n" + "foo();\n"); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test")); + v8::Local script(v8::Script::Compile(scriptSource, &origin)); + script->Run(); + for (int i = 0; i < 2; i++) { + CHECK(scriptIdInStack[i] != v8::Message::kNoScriptIdInfo); + CHECK_EQ(scriptIdInStack[i], script->GetId()); + } +} + + void AnalyzeStackOfInlineScriptWithSourceURL( const v8::FunctionCallbackInfo& args) { v8::HandleScope scope(args.GetIsolate()); -- 2.7.4