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

Side by Side Diff: src/isolate.cc

Issue 687253002: Introduce v8::Exception::GetMessage to find location of an error object. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: relanding Created 6 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/isolate.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 6
7 #include <fstream> // NOLINT(readability/streams) 7 #include <fstream> // NOLINT(readability/streams)
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/v8.h" 10 #include "src/v8.h"
(...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 !(Script::cast(script)->source()->IsUndefined())) { 1040 !(Script::cast(script)->source()->IsUndefined())) {
1041 int pos = frame->LookupCode()->SourcePosition(frame->pc()); 1041 int pos = frame->LookupCode()->SourcePosition(frame->pc());
1042 // Compute the location from the function and the reloc info. 1042 // Compute the location from the function and the reloc info.
1043 Handle<Script> casted_script(Script::cast(script)); 1043 Handle<Script> casted_script(Script::cast(script));
1044 *target = MessageLocation(casted_script, pos, pos + 1); 1044 *target = MessageLocation(casted_script, pos, pos + 1);
1045 } 1045 }
1046 } 1046 }
1047 } 1047 }
1048 1048
1049 1049
1050 void Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
1051 Handle<Object> exception) {
1052 *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1);
1053
1054 if (!exception->IsJSObject()) return;
1055 Handle<Name> key = factory()->stack_trace_symbol();
1056 Handle<Object> property =
1057 JSObject::GetDataProperty(Handle<JSObject>::cast(exception), key);
1058 if (!property->IsJSArray()) return;
1059 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
1060
1061 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements()));
1062 int elements_limit = Smi::cast(simple_stack_trace->length())->value();
1063
1064 for (int i = 1; i < elements_limit; i += 4) {
1065 Handle<JSFunction> fun =
1066 handle(JSFunction::cast(elements->get(i + 1)), this);
1067 if (fun->IsFromNativeScript()) continue;
1068 Handle<Code> code = handle(Code::cast(elements->get(i + 2)), this);
1069 Handle<Smi> offset = handle(Smi::cast(elements->get(i + 3)), this);
1070 Address pc = code->address() + offset->value();
1071
1072 Object* script = fun->shared()->script();
1073 if (script->IsScript() &&
1074 !(Script::cast(script)->source()->IsUndefined())) {
1075 int pos = code->SourcePosition(pc);
1076 Handle<Script> casted_script(Script::cast(script));
1077 *target = MessageLocation(casted_script, pos, pos + 1);
1078 break;
1079 }
1080 }
1081 }
1082
1083
1050 bool Isolate::ShouldReportException(bool* can_be_caught_externally, 1084 bool Isolate::ShouldReportException(bool* can_be_caught_externally,
1051 bool catchable_by_javascript) { 1085 bool catchable_by_javascript) {
1052 // Find the top-most try-catch handler. 1086 // Find the top-most try-catch handler.
1053 StackHandler* handler = 1087 StackHandler* handler =
1054 StackHandler::FromAddress(Isolate::handler(thread_local_top())); 1088 StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1055 while (handler != NULL && !handler->is_catch()) { 1089 while (handler != NULL && !handler->is_catch()) {
1056 handler = handler->next(); 1090 handler = handler->next();
1057 } 1091 }
1058 1092
1059 // Get the address of the external handler so we can compare the address to 1093 // Get the address of the external handler so we can compare the address to
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 } 1133 }
1100 return false; 1134 return false;
1101 } 1135 }
1102 1136
1103 static int fatal_exception_depth = 0; 1137 static int fatal_exception_depth = 0;
1104 1138
1105 1139
1106 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception, 1140 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception,
1107 MessageLocation* location) { 1141 MessageLocation* location) {
1108 Handle<JSArray> stack_trace_object; 1142 Handle<JSArray> stack_trace_object;
1143 MessageLocation potential_computed_location;
1109 if (capture_stack_trace_for_uncaught_exceptions_) { 1144 if (capture_stack_trace_for_uncaught_exceptions_) {
1110 if (IsErrorObject(exception)) { 1145 if (IsErrorObject(exception)) {
1111 // We fetch the stack trace that corresponds to this error object. 1146 // We fetch the stack trace that corresponds to this error object.
1112 // If the lookup fails, the exception is probably not a valid Error 1147 // If the lookup fails, the exception is probably not a valid Error
1113 // object. In that case, we fall through and capture the stack trace 1148 // object. In that case, we fall through and capture the stack trace
1114 // at this throw site. 1149 // at this throw site.
1115 stack_trace_object = 1150 stack_trace_object =
1116 GetDetailedStackTrace(Handle<JSObject>::cast(exception)); 1151 GetDetailedStackTrace(Handle<JSObject>::cast(exception));
1152 if (!location) {
1153 ComputeLocationFromStackTrace(&potential_computed_location, exception);
1154 location = &potential_computed_location;
1155 }
1117 } 1156 }
1118 if (stack_trace_object.is_null()) { 1157 if (stack_trace_object.is_null()) {
1119 // Not an error object, we capture at throw site. 1158 // Not an error object, we capture stack and location at throw site.
1120 stack_trace_object = CaptureCurrentStackTrace( 1159 stack_trace_object = CaptureCurrentStackTrace(
1121 stack_trace_for_uncaught_exceptions_frame_limit_, 1160 stack_trace_for_uncaught_exceptions_frame_limit_,
1122 stack_trace_for_uncaught_exceptions_options_); 1161 stack_trace_for_uncaught_exceptions_options_);
1123 } 1162 }
1124 } 1163 }
1164 if (!location) {
1165 ComputeLocation(&potential_computed_location);
1166 location = &potential_computed_location;
1167 }
1125 1168
1126 // If the exception argument is a custom object, turn it into a string 1169 // If the exception argument is a custom object, turn it into a string
1127 // before throwing as uncaught exception. Note that the pending 1170 // before throwing as uncaught exception. Note that the pending
1128 // exception object to be set later must not be turned into a string. 1171 // exception object to be set later must not be turned into a string.
1129 if (exception->IsJSObject() && !IsErrorObject(exception)) { 1172 if (exception->IsJSObject() && !IsErrorObject(exception)) {
1130 MaybeHandle<Object> maybe_exception = 1173 MaybeHandle<Object> maybe_exception =
1131 Execution::ToDetailString(this, exception); 1174 Execution::ToDetailString(this, exception);
1132 if (!maybe_exception.ToHandle(&exception)) { 1175 if (!maybe_exception.ToHandle(&exception)) {
1133 exception = 1176 exception =
1134 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("exception")); 1177 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("exception"));
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 1263
1221 if (bootstrapper()->IsActive()) { 1264 if (bootstrapper()->IsActive()) {
1222 // It's not safe to try to make message objects or collect stack traces 1265 // It's not safe to try to make message objects or collect stack traces
1223 // while the bootstrapper is active since the infrastructure may not have 1266 // while the bootstrapper is active since the infrastructure may not have
1224 // been properly initialized. 1267 // been properly initialized.
1225 ReportBootstrappingException(exception_handle, location); 1268 ReportBootstrappingException(exception_handle, location);
1226 } else { 1269 } else {
1227 Handle<Object> message_obj = CreateMessage(exception_handle, location); 1270 Handle<Object> message_obj = CreateMessage(exception_handle, location);
1228 1271
1229 thread_local_top()->pending_message_obj_ = *message_obj; 1272 thread_local_top()->pending_message_obj_ = *message_obj;
1230 if (location != NULL) { 1273 thread_local_top()->pending_message_script_ = *location->script();
1231 thread_local_top()->pending_message_script_ = *location->script(); 1274 thread_local_top()->pending_message_start_pos_ = location->start_pos();
1232 thread_local_top()->pending_message_start_pos_ = location->start_pos(); 1275 thread_local_top()->pending_message_end_pos_ = location->end_pos();
1233 thread_local_top()->pending_message_end_pos_ = location->end_pos();
1234 }
1235 1276
1236 // If the abort-on-uncaught-exception flag is specified, abort on any 1277 // If the abort-on-uncaught-exception flag is specified, abort on any
1237 // exception not caught by JavaScript, even when an external handler is 1278 // exception not caught by JavaScript, even when an external handler is
1238 // present. This flag is intended for use by JavaScript developers, so 1279 // present. This flag is intended for use by JavaScript developers, so
1239 // print a user-friendly stack trace (not an internal one). 1280 // print a user-friendly stack trace (not an internal one).
1240 if (fatal_exception_depth == 0 && FLAG_abort_on_uncaught_exception && 1281 if (fatal_exception_depth == 0 && FLAG_abort_on_uncaught_exception &&
1241 (report_exception || can_be_caught_externally)) { 1282 (report_exception || can_be_caught_externally)) {
1242 fatal_exception_depth++; 1283 fatal_exception_depth++;
1243 PrintF(stderr, "%s\n\nFROM\n", 1284 PrintF(stderr, "%s\n\nFROM\n",
1244 MessageHandler::GetLocalizedMessage(this, message_obj).get()); 1285 MessageHandler::GetLocalizedMessage(this, message_obj).get());
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 } 1368 }
1328 if (can_clear_message) clear_pending_message(); 1369 if (can_clear_message) clear_pending_message();
1329 } 1370 }
1330 1371
1331 1372
1332 MessageLocation Isolate::GetMessageLocation() { 1373 MessageLocation Isolate::GetMessageLocation() {
1333 DCHECK(has_pending_exception()); 1374 DCHECK(has_pending_exception());
1334 1375
1335 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && 1376 if (thread_local_top_.pending_exception_ != heap()->termination_exception() &&
1336 thread_local_top_.has_pending_message_ && 1377 thread_local_top_.has_pending_message_ &&
1337 !thread_local_top_.pending_message_obj_->IsTheHole() &&
1338 !thread_local_top_.pending_message_obj_->IsTheHole()) { 1378 !thread_local_top_.pending_message_obj_->IsTheHole()) {
1339 Handle<Script> script( 1379 Handle<Script> script(
1340 Script::cast(thread_local_top_.pending_message_script_)); 1380 Script::cast(thread_local_top_.pending_message_script_));
1341 int start_pos = thread_local_top_.pending_message_start_pos_; 1381 int start_pos = thread_local_top_.pending_message_start_pos_;
1342 int end_pos = thread_local_top_.pending_message_end_pos_; 1382 int end_pos = thread_local_top_.pending_message_end_pos_;
1343 return MessageLocation(script, start_pos, end_pos); 1383 return MessageLocation(script, start_pos, end_pos);
1344 } 1384 }
1345 1385
1346 return MessageLocation(); 1386 return MessageLocation();
1347 } 1387 }
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2496 if (prev_ && prev_->Intercept(flag)) return true; 2536 if (prev_ && prev_->Intercept(flag)) return true;
2497 // Then check whether this scope intercepts. 2537 // Then check whether this scope intercepts.
2498 if ((flag & intercept_mask_)) { 2538 if ((flag & intercept_mask_)) {
2499 intercepted_flags_ |= flag; 2539 intercepted_flags_ |= flag;
2500 return true; 2540 return true;
2501 } 2541 }
2502 return false; 2542 return false;
2503 } 2543 }
2504 2544
2505 } } // namespace v8::internal 2545 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698