wrappable.cc 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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.chromium file.
  4. #include "shell/common/gin_helper/wrappable.h"
  5. #include "base/logging.h"
  6. #include "base/threading/thread_task_runner_handle.h"
  7. #include "shell/common/gin_helper/dictionary.h"
  8. namespace gin_helper {
  9. WrappableBase::WrappableBase() = default;
  10. WrappableBase::~WrappableBase() {
  11. if (wrapper_.IsEmpty())
  12. return;
  13. GetWrapper()->SetAlignedPointerInInternalField(0, nullptr);
  14. wrapper_.ClearWeak();
  15. wrapper_.Reset();
  16. }
  17. v8::Local<v8::Object> WrappableBase::GetWrapper() const {
  18. if (!wrapper_.IsEmpty())
  19. return v8::Local<v8::Object>::New(isolate_, wrapper_);
  20. else
  21. return v8::Local<v8::Object>();
  22. }
  23. v8::MaybeLocal<v8::Object> WrappableBase::GetWrapper(
  24. v8::Isolate* isolate) const {
  25. if (!wrapper_.IsEmpty())
  26. return v8::MaybeLocal<v8::Object>(
  27. v8::Local<v8::Object>::New(isolate, wrapper_));
  28. else
  29. return v8::MaybeLocal<v8::Object>();
  30. }
  31. void WrappableBase::InitWithArgs(gin::Arguments* args) {
  32. v8::Local<v8::Object> holder;
  33. args->GetHolder(&holder);
  34. InitWith(args->isolate(), holder);
  35. }
  36. void WrappableBase::InitWith(v8::Isolate* isolate,
  37. v8::Local<v8::Object> wrapper) {
  38. CHECK(wrapper_.IsEmpty());
  39. isolate_ = isolate;
  40. wrapper->SetAlignedPointerInInternalField(0, this);
  41. wrapper_.Reset(isolate, wrapper);
  42. wrapper_.SetWeak(this, FirstWeakCallback,
  43. v8::WeakCallbackType::kInternalFields);
  44. // Call object._init if we have one.
  45. v8::Local<v8::Function> init;
  46. if (Dictionary(isolate, wrapper).Get("_init", &init))
  47. init->Call(isolate->GetCurrentContext(), wrapper, 0, nullptr).IsEmpty();
  48. AfterInit(isolate);
  49. }
  50. // static
  51. void WrappableBase::FirstWeakCallback(
  52. const v8::WeakCallbackInfo<WrappableBase>& data) {
  53. auto* wrappable = static_cast<WrappableBase*>(data.GetInternalField(0));
  54. if (wrappable) {
  55. wrappable->wrapper_.Reset();
  56. data.SetSecondPassCallback(SecondWeakCallback);
  57. }
  58. }
  59. // static
  60. void WrappableBase::SecondWeakCallback(
  61. const v8::WeakCallbackInfo<WrappableBase>& data) {
  62. auto* wrappable = static_cast<WrappableBase*>(data.GetInternalField(0));
  63. if (wrappable)
  64. delete wrappable;
  65. }
  66. namespace internal {
  67. void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val) {
  68. if (!val->IsObject())
  69. return nullptr;
  70. v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(val);
  71. if (obj->InternalFieldCount() != 1)
  72. return nullptr;
  73. return obj->GetAlignedPointerFromInternalField(0);
  74. }
  75. } // namespace internal
  76. } // namespace gin_helper