]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/ConsoleClient.cpp
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / runtime / ConsoleClient.cpp
CommitLineData
81345200
A
1/*
2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ConsoleClient.h"
28
29#include "ScriptArguments.h"
30#include "ScriptCallStack.h"
31#include "ScriptCallStackFactory.h"
32#include "ScriptValue.h"
33#include <wtf/Assertions.h>
34#include <wtf/text/CString.h>
35#include <wtf/text/StringBuilder.h>
36#include <wtf/text/WTFString.h>
37
38using namespace Inspector;
39
40namespace JSC {
41
42static void appendURLAndPosition(StringBuilder& builder, const String& url, unsigned lineNumber, unsigned columnNumber)
43{
44 if (url.isEmpty())
45 return;
46
47 builder.append(url);
48
49 if (lineNumber > 0) {
50 builder.append(':');
51 builder.appendNumber(lineNumber);
52 }
53
54 if (columnNumber > 0) {
55 builder.append(':');
56 builder.appendNumber(columnNumber);
57 }
58}
59
60static void appendMessagePrefix(StringBuilder& builder, MessageSource source, MessageType type, MessageLevel level)
61{
62 const char* sourceString;
63 switch (source) {
64 case MessageSource::XML:
65 sourceString = "XML";
66 break;
67 case MessageSource::JS:
68 sourceString = "JS";
69 break;
70 case MessageSource::Network:
71 sourceString = "NETWORK";
72 break;
73 case MessageSource::ConsoleAPI:
74 sourceString = "CONSOLE";
75 break;
76 case MessageSource::Storage:
77 sourceString = "STORAGE";
78 break;
79 case MessageSource::AppCache:
80 sourceString = "APPCACHE";
81 break;
82 case MessageSource::Rendering:
83 sourceString = "RENDERING";
84 break;
85 case MessageSource::CSS:
86 sourceString = "CSS";
87 break;
88 case MessageSource::Security:
89 sourceString = "SECURITY";
90 break;
91 case MessageSource::Other:
92 sourceString = "OTHER";
93 break;
94 default:
95 ASSERT_NOT_REACHED();
96 sourceString = "UNKNOWN";
97 break;
98 }
99
100 const char* levelString;
101 switch (level) {
102 case MessageLevel::Debug:
103 levelString = "DEBUG";
104 break;
105 case MessageLevel::Log:
106 levelString = "LOG";
107 break;
108 case MessageLevel::Warning:
109 levelString = "WARN";
110 break;
111 case MessageLevel::Error:
112 levelString = "ERROR";
113 break;
114 default:
115 ASSERT_NOT_REACHED();
116 levelString = "UNKNOWN";
117 break;
118 }
119
120 if (type == MessageType::Trace)
121 levelString = "TRACE";
122
123 builder.append(sourceString);
124 builder.append(' ');
125 builder.append(levelString);
126}
127
128void ConsoleClient::printConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber)
129{
130 StringBuilder builder;
131
132 if (!url.isEmpty()) {
133 appendURLAndPosition(builder, url, lineNumber, columnNumber);
134 builder.appendLiteral(": ");
135 }
136
137 appendMessagePrefix(builder, source, type, level);
138 builder.append(' ');
139 builder.append(message);
140
141 WTFLogAlways("%s", builder.toString().utf8().data());
142}
143
144void ConsoleClient::printConsoleMessageWithArguments(MessageSource source, MessageType type, MessageLevel level, JSC::ExecState* exec, PassRefPtr<ScriptArguments> prpArguments)
145{
146 RefPtr<ScriptArguments> arguments = prpArguments;
147
148 bool isTraceMessage = type == MessageType::Trace;
149 size_t stackSize = isTraceMessage ? ScriptCallStack::maxCallStackSizeToCapture : 1;
150 RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(exec, stackSize));
151 const ScriptCallFrame& lastCaller = callStack->at(0);
152
153 StringBuilder builder;
154
155 if (!lastCaller.sourceURL().isEmpty()) {
156 appendURLAndPosition(builder, lastCaller.sourceURL(), lastCaller.lineNumber(), lastCaller.columnNumber());
157 builder.appendLiteral(": ");
158 }
159
160 appendMessagePrefix(builder, source, type, level);
161 for (size_t i = 0; i < arguments->argumentCount(); ++i) {
162 String argAsString = arguments->argumentAt(i).toString(arguments->globalState());
163 builder.append(' ');
164 builder.append(argAsString.utf8().data());
165 }
166
167 WTFLogAlways("%s", builder.toString().utf8().data());
168
169 if (isTraceMessage) {
170 for (size_t i = 0; i < callStack->size(); ++i) {
171 const ScriptCallFrame& callFrame = callStack->at(i);
172 String functionName = String(callFrame.functionName());
173 if (functionName.isEmpty())
174 functionName = ASCIILiteral("(unknown)");
175
176 StringBuilder callFrameBuilder;
177 callFrameBuilder.appendNumber(static_cast<unsigned long>(i));
178 callFrameBuilder.appendLiteral(": ");
179 callFrameBuilder.append(functionName);
180 callFrameBuilder.append('(');
181 appendURLAndPosition(callFrameBuilder, callFrame.sourceURL(), callFrame.lineNumber(), callFrame.columnNumber());
182 callFrameBuilder.append(')');
183
184 WTFLogAlways("%s", callFrameBuilder.toString().utf8().data());
185 }
186 }
187}
188
189void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, PassRefPtr<ScriptArguments> prpArguments, ArgumentRequirement argumentRequirement)
190{
191 RefPtr<ScriptArguments> arguments = prpArguments;
192 if (argumentRequirement == ArgumentRequired && !arguments->argumentCount())
193 return;
194
195 messageWithTypeAndLevel(type, level, exec, arguments.release());
196}
197
198void ConsoleClient::logWithLevel(ExecState* exec, PassRefPtr<ScriptArguments> arguments, MessageLevel level)
199{
200 internalMessageWithTypeAndLevel(MessageType::Log, level, exec, arguments, ArgumentRequired);
201}
202
203void ConsoleClient::clear(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
204{
205 internalMessageWithTypeAndLevel(MessageType::Clear, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
206}
207
208void ConsoleClient::dir(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
209{
210 internalMessageWithTypeAndLevel(MessageType::Dir, MessageLevel::Log, exec, arguments, ArgumentRequired);
211}
212
213void ConsoleClient::dirXML(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
214{
215 internalMessageWithTypeAndLevel(MessageType::DirXML, MessageLevel::Log, exec, arguments, ArgumentRequired);
216}
217
218void ConsoleClient::table(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
219{
220 internalMessageWithTypeAndLevel(MessageType::Table, MessageLevel::Log, exec, arguments, ArgumentRequired);
221}
222
223void ConsoleClient::trace(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
224{
225 internalMessageWithTypeAndLevel(MessageType::Trace, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
226}
227
228void ConsoleClient::assertCondition(ExecState* exec, PassRefPtr<ScriptArguments> arguments, bool condition)
229{
230 if (condition)
231 return;
232
233 internalMessageWithTypeAndLevel(MessageType::Assert, MessageLevel::Error, exec, arguments, ArgumentNotRequired);
234}
235
236void ConsoleClient::group(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
237{
238 internalMessageWithTypeAndLevel(MessageType::StartGroup, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
239}
240
241void ConsoleClient::groupCollapsed(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
242{
243 internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
244}
245
246void ConsoleClient::groupEnd(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
247{
248 internalMessageWithTypeAndLevel(MessageType::EndGroup, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
249}
250
251} // namespace JSC