Line data Source code
1 : // Copyright 2017 the V8 project 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 "src/api-inl.h"
6 : #include "src/builtins/builtins-utils-inl.h"
7 : #include "src/builtins/builtins.h"
8 : #include "src/counters.h"
9 : #include "src/debug/interface-types.h"
10 : #include "src/objects-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : // -----------------------------------------------------------------------------
16 : // Console
17 :
18 : #define CONSOLE_METHOD_LIST(V) \
19 : V(Debug, debug) \
20 : V(Error, error) \
21 : V(Info, info) \
22 : V(Log, log) \
23 : V(Warn, warn) \
24 : V(Dir, dir) \
25 : V(DirXml, dirXml) \
26 : V(Table, table) \
27 : V(Trace, trace) \
28 : V(Group, group) \
29 : V(GroupCollapsed, groupCollapsed) \
30 : V(GroupEnd, groupEnd) \
31 : V(Clear, clear) \
32 : V(Count, count) \
33 : V(CountReset, countReset) \
34 : V(Assert, assert) \
35 : V(Profile, profile) \
36 : V(ProfileEnd, profileEnd) \
37 : V(TimeLog, timeLog)
38 :
39 : namespace {
40 12824 : void ConsoleCall(
41 25603 : Isolate* isolate, internal::BuiltinArguments& args,
42 : void (debug::ConsoleDelegate::*func)(const v8::debug::ConsoleCallArguments&,
43 : const v8::debug::ConsoleContext&)) {
44 12824 : CHECK(!isolate->has_pending_exception());
45 12824 : CHECK(!isolate->has_scheduled_exception());
46 12869 : if (!isolate->console_delegate()) return;
47 : HandleScope scope(isolate);
48 12779 : debug::ConsoleCallArguments wrapper(args);
49 : Handle<Object> context_id_obj = JSObject::GetDataProperty(
50 25558 : args.target(), isolate->factory()->console_context_id_symbol());
51 : int context_id =
52 38337 : context_id_obj->IsSmi() ? Handle<Smi>::cast(context_id_obj)->value() : 0;
53 : Handle<Object> context_name_obj = JSObject::GetDataProperty(
54 25558 : args.target(), isolate->factory()->console_context_name_symbol());
55 25558 : Handle<String> context_name = context_name_obj->IsString()
56 : ? Handle<String>::cast(context_name_obj)
57 12779 : : isolate->factory()->anonymous_string();
58 : (isolate->console_delegate()->*func)(
59 : wrapper,
60 25558 : v8::debug::ConsoleContext(context_id, Utils::ToLocal(context_name)));
61 : }
62 :
63 336 : void LogTimerEvent(Isolate* isolate, BuiltinArguments args,
64 : Logger::StartEnd se) {
65 602 : if (!isolate->logger()->is_logging()) return;
66 : HandleScope scope(isolate);
67 : std::unique_ptr<char[]> name;
68 : const char* raw_name = "default";
69 75 : if (args.length() > 1 && args[1]->IsString()) {
70 : // Try converting the first argument to a string.
71 40 : name = args.at<String>(1)->ToCString();
72 : raw_name = name.get();
73 : }
74 35 : LOG(isolate, TimerEvent(se, raw_name));
75 : }
76 : } // namespace
77 :
78 : #define CONSOLE_BUILTIN_IMPLEMENTATION(call, name) \
79 : BUILTIN(Console##call) { \
80 : ConsoleCall(isolate, args, &debug::ConsoleDelegate::call); \
81 : RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); \
82 : return ReadOnlyRoots(isolate).undefined_value(); \
83 : }
84 62565 : CONSOLE_METHOD_LIST(CONSOLE_BUILTIN_IMPLEMENTATION)
85 : #undef CONSOLE_BUILTIN_IMPLEMENTATION
86 :
87 392 : BUILTIN(ConsoleTime) {
88 98 : LogTimerEvent(isolate, args, Logger::START);
89 98 : ConsoleCall(isolate, args, &debug::ConsoleDelegate::Time);
90 98 : RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
91 98 : return ReadOnlyRoots(isolate).undefined_value();
92 : }
93 :
94 392 : BUILTIN(ConsoleTimeEnd) {
95 98 : LogTimerEvent(isolate, args, Logger::END);
96 98 : ConsoleCall(isolate, args, &debug::ConsoleDelegate::TimeEnd);
97 98 : RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
98 98 : return ReadOnlyRoots(isolate).undefined_value();
99 : }
100 :
101 420 : BUILTIN(ConsoleTimeStamp) {
102 105 : LogTimerEvent(isolate, args, Logger::STAMP);
103 105 : ConsoleCall(isolate, args, &debug::ConsoleDelegate::TimeStamp);
104 105 : RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
105 105 : return ReadOnlyRoots(isolate).undefined_value();
106 : }
107 :
108 : namespace {
109 52536 : void InstallContextFunction(Isolate* isolate, Handle<JSObject> target,
110 : const char* name, Builtins::Name builtin_id,
111 : int context_id, Handle<Object> context_name) {
112 : Factory* const factory = isolate->factory();
113 :
114 : Handle<String> name_string =
115 105072 : Name::ToFunctionName(isolate, factory->InternalizeUtf8String(name))
116 105072 : .ToHandleChecked();
117 : NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithoutPrototype(
118 52536 : name_string, builtin_id, i::LanguageMode::kSloppy);
119 52536 : Handle<JSFunction> fun = factory->NewFunction(args);
120 :
121 52536 : fun->shared()->set_native(true);
122 105072 : fun->shared()->DontAdaptArguments();
123 105072 : fun->shared()->set_length(1);
124 :
125 : JSObject::AddProperty(isolate, fun, factory->console_context_id_symbol(),
126 52536 : handle(Smi::FromInt(context_id), isolate), NONE);
127 105072 : if (context_name->IsString()) {
128 : JSObject::AddProperty(isolate, fun, factory->console_context_name_symbol(),
129 660 : context_name, NONE);
130 : }
131 52536 : JSObject::AddProperty(isolate, target, name_string, fun, NONE);
132 52536 : }
133 : } // namespace
134 :
135 11940 : BUILTIN(ConsoleContext) {
136 : HandleScope scope(isolate);
137 :
138 : Factory* const factory = isolate->factory();
139 2388 : Handle<String> name = factory->InternalizeUtf8String("Context");
140 : NewFunctionArgs arguments = NewFunctionArgs::ForFunctionWithoutCode(
141 2388 : name, isolate->sloppy_function_map(), LanguageMode::kSloppy);
142 2388 : Handle<JSFunction> cons = factory->NewFunction(arguments);
143 :
144 2388 : Handle<JSObject> prototype = factory->NewJSObject(isolate->object_function());
145 2388 : JSFunction::SetPrototype(cons, prototype);
146 :
147 2388 : Handle<JSObject> context = factory->NewJSObject(cons, TENURED);
148 : DCHECK(context->IsJSObject());
149 2388 : int id = isolate->last_console_context_id() + 1;
150 : isolate->set_last_console_context_id(id);
151 :
152 : #define CONSOLE_BUILTIN_SETUP(call, name) \
153 : InstallContextFunction(isolate, context, #name, Builtins::kConsole##call, \
154 : id, args.at(1));
155 2388 : CONSOLE_METHOD_LIST(CONSOLE_BUILTIN_SETUP)
156 : #undef CONSOLE_BUILTIN_SETUP
157 : InstallContextFunction(isolate, context, "time", Builtins::kConsoleTime, id,
158 2388 : args.at(1));
159 : InstallContextFunction(isolate, context, "timeEnd", Builtins::kConsoleTimeEnd,
160 2388 : id, args.at(1));
161 : InstallContextFunction(isolate, context, "timeStamp",
162 2388 : Builtins::kConsoleTimeStamp, id, args.at(1));
163 :
164 4776 : return *context;
165 : }
166 :
167 : #undef CONSOLE_METHOD_LIST
168 :
169 : } // namespace internal
170 183867 : } // namespace v8
|