13d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville/** 23d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * Copyright (C) 2010 The Android Open Source Project 33d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * 43d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 53d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * you may not use this file except in compliance with the License. 63d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * You may obtain a copy of the License at 73d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * 83d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 93d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * 103d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * Unless required by applicable law or agreed to in writing, software 113d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 123d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * See the License for the specific language governing permissions and 143d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville * limitations under the License. 153d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville */ 163d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 173d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <v8.h> 183d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <string.h> 193d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 203d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include "logging.h" 213d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include "util.h" 223d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 233d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// Extracts a C string from a V8 Utf8Value. 243d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleconst char* ToCString(const v8::String::Utf8Value& value) { 253d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return *value ? *value : "<string conversion failed>"; 263d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville} 273d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 289b92c6b4651e608125a48f8f06a7a840042e090dWink Saville// Extracts a C string from a V8 AsciiValue. 299b92c6b4651e608125a48f8f06a7a840042e090dWink Savilleconst char* ToCString(const v8::String::AsciiValue& value) { 309b92c6b4651e608125a48f8f06a7a840042e090dWink Saville return *value ? *value : "<string conversion failed>"; 319b92c6b4651e608125a48f8f06a7a840042e090dWink Saville} 329b92c6b4651e608125a48f8f06a7a840042e090dWink Saville 339b92c6b4651e608125a48f8f06a7a840042e090dWink Saville// Extracts a C string from a v8::Value 343d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleconst char* ToCString(v8::Handle<v8::Value> value) { 359b92c6b4651e608125a48f8f06a7a840042e090dWink Saville v8::String::AsciiValue strAsciiValue(value); 369b92c6b4651e608125a48f8f06a7a840042e090dWink Saville return ToCString(strAsciiValue); 373d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville} 383d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 393d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// Report an exception 403d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savillevoid LogErrorMessage(v8::Handle<v8::Message> message, 413d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const char *alternate_message) { 423d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville v8::HandleScope handle_scope; 433d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (message.IsEmpty()) { 443d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // V8 didn't provide any extra information about this error; just 453d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // print the exception. 463d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (alternate_message == NULL || strlen(alternate_message) == 0) { 476464068a31ff890d42d3da9cdf580d07c9c630d8Steve Block ALOGD("LogErrorMessage no message"); 483d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } else { 496464068a31ff890d42d3da9cdf580d07c9c630d8Steve Block ALOGD("LogErrorMessage no message: %s", alternate_message); 503d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 513d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } else { 523d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville v8::String::Utf8Value filename(message->GetScriptResourceName()); 533d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const char* filename_string = ToCString(filename); 543d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville int linenum = message->GetLineNumber(); 556464068a31ff890d42d3da9cdf580d07c9c630d8Steve Block ALOGD("file:%s line:%i", filename_string, linenum); 563d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 573d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // Print line of source code. 583d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville v8::String::Utf8Value sourceline(message->GetSourceLine()); 593d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const char* sourceline_string = ToCString(sourceline); 606464068a31ff890d42d3da9cdf580d07c9c630d8Steve Block ALOGD("%s", sourceline_string); 613d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 623d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // Print location information under source line 633d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville int start = message->GetStartColumn(); 643d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville int end = message->GetEndColumn(); 653d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville int lenErr = end - start; 663d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville int size = end + 1; 673d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (lenErr == 0) { 683d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville lenErr += 1; 693d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville size += 1; 703d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 713d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville char *error_string = new char[size]; 723d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville memset(error_string, ' ', start); 733d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville memset(&error_string[start], '^', lenErr); 743d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville error_string[size-1] = 0; 756464068a31ff890d42d3da9cdf580d07c9c630d8Steve Block ALOGD("%s", error_string); 766464068a31ff890d42d3da9cdf580d07c9c630d8Steve Block ALOGD("%s", ToCString(v8::String::Utf8Value(message->Get()))); 773d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville delete [] error_string; 783d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 793d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville} 803d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 813d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// Report an exception 823d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savillevoid ReportException(v8::TryCatch* try_catch) { 833d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville v8::HandleScope handle_scope; 843d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 853d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville v8::String::Utf8Value exception(try_catch->Exception()); 863d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville v8::Handle<v8::Message> msg = try_catch->Message(); 873d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (msg.IsEmpty()) { 883d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // Why is try_catch->Message empty? 893d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // it is always empty on compile errors 903d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 913d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville LogErrorMessage(msg, ToCString(exception)); 923d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville} 93