jdk

Форк
0
/
reflection.cpp 
1183 строки · 45.1 Кб
1
/*
2
 * Copyright (c) 1997, 2023, 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.
8
 *
9
 * This code is distributed in the hope that it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * version 2 for more details (a copy is included in the LICENSE file that
13
 * accompanied this code).
14
 *
15
 * You should have received a copy of the GNU General Public License version
16
 * 2 along with this work; if not, write to the Free Software Foundation,
17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
 * or visit www.oracle.com if you need additional information or have any
21
 * questions.
22
 *
23
 */
24

25
#include "precompiled.hpp"
26
#include "cds/cdsConfig.hpp"
27
#include "classfile/javaClasses.inline.hpp"
28
#include "classfile/moduleEntry.hpp"
29
#include "classfile/packageEntry.hpp"
30
#include "classfile/stringTable.hpp"
31
#include "classfile/verifier.hpp"
32
#include "classfile/vmClasses.hpp"
33
#include "classfile/vmSymbols.hpp"
34
#include "interpreter/linkResolver.hpp"
35
#include "jvm.h"
36
#include "logging/log.hpp"
37
#include "memory/oopFactory.hpp"
38
#include "memory/resourceArea.hpp"
39
#include "memory/universe.hpp"
40
#include "oops/instanceKlass.inline.hpp"
41
#include "oops/klass.inline.hpp"
42
#include "oops/objArrayKlass.hpp"
43
#include "oops/objArrayOop.inline.hpp"
44
#include "oops/oop.inline.hpp"
45
#include "oops/typeArrayOop.inline.hpp"
46
#include "prims/jvmtiExport.hpp"
47
#include "runtime/fieldDescriptor.inline.hpp"
48
#include "runtime/handles.inline.hpp"
49
#include "runtime/javaCalls.hpp"
50
#include "runtime/javaThread.hpp"
51
#include "runtime/reflection.hpp"
52
#include "runtime/signature.hpp"
53
#include "runtime/vframe.inline.hpp"
54
#include "utilities/formatBuffer.hpp"
55

56
static void trace_class_resolution(oop mirror) {
57
  if (mirror == nullptr || java_lang_Class::is_primitive(mirror)) {
58
    return;
59
  }
60
  Klass* to_class = java_lang_Class::as_Klass(mirror);
61
  ResourceMark rm;
62
  int line_number = -1;
63
  const char * source_file = nullptr;
64
  Klass* caller = nullptr;
65
  JavaThread* jthread = JavaThread::current();
66
  if (jthread->has_last_Java_frame()) {
67
    vframeStream vfst(jthread);
68
    // skip over any frames belonging to java.lang.Class
69
    while (!vfst.at_end() &&
70
           vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) {
71
      vfst.next();
72
    }
73
    if (!vfst.at_end()) {
74
      // this frame is a likely suspect
75
      caller = vfst.method()->method_holder();
76
      line_number = vfst.method()->line_number_from_bci(vfst.bci());
77
      Symbol* s = vfst.method()->method_holder()->source_file_name();
78
      if (s != nullptr) {
79
        source_file = s->as_C_string();
80
      }
81
    }
82
  }
83
  if (caller != nullptr) {
84
    const char * from = caller->external_name();
85
    const char * to = to_class->external_name();
86
    // print in a single call to reduce interleaving between threads
87
    if (source_file != nullptr) {
88
      log_debug(class, resolve)("%s %s %s:%d (reflection)", from, to, source_file, line_number);
89
    } else {
90
      log_debug(class, resolve)("%s %s (reflection)", from, to);
91
    }
92
  }
93
}
94

95

96
oop Reflection::box(jvalue* value, BasicType type, TRAPS) {
97
  if (type == T_VOID) {
98
    return nullptr;
99
  }
100
  if (is_reference_type(type)) {
101
    // regular objects are not boxed
102
    return cast_to_oop(value->l);
103
  }
104
  oop result = java_lang_boxing_object::create(type, value, CHECK_NULL);
105
  if (result == nullptr) {
106
    THROW_(vmSymbols::java_lang_IllegalArgumentException(), result);
107
  }
108
  return result;
109
}
110

111

112
BasicType Reflection::unbox_for_primitive(oop box, jvalue* value, TRAPS) {
113
  if (box == nullptr) {
114
    THROW_(vmSymbols::java_lang_IllegalArgumentException(), T_ILLEGAL);
115
  }
116
  return java_lang_boxing_object::get_value(box, value);
117
}
118

119
BasicType Reflection::unbox_for_regular_object(oop box, jvalue* value) {
120
  // Note:  box is really the unboxed oop.  It might even be a Short, etc.!
121
  value->l = cast_from_oop<jobject>(box);
122
  return T_OBJECT;
123
}
124

125

126
void Reflection::widen(jvalue* value, BasicType current_type, BasicType wide_type, TRAPS) {
127
  assert(wide_type != current_type, "widen should not be called with identical types");
128
  switch (wide_type) {
129
    case T_BOOLEAN:
130
    case T_BYTE:
131
    case T_CHAR:
132
      break;  // fail
133
    case T_SHORT:
134
      switch (current_type) {
135
        case T_BYTE:
136
          value->s = (jshort) value->b;
137
          return;
138
        default:
139
          break;
140
      }
141
      break;  // fail
142
    case T_INT:
143
      switch (current_type) {
144
        case T_BYTE:
145
          value->i = (jint) value->b;
146
          return;
147
        case T_CHAR:
148
          value->i = (jint) value->c;
149
          return;
150
        case T_SHORT:
151
          value->i = (jint) value->s;
152
          return;
153
        default:
154
          break;
155
      }
156
      break;  // fail
157
    case T_LONG:
158
      switch (current_type) {
159
        case T_BYTE:
160
          value->j = (jlong) value->b;
161
          return;
162
        case T_CHAR:
163
          value->j = (jlong) value->c;
164
          return;
165
        case T_SHORT:
166
          value->j = (jlong) value->s;
167
          return;
168
        case T_INT:
169
          value->j = (jlong) value->i;
170
          return;
171
        default:
172
          break;
173
      }
174
      break;  // fail
175
    case T_FLOAT:
176
      switch (current_type) {
177
        case T_BYTE:
178
          value->f = (jfloat) value->b;
179
          return;
180
        case T_CHAR:
181
          value->f = (jfloat) value->c;
182
          return;
183
        case T_SHORT:
184
          value->f = (jfloat) value->s;
185
          return;
186
        case T_INT:
187
          value->f = (jfloat) value->i;
188
          return;
189
        case T_LONG:
190
          value->f = (jfloat) value->j;
191
          return;
192
        default:
193
          break;
194
      }
195
      break;  // fail
196
    case T_DOUBLE:
197
      switch (current_type) {
198
        case T_BYTE:
199
          value->d = (jdouble) value->b;
200
          return;
201
        case T_CHAR:
202
          value->d = (jdouble) value->c;
203
          return;
204
        case T_SHORT:
205
          value->d = (jdouble) value->s;
206
          return;
207
        case T_INT:
208
          value->d = (jdouble) value->i;
209
          return;
210
        case T_FLOAT:
211
          value->d = (jdouble) value->f;
212
          return;
213
        case T_LONG:
214
          value->d = (jdouble) value->j;
215
          return;
216
        default:
217
          break;
218
      }
219
      break;  // fail
220
    default:
221
      break;  // fail
222
  }
223
  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
224
}
225

226

227
BasicType Reflection::array_get(jvalue* value, arrayOop a, int index, TRAPS) {
228
  if (!a->is_within_bounds(index)) {
229
    THROW_(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), T_ILLEGAL);
230
  }
231
  if (a->is_objArray()) {
232
    value->l = cast_from_oop<jobject>(objArrayOop(a)->obj_at(index));
233
    return T_OBJECT;
234
  } else {
235
    assert(a->is_typeArray(), "just checking");
236
    BasicType type = TypeArrayKlass::cast(a->klass())->element_type();
237
    switch (type) {
238
      case T_BOOLEAN:
239
        value->z = typeArrayOop(a)->bool_at(index);
240
        break;
241
      case T_CHAR:
242
        value->c = typeArrayOop(a)->char_at(index);
243
        break;
244
      case T_FLOAT:
245
        value->f = typeArrayOop(a)->float_at(index);
246
        break;
247
      case T_DOUBLE:
248
        value->d = typeArrayOop(a)->double_at(index);
249
        break;
250
      case T_BYTE:
251
        value->b = typeArrayOop(a)->byte_at(index);
252
        break;
253
      case T_SHORT:
254
        value->s = typeArrayOop(a)->short_at(index);
255
        break;
256
      case T_INT:
257
        value->i = typeArrayOop(a)->int_at(index);
258
        break;
259
      case T_LONG:
260
        value->j = typeArrayOop(a)->long_at(index);
261
        break;
262
      default:
263
        return T_ILLEGAL;
264
    }
265
    return type;
266
  }
267
}
268

269

270
void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value_type, TRAPS) {
271
  if (!a->is_within_bounds(index)) {
272
    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
273
  }
274
  if (a->is_objArray()) {
275
    if (value_type == T_OBJECT) {
276
      oop obj = cast_to_oop(value->l);
277
      if (obj != nullptr) {
278
        Klass* element_klass = ObjArrayKlass::cast(a->klass())->element_klass();
279
        if (!obj->is_a(element_klass)) {
280
          THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array element type mismatch");
281
        }
282
      }
283
      objArrayOop(a)->obj_at_put(index, obj);
284
    }
285
  } else {
286
    assert(a->is_typeArray(), "just checking");
287
    BasicType array_type = TypeArrayKlass::cast(a->klass())->element_type();
288
    if (array_type != value_type) {
289
      // The widen operation can potentially throw an exception, but cannot block,
290
      // so typeArrayOop a is safe if the call succeeds.
291
      widen(value, value_type, array_type, CHECK);
292
    }
293
    switch (array_type) {
294
      case T_BOOLEAN:
295
        typeArrayOop(a)->bool_at_put(index, value->z);
296
        break;
297
      case T_CHAR:
298
        typeArrayOop(a)->char_at_put(index, value->c);
299
        break;
300
      case T_FLOAT:
301
        typeArrayOop(a)->float_at_put(index, value->f);
302
        break;
303
      case T_DOUBLE:
304
        typeArrayOop(a)->double_at_put(index, value->d);
305
        break;
306
      case T_BYTE:
307
        typeArrayOop(a)->byte_at_put(index, value->b);
308
        break;
309
      case T_SHORT:
310
        typeArrayOop(a)->short_at_put(index, value->s);
311
        break;
312
      case T_INT:
313
        typeArrayOop(a)->int_at_put(index, value->i);
314
        break;
315
      case T_LONG:
316
        typeArrayOop(a)->long_at_put(index, value->j);
317
        break;
318
      default:
319
        THROW(vmSymbols::java_lang_IllegalArgumentException());
320
    }
321
  }
322
}
323

324
static Klass* basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) {
325
  assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
326
  BasicType type = java_lang_Class::primitive_type(basic_type_mirror);
327
  if (type == T_VOID) {
328
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
329
  }
330
  else {
331
    return Universe::typeArrayKlass(type);
332
  }
333
}
334

335
arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
336
  if (element_mirror == nullptr) {
337
    THROW_0(vmSymbols::java_lang_NullPointerException());
338
  }
339
  if (length < 0) {
340
    THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length));
341
  }
342
  if (java_lang_Class::is_primitive(element_mirror)) {
343
    Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
344
    return TypeArrayKlass::cast(tak)->allocate(length, THREAD);
345
  } else {
346
    Klass* k = java_lang_Class::as_Klass(element_mirror);
347
    if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
348
      THROW_0(vmSymbols::java_lang_IllegalArgumentException());
349
    }
350
    return oopFactory::new_objArray(k, length, THREAD);
351
  }
352
}
353

354

355
arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {
356
  assert(dim_array->is_typeArray(), "just checking");
357
  assert(TypeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking");
358

359
  if (element_mirror == nullptr) {
360
    THROW_0(vmSymbols::java_lang_NullPointerException());
361
  }
362

363
  int len = dim_array->length();
364
  if (len <= 0 || len > MAX_DIM) {
365
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
366
  }
367

368
  jint dimensions[MAX_DIM];   // C array copy of intArrayOop
369
  for (int i = 0; i < len; i++) {
370
    int d = dim_array->int_at(i);
371
    if (d < 0) {
372
      THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", d));
373
    }
374
    dimensions[i] = d;
375
  }
376

377
  Klass* klass;
378
  int dim = len;
379
  if (java_lang_Class::is_primitive(element_mirror)) {
380
    klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
381
  } else {
382
    klass = java_lang_Class::as_Klass(element_mirror);
383
    if (klass->is_array_klass()) {
384
      int k_dim = ArrayKlass::cast(klass)->dimension();
385
      if (k_dim + len > MAX_DIM) {
386
        THROW_0(vmSymbols::java_lang_IllegalArgumentException());
387
      }
388
      dim += k_dim;
389
    }
390
  }
391
  klass = klass->array_klass(dim, CHECK_NULL);
392
  oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL);
393
  assert(obj->is_array(), "just checking");
394
  return arrayOop(obj);
395
}
396

397

398
static bool can_relax_access_check_for(const Klass* accessor,
399
                                       const Klass* accessee,
400
                                       bool classloader_only) {
401

402
  const InstanceKlass* accessor_ik = InstanceKlass::cast(accessor);
403
  const InstanceKlass* accessee_ik = InstanceKlass::cast(accessee);
404

405
  if (RelaxAccessControlCheck &&
406
    accessor_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION &&
407
    accessee_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION) {
408
    return classloader_only &&
409
      Verifier::relax_access_for(accessor_ik->class_loader()) &&
410
      accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
411
      accessor_ik->class_loader() == accessee_ik->class_loader();
412
  }
413

414
  return false;
415
}
416

417
/*
418
    Type Accessibility check for public types: Callee Type T is accessible to Caller Type S if:
419

420
                        Callee T in             Callee T in package PT,
421
                        unnamed module          runtime module MT
422
 ------------------------------------------------------------------------------------------------
423

424
 Caller S in package     If MS is loose: YES      If same classloader/package (PS == PT): YES
425
 PS, runtime module MS   If MS can read T's       If same runtime module: (MS == MT): YES
426
                         unnamed module: YES
427
                                                  Else if (MS can read MT (establish readability) &&
428
                                                    ((MT exports PT to MS or to all modules) ||
429
                                                     (MT is open))): YES
430

431
 ------------------------------------------------------------------------------------------------
432
 Caller S in unnamed         YES                  Readability exists because unnamed module
433
 module UM                                            "reads" all modules
434
                                                  if (MT exports PT to UM or to all modules): YES
435

436
 ------------------------------------------------------------------------------------------------
437

438
 Note: a loose module is a module that can read all current and future unnamed modules.
439
*/
440
Reflection::VerifyClassAccessResults Reflection::verify_class_access(
441
  const Klass* current_class, const InstanceKlass* new_class, bool classloader_only) {
442

443
  // Verify that current_class can access new_class.  If the classloader_only
444
  // flag is set, we automatically allow any accesses in which current_class
445
  // doesn't have a classloader.
446
  if ((current_class == nullptr) ||
447
      (current_class == new_class) ||
448
      is_same_class_package(current_class, new_class)) {
449
    return ACCESS_OK;
450
  }
451
  // Allow all accesses from jdk/internal/reflect/SerializationConstructorAccessorImpl subclasses to
452
  // succeed trivially.
453
  if (vmClasses::reflect_SerializationConstructorAccessorImpl_klass_is_loaded() &&
454
      current_class->is_subclass_of(vmClasses::reflect_SerializationConstructorAccessorImpl_klass())) {
455
    return ACCESS_OK;
456
  }
457

458
  // module boundaries
459
  if (new_class->is_public()) {
460
    // Find the module entry for current_class, the accessor
461
    ModuleEntry* module_from = current_class->module();
462
    // Find the module entry for new_class, the accessee
463
    ModuleEntry* module_to = new_class->module();
464

465
    // both in same (possibly unnamed) module
466
    if (module_from == module_to) {
467
      return ACCESS_OK;
468
    }
469

470
    // Acceptable access to a type in an unnamed module. Note that since
471
    // unnamed modules can read all unnamed modules, this also handles the
472
    // case where module_from is also unnamed but in a different class loader.
473
    if (!module_to->is_named() &&
474
        (module_from->can_read_all_unnamed() || module_from->can_read(module_to))) {
475
      return ACCESS_OK;
476
    }
477

478
    // Establish readability, check if module_from is allowed to read module_to.
479
    if (!module_from->can_read(module_to)) {
480
      return MODULE_NOT_READABLE;
481
    }
482

483
    // Access is allowed if module_to is open, i.e. all its packages are unqualifiedly exported
484
    if (module_to->is_open()) {
485
      return ACCESS_OK;
486
    }
487

488
    PackageEntry* package_to = new_class->package();
489
    assert(package_to != nullptr, "can not obtain new_class' package");
490

491
    {
492
      MutexLocker m1(Module_lock);
493

494
      // Once readability is established, if module_to exports T unqualifiedly,
495
      // (to all modules), than whether module_from is in the unnamed module
496
      // or not does not matter, access is allowed.
497
      if (package_to->is_unqual_exported()) {
498
        return ACCESS_OK;
499
      }
500

501
      // Access is allowed if both 1 & 2 hold:
502
      //   1. Readability, module_from can read module_to (established above).
503
      //   2. Either module_to exports T to module_from qualifiedly.
504
      //      or
505
      //      module_to exports T to all unnamed modules and module_from is unnamed.
506
      //      or
507
      //      module_to exports T unqualifiedly to all modules (checked above).
508
      if (!package_to->is_qexported_to(module_from)) {
509
        return TYPE_NOT_EXPORTED;
510
      }
511
    }
512
    return ACCESS_OK;
513
  }
514

515
  if (can_relax_access_check_for(current_class, new_class, classloader_only)) {
516
    return ACCESS_OK;
517
  }
518
  return OTHER_PROBLEM;
519
}
520

521
// Return an error message specific to the specified Klass*'s and result.
522
// This function must be called from within a block containing a ResourceMark.
523
char* Reflection::verify_class_access_msg(const Klass* current_class,
524
                                          const InstanceKlass* new_class,
525
                                          const VerifyClassAccessResults result) {
526
  assert(result != ACCESS_OK, "must be failure result");
527
  char * msg = nullptr;
528
  if (result != OTHER_PROBLEM && new_class != nullptr && current_class != nullptr) {
529
    // Find the module entry for current_class, the accessor
530
    ModuleEntry* module_from = current_class->module();
531
    const char * module_from_name = module_from->is_named() ? module_from->name()->as_C_string() : UNNAMED_MODULE;
532
    const char * current_class_name = current_class->external_name();
533

534
    // Find the module entry for new_class, the accessee
535
    ModuleEntry* module_to = nullptr;
536
    module_to = new_class->module();
537
    const char * module_to_name = module_to->is_named() ? module_to->name()->as_C_string() : UNNAMED_MODULE;
538
    const char * new_class_name = new_class->external_name();
539

540
    if (result == MODULE_NOT_READABLE) {
541
      assert(module_from->is_named(), "Unnamed modules can read all modules");
542
      if (module_to->is_named()) {
543
        size_t len = 100 + strlen(current_class_name) + 2*strlen(module_from_name) +
544
          strlen(new_class_name) + 2*strlen(module_to_name);
545
        msg = NEW_RESOURCE_ARRAY(char, len);
546
        jio_snprintf(msg, len - 1,
547
          "class %s (in module %s) cannot access class %s (in module %s) because module %s does not read module %s",
548
          current_class_name, module_from_name, new_class_name,
549
          module_to_name, module_from_name, module_to_name);
550
      } else {
551
        oop jlm = module_to->module();
552
        assert(jlm != nullptr, "Null jlm in module_to ModuleEntry");
553
        intptr_t identity_hash = jlm->identity_hash();
554
        size_t len = 160 + strlen(current_class_name) + 2*strlen(module_from_name) +
555
          strlen(new_class_name) + 2*sizeof(uintx);
556
        msg = NEW_RESOURCE_ARRAY(char, len);
557
        jio_snprintf(msg, len - 1,
558
          "class %s (in module %s) cannot access class %s (in unnamed module @" SIZE_FORMAT_X ") because module %s does not read unnamed module @" SIZE_FORMAT_X,
559
          current_class_name, module_from_name, new_class_name, uintx(identity_hash),
560
          module_from_name, uintx(identity_hash));
561
      }
562

563
    } else if (result == TYPE_NOT_EXPORTED) {
564
      assert(new_class->package() != nullptr,
565
             "Unnamed packages are always exported");
566
      const char * package_name =
567
        new_class->package()->name()->as_klass_external_name();
568
      assert(module_to->is_named(), "Unnamed modules export all packages");
569
      if (module_from->is_named()) {
570
        size_t len = 118 + strlen(current_class_name) + 2*strlen(module_from_name) +
571
          strlen(new_class_name) + 2*strlen(module_to_name) + strlen(package_name);
572
        msg = NEW_RESOURCE_ARRAY(char, len);
573
        jio_snprintf(msg, len - 1,
574
          "class %s (in module %s) cannot access class %s (in module %s) because module %s does not export %s to module %s",
575
          current_class_name, module_from_name, new_class_name,
576
          module_to_name, module_to_name, package_name, module_from_name);
577
      } else {
578
        oop jlm = module_from->module();
579
        assert(jlm != nullptr, "Null jlm in module_from ModuleEntry");
580
        intptr_t identity_hash = jlm->identity_hash();
581
        size_t len = 170 + strlen(current_class_name) + strlen(new_class_name) +
582
          2*strlen(module_to_name) + strlen(package_name) + 2*sizeof(uintx);
583
        msg = NEW_RESOURCE_ARRAY(char, len);
584
        jio_snprintf(msg, len - 1,
585
          "class %s (in unnamed module @" SIZE_FORMAT_X ") cannot access class %s (in module %s) because module %s does not export %s to unnamed module @" SIZE_FORMAT_X,
586
          current_class_name, uintx(identity_hash), new_class_name, module_to_name,
587
          module_to_name, package_name, uintx(identity_hash));
588
      }
589
    } else {
590
        ShouldNotReachHere();
591
    }
592
  }  // result != OTHER_PROBLEM...
593
  return msg;
594
}
595

596
bool Reflection::verify_member_access(const Klass* current_class,
597
                                      const Klass* resolved_class,
598
                                      const Klass* member_class,
599
                                      AccessFlags access,
600
                                      bool classloader_only,
601
                                      bool protected_restriction,
602
                                      TRAPS) {
603
  // Verify that current_class can access a member of member_class, where that
604
  // field's access bits are "access".  We assume that we've already verified
605
  // that current_class can access member_class.
606
  //
607
  // If the classloader_only flag is set, we automatically allow any accesses
608
  // in which current_class doesn't have a classloader.
609
  //
610
  // "resolved_class" is the runtime type of "member_class". Sometimes we don't
611
  // need this distinction (e.g. if all we have is the runtime type, or during
612
  // class file parsing when we only care about the static type); in that case
613
  // callers should ensure that resolved_class == member_class.
614
  //
615
  if ((current_class == nullptr) ||
616
      (current_class == member_class) ||
617
      access.is_public()) {
618
    return true;
619
  }
620

621
  if (current_class == member_class) {
622
    return true;
623
  }
624

625
  if (access.is_protected()) {
626
    if (!protected_restriction) {
627
      // See if current_class (or outermost host class) is a subclass of member_class
628
      // An interface may not access protected members of j.l.Object
629
      if (!current_class->is_interface() && current_class->is_subclass_of(member_class)) {
630
        if (access.is_static() || // static fields are ok, see 6622385
631
            current_class == resolved_class ||
632
            member_class == resolved_class ||
633
            current_class->is_subclass_of(resolved_class) ||
634
            resolved_class->is_subclass_of(current_class)) {
635
          return true;
636
        }
637
      }
638
    }
639
  }
640

641
  // package access
642
  if (!access.is_private() && is_same_class_package(current_class, member_class)) {
643
    return true;
644
  }
645

646
  // private access between different classes needs a nestmate check.
647
  if (access.is_private()) {
648
    if (current_class->is_instance_klass() && member_class->is_instance_klass() ) {
649
      InstanceKlass* cur_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(current_class));
650
      InstanceKlass* field_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(member_class));
651
      // Nestmate access checks may require resolution and validation of the nest-host.
652
      // It is up to the caller to check for pending exceptions and handle appropriately.
653
      bool access = cur_ik->has_nestmate_access_to(field_ik, CHECK_false);
654
      if (access) {
655
        guarantee(resolved_class->is_subclass_of(member_class), "must be!");
656
        return true;
657
      }
658
    }
659
  }
660

661
  // Allow all accesses from jdk/internal/reflect/SerializationConstructorAccessorImpl subclasses to
662
  // succeed trivially.
663
  if (current_class->is_subclass_of(vmClasses::reflect_SerializationConstructorAccessorImpl_klass())) {
664
    return true;
665
  }
666

667
  // Check for special relaxations
668
  return can_relax_access_check_for(current_class, member_class, classloader_only);
669
}
670

671
bool Reflection::is_same_class_package(const Klass* class1, const Klass* class2) {
672
  return InstanceKlass::cast(class1)->is_same_class_package(class2);
673
}
674

675
// Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
676
// throw an incompatible class change exception
677
// If inner_is_member, require the inner to be a member of the outer.
678
// If !inner_is_member, require the inner to be hidden (non-member).
679
// Caller is responsible for figuring out in advance which case must be true.
680
void Reflection::check_for_inner_class(const InstanceKlass* outer, const InstanceKlass* inner,
681
                                       bool inner_is_member, TRAPS) {
682
  InnerClassesIterator iter(outer);
683
  constantPoolHandle cp   (THREAD, outer->constants());
684
  for (; !iter.done(); iter.next()) {
685
    int ioff = iter.inner_class_info_index();
686
    int ooff = iter.outer_class_info_index();
687

688
    if (inner_is_member && ioff != 0 && ooff != 0) {
689
      if (cp->klass_name_at_matches(outer, ooff) &&
690
          cp->klass_name_at_matches(inner, ioff)) {
691
        Klass* o = cp->klass_at(ooff, CHECK);
692
        if (o == outer) {
693
          Klass* i = cp->klass_at(ioff, CHECK);
694
          if (i == inner) {
695
            return;
696
          }
697
        }
698
      }
699
    }
700

701
    if (!inner_is_member && ioff != 0 && ooff == 0 &&
702
        cp->klass_name_at_matches(inner, ioff)) {
703
      Klass* i = cp->klass_at(ioff, CHECK);
704
      if (i == inner) {
705
        return;
706
      }
707
    }
708
  }
709

710
  // 'inner' not declared as an inner klass in outer
711
  ResourceMark rm(THREAD);
712
  Exceptions::fthrow(
713
    THREAD_AND_LOCATION,
714
    vmSymbols::java_lang_IncompatibleClassChangeError(),
715
    "%s and %s disagree on InnerClasses attribute",
716
    outer->external_name(),
717
    inner->external_name()
718
  );
719
}
720

721
static objArrayHandle get_parameter_types(const methodHandle& method,
722
                                          int parameter_count,
723
                                          oop* return_type,
724
                                          TRAPS) {
725
  objArrayOop m;
726
  if (parameter_count == 0) {
727
    // Avoid allocating an array for the empty case
728
    // Still need to parse the signature for the return type below
729
    m = Universe::the_empty_class_array();
730
  } else {
731
    // Allocate array holding parameter types (java.lang.Class instances)
732
    m = oopFactory::new_objArray(vmClasses::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
733
  }
734
  objArrayHandle mirrors(THREAD, m);
735
  int index = 0;
736
  // Collect parameter types
737
  ResourceMark rm(THREAD);
738
  for (ResolvingSignatureStream ss(method()); !ss.is_done(); ss.next()) {
739
    oop mirror = ss.as_java_mirror(SignatureStream::NCDFError, CHECK_(objArrayHandle()));
740
    if (log_is_enabled(Debug, class, resolve)) {
741
      trace_class_resolution(mirror);
742
    }
743
    if (!ss.at_return_type()) {
744
      mirrors->obj_at_put(index++, mirror);
745
    } else if (return_type != nullptr) {
746
      // Collect return type as well
747
      assert(ss.at_return_type(), "return type should be present");
748
      *return_type = mirror;
749
    }
750
  }
751
  assert(index == parameter_count, "invalid parameter count");
752
  return mirrors;
753
}
754

755
static objArrayHandle get_exception_types(const methodHandle& method, TRAPS) {
756
  return method->resolved_checked_exceptions(THREAD);
757
}
758

759
static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
760
  ResolvingSignatureStream ss(signature, k, false);
761
  oop nt = ss.as_java_mirror(SignatureStream::NCDFError, CHECK_NH);
762
  if (log_is_enabled(Debug, class, resolve)) {
763
    trace_class_resolution(nt);
764
  }
765
  return Handle(THREAD, nt);
766
}
767

768
oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
769
  // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
770
  assert(!method()->is_initializer() ||
771
         (for_constant_pool_access && method()->is_static()),
772
         "should call new_constructor instead");
773
  InstanceKlass* holder = method->method_holder();
774
  int slot = method->method_idnum();
775

776
  Symbol*  signature  = method->signature();
777
  int parameter_count = ArgumentCount(signature).size();
778
  oop return_type_oop = nullptr;
779
  objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
780
  if (parameter_types.is_null() || return_type_oop == nullptr) return nullptr;
781

782
  Handle return_type(THREAD, return_type_oop);
783

784
  objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
785
  assert(!exception_types.is_null(), "cannot return null");
786

787
  Symbol*  method_name = method->name();
788
  oop name_oop = StringTable::intern(method_name, CHECK_NULL);
789
  Handle name = Handle(THREAD, name_oop);
790
  if (name == nullptr) return nullptr;
791

792
  const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
793

794
  Handle mh = java_lang_reflect_Method::create(CHECK_NULL);
795

796
  java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror());
797
  java_lang_reflect_Method::set_slot(mh(), slot);
798
  java_lang_reflect_Method::set_name(mh(), name());
799
  java_lang_reflect_Method::set_return_type(mh(), return_type());
800
  java_lang_reflect_Method::set_parameter_types(mh(), parameter_types());
801
  java_lang_reflect_Method::set_exception_types(mh(), exception_types());
802
  java_lang_reflect_Method::set_modifiers(mh(), modifiers);
803
  java_lang_reflect_Method::set_override(mh(), false);
804
  if (method->generic_signature() != nullptr) {
805
    Symbol*  gs = method->generic_signature();
806
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
807
    java_lang_reflect_Method::set_signature(mh(), sig());
808
  }
809
  typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
810
  java_lang_reflect_Method::set_annotations(mh(), an_oop);
811
  an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
812
  java_lang_reflect_Method::set_parameter_annotations(mh(), an_oop);
813
  an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL);
814
  java_lang_reflect_Method::set_annotation_default(mh(), an_oop);
815
  return mh();
816
}
817

818

819
oop Reflection::new_constructor(const methodHandle& method, TRAPS) {
820
  assert(method()->is_initializer(), "should call new_method instead");
821

822
  InstanceKlass* holder = method->method_holder();
823
  int slot = method->method_idnum();
824

825
  Symbol*  signature  = method->signature();
826
  int parameter_count = ArgumentCount(signature).size();
827
  objArrayHandle parameter_types = get_parameter_types(method, parameter_count, nullptr, CHECK_NULL);
828
  if (parameter_types.is_null()) return nullptr;
829

830
  objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
831
  assert(!exception_types.is_null(), "cannot return null");
832

833
  const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
834

835
  Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL);
836

837
  java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror());
838
  java_lang_reflect_Constructor::set_slot(ch(), slot);
839
  java_lang_reflect_Constructor::set_parameter_types(ch(), parameter_types());
840
  java_lang_reflect_Constructor::set_exception_types(ch(), exception_types());
841
  java_lang_reflect_Constructor::set_modifiers(ch(), modifiers);
842
  java_lang_reflect_Constructor::set_override(ch(), false);
843
  if (method->generic_signature() != nullptr) {
844
    Symbol*  gs = method->generic_signature();
845
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
846
    java_lang_reflect_Constructor::set_signature(ch(), sig());
847
  }
848
  typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
849
  java_lang_reflect_Constructor::set_annotations(ch(), an_oop);
850
  an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
851
  java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
852
  return ch();
853
}
854

855

856
oop Reflection::new_field(fieldDescriptor* fd, TRAPS) {
857
  Symbol*  field_name = fd->name();
858
  oop name_oop = StringTable::intern(field_name, CHECK_NULL);
859
  Handle name = Handle(THREAD, name_oop);
860
  Symbol*  signature  = fd->signature();
861
  InstanceKlass* holder = fd->field_holder();
862
  Handle type = new_type(signature, holder, CHECK_NULL);
863
  Handle rh  = java_lang_reflect_Field::create(CHECK_NULL);
864

865
  java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
866
  java_lang_reflect_Field::set_slot(rh(), fd->index());
867
  java_lang_reflect_Field::set_name(rh(), name());
868
  java_lang_reflect_Field::set_type(rh(), type());
869
  if (fd->is_trusted_final()) {
870
    java_lang_reflect_Field::set_trusted_final(rh());
871
  }
872
  // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
873
  java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
874
  java_lang_reflect_Field::set_override(rh(), false);
875
  if (fd->has_generic_signature()) {
876
    Symbol*  gs = fd->generic_signature();
877
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
878
    java_lang_reflect_Field::set_signature(rh(), sig());
879
  }
880
  typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
881
  java_lang_reflect_Field::set_annotations(rh(), an_oop);
882
  return rh();
883
}
884

885
oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
886
                              int flags, TRAPS) {
887

888
  Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
889

890
  if(nullptr != sym) {
891
    Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
892
    java_lang_reflect_Parameter::set_name(rh(), name());
893
  } else {
894
    java_lang_reflect_Parameter::set_name(rh(), nullptr);
895
  }
896

897
  java_lang_reflect_Parameter::set_modifiers(rh(), flags);
898
  java_lang_reflect_Parameter::set_executable(rh(), method());
899
  java_lang_reflect_Parameter::set_index(rh(), index);
900
  return rh();
901
}
902

903

904
static methodHandle resolve_interface_call(InstanceKlass* klass,
905
                                           const methodHandle& method,
906
                                           Klass* recv_klass,
907
                                           Handle receiver,
908
                                           TRAPS) {
909

910
  assert(!method.is_null() , "method should not be null");
911

912
  CallInfo info;
913
  Symbol*  signature  = method->signature();
914
  Symbol*  name       = method->name();
915
  LinkResolver::resolve_interface_call(info, receiver, recv_klass,
916
                                       LinkInfo(klass, name, signature),
917
                                       true,
918
                                       CHECK_(methodHandle()));
919
  return methodHandle(THREAD, info.selected_method());
920
}
921

922
// Conversion
923
static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror) {
924
  assert(java_lang_Class::is_primitive(basic_type_mirror),
925
    "just checking");
926
  return java_lang_Class::primitive_type(basic_type_mirror);
927
}
928

929
// Narrowing of basic types. Used to create correct jvalues for
930
// boolean, byte, char and short return return values from interpreter
931
// which are returned as ints. Throws IllegalArgumentException.
932
static void narrow(jvalue* value, BasicType narrow_type, TRAPS) {
933
  switch (narrow_type) {
934
  case T_BOOLEAN:
935
    value->z = (jboolean) (value->i & 1);
936
    return;
937
  case T_BYTE:
938
    value->b = (jbyte)value->i;
939
    return;
940
  case T_CHAR:
941
    value->c = (jchar)value->i;
942
    return;
943
  case T_SHORT:
944
    value->s = (jshort)value->i;
945
    return;
946
  default:
947
    break; // fail
948
  }
949
  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
950
}
951

952

953
// Method call (shared by invoke_method and invoke_constructor)
954
static oop invoke(InstanceKlass* klass,
955
                  const methodHandle& reflected_method,
956
                  Handle receiver,
957
                  bool override,
958
                  objArrayHandle ptypes,
959
                  BasicType rtype,
960
                  objArrayHandle args,
961
                  bool is_method_invoke,
962
                  TRAPS) {
963

964
  ResourceMark rm(THREAD);
965

966
  methodHandle method;      // actual method to invoke
967
  Klass* target_klass;      // target klass, receiver's klass for non-static
968

969
  // Ensure klass is initialized
970
  klass->initialize(CHECK_NULL);
971

972
  bool is_static = reflected_method->is_static();
973
  if (is_static) {
974
    // ignore receiver argument
975
    method = reflected_method;
976
    target_klass = klass;
977
  } else {
978
    // check for null receiver
979
    if (receiver.is_null()) {
980
      THROW_0(vmSymbols::java_lang_NullPointerException());
981
    }
982
    // Check class of receiver against class declaring method
983
    if (!receiver->is_a(klass)) {
984
      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
985
    }
986
    // target klass is receiver's klass
987
    target_klass = receiver->klass();
988
    // no need to resolve if method is private or <init>
989
    if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
990
      method = reflected_method;
991
    } else {
992
      // resolve based on the receiver
993
      if (reflected_method->method_holder()->is_interface()) {
994
        // resolve interface call
995
        //
996
        // Match resolution errors with those thrown due to reflection inlining
997
        // Linktime resolution & IllegalAccessCheck already done by Class.getMethod()
998
        method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD);
999
        if (HAS_PENDING_EXCEPTION) {
1000
          // Method resolution threw an exception; wrap it in an InvocationTargetException
1001
          oop resolution_exception = PENDING_EXCEPTION;
1002
          CLEAR_PENDING_EXCEPTION;
1003
          // JVMTI has already reported the pending exception
1004
          // JVMTI internal flag reset is needed in order to report InvocationTargetException
1005
          JvmtiExport::clear_detected_exception(THREAD);
1006
          JavaCallArguments args(Handle(THREAD, resolution_exception));
1007
          THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
1008
                      vmSymbols::throwable_void_signature(),
1009
                      &args);
1010
        }
1011
      }  else {
1012
        // if the method can be overridden, we resolve using the vtable index.
1013
        assert(!reflected_method->has_itable_index(), "");
1014
        int index = reflected_method->vtable_index();
1015
        method = reflected_method;
1016
        if (index != Method::nonvirtual_vtable_index) {
1017
          method = methodHandle(THREAD, target_klass->method_at_vtable(index));
1018
        }
1019
        if (!method.is_null()) {
1020
          // Check for abstract methods as well
1021
          if (method->is_abstract()) {
1022
            // new default: 6531596
1023
            ResourceMark rm(THREAD);
1024
            stringStream ss;
1025
            ss.print("'");
1026
            Method::print_external_name(&ss, target_klass, method->name(), method->signature());
1027
            ss.print("'");
1028
            Handle h_origexception = Exceptions::new_exception(THREAD,
1029
              vmSymbols::java_lang_AbstractMethodError(), ss.as_string());
1030
            JavaCallArguments args(h_origexception);
1031
            THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
1032
              vmSymbols::throwable_void_signature(),
1033
              &args);
1034
          }
1035
        }
1036
      }
1037
    }
1038
  }
1039

1040
  // I believe this is a ShouldNotGetHere case which requires
1041
  // an internal vtable bug. If you ever get this please let Karen know.
1042
  if (method.is_null()) {
1043
    ResourceMark rm(THREAD);
1044
    stringStream ss;
1045
    ss.print("'");
1046
    Method::print_external_name(&ss, klass,
1047
                                     reflected_method->name(),
1048
                                     reflected_method->signature());
1049
    ss.print("'");
1050
    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), ss.as_string());
1051
  }
1052

1053
  assert(ptypes->is_objArray(), "just checking");
1054
  int args_len = args.is_null() ? 0 : args->length();
1055
  // Check number of arguments
1056
  if (ptypes->length() != args_len) {
1057
    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1058
                "wrong number of arguments");
1059
  }
1060

1061
  // Create object to contain parameters for the JavaCall
1062
  JavaCallArguments java_args(method->size_of_parameters());
1063

1064
  if (!is_static) {
1065
    java_args.push_oop(receiver);
1066
  }
1067

1068
  for (int i = 0; i < args_len; i++) {
1069
    oop type_mirror = ptypes->obj_at(i);
1070
    oop arg = args->obj_at(i);
1071
    if (java_lang_Class::is_primitive(type_mirror)) {
1072
      jvalue value;
1073
      BasicType ptype = basic_type_mirror_to_basic_type(type_mirror);
1074
      BasicType atype = Reflection::unbox_for_primitive(arg, &value, CHECK_NULL);
1075
      if (ptype != atype) {
1076
        Reflection::widen(&value, atype, ptype, CHECK_NULL);
1077
      }
1078
      switch (ptype) {
1079
        case T_BOOLEAN:     java_args.push_int(value.z);    break;
1080
        case T_CHAR:        java_args.push_int(value.c);    break;
1081
        case T_BYTE:        java_args.push_int(value.b);    break;
1082
        case T_SHORT:       java_args.push_int(value.s);    break;
1083
        case T_INT:         java_args.push_int(value.i);    break;
1084
        case T_LONG:        java_args.push_long(value.j);   break;
1085
        case T_FLOAT:       java_args.push_float(value.f);  break;
1086
        case T_DOUBLE:      java_args.push_double(value.d); break;
1087
        default:
1088
          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
1089
      }
1090
    } else {
1091
      if (arg != nullptr) {
1092
        Klass* k = java_lang_Class::as_Klass(type_mirror);
1093
        if (!arg->is_a(k)) {
1094
          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1095
                      "argument type mismatch");
1096
        }
1097
      }
1098
      Handle arg_handle(THREAD, arg);         // Create handle for argument
1099
      java_args.push_oop(arg_handle); // Push handle
1100
    }
1101
  }
1102

1103
  assert(java_args.size_of_parameters() == method->size_of_parameters(),
1104
    "just checking");
1105

1106
  // All oops (including receiver) is passed in as Handles. An potential oop is returned as an
1107
  // oop (i.e., NOT as an handle)
1108
  JavaValue result(rtype);
1109
  JavaCalls::call(&result, method, &java_args, THREAD);
1110

1111
  if (HAS_PENDING_EXCEPTION) {
1112
    // Method threw an exception; wrap it in an InvocationTargetException
1113
    oop target_exception = PENDING_EXCEPTION;
1114
    CLEAR_PENDING_EXCEPTION;
1115
    // JVMTI has already reported the pending exception
1116
    // JVMTI internal flag reset is needed in order to report InvocationTargetException
1117
    JvmtiExport::clear_detected_exception(THREAD);
1118

1119
    JavaCallArguments args(Handle(THREAD, target_exception));
1120
    THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
1121
                vmSymbols::throwable_void_signature(),
1122
                &args);
1123
  } else {
1124
    if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) {
1125
      narrow((jvalue*)result.get_value_addr(), rtype, CHECK_NULL);
1126
    }
1127
    return Reflection::box((jvalue*)result.get_value_addr(), rtype, THREAD);
1128
  }
1129
}
1130

1131
// This would be nicer if, say, java.lang.reflect.Method was a subclass
1132
// of java.lang.reflect.Constructor
1133

1134
oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
1135
  oop mirror             = java_lang_reflect_Method::clazz(method_mirror);
1136
  int slot               = java_lang_reflect_Method::slot(method_mirror);
1137
  bool override          = java_lang_reflect_Method::override(method_mirror) != 0;
1138
  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror)));
1139

1140
  oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror);
1141
  BasicType rtype;
1142
  if (java_lang_Class::is_primitive(return_type_mirror)) {
1143
    rtype = basic_type_mirror_to_basic_type(return_type_mirror);
1144
  } else {
1145
    rtype = T_OBJECT;
1146
  }
1147

1148
  InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
1149
  Method* m = klass->method_with_idnum(slot);
1150
  if (m == nullptr) {
1151
    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
1152
  }
1153
  methodHandle method(THREAD, m);
1154

1155
  return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
1156
}
1157

1158

1159
oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) {
1160
  oop mirror             = java_lang_reflect_Constructor::clazz(constructor_mirror);
1161
  int slot               = java_lang_reflect_Constructor::slot(constructor_mirror);
1162
  bool override          = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
1163
  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
1164

1165
  InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
1166
  Method* m = klass->method_with_idnum(slot);
1167
  if (m == nullptr) {
1168
    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
1169
  }
1170
  methodHandle method(THREAD, m);
1171
  assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
1172

1173
  // Make sure klass gets initialize
1174
  klass->initialize(CHECK_NULL);
1175

1176
  // Create new instance (the receiver)
1177
  klass->check_valid_for_instantiation(false, CHECK_NULL);
1178
  Handle receiver = klass->allocate_instance_handle(CHECK_NULL);
1179

1180
  // Ignore result from call and return receiver
1181
  invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
1182
  return receiver();
1183
}
1184

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

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

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

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