The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / messages.cc @ 40c0f755

History | View | Annotate | Download (6.55 KB)

1 40c0f755 Ryan
2
// Copyright 2006-2008 the V8 project authors. All rights reserved.
3
// Redistribution and use in source and binary forms, with or without
4
// modification, are permitted provided that the following conditions are
5
// met:
6
//
7
//     * Redistributions of source code must retain the above copyright
8
//       notice, this list of conditions and the following disclaimer.
9
//     * Redistributions in binary form must reproduce the above
10
//       copyright notice, this list of conditions and the following
11
//       disclaimer in the documentation and/or other materials provided
12
//       with the distribution.
13
//     * Neither the name of Google Inc. nor the names of its
14
//       contributors may be used to endorse or promote products derived
15
//       from this software without specific prior written permission.
16
//
17
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29
#include "v8.h"
30
31
#include "api.h"
32
#include "execution.h"
33
#include "spaces-inl.h"
34
#include "top.h"
35
36
namespace v8 { namespace internal {
37
38
39
// If no message listeners have been registered this one is called
40
// by default.
41
void MessageHandler::DefaultMessageReport(const MessageLocation* loc,
42
                                          Handle<Object> message_obj) {
43
  SmartPointer<char> str = GetLocalizedMessage(message_obj);
44
  if (loc == NULL) {
45
    PrintF("%s\n", *str);
46
  } else {
47
    HandleScope scope;
48
    Handle<Object> data(loc->script()->name());
49
    SmartPointer<char> data_str;
50
    if (data->IsString())
51
      data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS);
52
    PrintF("%s:%i: %s\n", *data_str ? *data_str : "<unknown>",
53
           loc->start_pos(), *str);
54
  }
55
}
56
57
58
void MessageHandler::ReportMessage(const char* msg) {
59
  PrintF("%s\n", msg);
60
}
61
62
63
Handle<Object> MessageHandler::MakeMessageObject(
64
    const char* type,
65
    MessageLocation* loc,
66
    Vector< Handle<Object> > args,
67
    Handle<String> stack_trace) {
68
  // Build error message object
69
  v8::HandleScope scope;  // Instantiate a closeable HandleScope for EscapeFrom.
70
  Handle<Object> type_str = Factory::LookupAsciiSymbol(type);
71
  Handle<Object> array = Factory::NewJSArray(args.length());
72
  for (int i = 0; i < args.length(); i++)
73
    SetElement(Handle<JSArray>::cast(array), i, args[i]);
74
75
  Handle<JSFunction> fun(Top::global_context()->make_message_fun());
76
  int start, end;
77
  Handle<Object> script;
78
  if (loc) {
79
    start = loc->start_pos();
80
    end = loc->end_pos();
81
    script = GetScriptWrapper(loc->script());
82
  } else {
83
    start = end = 0;
84
    script = Factory::undefined_value();
85
  }
86
  Handle<Object> start_handle(Smi::FromInt(start));
87
  Handle<Object> end_handle(Smi::FromInt(end));
88
  Handle<Object> stack_trace_val = stack_trace.is_null()
89
    ? Factory::undefined_value()
90
    : Handle<Object>::cast(stack_trace);
91
  const int argc = 6;
92
  Object** argv[argc] = { type_str.location(),
93
                          array.location(),
94
                          start_handle.location(),
95
                          end_handle.location(),
96
                          script.location(),
97
                          stack_trace_val.location() };
98
99
  // Setup a catch handler to catch exceptions in creating the message. This
100
  // handler is non-verbose to avoid calling MakeMessage recursively in case of
101
  // an exception.
102
  v8::TryCatch catcher;
103
  catcher.SetVerbose(false);
104
  catcher.SetCaptureMessage(false);
105
106
  // Format the message.
107
  bool caught_exception = false;
108
  Handle<Object> message =
109
      Execution::Call(fun, Factory::undefined_value(), argc, argv,
110
                      &caught_exception);
111
112
  // If creating the message (in JS code) resulted in an exception, we
113
  // skip doing the callback. This usually only happens in case of
114
  // stack overflow exceptions being thrown by the parser when the
115
  // stack is almost full.
116
  if (caught_exception) return Handle<Object>();
117
118
  return message.EscapeFrom(&scope);
119
}
120
121
122
void MessageHandler::ReportMessage(MessageLocation* loc,
123
                                   Handle<Object> message) {
124
  v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message);
125
126
  v8::NeanderArray global_listeners(Factory::message_listeners());
127
  int global_length = global_listeners.length();
128
  if (global_length == 0) {
129
    DefaultMessageReport(loc, message);
130
  } else {
131
    for (int i = 0; i < global_length; i++) {
132
      HandleScope scope;
133
      if (global_listeners.get(i)->IsUndefined()) continue;
134
      v8::NeanderObject listener(JSObject::cast(global_listeners.get(i)));
135
      Handle<Proxy> callback_obj(Proxy::cast(listener.get(0)));
136
      v8::MessageCallback callback =
137
          FUNCTION_CAST<v8::MessageCallback>(callback_obj->proxy());
138
      Handle<Object> callback_data(listener.get(1));
139
      callback(api_message_obj, v8::Utils::ToLocal(callback_data));
140
    }
141
  }
142
}
143
144
145
Handle<String> MessageHandler::GetMessage(Handle<Object> data) {
146
  Handle<String> fmt_str = Factory::LookupAsciiSymbol("FormatMessage");
147
  Handle<JSFunction> fun =
148
      Handle<JSFunction>(
149
          JSFunction::cast(
150
              Top::builtins()->GetProperty(*fmt_str)));
151
  Object** argv[1] = { data.location() };
152
153
  bool caught_exception;
154
  Handle<Object> result =
155
      Execution::TryCall(fun, Top::builtins(), 1, argv,
156
                         &caught_exception);
157
158
  if (caught_exception || !result->IsString()) {
159
    return Factory::LookupAsciiSymbol("<error>");
160
  }
161
  Handle<String> result_string = Handle<String>::cast(result);
162
  // A string that has been obtained from JS code in this way is
163
  // likely to be a complicated ConsString of some sort.  We flatten it
164
  // here to improve the efficiency of converting it to a C string and
165
  // other operations that are likely to take place (see GetLocalizedMessage
166
  // for example).
167
  FlattenString(result_string);
168
  return result_string;
169
}
170
171
172
SmartPointer<char> MessageHandler::GetLocalizedMessage(Handle<Object> data) {
173
  HandleScope scope;
174
  return GetMessage(data)->ToCString(DISALLOW_NULLS);
175
}
176
177
178
} }  // namespace v8::internal