wrappable.cc 2.6 KB

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