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