]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/ConsoleClient.cpp
JavaScriptCore-7601.1.46.3.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;
ed1e77d3
A
108 case MessageLevel::Info:
109 levelString = "INFO";
110 break;
81345200
A
111 case MessageLevel::Warning:
112 levelString = "WARN";
113 break;
114 case MessageLevel::Error:
115 levelString = "ERROR";
116 break;
117 default:
118 ASSERT_NOT_REACHED();
119 levelString = "UNKNOWN";
120 break;
121 }
122
123 if (type == MessageType::Trace)
124 levelString = "TRACE";
ed1e77d3
A
125 else if (type == MessageType::Table)
126 levelString = "TABLE";
81345200
A
127
128 builder.append(sourceString);
129 builder.append(' ');
130 builder.append(levelString);
131}
132
133void ConsoleClient::printConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber)
134{
135 StringBuilder builder;
136
137 if (!url.isEmpty()) {
138 appendURLAndPosition(builder, url, lineNumber, columnNumber);
139 builder.appendLiteral(": ");
140 }
141
142 appendMessagePrefix(builder, source, type, level);
143 builder.append(' ');
144 builder.append(message);
145
146 WTFLogAlways("%s", builder.toString().utf8().data());
147}
148
ed1e77d3 149void ConsoleClient::printConsoleMessageWithArguments(MessageSource source, MessageType type, MessageLevel level, JSC::ExecState* exec, RefPtr<ScriptArguments>&& prpArguments)
81345200
A
150{
151 RefPtr<ScriptArguments> arguments = prpArguments;
152
153 bool isTraceMessage = type == MessageType::Trace;
154 size_t stackSize = isTraceMessage ? ScriptCallStack::maxCallStackSizeToCapture : 1;
155 RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(exec, stackSize));
156 const ScriptCallFrame& lastCaller = callStack->at(0);
157
158 StringBuilder builder;
159
160 if (!lastCaller.sourceURL().isEmpty()) {
161 appendURLAndPosition(builder, lastCaller.sourceURL(), lastCaller.lineNumber(), lastCaller.columnNumber());
162 builder.appendLiteral(": ");
163 }
164
165 appendMessagePrefix(builder, source, type, level);
166 for (size_t i = 0; i < arguments->argumentCount(); ++i) {
167 String argAsString = arguments->argumentAt(i).toString(arguments->globalState());
168 builder.append(' ');
169 builder.append(argAsString.utf8().data());
170 }
171
172 WTFLogAlways("%s", builder.toString().utf8().data());
173
174 if (isTraceMessage) {
175 for (size_t i = 0; i < callStack->size(); ++i) {
176 const ScriptCallFrame& callFrame = callStack->at(i);
177 String functionName = String(callFrame.functionName());
178 if (functionName.isEmpty())
179 functionName = ASCIILiteral("(unknown)");
180
181 StringBuilder callFrameBuilder;
182 callFrameBuilder.appendNumber(static_cast<unsigned long>(i));
183 callFrameBuilder.appendLiteral(": ");
184 callFrameBuilder.append(functionName);
185 callFrameBuilder.append('(');
186 appendURLAndPosition(callFrameBuilder, callFrame.sourceURL(), callFrame.lineNumber(), callFrame.columnNumber());
187 callFrameBuilder.append(')');
188
189 WTFLogAlways("%s", callFrameBuilder.toString().utf8().data());
190 }
191 }
192}
193
ed1e77d3 194void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, RefPtr<ScriptArguments>&& prpArguments, ArgumentRequirement argumentRequirement)
81345200
A
195{
196 RefPtr<ScriptArguments> arguments = prpArguments;
197 if (argumentRequirement == ArgumentRequired && !arguments->argumentCount())
198 return;
199
200 messageWithTypeAndLevel(type, level, exec, arguments.release());
201}
202
ed1e77d3 203void ConsoleClient::logWithLevel(ExecState* exec, RefPtr<ScriptArguments>&& arguments, MessageLevel level)
81345200 204{
ed1e77d3 205 internalMessageWithTypeAndLevel(MessageType::Log, level, exec, WTF::move(arguments), ArgumentRequired);
81345200
A
206}
207
ed1e77d3 208void ConsoleClient::clear(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
81345200 209{
ed1e77d3 210 internalMessageWithTypeAndLevel(MessageType::Clear, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
81345200
A
211}
212
ed1e77d3 213void ConsoleClient::dir(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
81345200 214{
ed1e77d3 215 internalMessageWithTypeAndLevel(MessageType::Dir, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired);
81345200
A
216}
217
ed1e77d3 218void ConsoleClient::dirXML(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
81345200 219{
ed1e77d3 220 internalMessageWithTypeAndLevel(MessageType::DirXML, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired);
81345200
A
221}
222
ed1e77d3 223void ConsoleClient::table(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
81345200 224{
ed1e77d3 225 internalMessageWithTypeAndLevel(MessageType::Table, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired);
81345200
A
226}
227
ed1e77d3 228void ConsoleClient::trace(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
81345200 229{
ed1e77d3 230 internalMessageWithTypeAndLevel(MessageType::Trace, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
81345200
A
231}
232
ed1e77d3 233void ConsoleClient::assertCondition(ExecState* exec, RefPtr<ScriptArguments>&& arguments, bool condition)
81345200
A
234{
235 if (condition)
236 return;
237
ed1e77d3 238 internalMessageWithTypeAndLevel(MessageType::Assert, MessageLevel::Error, exec, WTF::move(arguments), ArgumentNotRequired);
81345200
A
239}
240
ed1e77d3 241void ConsoleClient::group(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
81345200 242{
ed1e77d3 243 internalMessageWithTypeAndLevel(MessageType::StartGroup, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
81345200
A
244}
245
ed1e77d3 246void ConsoleClient::groupCollapsed(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
81345200 247{
ed1e77d3 248 internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
81345200
A
249}
250
ed1e77d3 251void ConsoleClient::groupEnd(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
81345200 252{
ed1e77d3 253 internalMessageWithTypeAndLevel(MessageType::EndGroup, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
81345200
A
254}
255
256} // namespace JSC