OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "platform/v8_inspector/V8Console.h" |
| 6 |
| 7 #include "platform/inspector_protocol/String16.h" |
| 8 #include "platform/v8_inspector/InspectedContext.h" |
| 9 #include "platform/v8_inspector/V8DebuggerImpl.h" |
| 10 #include "platform/v8_inspector/V8InspectorSessionImpl.h" |
| 11 #include "platform/v8_inspector/V8ProfilerAgentImpl.h" |
| 12 #include "platform/v8_inspector/V8StackTraceImpl.h" |
| 13 #include "platform/v8_inspector/V8StringUtil.h" |
| 14 #include "platform/v8_inspector/public/ConsoleAPITypes.h" |
| 15 #include "platform/v8_inspector/public/ConsoleTypes.h" |
| 16 #include "platform/v8_inspector/public/V8DebuggerClient.h" |
| 17 |
| 18 namespace blink { |
| 19 |
| 20 namespace { |
| 21 |
| 22 v8::Local<v8::Private> inspectedContextPrivateKey(v8::Isolate* isolate) |
| 23 { |
| 24 return v8::Private::ForApi(isolate, toV8StringInternalized(isolate, "V8Conso
le#InspectedContext")); |
| 25 } |
| 26 |
| 27 class ConsoleHelper { |
| 28 PROTOCOL_DISALLOW_COPY(ConsoleHelper); |
| 29 public: |
| 30 ConsoleHelper(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 31 : m_info(info) |
| 32 , m_isolate(info.GetIsolate()) |
| 33 , m_context(info.GetIsolate()->GetCurrentContext()) |
| 34 , m_inspectedContext(nullptr) |
| 35 , m_debuggerClient(nullptr) |
| 36 { |
| 37 } |
| 38 |
| 39 v8::Local<v8::Object> ensureConsole() |
| 40 { |
| 41 if (m_console.IsEmpty()) { |
| 42 ASSERT(!m_info.Data().IsEmpty()); |
| 43 ASSERT(!m_info.Data()->IsUndefined()); |
| 44 m_console = m_info.Data().As<v8::Object>(); |
| 45 } |
| 46 return m_console; |
| 47 } |
| 48 |
| 49 InspectedContext* ensureInspectedContext() |
| 50 { |
| 51 if (m_inspectedContext) |
| 52 return m_inspectedContext; |
| 53 v8::Local<v8::Object> console = ensureConsole(); |
| 54 |
| 55 v8::Local<v8::Private> key = inspectedContextPrivateKey(m_isolate); |
| 56 v8::Local<v8::Value> inspectedContextValue; |
| 57 if (!console->GetPrivate(m_context, key).ToLocal(&inspectedContextValue)
) |
| 58 return nullptr; |
| 59 ASSERT(inspectedContextValue->IsExternal()); |
| 60 m_inspectedContext = static_cast<InspectedContext*>(inspectedContextValu
e.As<v8::External>()->Value()); |
| 61 return m_inspectedContext; |
| 62 } |
| 63 |
| 64 V8DebuggerClient* ensureDebuggerClient() |
| 65 { |
| 66 if (m_debuggerClient) |
| 67 return m_debuggerClient; |
| 68 InspectedContext* inspectedContext = ensureInspectedContext(); |
| 69 if (!inspectedContext) |
| 70 return nullptr; |
| 71 m_debuggerClient = inspectedContext->debugger()->client(); |
| 72 return m_debuggerClient; |
| 73 } |
| 74 |
| 75 void addMessage(MessageType type, MessageLevel level, bool allowEmptyArgumen
ts, int skipArgumentCount) |
| 76 { |
| 77 if (!allowEmptyArguments && !m_info.Length()) |
| 78 return; |
| 79 if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) |
| 80 debuggerClient->reportMessageToConsole(m_context, type, level, Strin
g16(), &m_info, skipArgumentCount, -1); |
| 81 } |
| 82 |
| 83 void addMessage(MessageType type, MessageLevel level, const String16& messag
e) |
| 84 { |
| 85 if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) |
| 86 debuggerClient->reportMessageToConsole(m_context, type, level, messa
ge, nullptr, 0 /* skipArgumentsCount */, 1 /* maxStackSize */); |
| 87 } |
| 88 |
| 89 void addDeprecationMessage(const char* id, const String16& message) |
| 90 { |
| 91 if (checkAndSetPrivateFlagOnConsole(id, false)) |
| 92 return; |
| 93 if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) |
| 94 debuggerClient->reportMessageToConsole(m_context, LogMessageType, Wa
rningMessageLevel, message, nullptr, 0 /* skipArgumentsCount */, 0 /* maxStackSi
ze */); |
| 95 } |
| 96 |
| 97 bool firstArgToBoolean(bool defaultValue) |
| 98 { |
| 99 if (m_info.Length() < 1) |
| 100 return defaultValue; |
| 101 if (m_info[0]->IsBoolean()) |
| 102 return m_info[0].As<v8::Boolean>()->Value(); |
| 103 return m_info[0]->BooleanValue(m_context).FromMaybe(defaultValue); |
| 104 } |
| 105 |
| 106 String16 firstArgToString(const String16& defaultValue) |
| 107 { |
| 108 if (m_info.Length() < 1) |
| 109 return defaultValue; |
| 110 v8::Local<v8::String> titleValue; |
| 111 if (m_info[0]->IsObject()) { |
| 112 if (!m_info[0].As<v8::Object>()->ObjectProtoToString(m_context).ToLo
cal(&titleValue)) |
| 113 return defaultValue; |
| 114 } else { |
| 115 if (!m_info[0]->ToString(m_context).ToLocal(&titleValue)) |
| 116 return defaultValue; |
| 117 } |
| 118 return toProtocolString(titleValue); |
| 119 } |
| 120 |
| 121 v8::MaybeLocal<v8::Map> privateMap(const char* name) |
| 122 { |
| 123 v8::Local<v8::Object> console = ensureConsole(); |
| 124 v8::Local<v8::Private> privateKey = v8::Private::ForApi(m_isolate, toV8S
tringInternalized(m_isolate, name)); |
| 125 v8::Local<v8::Value> mapValue; |
| 126 if (!console->GetPrivate(m_context, privateKey).ToLocal(&mapValue)) |
| 127 return v8::MaybeLocal<v8::Map>(); |
| 128 if (mapValue->IsUndefined()) { |
| 129 v8::Local<v8::Map> map = v8::Map::New(m_isolate); |
| 130 if (!console->SetPrivate(m_context, privateKey, map).FromMaybe(false
)) |
| 131 return v8::MaybeLocal<v8::Map>(); |
| 132 return map; |
| 133 } |
| 134 return mapValue->IsMap() ? mapValue.As<v8::Map>() : v8::MaybeLocal<v8::M
ap>(); |
| 135 } |
| 136 |
| 137 int64_t getIntFromMap(v8::Local<v8::Map> map, const String16& key, int64_t d
efaultValue) |
| 138 { |
| 139 v8::Local<v8::String> v8Key = toV8String(m_isolate, key); |
| 140 if (!map->Has(m_context, v8Key).FromMaybe(false)) |
| 141 return defaultValue; |
| 142 v8::Local<v8::Value> intValue; |
| 143 if (!map->Get(m_context, v8Key).ToLocal(&intValue)) |
| 144 return defaultValue; |
| 145 return intValue.As<v8::Integer>()->Value(); |
| 146 } |
| 147 |
| 148 void setIntOnMap(v8::Local<v8::Map> map, const String16& key, int64_t value) |
| 149 { |
| 150 v8::Local<v8::String> v8Key = toV8String(m_isolate, key); |
| 151 if (!map->Set(m_context, v8Key, v8::Integer::New(m_isolate, value)).ToLo
cal(&map)) |
| 152 return; |
| 153 } |
| 154 |
| 155 double getDoubleFromMap(v8::Local<v8::Map> map, const String16& key, double
defaultValue) |
| 156 { |
| 157 v8::Local<v8::String> v8Key = toV8String(m_isolate, key); |
| 158 if (!map->Has(m_context, v8Key).FromMaybe(false)) |
| 159 return defaultValue; |
| 160 v8::Local<v8::Value> intValue; |
| 161 if (!map->Get(m_context, v8Key).ToLocal(&intValue)) |
| 162 return defaultValue; |
| 163 return intValue.As<v8::Number>()->Value(); |
| 164 } |
| 165 |
| 166 void setDoubleOnMap(v8::Local<v8::Map> map, const String16& key, double valu
e) |
| 167 { |
| 168 v8::Local<v8::String> v8Key = toV8String(m_isolate, key); |
| 169 if (!map->Set(m_context, v8Key, v8::Number::New(m_isolate, value)).ToLoc
al(&map)) |
| 170 return; |
| 171 } |
| 172 |
| 173 V8ProfilerAgentImpl* profilerAgent() |
| 174 { |
| 175 InspectedContext* inspectedContext = ensureInspectedContext(); |
| 176 if (!inspectedContext) |
| 177 return nullptr; |
| 178 V8InspectorSessionImpl* session = inspectedContext->debugger()->sessionF
orContextGroup(inspectedContext->contextGroupId()); |
| 179 if (session && session->profilerAgentImpl()->enabled()) |
| 180 return session->profilerAgentImpl(); |
| 181 return nullptr; |
| 182 } |
| 183 private: |
| 184 const v8::FunctionCallbackInfo<v8::Value>& m_info; |
| 185 v8::Isolate* m_isolate; |
| 186 v8::Local<v8::Context> m_context; |
| 187 v8::Local<v8::Object> m_console; |
| 188 InspectedContext* m_inspectedContext; |
| 189 V8DebuggerClient* m_debuggerClient; |
| 190 |
| 191 bool checkAndSetPrivateFlagOnConsole(const char* name, bool defaultValue) |
| 192 { |
| 193 v8::Local<v8::Object> console = ensureConsole(); |
| 194 v8::Local<v8::Private> key = v8::Private::ForApi(m_isolate, toV8StringIn
ternalized(m_isolate, name)); |
| 195 v8::Local<v8::Value> flagValue; |
| 196 if (!console->GetPrivate(m_context, key).ToLocal(&flagValue)) |
| 197 return defaultValue; |
| 198 ASSERT(flagValue->IsUndefined() || flagValue->IsBoolean()); |
| 199 if (flagValue->IsBoolean()) { |
| 200 ASSERT(flagValue.As<v8::Boolean>()->Value()); |
| 201 return true; |
| 202 } |
| 203 if (!console->SetPrivate(m_context, key, v8::True(m_isolate)).FromMaybe(
false)) |
| 204 return defaultValue; |
| 205 return false; |
| 206 } |
| 207 }; |
| 208 |
| 209 v8::MaybeLocal<v8::Object> createObjectWithClassName(V8DebuggerImpl* debugger, v
8::Local<v8::Context> context, const char* className) |
| 210 { |
| 211 v8::Isolate* isolate = debugger->isolate(); |
| 212 v8::Local<v8::FunctionTemplate> functionTemplate; |
| 213 String16 functionTemplateName = String16("V8Console#") + className; |
| 214 if (!debugger->functionTemplate(functionTemplateName).ToLocal(&functionTempl
ate)) { |
| 215 functionTemplate = v8::FunctionTemplate::New(isolate); |
| 216 functionTemplate->SetClassName(toV8StringInternalized(isolate, className
)); |
| 217 debugger->setFunctionTemplate(functionTemplateName, functionTemplate); |
| 218 } |
| 219 v8::Local<v8::Function> constructor; |
| 220 if (!functionTemplate->GetFunction(context).ToLocal(&constructor)) |
| 221 return v8::MaybeLocal<v8::Object>(); |
| 222 return constructor->NewInstance(context, 0, nullptr); |
| 223 } |
| 224 |
| 225 void createBoundFunctionProperty(v8::Local<v8::Context> context, v8::Local<v8::O
bject> obj, v8::Local<v8::Object> prototype, const char* name, v8::FunctionCallb
ack callback) |
| 226 { |
| 227 v8::Local<v8::String> funcName = toV8StringInternalized(context->GetIsolate(
), name); |
| 228 v8::Local<v8::Function> func; |
| 229 if (!v8::Function::New(context, callback, obj).ToLocal(&func)) |
| 230 return; |
| 231 func->SetName(funcName); |
| 232 if (!prototype->Set(context, funcName, func).FromMaybe(false)) |
| 233 return; |
| 234 } |
| 235 |
| 236 } // namespace |
| 237 |
| 238 void V8Console::debugCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 239 { |
| 240 ConsoleHelper(info).addMessage(LogMessageType, DebugMessageLevel, false, 0); |
| 241 } |
| 242 |
| 243 void V8Console::errorCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 244 { |
| 245 ConsoleHelper(info).addMessage(LogMessageType, ErrorMessageLevel, false, 0); |
| 246 } |
| 247 |
| 248 void V8Console::infoCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 249 { |
| 250 ConsoleHelper(info).addMessage(LogMessageType, InfoMessageLevel, false, 0); |
| 251 } |
| 252 |
| 253 void V8Console::logCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 254 { |
| 255 ConsoleHelper(info).addMessage(LogMessageType, LogMessageLevel, false, 0); |
| 256 } |
| 257 |
| 258 void V8Console::warnCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 259 { |
| 260 ConsoleHelper(info).addMessage(LogMessageType, WarningMessageLevel, false, 0
); |
| 261 } |
| 262 |
| 263 void V8Console::dirCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 264 { |
| 265 ConsoleHelper(info).addMessage(DirMessageType, LogMessageLevel, false, 0); |
| 266 } |
| 267 |
| 268 void V8Console::dirxmlCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 269 { |
| 270 ConsoleHelper(info).addMessage(DirXMLMessageType, LogMessageLevel, false, 0)
; |
| 271 } |
| 272 |
| 273 void V8Console::tableCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 274 { |
| 275 ConsoleHelper(info).addMessage(TableMessageType, LogMessageLevel, false, 0); |
| 276 } |
| 277 |
| 278 void V8Console::traceCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 279 { |
| 280 ConsoleHelper(info).addMessage(TraceMessageType, LogMessageLevel, true, 0); |
| 281 } |
| 282 |
| 283 void V8Console::groupCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 284 { |
| 285 ConsoleHelper(info).addMessage(StartGroupMessageType, LogMessageLevel, true,
0); |
| 286 } |
| 287 |
| 288 void V8Console::groupCollapsedCallback(const v8::FunctionCallbackInfo<v8::Value>
& info) |
| 289 { |
| 290 ConsoleHelper(info).addMessage(StartGroupCollapsedMessageType, LogMessageLev
el, true, 0); |
| 291 } |
| 292 |
| 293 void V8Console::groupEndCallback(const v8::FunctionCallbackInfo<v8::Value>& info
) |
| 294 { |
| 295 ConsoleHelper(info).addMessage(EndGroupMessageType, LogMessageLevel, true, 0
); |
| 296 } |
| 297 |
| 298 void V8Console::clearCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 299 { |
| 300 ConsoleHelper(info).addMessage(ClearMessageType, LogMessageLevel, true, 0); |
| 301 } |
| 302 |
| 303 void V8Console::countCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 304 { |
| 305 ConsoleHelper helper(info); |
| 306 |
| 307 String16 title = helper.firstArgToString(String16()); |
| 308 String16 identifier; |
| 309 if (title.isEmpty()) { |
| 310 OwnPtr<V8StackTraceImpl> stackTrace = V8StackTraceImpl::capture(nullptr,
1); |
| 311 if (stackTrace) |
| 312 identifier = stackTrace->topSourceURL() + ":" + String16::number(sta
ckTrace->topLineNumber()); |
| 313 } else { |
| 314 identifier = title + "@"; |
| 315 } |
| 316 |
| 317 v8::Local<v8::Map> countMap; |
| 318 if (!helper.privateMap("V8Console#countMap").ToLocal(&countMap)) |
| 319 return; |
| 320 int64_t count = helper.getIntFromMap(countMap, identifier, 0) + 1; |
| 321 helper.setIntOnMap(countMap, identifier, count); |
| 322 helper.addMessage(CountMessageType, DebugMessageLevel, title + ": " + String
16::number(count)); |
| 323 } |
| 324 |
| 325 void V8Console::assertCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 326 { |
| 327 ConsoleHelper helper(info); |
| 328 if (helper.firstArgToBoolean(false)) |
| 329 return; |
| 330 helper.addMessage(AssertMessageType, ErrorMessageLevel, true, 1); |
| 331 } |
| 332 |
| 333 void V8Console::markTimelineCallback(const v8::FunctionCallbackInfo<v8::Value>&
info) |
| 334 { |
| 335 ConsoleHelper(info).addDeprecationMessage("V8Console#markTimelineDeprecated"
, "'console.markTimeline' is deprecated. Please use 'console.timeStamp' instead.
"); |
| 336 timeStampCallback(info); |
| 337 } |
| 338 |
| 339 void V8Console::profileCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 340 { |
| 341 ConsoleHelper helper(info); |
| 342 if (V8ProfilerAgentImpl* profilerAgent = helper.profilerAgent()) |
| 343 profilerAgent->consoleProfile(helper.firstArgToString(String16())); |
| 344 } |
| 345 |
| 346 void V8Console::profileEndCallback(const v8::FunctionCallbackInfo<v8::Value>& in
fo) |
| 347 { |
| 348 ConsoleHelper helper(info); |
| 349 if (V8ProfilerAgentImpl* profilerAgent = helper.profilerAgent()) |
| 350 profilerAgent->consoleProfileEnd(helper.firstArgToString(String16())); |
| 351 } |
| 352 |
| 353 static void timeFunction(const v8::FunctionCallbackInfo<v8::Value>& info, bool t
imelinePrefix) |
| 354 { |
| 355 ConsoleHelper helper(info); |
| 356 if (V8DebuggerClient* client = helper.ensureDebuggerClient()) { |
| 357 String16 protocolTitle = helper.firstArgToString(String16()); |
| 358 if (timelinePrefix) |
| 359 protocolTitle = "Timeline '" + protocolTitle + "'"; |
| 360 client->consoleTime(protocolTitle); |
| 361 |
| 362 if (info.Length() < 1) |
| 363 return; |
| 364 v8::Local<v8::Map> timeMap; |
| 365 if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) |
| 366 return; |
| 367 helper.setDoubleOnMap(timeMap, protocolTitle, client->currentTimeMS()); |
| 368 } |
| 369 } |
| 370 |
| 371 static void timeEndFunction(const v8::FunctionCallbackInfo<v8::Value>& info, boo
l timelinePrefix) |
| 372 { |
| 373 ConsoleHelper helper(info); |
| 374 if (V8DebuggerClient* client = helper.ensureDebuggerClient()) { |
| 375 String16 protocolTitle = helper.firstArgToString(String16()); |
| 376 if (timelinePrefix) |
| 377 protocolTitle = "Timeline '" + protocolTitle + "'"; |
| 378 client->consoleTimeEnd(protocolTitle); |
| 379 |
| 380 if (info.Length() < 1) |
| 381 return; |
| 382 v8::Local<v8::Map> timeMap; |
| 383 if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) |
| 384 return; |
| 385 double elapsed = client->currentTimeMS() - helper.getDoubleFromMap(timeM
ap, protocolTitle, 0.0); |
| 386 String16 message = protocolTitle + ": " + String16::fromDoubleFixedPreci
sion(elapsed, 3) + "ms"; |
| 387 helper.addMessage(TimeEndMessageType, DebugMessageLevel, message); |
| 388 } |
| 389 } |
| 390 |
| 391 void V8Console::timelineCallback(const v8::FunctionCallbackInfo<v8::Value>& info
) |
| 392 { |
| 393 ConsoleHelper(info).addDeprecationMessage("V8Console#timeline", "'console.ti
meline' is deprecated. Please use 'console.time' instead."); |
| 394 timeFunction(info, true); |
| 395 } |
| 396 |
| 397 void V8Console::timelineEndCallback(const v8::FunctionCallbackInfo<v8::Value>& i
nfo) |
| 398 { |
| 399 ConsoleHelper(info).addDeprecationMessage("V8Console#timelineEnd", "'console
.timelineEnd' is deprecated. Please use 'console.timeEnd' instead."); |
| 400 timeEndFunction(info, true); |
| 401 } |
| 402 |
| 403 void V8Console::timeCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 404 { |
| 405 timeFunction(info, false); |
| 406 } |
| 407 |
| 408 void V8Console::timeEndCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
| 409 { |
| 410 timeEndFunction(info, false); |
| 411 } |
| 412 |
| 413 void V8Console::timeStampCallback(const v8::FunctionCallbackInfo<v8::Value>& inf
o) |
| 414 { |
| 415 ConsoleHelper helper(info); |
| 416 if (V8DebuggerClient* client = helper.ensureDebuggerClient()) |
| 417 client->consoleTimeStamp(helper.firstArgToString(String16())); |
| 418 } |
| 419 |
| 420 void V8Console::memoryGetterCallback(const v8::FunctionCallbackInfo<v8::Value>&
info) |
| 421 { |
| 422 if (V8DebuggerClient* client = ConsoleHelper(info).ensureDebuggerClient()) { |
| 423 v8::Local<v8::Value> memoryValue; |
| 424 if (!client->memoryInfo(info.GetIsolate(), info.GetIsolate()->GetCurrent
Context(), info.Holder()).ToLocal(&memoryValue)) |
| 425 return; |
| 426 info.GetReturnValue().Set(memoryValue); |
| 427 } |
| 428 } |
| 429 |
| 430 void V8Console::memorySetterCallback(const v8::FunctionCallbackInfo<v8::Value>&
info) |
| 431 { |
| 432 // We can't make the attribute readonly as it breaks existing code that reli
es on being able to assign to console.memory in strict mode. Instead, the setter
just ignores the passed value. http://crbug.com/468611 |
| 433 } |
| 434 |
| 435 v8::MaybeLocal<v8::Object> V8Console::create(v8::Local<v8::Context> context, Ins
pectedContext* inspectedContext, bool hasMemoryAttribute) |
| 436 { |
| 437 v8::Isolate* isolate = context->GetIsolate(); |
| 438 v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunM
icrotasks); |
| 439 |
| 440 v8::Local<v8::Object> console; |
| 441 if (!createObjectWithClassName(inspectedContext->debugger(), context, "Conso
le").ToLocal(&console)) |
| 442 return v8::MaybeLocal<v8::Object>(); |
| 443 |
| 444 v8::Local<v8::Object> prototype; |
| 445 if (!createObjectWithClassName(inspectedContext->debugger(), context, "Conso
lePrototype").ToLocal(&prototype)) |
| 446 return v8::MaybeLocal<v8::Object>(); |
| 447 |
| 448 createBoundFunctionProperty(context, console, prototype, "debug", V8Console:
:debugCallback); |
| 449 createBoundFunctionProperty(context, console, prototype, "error", V8Console:
:errorCallback); |
| 450 createBoundFunctionProperty(context, console, prototype, "info", V8Console::
infoCallback); |
| 451 createBoundFunctionProperty(context, console, prototype, "log", V8Console::l
ogCallback); |
| 452 createBoundFunctionProperty(context, console, prototype, "warn", V8Console::
warnCallback); |
| 453 createBoundFunctionProperty(context, console, prototype, "dir", V8Console::d
irCallback); |
| 454 createBoundFunctionProperty(context, console, prototype, "dirxml", V8Console
::dirxmlCallback); |
| 455 createBoundFunctionProperty(context, console, prototype, "table", V8Console:
:tableCallback); |
| 456 createBoundFunctionProperty(context, console, prototype, "trace", V8Console:
:traceCallback); |
| 457 createBoundFunctionProperty(context, console, prototype, "group", V8Console:
:groupCallback); |
| 458 createBoundFunctionProperty(context, console, prototype, "groupCollapsed", V
8Console::groupCollapsedCallback); |
| 459 createBoundFunctionProperty(context, console, prototype, "groupEnd", V8Conso
le::groupEndCallback); |
| 460 createBoundFunctionProperty(context, console, prototype, "clear", V8Console:
:clearCallback); |
| 461 createBoundFunctionProperty(context, console, prototype, "count", V8Console:
:countCallback); |
| 462 createBoundFunctionProperty(context, console, prototype, "assert", V8Console
::assertCallback); |
| 463 createBoundFunctionProperty(context, console, prototype, "markTimeline", V8C
onsole::markTimelineCallback); |
| 464 createBoundFunctionProperty(context, console, prototype, "profile", V8Consol
e::profileCallback); |
| 465 createBoundFunctionProperty(context, console, prototype, "profileEnd", V8Con
sole::profileEndCallback); |
| 466 createBoundFunctionProperty(context, console, prototype, "timeline", V8Conso
le::timelineCallback); |
| 467 createBoundFunctionProperty(context, console, prototype, "timelineEnd", V8Co
nsole::timelineEndCallback); |
| 468 createBoundFunctionProperty(context, console, prototype, "time", V8Console::
timeCallback); |
| 469 createBoundFunctionProperty(context, console, prototype, "timeEnd", V8Consol
e::timeEndCallback); |
| 470 createBoundFunctionProperty(context, console, prototype, "timeStamp", V8Cons
ole::timeStampCallback); |
| 471 |
| 472 if (!console->SetPrototype(context, prototype).FromMaybe(false)) |
| 473 return v8::MaybeLocal<v8::Object>(); |
| 474 |
| 475 if (hasMemoryAttribute) |
| 476 console->SetAccessorProperty(toV8StringInternalized(isolate, "memory"),
v8::Function::New(isolate, V8Console::memoryGetterCallback, console), v8::Functi
on::New(isolate, V8Console::memorySetterCallback), static_cast<v8::PropertyAttri
bute>(v8::None), v8::DEFAULT); |
| 477 |
| 478 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern
al::New(isolate, inspectedContext)); |
| 479 return console; |
| 480 } |
| 481 |
| 482 } // namespace blink |
OLD | NEW |