jdk

Форк
0
329 строк · 9.2 Кб
1
/*
2
 * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Oracle designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Oracle in the LICENSE file that accompanied this code.
10
 *
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * version 2 for more details (a copy is included in the LICENSE file that
15
 * accompanied this code).
16
 *
17
 * You should have received a copy of the GNU General Public License version
18
 * 2 along with this work; if not, write to the Free Software Foundation,
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
 *
21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
 * or visit www.oracle.com if you need additional information or have any
23
 * questions.
24
 */
25

26
#include <assert.h>
27
#include <stdlib.h>
28
#include <string.h>
29

30
#include "check_classname.h"
31
#include "java_lang_ClassLoader.h"
32
#include "jlong.h"
33
#include "jni.h"
34
#include "jni_util.h"
35
#include "jvm.h"
36

37
static JNINativeMethod methods[] = {
38
    {"retrieveDirectives",  "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
39
};
40

41
JNIEXPORT void JNICALL
42
Java_java_lang_ClassLoader_registerNatives(JNIEnv *env, jclass cls)
43
{
44
    (*env)->RegisterNatives(env, cls, methods,
45
                            sizeof(methods)/sizeof(JNINativeMethod));
46
}
47

48
/* Convert java string to UTF char*. Use local buffer if possible,
49
   otherwise malloc new memory. Returns null IFF malloc failed. */
50
static char*
51
getUTF(JNIEnv *env, jstring str, char* localBuf, int bufSize)
52
{
53
    char* utfStr = NULL;
54

55
    int len = (*env)->GetStringUTFLength(env, str);
56
    int unicode_len = (*env)->GetStringLength(env, str);
57
    if (len >= bufSize) {
58
        utfStr = malloc(len + 1);
59
        if (utfStr == NULL) {
60
            JNU_ThrowOutOfMemoryError(env, NULL);
61
            return NULL;
62
        }
63
    } else {
64
        utfStr = localBuf;
65
    }
66
    (*env)->GetStringUTFRegion(env, str, 0, unicode_len, utfStr);
67

68
    return utfStr;
69
}
70

71
JNIEXPORT jclass JNICALL
72
Java_java_lang_ClassLoader_defineClass1(JNIEnv *env,
73
                                        jclass cls,
74
                                        jobject loader,
75
                                        jstring name,
76
                                        jbyteArray data,
77
                                        jint offset,
78
                                        jint length,
79
                                        jobject pd,
80
                                        jstring source)
81
{
82
    jbyte *body;
83
    char *utfName;
84
    jclass result = 0;
85
    char buf[128];
86
    char* utfSource;
87
    char sourceBuf[1024];
88

89
    if (data == NULL) {
90
        JNU_ThrowNullPointerException(env, 0);
91
        return NULL;
92
    }
93

94
    /* Work around 4153825. malloc crashes on Solaris when passed a
95
     * negative size.
96
     */
97
    if (length < 0) {
98
        JNU_ThrowArrayIndexOutOfBoundsException(env, 0);
99
        return NULL;
100
    }
101

102
    // On AIX malloc(0) returns NULL which looks like an out-of-memory
103
    // condition; so adjust it to malloc(1)
104
    #ifdef _AIX
105
        body = (jbyte *)malloc(length == 0 ? 1 : length);
106
    #else
107
        body = (jbyte *)malloc(length);
108
    #endif
109

110
    if (body == NULL) {
111
        JNU_ThrowOutOfMemoryError(env, 0);
112
        return NULL;
113
    }
114

115
    (*env)->GetByteArrayRegion(env, data, offset, length, body);
116

117
    if ((*env)->ExceptionOccurred(env)) {
118
        goto free_body;
119
    }
120

121
    if (name != NULL) {
122
        utfName = getUTF(env, name, buf, sizeof(buf));
123
        if (utfName == NULL) {
124
            goto free_body;
125
        }
126
        fixClassname(utfName);
127
    } else {
128
        utfName = NULL;
129
    }
130

131
    if (source != NULL) {
132
        utfSource = getUTF(env, source, sourceBuf, sizeof(sourceBuf));
133
        if (utfSource == NULL) {
134
            goto free_utfName;
135
        }
136
    } else {
137
        utfSource = NULL;
138
    }
139
    result = JVM_DefineClassWithSource(env, utfName, loader, body, length, pd, utfSource);
140

141
    if (utfSource && utfSource != sourceBuf)
142
        free(utfSource);
143

144
 free_utfName:
145
    if (utfName && utfName != buf)
146
        free(utfName);
147

148
 free_body:
149
    free(body);
150
    return result;
151
}
152

153
JNIEXPORT jclass JNICALL
154
Java_java_lang_ClassLoader_defineClass2(JNIEnv *env,
155
                                        jclass cls,
156
                                        jobject loader,
157
                                        jstring name,
158
                                        jobject data,
159
                                        jint offset,
160
                                        jint length,
161
                                        jobject pd,
162
                                        jstring source)
163
{
164
    jbyte *body;
165
    char *utfName;
166
    jclass result = 0;
167
    char buf[128];
168
    char* utfSource;
169
    char sourceBuf[1024];
170

171
    assert(data != NULL); // caller fails if data is null.
172
    assert(length >= 0);  // caller passes ByteBuffer.remaining() for length, so never neg.
173
    // caller passes ByteBuffer.position() for offset, and capacity() >= position() + remaining()
174
    assert((*env)->GetDirectBufferCapacity(env, data) >= (offset + length));
175

176
    body = (*env)->GetDirectBufferAddress(env, data);
177

178
    if (body == NULL) {
179
        JNU_ThrowNullPointerException(env, 0);
180
        return NULL;
181
    }
182

183
    body += offset;
184

185
    if (name != NULL) {
186
        utfName = getUTF(env, name, buf, sizeof(buf));
187
        if (utfName == NULL) {
188
            return result;
189
        }
190
        fixClassname(utfName);
191
    } else {
192
        utfName = NULL;
193
    }
194

195
    if (source != NULL) {
196
        utfSource = getUTF(env, source, sourceBuf, sizeof(sourceBuf));
197
        if (utfSource == NULL) {
198
            goto free_utfName;
199
        }
200
    } else {
201
        utfSource = NULL;
202
    }
203
    result = JVM_DefineClassWithSource(env, utfName, loader, body, length, pd, utfSource);
204

205
    if (utfSource && utfSource != sourceBuf)
206
        free(utfSource);
207

208
 free_utfName:
209
    if (utfName && utfName != buf)
210
        free(utfName);
211

212
    return result;
213
}
214

215
JNIEXPORT jclass JNICALL
216
Java_java_lang_ClassLoader_defineClass0(JNIEnv *env,
217
                                        jclass cls,
218
                                        jobject loader,
219
                                        jclass lookup,
220
                                        jstring name,
221
                                        jbyteArray data,
222
                                        jint offset,
223
                                        jint length,
224
                                        jobject pd,
225
                                        jboolean initialize,
226
                                        jint flags,
227
                                        jobject classData)
228
{
229
    jbyte *body;
230
    char *utfName;
231
    jclass result = 0;
232
    char buf[128];
233

234
    if (data == NULL) {
235
        JNU_ThrowNullPointerException(env, 0);
236
        return NULL;
237
    }
238

239
    /* Work around 4153825. malloc crashes on Solaris when passed a
240
     * negative size.
241
     */
242
    if (length < 0) {
243
        JNU_ThrowArrayIndexOutOfBoundsException(env, 0);
244
        return NULL;
245
    }
246

247
    // On AIX malloc(0) returns NULL which looks like an out-of-memory
248
    // condition; so adjust it to malloc(1)
249
    #ifdef _AIX
250
        body = (jbyte *)malloc(length == 0 ? 1 : length);
251
    #else
252
        body = (jbyte *)malloc(length);
253
    #endif
254

255
    if (body == NULL) {
256
        JNU_ThrowOutOfMemoryError(env, 0);
257
        return NULL;
258
    }
259

260
    (*env)->GetByteArrayRegion(env, data, offset, length, body);
261

262
    if ((*env)->ExceptionOccurred(env))
263
        goto free_body;
264

265
    if (name != NULL) {
266
        utfName = getUTF(env, name, buf, sizeof(buf));
267
        if (utfName == NULL) {
268
            goto free_body;
269
        }
270
        fixClassname(utfName);
271
    } else {
272
        utfName = NULL;
273
    }
274

275
    result = JVM_LookupDefineClass(env, lookup, utfName, body, length, pd, initialize, flags, classData);
276

277
    if (utfName && utfName != buf)
278
        free(utfName);
279

280
 free_body:
281
    free(body);
282
    return result;
283
}
284

285
/*
286
 * Returns NULL if class not found.
287
 */
288
JNIEXPORT jclass JNICALL
289
Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jclass dummy,
290
                                              jstring classname)
291
{
292
    char *clname;
293
    jclass cls = 0;
294
    char buf[128];
295

296
    if (classname == NULL) {
297
        return NULL;
298
    }
299

300
    clname = getUTF(env, classname, buf, sizeof(buf));
301
    if (clname == NULL) {
302
        return NULL;
303
    }
304
    fixClassname(clname);
305

306
    if (!verifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
307
        goto done;
308
    }
309

310
    cls = JVM_FindClassFromBootLoader(env, clname);
311

312
 done:
313
    if (clname != buf) {
314
        free(clname);
315
    }
316

317
    return cls;
318
}
319

320
JNIEXPORT jclass JNICALL
321
Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader,
322
                                           jstring name)
323
{
324
    if (name == NULL) {
325
        return NULL;
326
    } else {
327
        return JVM_FindLoadedClass(env, loader, name);
328
    }
329
}
330

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.