1 /*
2 * Copyright (c) 2024 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 #ifndef JSVM_REFERENCE_INL_H
17 #define JSVM_REFERENCE_INL_H
18 #include "jsvm_env.h"
19 #include "jsvm_reference.h"
20
21 namespace v8impl {
CanBeHeldWeakly(v8::Local<v8::Value> value)22 inline bool CanBeHeldWeakly(v8::Local<v8::Value> value)
23 {
24 return value->IsObject() || value->IsSymbol();
25 }
26
27 // RefTracker
Link(RefList * list)28 inline void RefTracker::Link(RefList* list)
29 {
30 DCHECK(list != nullptr);
31 prev = list;
32 next = list->next;
33 if (next != nullptr) {
34 next->prev = this;
35 }
36 list->next = this;
37 }
38
Unlink()39 inline void RefTracker::Unlink()
40 {
41 if (prev != nullptr) {
42 prev->next = next;
43 }
44 if (next != nullptr) {
45 next->prev = prev;
46 }
47 prev = nullptr;
48 next = nullptr;
49 }
50
51 // UserReference
SetWeak()52 inline void UserReference::SetWeak()
53 {
54 if (canBeWeak) {
55 persistent.SetWeak();
56 } else {
57 persistent.Reset();
58 }
59 }
60
Ref()61 inline uint32_t UserReference::Ref()
62 {
63 // If persistent is cleared by GC, return 0 unconditionally.
64 if (persistent.IsEmpty()) {
65 return 0;
66 }
67
68 if (++refcount == 1) {
69 // If persistent can not be weak, it will be cleared in SetWeak().
70 DCHECK(canBeWeak);
71 persistent.ClearWeak();
72 }
73
74 return refcount;
75 }
76
Unref()77 inline uint32_t UserReference::Unref()
78 {
79 // If persistent is cleared by GC, return 0 unconditionally.
80 if (persistent.IsEmpty() || refcount == 0) {
81 return 0;
82 }
83
84 if (--refcount == 0) {
85 SetWeak();
86 }
87
88 return refcount;
89 }
90
Get()91 inline v8::Local<v8::Value> UserReference::Get()
92 {
93 DCHECK(isValue);
94 if (persistent.IsEmpty()) {
95 return v8::Local<v8::Value>();
96 } else {
97 return v8::Local<v8::Data>::New(env->isolate, persistent).As<v8::Value>();
98 }
99 }
100
GetData()101 inline v8::Local<v8::Data> UserReference::GetData()
102 {
103 if (persistent.IsEmpty()) {
104 return v8::Local<v8::Data>();
105 } else {
106 return v8::Local<v8::Data>::New(env->isolate, persistent);
107 }
108 }
109
110 } // namespace v8impl
111
112 #endif