Home | History | Annotate | Download | only in src
      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 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)->Name();
     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 
     36 D8Console::D8Console(Isolate* isolate) : isolate_(isolate) {
     37   default_timer_ = base::TimeTicks::HighResolutionNow();
     38 }
     39 
     40 void D8Console::Assert(const debug::ConsoleCallArguments& args,
     41                        const v8::debug::ConsoleContext&) {
     42   Local<Boolean> arg;
     43   if (args.Length() > 0) {
     44     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     arg = v8::False(isolate_);
     50   }
     51   if (arg->IsTrue()) return;
     52   WriteToFile("console.assert", stdout, isolate_, args);
     53   isolate_->ThrowException(v8::Exception::Error(
     54       v8::String::NewFromUtf8(isolate_, "console.assert failed",
     55                               v8::NewStringType::kNormal)
     56           .ToLocalChecked()));
     57 }
     58 
     59 void D8Console::Log(const debug::ConsoleCallArguments& args,
     60                     const v8::debug::ConsoleContext&) {
     61   WriteToFile(nullptr, stdout, isolate_, args);
     62 }
     63 
     64 void D8Console::Error(const debug::ConsoleCallArguments& args,
     65                       const v8::debug::ConsoleContext&) {
     66   WriteToFile("console.error", stderr, isolate_, args);
     67 }
     68 
     69 void D8Console::Warn(const debug::ConsoleCallArguments& args,
     70                      const v8::debug::ConsoleContext&) {
     71   WriteToFile("console.warn", stdout, isolate_, args);
     72 }
     73 
     74 void D8Console::Info(const debug::ConsoleCallArguments& args,
     75                      const v8::debug::ConsoleContext&) {
     76   WriteToFile("console.info", stdout, isolate_, args);
     77 }
     78 
     79 void D8Console::Debug(const debug::ConsoleCallArguments& args,
     80                       const v8::debug::ConsoleContext&) {
     81   WriteToFile("console.debug", stdout, isolate_, args);
     82 }
     83 
     84 void D8Console::Time(const debug::ConsoleCallArguments& args,
     85                      const v8::debug::ConsoleContext&) {
     86   if (args.Length() == 0) {
     87     default_timer_ = base::TimeTicks::HighResolutionNow();
     88   } else {
     89     Local<Value> arg = args[0];
     90     Local<String> label;
     91     v8::TryCatch try_catch(isolate_);
     92     if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return;
     93     v8::String::Utf8Value utf8(isolate_, label);
     94     std::string string(*utf8);
     95     auto find = timers_.find(string);
     96     if (find != timers_.end()) {
     97       find->second = base::TimeTicks::HighResolutionNow();
     98     } else {
     99       timers_.insert(std::pair<std::string, base::TimeTicks>(
    100           string, base::TimeTicks::HighResolutionNow()));
    101     }
    102   }
    103 }
    104 
    105 void D8Console::TimeEnd(const debug::ConsoleCallArguments& args,
    106                         const v8::debug::ConsoleContext&) {
    107   base::TimeDelta delta;
    108   if (args.Length() == 0) {
    109     delta = base::TimeTicks::HighResolutionNow() - default_timer_;
    110     printf("console.timeEnd: default, %f\n", delta.InMillisecondsF());
    111   } else {
    112     base::TimeTicks now = base::TimeTicks::HighResolutionNow();
    113     Local<Value> arg = args[0];
    114     Local<String> label;
    115     v8::TryCatch try_catch(isolate_);
    116     if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return;
    117     v8::String::Utf8Value utf8(isolate_, label);
    118     std::string string(*utf8);
    119     auto find = timers_.find(string);
    120     if (find != timers_.end()) {
    121       delta = now - find->second;
    122     }
    123     printf("console.timeEnd: %s, %f\n", *utf8, delta.InMillisecondsF());
    124   }
    125 }
    126 
    127 void D8Console::TimeStamp(const debug::ConsoleCallArguments& args,
    128                           const v8::debug::ConsoleContext&) {
    129   base::TimeDelta delta = base::TimeTicks::HighResolutionNow() - default_timer_;
    130   if (args.Length() == 0) {
    131     printf("console.timeStamp: default, %f\n", delta.InMillisecondsF());
    132   } else {
    133     Local<Value> arg = args[0];
    134     Local<String> label;
    135     v8::TryCatch try_catch(isolate_);
    136     if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return;
    137     v8::String::Utf8Value utf8(isolate_, label);
    138     std::string string(*utf8);
    139     printf("console.timeStamp: %s, %f\n", *utf8, delta.InMillisecondsF());
    140   }
    141 }
    142 
    143 void D8Console::Trace(const debug::ConsoleCallArguments& args,
    144                       const v8::debug::ConsoleContext&) {
    145   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
    146   i_isolate->PrintStack(stderr, i::Isolate::kPrintStackConcise);
    147 }
    148 
    149 }  // namespace v8
    150