// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/d8-console.h" #include "src/d8.h" #include "src/isolate.h" namespace v8 { namespace { void WriteToFile(const char* prefix, FILE* file, Isolate* isolate, const debug::ConsoleCallArguments& args) { if (prefix) fprintf(file, "%s: ", prefix); for (int i = 0; i < args.Length(); i++) { HandleScope handle_scope(isolate); if (i > 0) fprintf(file, " "); Local arg = args[i]; Local str_obj; if (arg->IsSymbol()) arg = Local::Cast(arg)->Name(); if (!arg->ToString(isolate->GetCurrentContext()).ToLocal(&str_obj)) return; v8::String::Utf8Value str(isolate, str_obj); int n = static_cast(fwrite(*str, sizeof(**str), str.length(), file)); if (n != str.length()) { printf("Error in fwrite\n"); base::OS::ExitProcess(1); } } fprintf(file, "\n"); } } // anonymous namespace D8Console::D8Console(Isolate* isolate) : isolate_(isolate) { default_timer_ = base::TimeTicks::HighResolutionNow(); } void D8Console::Assert(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { Local arg; if (args.Length() > 0) { if (!args[0]->ToBoolean(isolate_->GetCurrentContext()).ToLocal(&arg)) { return; } } else { // No arguments given, the "first" argument is undefined which is false-ish. arg = v8::False(isolate_); } if (arg->IsTrue()) return; WriteToFile("console.assert", stdout, isolate_, args); isolate_->ThrowException(v8::Exception::Error( v8::String::NewFromUtf8(isolate_, "console.assert failed", v8::NewStringType::kNormal) .ToLocalChecked())); } void D8Console::Log(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { WriteToFile(nullptr, stdout, isolate_, args); } void D8Console::Error(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { WriteToFile("console.error", stderr, isolate_, args); } void D8Console::Warn(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { WriteToFile("console.warn", stdout, isolate_, args); } void D8Console::Info(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { WriteToFile("console.info", stdout, isolate_, args); } void D8Console::Debug(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { WriteToFile("console.debug", stdout, isolate_, args); } void D8Console::Time(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { if (args.Length() == 0) { default_timer_ = base::TimeTicks::HighResolutionNow(); } else { Local arg = args[0]; Local label; v8::TryCatch try_catch(isolate_); if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return; v8::String::Utf8Value utf8(isolate_, label); std::string string(*utf8); auto find = timers_.find(string); if (find != timers_.end()) { find->second = base::TimeTicks::HighResolutionNow(); } else { timers_.insert(std::pair( string, base::TimeTicks::HighResolutionNow())); } } } void D8Console::TimeEnd(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { base::TimeDelta delta; if (args.Length() == 0) { delta = base::TimeTicks::HighResolutionNow() - default_timer_; printf("console.timeEnd: default, %f\n", delta.InMillisecondsF()); } else { base::TimeTicks now = base::TimeTicks::HighResolutionNow(); Local arg = args[0]; Local label; v8::TryCatch try_catch(isolate_); if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return; v8::String::Utf8Value utf8(isolate_, label); std::string string(*utf8); auto find = timers_.find(string); if (find != timers_.end()) { delta = now - find->second; } printf("console.timeEnd: %s, %f\n", *utf8, delta.InMillisecondsF()); } } void D8Console::TimeStamp(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { base::TimeDelta delta = base::TimeTicks::HighResolutionNow() - default_timer_; if (args.Length() == 0) { printf("console.timeStamp: default, %f\n", delta.InMillisecondsF()); } else { Local arg = args[0]; Local label; v8::TryCatch try_catch(isolate_); if (!arg->ToString(isolate_->GetCurrentContext()).ToLocal(&label)) return; v8::String::Utf8Value utf8(isolate_, label); std::string string(*utf8); printf("console.timeStamp: %s, %f\n", *utf8, delta.InMillisecondsF()); } } void D8Console::Trace(const debug::ConsoleCallArguments& args, const v8::debug::ConsoleContext&) { i::Isolate* i_isolate = reinterpret_cast(isolate_); i_isolate->PrintStack(stderr, i::Isolate::kPrintStackConcise); } } // namespace v8