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.
ToCString(const v8::String::Utf8Value & value)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.
ToCString(const v8::String::AsciiValue & value)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
ToCString(v8::Handle<v8::Value> 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
LogErrorMessage(v8::Handle<v8::Message> message,const char * alternate_message)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 ALOGD("LogErrorMessage no message");
48 } else {
49 ALOGD("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 ALOGD("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 ALOGD("%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 ALOGD("%s", error_string);
76 ALOGD("%s", ToCString(v8::String::Utf8Value(message->Get())));
77 delete [] error_string;
78 }
79 }
80
81 // Report an exception
ReportException(v8::TryCatch * try_catch)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