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/d8-console.h"
6 : #include "src/d8.h"
7 : #include "src/isolate.h"
8 :
9 : namespace v8 {
10 :
11 : namespace {
12 748 : void WriteToFile(const char* prefix, FILE* file, Isolate* isolate,
13 : const debug::ConsoleCallArguments& args) {
14 748 : if (prefix) fprintf(file, "%s: ", prefix);
15 3004 : for (int i = 0; i < args.Length(); i++) {
16 1148 : HandleScope handle_scope(isolate);
17 1148 : if (i > 0) fprintf(file, " ");
18 :
19 : Local<Value> arg = args[i];
20 : Local<String> str_obj;
21 :
22 1148 : if (arg->IsSymbol()) arg = Local<Symbol>::Cast(arg)->Name();
23 3064 : if (!arg->ToString(isolate->GetCurrentContext()).ToLocal(&str_obj)) return;
24 :
25 2256 : v8::String::Utf8Value str(isolate, str_obj);
26 1128 : int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), file));
27 1128 : if (n != str.length()) {
28 : printf("Error in fwrite\n");
29 0 : Shell::Exit(1);
30 : }
31 1128 : }
32 : fprintf(file, "\n");
33 : }
34 : } // anonymous namespace
35 :
36 54340 : D8Console::D8Console(Isolate* isolate) : isolate_(isolate) {
37 27170 : default_timer_ = base::TimeTicks::HighResolutionNow();
38 27170 : }
39 :
40 30 : void D8Console::Assert(const debug::ConsoleCallArguments& args,
41 : const v8::debug::ConsoleContext&) {
42 : Local<Boolean> arg;
43 30 : if (args.Length() > 0) {
44 90 : if (!args[0]->ToBoolean(isolate_->GetCurrentContext()).ToLocal(&arg)) {
45 : return;
46 : }
47 : } else {
48 : // No arguments given, the "first" argument is undefined which is false-ish.
49 0 : arg = v8::False(isolate_);
50 : }
51 30 : if (arg->IsTrue()) return;
52 30 : WriteToFile("console.assert", stdout, isolate_, args);
53 : isolate_->ThrowException(v8::Exception::Error(
54 : v8::String::NewFromUtf8(isolate_, "console.assert failed",
55 30 : v8::NewStringType::kNormal)
56 60 : .ToLocalChecked()));
57 : }
58 :
59 678 : void D8Console::Log(const debug::ConsoleCallArguments& args,
60 : const v8::debug::ConsoleContext&) {
61 678 : WriteToFile(nullptr, stdout, isolate_, args);
62 678 : }
63 :
64 10 : void D8Console::Error(const debug::ConsoleCallArguments& args,
65 : const v8::debug::ConsoleContext&) {
66 10 : WriteToFile("console.error", stderr, isolate_, args);
67 10 : }
68 :
69 10 : void D8Console::Warn(const debug::ConsoleCallArguments& args,
70 : const v8::debug::ConsoleContext&) {
71 10 : WriteToFile("console.warn", stdout, isolate_, args);
72 10 : }
73 :
74 10 : void D8Console::Info(const debug::ConsoleCallArguments& args,
75 : const v8::debug::ConsoleContext&) {
76 10 : WriteToFile("console.info", stdout, isolate_, args);
77 10 : }
78 :
79 10 : void D8Console::Debug(const debug::ConsoleCallArguments& args,
80 : const v8::debug::ConsoleContext&) {
81 10 : WriteToFile("console.debug", stdout, isolate_, args);
82 10 : }
83 :
84 20 : void D8Console::Time(const debug::ConsoleCallArguments& args,
85 : const v8::debug::ConsoleContext&) {
86 20 : if (args.Length() == 0) {
87 10 : default_timer_ = base::TimeTicks::HighResolutionNow();
88 : } else {
89 : Local<Value> arg = args[0];
90 : Local<String> label;
91 10 : v8::TryCatch try_catch(isolate_);
92 20 : if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return;
93 20 : v8::String::Utf8Value utf8(isolate_, label);
94 10 : std::string string(*utf8);
95 : auto find = timers_.find(string);
96 10 : if (find != timers_.end()) {
97 4 : find->second = base::TimeTicks::HighResolutionNow();
98 : } else {
99 : timers_.insert(std::pair<std::string, base::TimeTicks>(
100 12 : string, base::TimeTicks::HighResolutionNow()));
101 10 : }
102 : }
103 : }
104 :
105 20 : void D8Console::TimeEnd(const debug::ConsoleCallArguments& args,
106 : const v8::debug::ConsoleContext&) {
107 : base::TimeDelta delta;
108 20 : if (args.Length() == 0) {
109 20 : delta = base::TimeTicks::HighResolutionNow() - default_timer_;
110 10 : printf("console.timeEnd: default, %f\n", delta.InMillisecondsF());
111 : } else {
112 10 : base::TimeTicks now = base::TimeTicks::HighResolutionNow();
113 : Local<Value> arg = args[0];
114 : Local<String> label;
115 10 : v8::TryCatch try_catch(isolate_);
116 20 : if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return;
117 20 : v8::String::Utf8Value utf8(isolate_, label);
118 10 : std::string string(*utf8);
119 : auto find = timers_.find(string);
120 10 : if (find != timers_.end()) {
121 : delta = now - find->second;
122 : }
123 20 : printf("console.timeEnd: %s, %f\n", *utf8, delta.InMillisecondsF());
124 : }
125 : }
126 :
127 100 : void D8Console::TimeStamp(const debug::ConsoleCallArguments& args,
128 : const v8::debug::ConsoleContext&) {
129 200 : base::TimeDelta delta = base::TimeTicks::HighResolutionNow() - default_timer_;
130 100 : if (args.Length() == 0) {
131 10 : printf("console.timeStamp: default, %f\n", delta.InMillisecondsF());
132 : } else {
133 : Local<Value> arg = args[0];
134 : Local<String> label;
135 90 : v8::TryCatch try_catch(isolate_);
136 180 : if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return;
137 180 : v8::String::Utf8Value utf8(isolate_, label);
138 90 : std::string string(*utf8);
139 180 : printf("console.timeStamp: %s, %f\n", *utf8, delta.InMillisecondsF());
140 : }
141 : }
142 :
143 10 : void D8Console::Trace(const debug::ConsoleCallArguments& args,
144 : const v8::debug::ConsoleContext&) {
145 10 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
146 10 : i_isolate->PrintStack(stderr, i::Isolate::kPrintStackConcise);
147 10 : }
148 :
149 : } // namespace v8
|