• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/jni_zero/java_refs.h"
6 
7 #include "third_party/jni_zero/jni_methods.h"
8 
9 namespace jni_zero {
10 namespace {
11 const int kDefaultLocalFrameCapacity = 16;
12 }
13 
ScopedJavaLocalFrame(JNIEnv * env)14 ScopedJavaLocalFrame::ScopedJavaLocalFrame(JNIEnv* env) : env_(env) {
15   int failed = env_->PushLocalFrame(kDefaultLocalFrameCapacity);
16   JNI_ZERO_DCHECK(!failed);
17 }
18 
ScopedJavaLocalFrame(JNIEnv * env,int capacity)19 ScopedJavaLocalFrame::ScopedJavaLocalFrame(JNIEnv* env, int capacity)
20     : env_(env) {
21   int failed = env_->PushLocalFrame(capacity);
22   JNI_ZERO_DCHECK(!failed);
23 }
24 
~ScopedJavaLocalFrame()25 ScopedJavaLocalFrame::~ScopedJavaLocalFrame() {
26   env_->PopLocalFrame(nullptr);
27 }
28 
29 #if JNI_ZERO_DCHECK_IS_ON()
30 // This constructor is inlined when DCHECKs are disabled; don't add anything
31 // else here.
JavaRef(JNIEnv * env,jobject obj)32 JavaRef<jobject>::JavaRef(JNIEnv* env, jobject obj) : obj_(obj) {
33   if (obj) {
34     JNI_ZERO_DCHECK(env && env->GetObjectRefType(obj) == JNILocalRefType);
35   }
36 }
37 #endif
38 
SetNewLocalRef(JNIEnv * env,jobject obj)39 JNIEnv* JavaRef<jobject>::SetNewLocalRef(JNIEnv* env, jobject obj) {
40   if (!env) {
41     env = AttachCurrentThread();
42   } else {
43     JNI_ZERO_DCHECK(env ==
44                     AttachCurrentThread());  // Is |env| on correct thread.
45   }
46   if (obj) {
47     obj = env->NewLocalRef(obj);
48   }
49   if (obj_) {
50     env->DeleteLocalRef(obj_);
51   }
52   obj_ = obj;
53   return env;
54 }
55 
SetNewGlobalRef(JNIEnv * env,jobject obj)56 void JavaRef<jobject>::SetNewGlobalRef(JNIEnv* env, jobject obj) {
57   if (!env) {
58     env = AttachCurrentThread();
59   } else {
60     JNI_ZERO_DCHECK(env ==
61                     AttachCurrentThread());  // Is |env| on correct thread.
62   }
63   if (obj) {
64     obj = env->NewGlobalRef(obj);
65   }
66   if (obj_) {
67     env->DeleteGlobalRef(obj_);
68   }
69   obj_ = obj;
70 }
71 
ResetLocalRef(JNIEnv * env)72 void JavaRef<jobject>::ResetLocalRef(JNIEnv* env) {
73   if (obj_) {
74     JNI_ZERO_DCHECK(env ==
75                     AttachCurrentThread());  // Is |env| on correct thread.
76     env->DeleteLocalRef(obj_);
77     obj_ = nullptr;
78   }
79 }
80 
ResetGlobalRef()81 void JavaRef<jobject>::ResetGlobalRef() {
82   if (obj_) {
83     AttachCurrentThread()->DeleteGlobalRef(obj_);
84     obj_ = nullptr;
85   }
86 }
87 
ScopedJavaGlobalWeakRef(const ScopedJavaGlobalWeakRef & orig)88 ScopedJavaGlobalWeakRef::ScopedJavaGlobalWeakRef(
89     const ScopedJavaGlobalWeakRef& orig) {
90   Assign(orig);
91 }
92 
ScopedJavaGlobalWeakRef(JNIEnv * env,const JavaRef<jobject> & obj)93 ScopedJavaGlobalWeakRef::ScopedJavaGlobalWeakRef(JNIEnv* env,
94                                                  const JavaRef<jobject>& obj)
95     : obj_(env->NewWeakGlobalRef(obj.obj())) {}
96 
reset()97 void ScopedJavaGlobalWeakRef::reset() {
98   if (obj_) {
99     AttachCurrentThread()->DeleteWeakGlobalRef(obj_);
100     obj_ = nullptr;
101   }
102 }
103 
get(JNIEnv * env) const104 ScopedJavaLocalRef<jobject> ScopedJavaGlobalWeakRef::get(JNIEnv* env) const {
105   jobject real = obj_ ? real = env->NewLocalRef(obj_) : nullptr;
106   return ScopedJavaLocalRef<jobject>(env, real);
107 }
108 
Assign(const ScopedJavaGlobalWeakRef & other)109 void ScopedJavaGlobalWeakRef::Assign(const ScopedJavaGlobalWeakRef& other) {
110   if (&other == this) {
111     return;
112   }
113 
114   JNIEnv* env = AttachCurrentThread();
115   if (obj_) {
116     env->DeleteWeakGlobalRef(obj_);
117   }
118 
119   obj_ = other.obj_ ? env->NewWeakGlobalRef(other.obj_) : nullptr;
120 }
121 
122 }  // namespace jni_zero
123