1// Copyright 2013 The Chromium 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 "chrome/renderer/extensions/logging_native_handler.h"
6
7#include "base/logging.h"
8#include "base/strings/stringprintf.h"
9
10namespace extensions {
11
12LoggingNativeHandler::LoggingNativeHandler(ChromeV8Context* context)
13    : ObjectBackedNativeHandler(context) {
14  RouteFunction("DCHECK",
15      base::Bind(&LoggingNativeHandler::Dcheck, base::Unretained(this)));
16  RouteFunction("CHECK",
17      base::Bind(&LoggingNativeHandler::Check, base::Unretained(this)));
18  RouteFunction("DCHECK_IS_ON",
19      base::Bind(&LoggingNativeHandler::DcheckIsOn, base::Unretained(this)));
20  RouteFunction("LOG",
21      base::Bind(&LoggingNativeHandler::Log, base::Unretained(this)));
22  RouteFunction("WARNING",
23      base::Bind(&LoggingNativeHandler::Warning, base::Unretained(this)));
24}
25
26LoggingNativeHandler::~LoggingNativeHandler() {}
27
28void LoggingNativeHandler::Check(
29    const v8::FunctionCallbackInfo<v8::Value>& args) {
30  bool check_value;
31  std::string error_message;
32  ParseArgs(args, &check_value, &error_message);
33  CHECK(check_value) << error_message;
34}
35
36void LoggingNativeHandler::Dcheck(
37    const v8::FunctionCallbackInfo<v8::Value>& args) {
38  bool check_value;
39  std::string error_message;
40  ParseArgs(args, &check_value, &error_message);
41  DCHECK(check_value) << error_message;
42}
43
44void LoggingNativeHandler::DcheckIsOn(
45    const v8::FunctionCallbackInfo<v8::Value>& args) {
46  args.GetReturnValue().Set(DCHECK_IS_ON());
47}
48
49void LoggingNativeHandler::Log(
50    const v8::FunctionCallbackInfo<v8::Value>& args) {
51  CHECK_EQ(1, args.Length());
52  LOG(INFO) << *v8::String::AsciiValue(args[0]);
53}
54
55void LoggingNativeHandler::Warning(
56    const v8::FunctionCallbackInfo<v8::Value>& args) {
57  CHECK_EQ(1, args.Length());
58  LOG(WARNING) << *v8::String::AsciiValue(args[0]);
59}
60
61void LoggingNativeHandler::ParseArgs(
62    const v8::FunctionCallbackInfo<v8::Value>& args,
63    bool* check_value,
64    std::string* error_message) {
65  CHECK_LE(args.Length(), 2);
66  *check_value = args[0]->BooleanValue();
67  if (args.Length() == 2) {
68    *error_message = "Error: " + std::string(
69        *v8::String::AsciiValue(args[1]));
70  }
71
72  v8::Handle<v8::StackTrace> stack_trace =
73      v8::StackTrace::CurrentStackTrace(10);
74  if (stack_trace.IsEmpty() || stack_trace->GetFrameCount() <= 0) {
75    *error_message += "\n    <no stack trace>";
76  } else {
77    for (size_t i = 0; i < (size_t) stack_trace->GetFrameCount(); ++i) {
78      v8::Handle<v8::StackFrame> frame = stack_trace->GetFrame(i);
79      CHECK(!frame.IsEmpty());
80      *error_message += base::StringPrintf("\n    at %s (%s:%d:%d)",
81          ToStringOrDefault(frame->GetFunctionName(), "<anonymous>").c_str(),
82          ToStringOrDefault(frame->GetScriptName(), "<anonymous>").c_str(),
83          frame->GetLineNumber(),
84          frame->GetColumn());
85    }
86  }
87}
88
89std::string LoggingNativeHandler::ToStringOrDefault(
90    const v8::Handle<v8::String>& v8_string,
91    const std::string& dflt) {
92  if (v8_string.IsEmpty())
93    return dflt;
94  std::string ascii_value = *v8::String::AsciiValue(v8_string);
95  return ascii_value.empty() ? dflt : ascii_value;
96}
97
98}  // namespace extensions
99
100