e9751ed9612769bf2a0ea3dadfc88fadc982f931
[WebKit-https.git] / Source / JavaScriptCore / runtime / ConsolePrototype.cpp
1 /*
2  * Copyright (C) 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 "ConsolePrototype.h"
28
29 #include "ConsoleClient.h"
30 #include "Error.h"
31 #include "ExceptionHelpers.h"
32 #include "JSCInlines.h"
33 #include "JSConsole.h"
34 #include "ScriptArguments.h"
35 #include "ScriptCallStackFactory.h"
36
37 namespace JSC {
38
39 const ClassInfo ConsolePrototype::s_info = { "ConsolePrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(ConsolePrototype) };
40
41 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState*);
42 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState*);
43 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState*);
44 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState*);
45 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncClear(ExecState*);
46 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDir(ExecState*);
47 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDirXML(ExecState*);
48 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTable(ExecState*);
49 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTrace(ExecState*);
50 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncAssert(ExecState*);
51 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncCount(ExecState*);
52 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfile(ExecState*);
53 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfileEnd(ExecState*);
54 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTime(ExecState*);
55 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeEnd(ExecState*);
56 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeStamp(ExecState*);
57 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroup(ExecState*);
58 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupCollapsed(ExecState*);
59 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupEnd(ExecState*);
60
61 void ConsolePrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
62 {
63     Base::finishCreation(vm);
64     ASSERT(inherits(info()));
65     vm.prototypeMap.addPrototype(this);
66
67     // For legacy reasons, console properties are enumerable, writable, deleteable,
68     // and all have a length of 0. This may change if Console is standardized.
69
70     JSC_NATIVE_FUNCTION("debug", consoleProtoFuncDebug, None, 0);
71     JSC_NATIVE_FUNCTION("error", consoleProtoFuncError, None, 0);
72     JSC_NATIVE_FUNCTION("log", consoleProtoFuncLog, None, 0);
73     JSC_NATIVE_FUNCTION("info", consoleProtoFuncLog, None, 0); // "info" is an alias of "log".
74     JSC_NATIVE_FUNCTION("warn", consoleProtoFuncWarn, None, 0);
75
76     JSC_NATIVE_FUNCTION("clear", consoleProtoFuncClear, None, 0);
77     JSC_NATIVE_FUNCTION("dir", consoleProtoFuncDir, None, 0);
78     JSC_NATIVE_FUNCTION("dirxml", consoleProtoFuncDirXML, None, 0);
79     JSC_NATIVE_FUNCTION("table", consoleProtoFuncTable, None, 0);
80     JSC_NATIVE_FUNCTION("trace", consoleProtoFuncTrace, None, 0);
81     JSC_NATIVE_FUNCTION("assert", consoleProtoFuncAssert, None, 0);
82     JSC_NATIVE_FUNCTION("count", consoleProtoFuncCount, None, 0);
83     JSC_NATIVE_FUNCTION("profile", consoleProtoFuncProfile, None, 0);
84     JSC_NATIVE_FUNCTION("profileEnd", consoleProtoFuncProfileEnd, None, 0);
85     JSC_NATIVE_FUNCTION("time", consoleProtoFuncTime, None, 0);
86     JSC_NATIVE_FUNCTION("timeEnd", consoleProtoFuncTimeEnd, None, 0);
87     JSC_NATIVE_FUNCTION("timeStamp", consoleProtoFuncTimeStamp, None, 0);
88     JSC_NATIVE_FUNCTION("group", consoleProtoFuncGroup, None, 0);
89     JSC_NATIVE_FUNCTION("groupCollapsed", consoleProtoFuncGroupCollapsed, None, 0);
90     JSC_NATIVE_FUNCTION("groupEnd", consoleProtoFuncGroupEnd, None, 0);
91 }
92
93 static String valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue value)
94 {
95     if (value.isUndefinedOrNull())
96         return String();
97     return value.toString(exec)->value(exec);
98 }
99
100 static EncodedJSValue consoleLogWithLevel(ExecState* exec, MessageLevel level)
101 {
102     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
103     if (!castedThis)
104         return throwVMTypeError(exec);
105     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
106     ConsoleClient* client = castedThis->globalObject()->consoleClient();
107     if (!client)
108         return JSValue::encode(jsUndefined());
109
110     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
111     client->logWithLevel(exec, arguments.release(), level);
112     return JSValue::encode(jsUndefined());
113 }
114
115 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState* exec)
116 {
117     return consoleLogWithLevel(exec, MessageLevel::Debug);
118 }
119
120 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState* exec)
121 {
122     return consoleLogWithLevel(exec, MessageLevel::Error);
123 }
124
125 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState* exec)
126 {
127     return consoleLogWithLevel(exec, MessageLevel::Log);
128 }
129
130 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState* exec)
131 {
132     return consoleLogWithLevel(exec, MessageLevel::Warning);
133 }
134
135 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncClear(ExecState* exec)
136 {
137     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
138     if (!castedThis)
139         return throwVMTypeError(exec);
140     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
141     ConsoleClient* client = castedThis->globalObject()->consoleClient();
142     if (!client)
143         return JSValue::encode(jsUndefined());
144
145     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
146     client->clear(exec, arguments.release());
147     return JSValue::encode(jsUndefined());
148 }
149
150 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDir(ExecState* exec)
151 {
152     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
153     if (!castedThis)
154         return throwVMTypeError(exec);
155     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
156     ConsoleClient* client = castedThis->globalObject()->consoleClient();
157     if (!client)
158         return JSValue::encode(jsUndefined());
159
160     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
161     client->dir(exec, arguments.release());
162     return JSValue::encode(jsUndefined());
163 }
164
165 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDirXML(ExecState* exec)
166 {
167     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
168     if (!castedThis)
169         return throwVMTypeError(exec);
170     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
171     ConsoleClient* client = castedThis->globalObject()->consoleClient();
172     if (!client)
173         return JSValue::encode(jsUndefined());
174
175     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
176     client->dirXML(exec, arguments.release());
177     return JSValue::encode(jsUndefined());
178 }
179
180 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTable(ExecState* exec)
181 {
182     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
183     if (!castedThis)
184         return throwVMTypeError(exec);
185     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
186     ConsoleClient* client = castedThis->globalObject()->consoleClient();
187     if (!client)
188         return JSValue::encode(jsUndefined());
189
190     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
191     client->table(exec, arguments.release());
192     return JSValue::encode(jsUndefined());
193 }
194
195 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTrace(ExecState* exec)
196 {
197     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
198     if (!castedThis)
199         return throwVMTypeError(exec);
200     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
201     ConsoleClient* client = castedThis->globalObject()->consoleClient();
202     if (!client)
203         return JSValue::encode(jsUndefined());
204
205     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
206     client->trace(exec, arguments.release());
207     return JSValue::encode(jsUndefined());
208 }
209
210 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncAssert(ExecState* exec)
211 {
212     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
213     if (!castedThis)
214         return throwVMTypeError(exec);
215     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
216     ConsoleClient* client = castedThis->globalObject()->consoleClient();
217     if (!client)
218         return JSValue::encode(jsUndefined());
219
220     bool condition(exec->argument(0).toBoolean(exec));
221     if (exec->hadException())
222         return JSValue::encode(jsUndefined());
223
224     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 1));
225     client->assertCondition(exec, arguments.release(), condition);
226     return JSValue::encode(jsUndefined());
227 }
228
229 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncCount(ExecState* exec)
230 {
231     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
232     if (!castedThis)
233         return throwVMTypeError(exec);
234     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
235     ConsoleClient* client = castedThis->globalObject()->consoleClient();
236     if (!client)
237         return JSValue::encode(jsUndefined());
238
239     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
240     client->count(exec, arguments.release());
241     return JSValue::encode(jsUndefined());
242 }
243
244 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfile(ExecState* exec)
245 {
246     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
247     if (!castedThis)
248         return throwVMTypeError(exec);
249     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
250     ConsoleClient* client = castedThis->globalObject()->consoleClient();
251     if (!client)
252         return JSValue::encode(jsUndefined());
253
254     size_t argsCount = exec->argumentCount();
255     if (argsCount <= 0) {
256         client->profile(exec, String());
257         return JSValue::encode(jsUndefined());
258     }
259
260     const String& title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
261     if (exec->hadException())
262         return JSValue::encode(jsUndefined());
263
264     client->profile(exec, title);
265     return JSValue::encode(jsUndefined());
266 }
267
268 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfileEnd(ExecState* exec)
269 {
270     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
271     if (!castedThis)
272         return throwVMTypeError(exec);
273     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
274     ConsoleClient* client = castedThis->globalObject()->consoleClient();
275     if (!client)
276         return JSValue::encode(jsUndefined());
277
278     size_t argsCount = exec->argumentCount();
279     if (argsCount <= 0) {
280         client->profileEnd(exec, String());
281         return JSValue::encode(jsUndefined());
282     }
283
284     const String& title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
285     if (exec->hadException())
286         return JSValue::encode(jsUndefined());
287
288     client->profileEnd(exec, title);
289     return JSValue::encode(jsUndefined());
290 }
291
292 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTime(ExecState* exec)
293 {
294     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
295     if (!castedThis)
296         return throwVMTypeError(exec);
297     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
298     ConsoleClient* client = castedThis->globalObject()->consoleClient();
299     if (!client)
300         return JSValue::encode(jsUndefined());
301
302     if (exec->argumentCount() < 1)
303         return throwVMError(exec, createNotEnoughArgumentsError(exec));
304
305     const String& title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
306     if (exec->hadException())
307         return JSValue::encode(jsUndefined());
308
309     client->time(exec, title);
310     return JSValue::encode(jsUndefined());
311 }
312
313 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeEnd(ExecState* exec)
314 {
315     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
316     if (!castedThis)
317         return throwVMTypeError(exec);
318     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
319     ConsoleClient* client = castedThis->globalObject()->consoleClient();
320     if (!client)
321         return JSValue::encode(jsUndefined());
322
323     if (exec->argumentCount() < 1)
324         return throwVMError(exec, createNotEnoughArgumentsError(exec));
325
326     const String& title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
327     if (exec->hadException())
328         return JSValue::encode(jsUndefined());
329
330     client->timeEnd(exec, title);
331     return JSValue::encode(jsUndefined());
332 }
333
334 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeStamp(ExecState* exec)
335 {
336     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
337     if (!castedThis)
338         return throwVMTypeError(exec);
339     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
340     ConsoleClient* client = castedThis->globalObject()->consoleClient();
341     if (!client)
342         return JSValue::encode(jsUndefined());
343
344     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
345     client->timeStamp(exec, arguments.release());
346     return JSValue::encode(jsUndefined());
347 }
348
349 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroup(ExecState* exec)
350 {
351     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
352     if (!castedThis)
353         return throwVMTypeError(exec);
354     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
355     ConsoleClient* client = castedThis->globalObject()->consoleClient();
356     if (!client)
357         return JSValue::encode(jsUndefined());
358
359     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
360     client->group(exec, arguments.release());
361     return JSValue::encode(jsUndefined());
362 }
363
364 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupCollapsed(ExecState* exec)
365 {
366     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
367     if (!castedThis)
368         return throwVMTypeError(exec);
369     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
370     ConsoleClient* client = castedThis->globalObject()->consoleClient();
371     if (!client)
372         return JSValue::encode(jsUndefined());
373
374     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
375     client->groupCollapsed(exec, arguments.release());
376     return JSValue::encode(jsUndefined());
377 }
378
379 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupEnd(ExecState* exec)
380 {
381     JSConsole* castedThis = jsDynamicCast<JSConsole*>(exec->thisValue());
382     if (!castedThis)
383         return throwVMTypeError(exec);
384     ASSERT_GC_OBJECT_INHERITS(castedThis, JSConsole::info());
385     ConsoleClient* client = castedThis->globalObject()->consoleClient();
386     if (!client)
387         return JSValue::encode(jsUndefined());
388
389     RefPtr<Inspector::ScriptArguments> arguments(Inspector::createScriptArguments(exec, 0));
390     client->groupEnd(exec, arguments.release());
391     return JSValue::encode(jsUndefined());
392 }
393
394 }