Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp

Issue 1859293002: [DevTools] Move Console to v8_inspector (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 ConsoleScope {
dgozman 2016/04/12 23:21:57 ConsoleHelper
kozy 2016/04/12 23:34:25 Done.
28 PROTOCOL_DISALLOW_COPY(ConsoleScope);
29 public:
30 ConsoleScope(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_info.GetIsolate()->GetCurre ntContext(), type, level, String16(), &m_info, skipArgumentCount, -1);
dgozman 2016/04/12 23:21:57 m_context
kozy 2016/04/12 23:34:25 Done.
81 }
82
83 void addMessage(MessageType type, MessageLevel level, const String16& messag e)
84 {
85 if (V8DebuggerClient* debuggerClient = ensureDebuggerClient())
86 debuggerClient->reportMessageToConsole(m_info.GetIsolate()->GetCurre ntContext(), type, level, message, nullptr, 0, 1);
dgozman 2016/04/12 23:21:57 0 /* skipArgumentsCount */, 1 /* maxStackSize */
dgozman 2016/04/12 23:21:58 ditto
kozy 2016/04/12 23:34:25 Done.
kozy 2016/04/12 23:34:26 Done.
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_info.GetIsolate()->GetCurre ntContext(), LogMessageType, WarningMessageLevel, message, nullptr, false, 0);
dgozman 2016/04/12 23:21:57 0 /* skipArgumentsCount */, 0 /* maxStackSize */
kozy 2016/04/12 23:34:25 Done.
95 }
96
97 bool firstArgAsBoolean(bool defaultValue)
dgozman 2016/04/12 23:21:57 firstArgToBoolean
kozy 2016/04/12 23:34:25 Done.
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_info.GetIsolate()->GetCurrentContext()) .FromMaybe(defaultValue);
104 }
105
106 String16 firstArgAsString(const String16& defaultValue)
107 {
108 return m_info.Length() > 0 ? toProtocolStringWithTypeCheck(m_info[0]) : defaultValue;
109 }
110
111 String16 firstArgToString(const String16& defaultValue)
112 {
113 if (m_info.Length() > 0 && (!m_info[0]->IsNull() || !m_info[0]->IsUndefi ned())) {
dgozman 2016/04/12 23:21:57 Let's treat null and undefined as everything else.
kozy 2016/04/12 23:34:25 Done.
114 v8::Local<v8::String> titleValue;
115 if (m_info[0]->IsObject()) {
116 if (!m_info[0].As<v8::Object>()->ObjectProtoToString(m_context). ToLocal(&titleValue))
117 return defaultValue;
118 } else {
119 if (!m_info[0]->ToString(m_context).ToLocal(&titleValue))
120 return defaultValue;
121 }
122 return toProtocolString(titleValue);
123 }
124 return defaultValue;
dgozman 2016/04/12 23:21:57 nit: let's do early bailout
kozy 2016/04/12 23:34:25 Done.
125 }
126
127 v8::MaybeLocal<v8::Map> privateMapFromConsole(const char* name)
dgozman 2016/04/12 23:21:57 nit: privateMap
kozy 2016/04/12 23:34:26 Done.
128 {
129 v8::Local<v8::Object> console = ensureConsole();
130 v8::Local<v8::Private> privateKey = v8::Private::ForApi(m_isolate, toV8S tringInternalized(m_isolate, name));
131 v8::Local<v8::Value> mapValue;
132 if (!console->GetPrivate(m_context, privateKey).ToLocal(&mapValue))
133 return v8::MaybeLocal<v8::Map>();
134 if (mapValue->IsUndefined()) {
135 v8::Local<v8::Map> map = v8::Map::New(m_isolate);
136 if (!console->SetPrivate(m_context, privateKey, map).FromMaybe(false ))
137 return v8::MaybeLocal<v8::Map>();
138 return map;
139 }
140 return mapValue->IsMap() ? mapValue.As<v8::Map>() : v8::MaybeLocal<v8::M ap>();
141 }
142
143 int64_t getIntFromMap(v8::Local<v8::Map> map, const String16& key, int64_t d efaultValue)
144 {
145 v8::Local<v8::String> v8Key = toV8String(m_isolate, key);
146 if (!map->Has(m_context, v8Key).FromMaybe(false))
147 return defaultValue;
148 v8::Local<v8::Value> intValue;
149 if (!map->Get(m_context, v8Key).ToLocal(&intValue))
150 return defaultValue;
151 return intValue.As<v8::Integer>()->Value();
152 }
153
154 void setIntOnMap(v8::Local<v8::Map> map, const String16& key, int64_t value)
155 {
156 v8::Local<v8::String> v8Key = toV8String(m_isolate, key);
157 if (!map->Set(m_context, v8Key, v8::Integer::New(m_isolate, value)).ToLo cal(&map))
158 return;
159 }
160
161 double getDoubleFromMap(v8::Local<v8::Map> map, const String16& key, double defaultValue)
162 {
163 v8::Local<v8::String> v8Key = toV8String(m_isolate, key);
164 if (!map->Has(m_context, v8Key).FromMaybe(false))
165 return defaultValue;
166 v8::Local<v8::Value> intValue;
167 if (!map->Get(m_context, v8Key).ToLocal(&intValue))
168 return defaultValue;
169 return intValue.As<v8::Number>()->Value();
170 }
171
172 void setDoubleOnMap(v8::Local<v8::Map> map, const String16& key, double valu e)
173 {
174 v8::Local<v8::String> v8Key = toV8String(m_isolate, key);
175 if (!map->Set(m_context, v8Key, v8::Number::New(m_isolate, value)).ToLoc al(&map))
176 return;
177 }
178
179 V8ProfilerAgentImpl* profileAgent()
180 {
181 InspectedContext* inspectedContext = ensureInspectedContext();
182 if (!inspectedContext)
183 return nullptr;
184 V8InspectorSessionImpl* session = inspectedContext->debugger()->sessionF orContextGroup(inspectedContext->contextGroupId());
185 if (session && session->profileAgentImpl()->enabled())
186 return session->profileAgentImpl();
187 return nullptr;
188 }
189 private:
190 const v8::FunctionCallbackInfo<v8::Value>& m_info;
191 v8::Isolate* m_isolate;
192 v8::Local<v8::Context> m_context;
193 v8::Local<v8::Object> m_console;
194 InspectedContext* m_inspectedContext;
195 V8DebuggerClient* m_debuggerClient;
196
197 bool checkAndSetPrivateFlagOnConsole(const char* name, bool defaultValue)
198 {
199 v8::Local<v8::Object> console = ensureConsole();
200 v8::Local<v8::Private> key = v8::Private::ForApi(m_isolate, toV8StringIn ternalized(m_isolate, name));
201 v8::Local<v8::Value> flagValue;
202 if (!console->GetPrivate(m_context, key).ToLocal(&flagValue))
203 return defaultValue;
204 ASSERT(flagValue->IsUndefined() || flagValue->IsBoolean());
205 if (flagValue->IsBoolean()) {
206 ASSERT(flagValue.As<v8::Boolean>()->Value());
207 return true;
208 }
209 if (!console->SetPrivate(m_context, key, v8::True(m_isolate)).FromMaybe( false))
210 return defaultValue;
211 return false;
212 }
213 };
214
215 v8::MaybeLocal<v8::Object> createObjectWithClassName(V8DebuggerImpl* debugger, v 8::Local<v8::Context> context, const char* className)
216 {
217 v8::Isolate* isolate = debugger->isolate();
218 v8::Local<v8::FunctionTemplate> functionTemplate;
219 String16 functionTemplateName = String16("V8Console#") + className;
220 if (!debugger->functionTemplate(functionTemplateName).ToLocal(&functionTempl ate)) {
221 functionTemplate = v8::FunctionTemplate::New(isolate);
222 functionTemplate->SetClassName(toV8StringInternalized(isolate, className ));
223 debugger->setFunctionTemplate(functionTemplateName, functionTemplate);
224 }
225 v8::Local<v8::Function> constructor;
226 if (!functionTemplate->GetFunction(context).ToLocal(&constructor))
227 return v8::MaybeLocal<v8::Object>();
228 return constructor->NewInstance(context, 0, nullptr);
229 }
230
231 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)
232 {
233 v8::Local<v8::String> funcName = toV8StringInternalized(context->GetIsolate( ), name);
234 v8::Local<v8::Function> func;
235 if (!v8::Function::New(context, callback, obj).ToLocal(&func))
236 return;
237 func->SetName(funcName);
238 if (!prototype->Set(context, funcName, func).FromMaybe(false))
239 return;
240 }
241
242 } // namespace
243
244 void V8Console::debugCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
245 {
246 ConsoleScope(info).addMessage(LogMessageType, DebugMessageLevel, false, 0);
247 }
248
249 void V8Console::errorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
250 {
251 ConsoleScope(info).addMessage(LogMessageType, ErrorMessageLevel, false, 0);
252 }
253
254 void V8Console::infoCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
255 {
256 ConsoleScope(info).addMessage(LogMessageType, InfoMessageLevel, false, 0);
257 }
258
259 void V8Console::logCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
260 {
261 ConsoleScope(info).addMessage(LogMessageType, LogMessageLevel, false, 0);
262 }
263
264 void V8Console::warnCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
265 {
266 ConsoleScope(info).addMessage(LogMessageType, WarningMessageLevel, false, 0) ;
267 }
268
269 void V8Console::dirCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
270 {
271 ConsoleScope(info).addMessage(DirMessageType, LogMessageLevel, false, 0);
272 }
273
274 void V8Console::dirxmlCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
275 {
276 ConsoleScope(info).addMessage(DirXMLMessageType, LogMessageLevel, false, 0);
277 }
278
279 void V8Console::tableCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
280 {
281 ConsoleScope(info).addMessage(TableMessageType, LogMessageLevel, false, 0);
282 }
283
284 void V8Console::traceCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
285 {
286 ConsoleScope(info).addMessage(TraceMessageType, LogMessageLevel, true, 0);
287 }
288
289 void V8Console::groupCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
290 {
291 ConsoleScope(info).addMessage(StartGroupMessageType, LogMessageLevel, true, 0);
292 }
293
294 void V8Console::groupCollapsedCallback(const v8::FunctionCallbackInfo<v8::Value> & info)
295 {
296 ConsoleScope(info).addMessage(StartGroupCollapsedMessageType, LogMessageLeve l, true, 0);
297 }
298
299 void V8Console::groupEndCallback(const v8::FunctionCallbackInfo<v8::Value>& info )
300 {
301 ConsoleScope(info).addMessage(EndGroupMessageType, LogMessageLevel, true, 0) ;
302 }
303
304 void V8Console::clearCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
305 {
306 ConsoleScope(info).addMessage(ClearMessageType, LogMessageLevel, true, 0);
307 }
308
309 void V8Console::countCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
310 {
311 ConsoleScope scope(info);
312
313 // Follow Firebug's behavior of counting with null and undefined title in
dgozman 2016/04/12 23:21:57 This is not true in stable. Let's abandon.
kozy 2016/04/12 23:34:25 Done.
314 // the same bucket as no argument
315 String16 title = scope.firstArgToString(String16());
316 String16 identifier;
317 if (title.isEmpty()) {
318 OwnPtr<V8StackTraceImpl> stackTrace = V8StackTraceImpl::capture(nullptr, 1);
319 if (stackTrace)
320 identifier = stackTrace->topSourceURL() + ":" + String16::number(sta ckTrace->topLineNumber());
321 } else {
322 identifier = title + "@";
323 }
324
325 v8::Local<v8::Map> countMap;
326 if (!scope.privateMapFromConsole("V8Console#countMap").ToLocal(&countMap))
327 return;
328 int64_t count = scope.getIntFromMap(countMap, identifier, 0) + 1;
329 scope.setIntOnMap(countMap, identifier, count);
330 scope.addMessage(CountMessageType, DebugMessageLevel, title + ": " + String1 6::number(count));
331 }
332
333 void V8Console::assertCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
334 {
335 ConsoleScope scope(info);
336 if (scope.firstArgAsBoolean(false))
337 return;
338 scope.addMessage(AssertMessageType, ErrorMessageLevel, true, 1);
339 }
340
341 void V8Console::markTimelineCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
342 {
343 ConsoleScope(info).addDeprecationMessage("V8Console#markTimelineDeprecated", "'console.markTimeline' is deprecated. Please use 'console.timeStamp' instead." );
344 timeStampCallback(info);
345 }
346
347 void V8Console::profileCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
348 {
349 ConsoleScope scope(info);
350 if (V8ProfilerAgentImpl* profileAgent = scope.profileAgent())
351 profileAgent->consoleProfile(scope.firstArgAsString(String16()));
352 }
353
354 void V8Console::profileEndCallback(const v8::FunctionCallbackInfo<v8::Value>& in fo)
355 {
356 ConsoleScope scope(info);
357 if (V8ProfilerAgentImpl* profileAgent = scope.profileAgent())
dgozman 2016/04/12 23:21:57 nit: profilerAgent
kozy 2016/04/12 23:34:25 Done.
358 profileAgent->consoleProfileEnd(scope.firstArgAsString(String16()));
359 }
360
361 static void timeFunction(const v8::FunctionCallbackInfo<v8::Value>& info, bool t imelinePrefix)
362 {
363 ConsoleScope scope(info);
364 if (V8DebuggerClient* client = scope.ensureDebuggerClient()) {
365 String16 protocolTitle = scope.firstArgAsString(String16());
366 if (timelinePrefix)
367 protocolTitle = "Timeline '" + protocolTitle + "'";
368 client->consoleTime(protocolTitle);
369
370 if (info.Length() < 1)
371 return;
372 v8::Local<v8::Map> timeMap;
373 if (!scope.privateMapFromConsole("V8Console#timeMap").ToLocal(&timeMap))
374 return;
375 scope.setDoubleOnMap(timeMap, protocolTitle, client->currentTimeMS());
376 }
377 }
378
379 static void timeEndFunction(const v8::FunctionCallbackInfo<v8::Value>& info, boo l timelinePrefix)
380 {
381 ConsoleScope scope(info);
382 if (V8DebuggerClient* client = scope.ensureDebuggerClient()) {
383 String16 protocolTitle = scope.firstArgAsString(String16());
384 if (timelinePrefix)
385 protocolTitle = "Timeline '" + protocolTitle + "'";
386 client->consoleTimeEnd(protocolTitle);
387
388 if (info.Length() < 1)
389 return;
390 v8::Local<v8::Map> timeMap;
391 if (!scope.privateMapFromConsole("V8Console#timeMap").ToLocal(&timeMap))
392 return;
393 double elapsed = client->currentTimeMS() - scope.getDoubleFromMap(timeMa p, protocolTitle, 0.0);
394 String16 message = protocolTitle + ": " + String16::fromDoubleFixedPreci sion(elapsed, 3) + "ms";
395 scope.addMessage(TimeEndMessageType, DebugMessageLevel, message);
396 }
397 }
398
399 void V8Console::timelineCallback(const v8::FunctionCallbackInfo<v8::Value>& info )
400 {
401 ConsoleScope(info).addDeprecationMessage("V8Console#timeline", "'console.tim eline' is deprecated. Please use 'console.time' instead.");
402 timeFunction(info, true);
403 }
404
405 void V8Console::timelineEndCallback(const v8::FunctionCallbackInfo<v8::Value>& i nfo)
406 {
407 ConsoleScope(info).addDeprecationMessage("V8Console#timelineEnd", "'console. timelineEnd' is deprecated. Please use 'console.timeEnd' instead.");
408 timeEndFunction(info, true);
409 }
410
411 void V8Console::timeCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
412 {
413 timeFunction(info, false);
414 }
415
416 void V8Console::timeEndCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
417 {
418 timeEndFunction(info, false);
419 }
420
421 void V8Console::timeStampCallback(const v8::FunctionCallbackInfo<v8::Value>& inf o)
422 {
423 ConsoleScope scope(info);
424 if (V8DebuggerClient* client = scope.ensureDebuggerClient())
425 client->consoleTimeStamp(scope.firstArgAsString(String16()));
426 }
427
428 void V8Console::memoryGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
429 {
430 if (V8DebuggerClient* client = ConsoleScope(info).ensureDebuggerClient()) {
431 v8::Local<v8::Value> memoryValue;
432 if (!client->memoryInfo(info.GetIsolate(), info.GetIsolate()->GetCurrent Context(), info.Holder()).ToLocal(&memoryValue))
433 return;
434 info.GetReturnValue().Set(memoryValue);
435 }
436 }
437
438 void V8Console::memorySetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
439 {
440 // 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
441 }
442
443 v8::MaybeLocal<v8::Object> V8Console::create(v8::Local<v8::Context> context, Ins pectedContext* inspectedContext, bool hasMemoryAttribute)
444 {
445 v8::Isolate* isolate = context->GetIsolate();
446 v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunM icrotasks);
447
448 v8::Local<v8::Object> console;
449 if (!createObjectWithClassName(inspectedContext->debugger(), context, "Conso le").ToLocal(&console))
450 return v8::MaybeLocal<v8::Object>();
451
452 v8::Local<v8::Object> prototype;
453 if (!createObjectWithClassName(inspectedContext->debugger(), context, "Conso lePrototype").ToLocal(&prototype))
454 return v8::MaybeLocal<v8::Object>();
455
456 createBoundFunctionProperty(context, console, prototype, "debug", V8Console: :debugCallback);
457 createBoundFunctionProperty(context, console, prototype, "error", V8Console: :errorCallback);
458 createBoundFunctionProperty(context, console, prototype, "info", V8Console:: infoCallback);
459 createBoundFunctionProperty(context, console, prototype, "log", V8Console::l ogCallback);
460 createBoundFunctionProperty(context, console, prototype, "warn", V8Console:: warnCallback);
461 createBoundFunctionProperty(context, console, prototype, "dir", V8Console::d irCallback);
462 createBoundFunctionProperty(context, console, prototype, "dirxml", V8Console ::dirxmlCallback);
463 createBoundFunctionProperty(context, console, prototype, "table", V8Console: :tableCallback);
464 createBoundFunctionProperty(context, console, prototype, "trace", V8Console: :traceCallback);
465 createBoundFunctionProperty(context, console, prototype, "group", V8Console: :groupCallback);
466 createBoundFunctionProperty(context, console, prototype, "groupCollapsed", V 8Console::groupCollapsedCallback);
467 createBoundFunctionProperty(context, console, prototype, "groupEnd", V8Conso le::groupEndCallback);
468 createBoundFunctionProperty(context, console, prototype, "clear", V8Console: :clearCallback);
469 createBoundFunctionProperty(context, console, prototype, "count", V8Console: :countCallback);
470 createBoundFunctionProperty(context, console, prototype, "assert", V8Console ::assertCallback);
471 createBoundFunctionProperty(context, console, prototype, "markTimeline", V8C onsole::markTimelineCallback);
472 createBoundFunctionProperty(context, console, prototype, "profile", V8Consol e::profileCallback);
473 createBoundFunctionProperty(context, console, prototype, "profileEnd", V8Con sole::profileEndCallback);
474 createBoundFunctionProperty(context, console, prototype, "timeline", V8Conso le::timelineCallback);
475 createBoundFunctionProperty(context, console, prototype, "timelineEnd", V8Co nsole::timelineEndCallback);
476 createBoundFunctionProperty(context, console, prototype, "time", V8Console:: timeCallback);
477 createBoundFunctionProperty(context, console, prototype, "timeEnd", V8Consol e::timeEndCallback);
478 createBoundFunctionProperty(context, console, prototype, "timeStamp", V8Cons ole::timeStampCallback);
479
480 if (!console->SetPrototype(context, prototype).FromMaybe(false))
481 return v8::MaybeLocal<v8::Object>();
482
483 if (hasMemoryAttribute)
484 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);
485
486 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern al::New(isolate, inspectedContext));
487 return console;
488 }
489
490 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698