wrappable.cc 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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 "shell/common/gin_helper/dictionary.h"
  7. namespace gin_helper {
  8. WrappableBase::WrappableBase() = default;
  9. WrappableBase::~WrappableBase() {
  10. if (wrapper_.IsEmpty())
  11. return;
  12. v8::HandleScope scope(isolate());
  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. delete static_cast<WrappableBase*>(data.GetInternalField(0));
  63. }
  64. namespace internal {
  65. void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val) {
  66. if (!val->IsObject())
  67. return nullptr;
  68. v8::Local<v8::Object> obj = val.As<v8::Object>();
  69. if (obj->InternalFieldCount() != 1)
  70. return nullptr;
  71. return obj->GetAlignedPointerFromInternalField(0);
  72. }
  73. } // namespace internal
  74. } // namespace gin_helper