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