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 37namespace JSC { 38 39const ClassInfo ConsolePrototype::s_info = { "ConsolePrototype", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ConsolePrototype) }; 40 41static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState*); 42static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState*); 43static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState*); 44static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState*); 45static EncodedJSValue JSC_HOST_CALL consoleProtoFuncClear(ExecState*); 46static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDir(ExecState*); 47static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDirXML(ExecState*); 48static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTable(ExecState*); 49static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTrace(ExecState*); 50static EncodedJSValue JSC_HOST_CALL consoleProtoFuncAssert(ExecState*); 51static EncodedJSValue JSC_HOST_CALL consoleProtoFuncCount(ExecState*); 52static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfile(ExecState*); 53static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfileEnd(ExecState*); 54static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTime(ExecState*); 55static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeEnd(ExecState*); 56static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeStamp(ExecState*); 57static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroup(ExecState*); 58static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupCollapsed(ExecState*); 59static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupEnd(ExecState*); 60 61void 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 93static String valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue value) 94{ 95 if (value.isUndefinedOrNull()) 96 return String(); 97 return value.toString(exec)->value(exec); 98} 99 100static 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 115static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState* exec) 116{ 117 return consoleLogWithLevel(exec, MessageLevel::Debug); 118} 119 120static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState* exec) 121{ 122 return consoleLogWithLevel(exec, MessageLevel::Error); 123} 124 125static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState* exec) 126{ 127 return consoleLogWithLevel(exec, MessageLevel::Log); 128} 129 130static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState* exec) 131{ 132 return consoleLogWithLevel(exec, MessageLevel::Warning); 133} 134 135static 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 150static 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 165static 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 180static 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 195static 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 210static 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 229static 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 244static 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 268static 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 292static 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 313static 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 334static 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 349static 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 364static 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 379static 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} 395