LGTM.
top.cc:696: I would probably indent like this:
Handle<Object> message =
MessageHandler::MakeMessageObject("uncaught_exception",
location,
HandleVector<Object>(&exception, 1),
stack_trace);
test-api.cc:4865: I would probably indent like this:
v8::Handle<v8::Script> script =
v8::Script::Compile(source, v8::String::New("test.js"));
On Tue, Sep 9, 2008 at 2:18 PM, <[EMAIL PROTECTED]> wrote:
> I'd like you to do a code review. To review this change, run
>
> gvn review --project https://v8.googlecode.com/svn
[EMAIL PROTECTED]/[EMAIL PROTECTED]
>
> Alternatively, to review the latest snapshot of this change
> branch, run
>
> gvn --project https://v8.googlecode.com/svn review
[EMAIL PROTECTED]/try-catch-src-info
>
> to review the following change:
>
> [EMAIL PROTECTED]/[EMAIL PROTECTED] |
[EMAIL PROTECTED] | 2008-09-09 13:16:57 +-100 (Tue, 09 Sep
2008)
>
> Description:
>
> Added source info to TryCatches. Reorganized exception messaging
> somewhat and folded stack traces into message. Use of this in the
> shell will follow in a separate changelist.
>
>
>
>
> Affected Paths:
> M //branches/bleeding_edge/include/v8.h
> M //branches/bleeding_edge/src/api.cc
> M //branches/bleeding_edge/src/debug.cc
> M //branches/bleeding_edge/src/messages.cc
> M //branches/bleeding_edge/src/messages.h
> M //branches/bleeding_edge/src/messages.js
> M //branches/bleeding_edge/src/top.cc
> M //branches/bleeding_edge/src/top.h
> M //branches/bleeding_edge/test/cctest/test-api.cc
>
>
> This is a semiautomated message from "gvn mail". See
> <http://code.google.com/p/gvn/> to learn more.
>
> Index: include/v8.h
> ===================================================================
> --- include/v8.h (^/branches/bleeding_edge/include/[EMAIL PROTECTED])
> +++ include/v8.h (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/include/[EMAIL PROTECTED]
)
> @@ -553,7 +553,7 @@ class EXPORT Script {
> class EXPORT Message {
> public:
> Local<String> Get();
> - Local<Value> GetSourceLine();
> + Local<String> GetSourceLine();
>
> // TODO(1241256): Rewrite (or remove) this method. We don't want to
> // deal with ownership of the returned string and we want to use
> @@ -566,8 +566,41 @@ class EXPORT Message {
> // bindings.
> Handle<Value> GetSourceData();
>
> + /**
> + * Returns the number, 1-based, of the line where the error occurred.
> + */
> int GetLineNumber();
>
> + /**
> + * Returns the index within the script of the first character where
> + * the error occurred.
> + */
> + int GetStartPosition();
> +
> + /**
> + * Returns the index within the script of the last character where
> + * the error occurred.
> + */
> + int GetEndPosition();
> +
> + /**
> + * Returns the index within the line of the first character where
> + * the error occurred.
> + */
> + int GetStartColumn();
> +
> + /**
> + * Returns the index within the line of the last character where
> + * the error occurred.
> + */
> + int GetEndColumn();
> +
> + /**
> + * Returns a string stack trace if trace_exceptions is enabled and
> + * one is available.
> + */
> + Local<String> GetStackTrace();
> +
> // TODO(1245381): Print to a string instead of on a FILE.
> static void PrintCurrentStackTrace(FILE* out);
> };
> @@ -1912,6 +1945,15 @@ class EXPORT TryCatch {
> Local<Value> Exception();
>
> /**
> + * Returns the message associated with this exception. If there is
> + * no message associated an empty handle is returned.
> + *
> + * The returned handle is valid until this TryCatch block has been
> + * destroyed.
> + */
> + Local<v8::Message> Message();
> +
> + /**
> * Clears any exceptions that may have been caught by this try/catch
block.
> * After this method has been called, HasCaught() will return false.
> *
> @@ -1935,6 +1977,7 @@ class EXPORT TryCatch {
> public:
> TryCatch* next_;
> void* exception_;
> + void* message_;
> bool is_verbose_;
> };
>
> Index: src/api.cc
> ===================================================================
> --- src/api.cc (^/branches/bleeding_edge/src/[EMAIL PROTECTED])
> +++ src/api.cc (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/[EMAIL PROTECTED]
)
> @@ -1081,6 +1081,7 @@ Local<Value> Script::Run() {
> v8::TryCatch::TryCatch()
> : next_(i::Top::try_catch_handler()),
> exception_(i::Heap::the_hole_value()),
> + message_(i::Smi::FromInt(0)),
> is_verbose_(false) {
> i::Top::RegisterTryCatchHandler(this);
> }
> @@ -1107,8 +1108,19 @@ v8::Local<Value> v8::TryCatch::Exception() {
> }
>
>
> +v8::Local<v8::Message> v8::TryCatch::Message() {
> + if (HasCaught() && message_ != i::Smi::FromInt(0)) {
> + i::Object* message = reinterpret_cast<i::Object*>(message_);
> + return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
> + } else {
> + return v8::Local<v8::Message>();
> + }
> +}
> +
> +
> void v8::TryCatch::Reset() {
> exception_ = i::Heap::the_hole_value();
> + message_ = i::Smi::FromInt(0);
> }
>
>
> @@ -1196,15 +1208,80 @@ int Message::GetLineNumber() {
> }
>
>
> -Local<Value> Message::GetSourceLine() {
> - ON_BAILOUT("v8::Message::GetSourceLine()", return Local<Value>());
> +int Message::GetStartPosition() {
> + if (IsDeadCheck("v8::Message::GetStartPosition()")) return 0;
> HandleScope scope;
> +
> + i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
> + return static_cast<int>(GetProperty(data_obj, "startPos")->Number());
> +}
> +
> +
> +int Message::GetEndPosition() {
> + if (IsDeadCheck("v8::Message::GetEndPosition()")) return 0;
> + HandleScope scope;
> + i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
> + return static_cast<int>(GetProperty(data_obj, "endPos")->Number());
> +}
> +
> +
> +int Message::GetStartColumn() {
> + if (IsDeadCheck("v8::Message::GetStartColumn()")) return 0;
> + HandleScope scope;
> + i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
> EXCEPTION_PREAMBLE();
> + i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
> + "GetPositionInLine",
> + data_obj,
> + &has_pending_exception);
> + EXCEPTION_BAILOUT_CHECK(0);
> + return static_cast<int>(start_col_obj->Number());
> +}
> +
> +
> +int Message::GetEndColumn() {
> + if (IsDeadCheck("v8::Message::GetEndColumn()")) return 0;
> + HandleScope scope;
> + i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
> + EXCEPTION_PREAMBLE();
> + i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
> + "GetPositionInLine",
> + data_obj,
> + &has_pending_exception);
> + EXCEPTION_BAILOUT_CHECK(0);
> + int start = static_cast<int>(GetProperty(data_obj,
"startPos")->Number());
> + int end = static_cast<int>(GetProperty(data_obj, "endPos")->Number());
> + return static_cast<int>(start_col_obj->Number()) + (end - start);
> +}
> +
> +
> +v8::Local<v8::String> Message::GetStackTrace() {
> + if (IsDeadCheck("v8::Message::GetStackTrace()"))
> + return v8::Local<v8::String>();
> + HandleScope scope;
> + i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
> + i::Handle<i::Object> trace = GetProperty(data_obj, "stackTrace");
> + if (trace->IsString()) {
> + return
scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(trace)));
> + } else {
> + return Local<String>();
> + }
> +}
> +
> +
> +Local<String> Message::GetSourceLine() {
> + ON_BAILOUT("v8::Message::GetSourceLine()", return Local<String>());
> + HandleScope scope;
> + EXCEPTION_PREAMBLE();
> i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
>
Utils::OpenHandle(this),
>
&has_pending_exception);
> - EXCEPTION_BAILOUT_CHECK(Local<v8::Value>());
> - return scope.Close(Utils::ToLocal(result));
> + EXCEPTION_BAILOUT_CHECK(Local<v8::String>());
> + if (result->IsString()) {
> + return
scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
> + } else {
> + return Local<String>();
> + }
> }
>
>
> Index: src/debug.cc
> ===================================================================
> --- src/debug.cc (^/branches/bleeding_edge/src/[EMAIL PROTECTED])
> +++ src/debug.cc (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/[EMAIL PROTECTED]
)
> @@ -537,8 +537,10 @@ bool Debug::CompileDebuggerScript(int index) {
>
> // Check for caught exceptions.
> if (caught_exception) {
> - MessageHandler::ReportMessage("error_loading_debugger", NULL,
> - HandleVector<Object>(&result, 1));
> + Handle<Object> message = MessageHandler::MakeMessageObject(
> + "error_loading_debugger", NULL, HandleVector<Object>(&result, 1),
> + Handle<String>());
> + MessageHandler::ReportMessage(NULL, message);
> return false;
> }
>
> Index: src/messages.cc
> ===================================================================
> --- src/messages.cc (^/branches/bleeding_edge/src/[EMAIL PROTECTED])
> +++ src/messages.cc (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/[EMAIL PROTECTED]
)
> @@ -60,8 +60,11 @@ void MessageHandler::ReportMessage(const char* msg
> }
>
>
> -void MessageHandler::ReportMessage(const char* type, MessageLocation*
loc,
> - Vector< Handle<Object> > args) {
> +Handle<Object> MessageHandler::MakeMessageObject(
> + const char* type,
> + MessageLocation* loc,
> + Vector< Handle<Object> > args,
> + Handle<String> stack_trace) {
> // Build error message object
> HandleScope scope;
> Handle<Object> type_str = Factory::LookupAsciiSymbol(type);
> @@ -82,12 +85,16 @@ void MessageHandler::ReportMessage(const char* msg
> }
> Handle<Object> start_handle(Smi::FromInt(start));
> Handle<Object> end_handle(Smi::FromInt(end));
> - const int argc = 5;
> + Handle<Object> stack_trace_val = stack_trace.is_null()
> + ? Factory::undefined_value()
> + : Handle<Object>::cast(stack_trace);
> + const int argc = 6;
> Object** argv[argc] = { type_str.location(),
> array.location(),
> start_handle.location(),
> end_handle.location(),
> - script.location() };
> + script.location(),
> + stack_trace_val.location() };
>
> bool caught_exception = false;
> Handle<Object> message =
> @@ -97,8 +104,13 @@ void MessageHandler::ReportMessage(const char* msg
> // skip doing the callback. This usually only happens in case of
> // stack overflow exceptions being thrown by the parser when the
> // stack is almost full.
> - if (caught_exception) return;
> + if (caught_exception) return Handle<Object>();
> + return message.EscapeFrom(&scope);
> +}
>
> +
> +void MessageHandler::ReportMessage(MessageLocation* loc,
> + Handle<Object> message) {
> v8::Local<v8::Message> api_message_obj =
v8::Utils::MessageToLocal(message);
>
> v8::NeanderArray global_listeners(Factory::message_listeners());
> Index: src/messages.h
> ===================================================================
> --- src/messages.h (^/branches/bleeding_edge/src/[EMAIL PROTECTED])
> +++ src/messages.h (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/[EMAIL PROTECTED]
)
> @@ -70,6 +70,7 @@ class MessageLocation {
> : script_(script),
> start_pos_(start_pos),
> end_pos_(end_pos) { }
> + MessageLocation() : start_pos_(-1), end_pos_(-1) { }
>
> Handle<Script> script() const { return script_; }
> int start_pos() const { return start_pos_; }
> @@ -89,10 +90,14 @@ class MessageHandler {
> // Report a message (w/o JS heap allocation).
> static void ReportMessage(const char* msg);
>
> + // Returns a message object for the API to use.
> + static Handle<Object> MakeMessageObject(const char* type,
> + MessageLocation* loc,
> + Vector< Handle<Object> > args,
> + Handle<String> stack_trace);
> +
> // Report a formatted message (needs JS allocation).
> - static void ReportMessage(const char* type,
> - MessageLocation* loc,
> - Vector< Handle<Object> > args);
> + static void ReportMessage(MessageLocation* loc, Handle<Object>
message);
>
> static void DefaultMessageReport(const MessageLocation* loc,
> Handle<Object> message_obj);
> Index: src/messages.js
> ===================================================================
> --- src/messages.js (^/branches/bleeding_edge/src/[EMAIL PROTECTED])
> +++ src/messages.js (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/[EMAIL PROTECTED]
)
> @@ -555,17 +555,18 @@ function GetPositionInLine(message) {
> };
>
>
> -function ErrorMessage(type, args, startPos, endPos, script) {
> +function ErrorMessage(type, args, startPos, endPos, script, stackTrace) {
> this.startPos = startPos;
> this.endPos = endPos;
> this.type = type;
> this.args = args;
> this.script = script;
> + this.stackTrace = stackTrace;
> };
>
>
> -function MakeMessage(type, args, startPos, endPos, script) {
> - return new ErrorMessage(type, args, startPos, endPos, script);
> +function MakeMessage(type, args, startPos, endPos, script, stackTrace) {
> + return new ErrorMessage(type, args, startPos, endPos, script,
stackTrace);
> };
>
>
> Index: src/top.cc
> ===================================================================
> --- src/top.cc (^/branches/bleeding_edge/src/[EMAIL PROTECTED])
> +++ src/top.cc (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/[EMAIL PROTECTED]
)
> @@ -79,6 +79,7 @@ void Top::Iterate(ObjectVisitor* v, ThreadLocalTop
> block != NULL;
> block = block->next_) {
> VISIT(reinterpret_cast<Object*&>(block->exception_));
> + VISIT(reinterpret_cast<Object*&>(block->message_));
> }
>
> // Iterate over pointers on native execution stack.
> @@ -671,39 +672,34 @@ void Top::PrintCurrentStackTrace(FILE* out) {
> }
>
>
> +void Top::ComputeLocation(MessageLocation* target) {
> + *target = MessageLocation(empty_script(), -1, -1);
> + StackTraceFrameIterator it;
> + if (!it.done()) {
> + JavaScriptFrame* frame = it.frame();
> + JSFunction* fun = JSFunction::cast(frame->function());
> + Object* script = fun->shared()->script();
> + if (script->IsScript() &&
> + !(Script::cast(script)->source()->IsUndefined())) {
> + int pos = frame->FindCode()->SourcePosition(frame->pc());
> + // Compute the location from the function and the reloc info.
> + Handle<Script> casted_script(Script::cast(script));
> + *target = MessageLocation(casted_script, pos, pos + 1);
> + }
> + }
> +}
> +
> +
> void Top::ReportUncaughtException(Handle<Object> exception,
> MessageLocation* location,
> Handle<String> stack_trace) {
> - MessageLocation computed_location(empty_script(), -1, -1);
> - if (location == NULL) {
> - location = &computed_location;
> + Handle<Object> message = MessageHandler::MakeMessageObject(
> + "uncaught_exception", location, HandleVector<Object>(&exception,
1),
> + stack_trace);
>
> - StackTraceFrameIterator it;
> - if (!it.done()) {
> - JavaScriptFrame* frame = it.frame();
> - JSFunction* fun = JSFunction::cast(frame->function());
> - Object* script = fun->shared()->script();
> - if (script->IsScript() &&
> - !(Script::cast(script)->source()->IsUndefined())) {
> - int pos = frame->FindCode()->SourcePosition(frame->pc());
> - // Compute the location from the function and the reloc info.
> - Handle<Script> casted_script(Script::cast(script));
> - computed_location = MessageLocation(casted_script, pos, pos + 1);
> - }
> - }
> - }
>
> // Report the uncaught exception.
> - MessageHandler::ReportMessage("uncaught_exception",
> - location,
> - HandleVector<Object>(&exception, 1));
> -
> - // Optionally, report the stack trace separately.
> - if (!stack_trace.is_null()) {
> - MessageHandler::ReportMessage("stack_trace",
> - location,
> - HandleVector<String>(&stack_trace, 1));
> - }
> + MessageHandler::ReportMessage(location, message);
> }
>
>
> @@ -771,12 +767,30 @@ void Top::DoThrow(Object* exception,
> ShouldReportException(&is_caught_externally);
> if (is_rethrow) report_exception = false;
>
> + Handle<Object> message_obj;
> + MessageLocation potential_computed_location;
> + if (is_caught_externally || report_exception) {
> + if (location == NULL) {
> + // If no location was specified we use a computed one instead
> + ComputeLocation(&potential_computed_location);
> + location = &potential_computed_location;
> + }
> + Handle<String> stack_trace;
> + if (FLAG_trace_exception) stack_trace = StackTrace();
> + message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
> + location, HandleVector<Object>(&exception_handle, 1),
stack_trace);
> + }
> +
> // If the exception is caught externally, we store it in the
> // try/catch handler. The C code can find it later and process it if
> // necessary.
> if (is_caught_externally) {
> thread_local_.try_catch_handler_->exception_ =
> reinterpret_cast<void*>(*exception_handle);
> + if (!message_obj.is_null()) {
> + thread_local_.try_catch_handler_->message_ =
> + reinterpret_cast<void*>(*message_obj);
> + }
> }
>
> // Notify debugger of exception.
> @@ -786,9 +800,7 @@ void Top::DoThrow(Object* exception,
> if (message != NULL) {
> MessageHandler::ReportMessage(message);
> } else {
> - Handle<String> stack_trace;
> - if (FLAG_trace_exception) stack_trace = StackTrace();
> - ReportUncaughtException(exception_handle, location, stack_trace);
> + MessageHandler::ReportMessage(location, message_obj);
> }
> }
> thread_local_.external_caught_exception_ = is_caught_externally;
> Index: src/top.h
> ===================================================================
> --- src/top.h (^/branches/bleeding_edge/src/[EMAIL PROTECTED])
> +++ src/top.h (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/[EMAIL PROTECTED]
)
> @@ -226,6 +226,10 @@ class Top {
> MessageLocation* location,
> Handle<String> stack_trace);
>
> + // Attempts to compute the current source location, storing the
> + // result in the target out parameter.
> + static void ComputeLocation(MessageLocation* target);
> +
> // Override command line flag.
> static void TraceException(bool flag);
>
> Index: test/cctest/test-api.cc
> ===================================================================
> --- test/cctest/test-api.cc
(^/branches/bleeding_edge/test/cctest/[EMAIL PROTECTED])
> +++ test/cctest/test-api.cc (^/changes/
[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/test/cctest/[EMAIL PROTECTED]
)
> @@ -4843,3 +4843,40 @@ THREADED_TEST(Regress54) {
> v8::Handle<v8::Object> result = templ->NewInstance();
> CHECK_EQ(1, result->InternalFieldCount());
> }
> +
> +
> +THREADED_TEST(TryCatchSourceInfo) {
> + v8::HandleScope scope;
> + LocalContext context;
> + v8::Handle<v8::String> source = v8::String::New(
> + "function Foo() {\n"
> + " return Bar();\n"
> + "}\n"
> + "\n"
> + "function Bar() {\n"
> + " return Baz();\n"
> + "}\n"
> + "\n"
> + "function Baz() {\n"
> + " throw 'nirk';\n"
> + "}\n"
> + "\n"
> + "Foo();\n");
> + v8::Handle<v8::Script> script = v8::Script::Compile(source,
> + v8::String::New("test.js"));
> + v8::TryCatch try_catch;
> + v8::Handle<v8::Value> result = script->Run();
> + CHECK(result.IsEmpty());
> + CHECK(try_catch.HasCaught());
> + v8::Handle<v8::Message> message = try_catch.Message();
> + CHECK(!message.IsEmpty());
> + CHECK_EQ(10, message->GetLineNumber());
> + CHECK_EQ(91, message->GetStartPosition());
> + CHECK_EQ(92, message->GetEndPosition());
> + CHECK_EQ(2, message->GetStartColumn());
> + CHECK_EQ(3, message->GetEndColumn());
> + v8::String::AsciiValue line(message->GetSourceLine());
> + CHECK_EQ(" throw 'nirk';", *line);
> + v8::String::AsciiValue name(message->GetScriptResourceName());
> + CHECK_EQ("test.js", *name);
> +}
>
>
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---