[go: nahoru, domu]

blob: 402355cb836cea14e9ee725a142a4bad44fd5bed [file] [log] [blame]
Avi Drissman468e51b62022-09-13 20:47:011// Copyright 2013 The Chromium Authors
abarth@chromium.org93f9f3602013-11-21 18:38:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "gin/wrappable.h"
6
Hans Wennborgdcc5ada2020-04-27 13:27:237#include "base/check_op.h"
jochen@chromium.orgcb6c2bb2013-12-17 21:47:048#include "gin/object_template_builder.h"
abarth@chromium.org93f9f3602013-11-21 18:38:519#include "gin/per_isolate_data.h"
10
11namespace gin {
12
Chris Watkins756035a2017-12-01 03:03:2713WrappableBase::WrappableBase() = default;
abarth@chromium.org93f9f3602013-11-21 18:38:5114
aa@chromium.org6fe56102013-12-08 07:10:5815WrappableBase::~WrappableBase() {
abarth@chromium.org93f9f3602013-11-21 18:38:5116 wrapper_.Reset();
17}
18
aa@chromium.org13c977e62013-12-19 00:52:4419ObjectTemplateBuilder WrappableBase::GetObjectTemplateBuilder(
jochen@chromium.orgcb6c2bb2013-12-17 21:47:0420 v8::Isolate* isolate) {
Devlin Cronine9db9842018-04-09 17:51:0521 return ObjectTemplateBuilder(isolate, GetTypeName());
22}
23
24const char* WrappableBase::GetTypeName() {
25 return nullptr;
jochen@chromium.orgcb6c2bb2013-12-17 21:47:0426}
27
dcarney99ade9082015-04-22 09:55:4228void WrappableBase::FirstWeakCallback(
29 const v8::WeakCallbackInfo<WrappableBase>& data) {
aa@chromium.org6fe56102013-12-08 07:10:5830 WrappableBase* wrappable = data.GetParameter();
Ken Rockot2b0f07652017-04-12 19:10:4931 wrappable->dead_ = true;
abarth@chromium.org93f9f3602013-11-21 18:38:5132 wrappable->wrapper_.Reset();
dcarney99ade9082015-04-22 09:55:4233 data.SetSecondPassCallback(SecondWeakCallback);
34}
35
36void WrappableBase::SecondWeakCallback(
37 const v8::WeakCallbackInfo<WrappableBase>& data) {
38 WrappableBase* wrappable = data.GetParameter();
abarth@chromium.orgd379b0c2013-12-05 05:48:0139 delete wrappable;
abarth@chromium.org93f9f3602013-11-21 18:38:5140}
41
Ken Rockot2b0f07652017-04-12 19:10:4942v8::MaybeLocal<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
43 WrapperInfo* info) {
aa@chromium.org13c977e62013-12-19 00:52:4444 if (!wrapper_.IsEmpty()) {
Ken Rockot2b0f07652017-04-12 19:10:4945 return v8::MaybeLocal<v8::Object>(
46 v8::Local<v8::Object>::New(isolate, wrapper_));
aa@chromium.org13c977e62013-12-19 00:52:4447 }
48
Ken Rockot2b0f07652017-04-12 19:10:4949 if (dead_)
50 return v8::MaybeLocal<v8::Object>();
51
abarth@chromium.org93f9f3602013-11-21 18:38:5152 PerIsolateData* data = PerIsolateData::From(isolate);
53 v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(info);
jochen@chromium.orgcb6c2bb2013-12-17 21:47:0454 if (templ.IsEmpty()) {
aa@chromium.org13c977e62013-12-19 00:52:4455 templ = GetObjectTemplateBuilder(isolate).Build();
jochen@chromium.orgcb6c2bb2013-12-17 21:47:0456 CHECK(!templ.IsEmpty());
57 data->SetObjectTemplate(info, templ);
58 }
aa@chromium.orgbf3dd3c2013-12-06 06:55:2559 CHECK_EQ(kNumberOfInternalFields, templ->InternalFieldCount());
bashidbd2ef9bb2015-06-02 01:39:3260 v8::Local<v8::Object> wrapper;
hajimehoshi@chromium.orge0719edc2014-02-28 14:48:2561 // |wrapper| may be empty in some extreme cases, e.g., when
62 // Object.prototype.constructor is overwritten.
bashidbd2ef9bb2015-06-02 01:39:3263 if (!templ->NewInstance(isolate->GetCurrentContext()).ToLocal(&wrapper)) {
hajimehoshi@chromium.orge0719edc2014-02-28 14:48:2564 // The current wrappable object will be no longer managed by V8. Delete this
65 // now.
66 delete this;
Ken Rockot2b0f07652017-04-12 19:10:4967 return v8::MaybeLocal<v8::Object>(wrapper);
hajimehoshi@chromium.orge0719edc2014-02-28 14:48:2568 }
cbrunic0363fd2016-08-31 16:21:3369
70 int indices[] = {kWrapperInfoIndex, kEncodedValueIndex};
71 void* values[] = {info, this};
72 wrapper->SetAlignedPointerInInternalFields(2, indices, values);
abarth@chromium.org93f9f3602013-11-21 18:38:5173 wrapper_.Reset(isolate, wrapper);
dcarney99ade9082015-04-22 09:55:4274 wrapper_.SetWeak(this, FirstWeakCallback, v8::WeakCallbackType::kParameter);
Ken Rockot2b0f07652017-04-12 19:10:4975 return v8::MaybeLocal<v8::Object>(wrapper);
abarth@chromium.org93f9f3602013-11-21 18:38:5176}
77
aa@chromium.org6fe56102013-12-08 07:10:5878namespace internal {
79
deepak.sfaaa1b62015-04-30 07:30:4880void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val,
aa@chromium.org6fe56102013-12-08 07:10:5881 WrapperInfo* wrapper_info) {
82 if (!val->IsObject())
83 return NULL;
deepak.sfaaa1b62015-04-30 07:30:4884 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(val);
aa@chromium.org6fe56102013-12-08 07:10:5885 WrapperInfo* info = WrapperInfo::From(obj);
86
87 // If this fails, the object is not managed by Gin. It is either a normal JS
88 // object that's not wrapping any external C++ object, or it is wrapping some
89 // C++ object, but that object isn't managed by Gin (maybe Blink).
90 if (!info)
91 return NULL;
92
93 // If this fails, the object is managed by Gin, but it's not wrapping an
94 // instance of the C++ class associated with wrapper_info.
95 if (info != wrapper_info)
96 return NULL;
97
98 return obj->GetAlignedPointerFromInternalField(kEncodedValueIndex);
99}
100
101} // namespace internal
102
abarth@chromium.org93f9f3602013-11-21 18:38:51103} // namespace gin