console.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. #include "extensions/renderer/console.h"
  5. #include "base/compiler_specific.h"
  6. #include "base/debug/alias.h"
  7. #include "base/lazy_instance.h"
  8. #include "base/strings/string_util.h"
  9. #include "base/strings/utf_string_conversions.h"
  10. #include "extensions/renderer/get_script_context.h"
  11. #include "extensions/renderer/script_context.h"
  12. #include "extensions/renderer/script_context_set.h"
  13. #include "extensions/renderer/v8_helpers.h"
  14. #include "extensions/renderer/worker_thread_dispatcher.h"
  15. #include "gin/converter.h"
  16. #include "gin/per_isolate_data.h"
  17. #include "third_party/blink/public/web/web_console_message.h"
  18. #include "v8/include/v8-function-callback.h"
  19. #include "v8/include/v8-primitive.h"
  20. #include "v8/include/v8-template.h"
  21. namespace extensions {
  22. namespace console {
  23. namespace {
  24. // Writes |message| to stack to show up in minidump, then crashes.
  25. void CheckWithMinidump(const std::string& message) {
  26. DEBUG_ALIAS_FOR_CSTR(minidump, message.c_str(), 1024);
  27. CHECK(false) << message;
  28. }
  29. void BoundLogMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
  30. std::string message;
  31. for (int i = 0; i < info.Length(); ++i) {
  32. if (i > 0)
  33. message += " ";
  34. message += *v8::String::Utf8Value(info.GetIsolate(), info[i]);
  35. }
  36. ScriptContext* script_context =
  37. GetScriptContextFromV8Context(info.GetIsolate()->GetCurrentContext());
  38. // TODO(devlin): Consider (D)CHECK(script_context)
  39. const auto level = static_cast<blink::mojom::ConsoleMessageLevel>(
  40. info.Data().As<v8::Int32>()->Value());
  41. AddMessage(script_context, level, message);
  42. }
  43. gin::WrapperInfo kWrapperInfo = {gin::kEmbedderNativeGin};
  44. } // namespace
  45. void Fatal(ScriptContext* context, const std::string& message) {
  46. AddMessage(context, blink::mojom::ConsoleMessageLevel::kError, message);
  47. CheckWithMinidump(message);
  48. }
  49. void AddMessage(ScriptContext* script_context,
  50. blink::mojom::ConsoleMessageLevel level,
  51. const std::string& message) {
  52. if (!script_context) {
  53. LOG(WARNING) << "Could not log \"" << message
  54. << "\": no ScriptContext found";
  55. return;
  56. }
  57. if (!script_context->is_valid()) {
  58. LOG(WARNING) << "Could not log \"" << message
  59. << "\": ScriptContext invalidated.";
  60. return;
  61. }
  62. blink::WebConsoleMessage web_console_message(
  63. level, blink::WebString::FromUTF8(message));
  64. blink::WebConsoleMessage::LogWebConsoleMessage(script_context->v8_context(),
  65. web_console_message);
  66. }
  67. v8::Local<v8::Object> AsV8Object(v8::Isolate* isolate) {
  68. v8::EscapableHandleScope handle_scope(isolate);
  69. gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
  70. v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(&kWrapperInfo);
  71. if (templ.IsEmpty()) {
  72. templ = v8::ObjectTemplate::New(isolate);
  73. static const struct {
  74. const char* name;
  75. blink::mojom::ConsoleMessageLevel level;
  76. } methods[] = {
  77. {"debug", blink::mojom::ConsoleMessageLevel::kVerbose},
  78. {"log", blink::mojom::ConsoleMessageLevel::kInfo},
  79. {"warn", blink::mojom::ConsoleMessageLevel::kWarning},
  80. {"error", blink::mojom::ConsoleMessageLevel::kError},
  81. };
  82. for (const auto& method : methods) {
  83. v8::Local<v8::FunctionTemplate> function = v8::FunctionTemplate::New(
  84. isolate, BoundLogMethodCallback,
  85. v8::Integer::New(isolate, static_cast<int>(method.level)),
  86. v8::Local<v8::Signature>(), 0, v8::ConstructorBehavior::kThrow);
  87. templ->Set(gin::StringToSymbol(isolate, method.name), function);
  88. }
  89. data->SetObjectTemplate(&kWrapperInfo, templ);
  90. }
  91. return handle_scope.Escape(
  92. templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked());
  93. }
  94. } // namespace console
  95. } // namespace extensions