1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "v8_native_engine.h"
17
18 #include "utils/log.h"
19 #include "v8_native_reference.h"
20
V8NativeReference(V8NativeEngine * engine,NativeValue * value,uint32_t initialRefcount,bool deleteSelf,NativeFinalize callback,void * data,void * hint)21 V8NativeReference::V8NativeReference(V8NativeEngine* engine,
22 NativeValue* value,
23 uint32_t initialRefcount,
24 bool deleteSelf,
25 NativeFinalize callback,
26 void* data,
27 void* hint)
28 : engine_(engine),
29 value_(),
30 refCount_(initialRefcount),
31 deleteSelf_(deleteSelf),
32 callback_(callback),
33 data_(data),
34 hint_(hint)
35 {
36 v8::Local<v8::Value> v8Value = *value;
37 value_.Reset(engine->GetIsolate(), v8Value);
38 if (initialRefcount == 0) {
39 value_.SetWeak(this, FinalizeCallback, v8::WeakCallbackType::kParameter);
40 }
41 if (deleteSelf) {
42 NativeReferenceManager* referenceManager = engine->GetReferenceManager();
43 if (referenceManager != nullptr) {
44 referenceManager->CreateHandler(this);
45 }
46 }
47 }
48
~V8NativeReference()49 V8NativeReference::~V8NativeReference()
50 {
51 if (deleteSelf_ && engine_->GetReferenceManager()) {
52 engine_->GetReferenceManager()->ReleaseHandler(this);
53 }
54 if (value_.IsEmpty()) {
55 HILOG_WARN("V8NativeReference::~V8NativeReference value is empty");
56 return;
57 }
58
59 value_.SetWeak(this, FinalizeCallback, v8::WeakCallbackType::kParameter);
60 if (callback_) {
61 callback_(engine_, data_, hint_);
62 }
63 }
64
Ref()65 uint32_t V8NativeReference::Ref()
66 {
67 ++refCount_;
68 if (refCount_ == 1) {
69 value_.ClearWeak();
70 }
71 return refCount_;
72 }
73
Unref()74 uint32_t V8NativeReference::Unref()
75 {
76 --refCount_;
77 uint32_t refCount = refCount_;
78 if (refCount == 0) {
79 value_.SetWeak(this, FinalizeCallback, v8::WeakCallbackType::kParameter);
80 }
81 return refCount;
82 }
83
Get()84 NativeValue* V8NativeReference::Get()
85 {
86 v8::Local<v8::Value> value = value_.Get(engine_->GetIsolate());
87 return V8NativeEngine::V8ValueToNativeValue(engine_, value);
88 }
89
GetData()90 void* V8NativeReference::GetData()
91 {
92 return data_;
93 }
94
operator NativeValue*()95 V8NativeReference::operator NativeValue*()
96 {
97 return Get();
98 }
99
FinalizeCallback(const v8::WeakCallbackInfo<V8NativeReference> & data)100 void V8NativeReference::FinalizeCallback(const v8::WeakCallbackInfo<V8NativeReference>& data)
101 {
102 V8NativeReference* that = data.GetParameter();
103 that->value_.Reset();
104 data.SetSecondPassCallback(SecondPassCallback);
105 }
106
SecondPassCallback(const v8::WeakCallbackInfo<V8NativeReference> & data)107 void V8NativeReference::SecondPassCallback(const v8::WeakCallbackInfo<V8NativeReference>& data)
108 {
109 V8NativeReference* that = data.GetParameter();
110 if (that->callback_ != nullptr) {
111 that->callback_(that->engine_, that->data_, that->hint_);
112 }
113 }
114