1 /** 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <v8.h> 18 #include <string.h> 19 20 #include "logging.h" 21 #include "util.h" 22 23 // Extracts a C string from a V8 Utf8Value. 24 const char* ToCString(const v8::String::Utf8Value& value) { 25 return *value ? *value : "<string conversion failed>"; 26 } 27 28 // Extracts a C string from a V8 AsciiValue. 29 const char* ToCString(const v8::String::AsciiValue& value) { 30 return *value ? *value : "<string conversion failed>"; 31 } 32 33 // Extracts a C string from a v8::Value 34 const char* ToCString(v8::Handle<v8::Value> value) { 35 v8::String::AsciiValue strAsciiValue(value); 36 return ToCString(strAsciiValue); 37 } 38 39 // Report an exception 40 void LogErrorMessage(v8::Handle<v8::Message> message, 41 const char *alternate_message) { 42 v8::HandleScope handle_scope; 43 if (message.IsEmpty()) { 44 // V8 didn't provide any extra information about this error; just 45 // print the exception. 46 if (alternate_message == NULL || strlen(alternate_message) == 0) { 47 LOGD("LogErrorMessage no message"); 48 } else { 49 LOGD("LogErrorMessage no message: %s", alternate_message); 50 } 51 } else { 52 v8::String::Utf8Value filename(message->GetScriptResourceName()); 53 const char* filename_string = ToCString(filename); 54 int linenum = message->GetLineNumber(); 55 LOGD("file:%s line:%i", filename_string, linenum); 56 57 // Print line of source code. 58 v8::String::Utf8Value sourceline(message->GetSourceLine()); 59 const char* sourceline_string = ToCString(sourceline); 60 LOGD("%s", sourceline_string); 61 62 // Print location information under source line 63 int start = message->GetStartColumn(); 64 int end = message->GetEndColumn(); 65 int lenErr = end - start; 66 int size = end + 1; 67 if (lenErr == 0) { 68 lenErr += 1; 69 size += 1; 70 } 71 char *error_string = new char[size]; 72 memset(error_string, ' ', start); 73 memset(&error_string[start], '^', lenErr); 74 error_string[size-1] = 0; 75 LOGD("%s", error_string); 76 LOGD("%s", ToCString(v8::String::Utf8Value(message->Get()))); 77 delete [] error_string; 78 } 79 } 80 81 // Report an exception 82 void ReportException(v8::TryCatch* try_catch) { 83 v8::HandleScope handle_scope; 84 85 v8::String::Utf8Value exception(try_catch->Exception()); 86 v8::Handle<v8::Message> msg = try_catch->Message(); 87 if (msg.IsEmpty()) { 88 // Why is try_catch->Message empty? 89 // it is always empty on compile errors 90 } 91 LogErrorMessage(msg, ToCString(exception)); 92 } 93