reflection.cpp revision 3602:da91efe96a93
169408Sache/*
2100616Smp * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3100616Smp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4231990Smp *
5195609Smp * This code is free software; you can redistribute it and/or modify it
6100616Smp * under the terms of the GNU General Public License version 2 only, as
7231990Smp * published by the Free Software Foundation.
8100616Smp *
969408Sache * This code is distributed in the hope that it will be useful, but WITHOUT
1069408Sache * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1169408Sache * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1269408Sache * version 2 for more details (a copy is included in the LICENSE file that
1369408Sache * accompanied this code).
1469408Sache *
1569408Sache * You should have received a copy of the GNU General Public License version
1669408Sache * 2 along with this work; if not, write to the Free Software Foundation,
1769408Sache * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1869408Sache *
1969408Sache * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2069408Sache * or visit www.oracle.com if you need additional information or have any
2169408Sache * questions.
2269408Sache *
2369408Sache */
2469408Sache
25195609Smp#include "precompiled.hpp"
26195609Smp#include "classfile/javaClasses.hpp"
27195609Smp#include "classfile/symbolTable.hpp"
2869408Sache#include "classfile/systemDictionary.hpp"
2969408Sache#include "classfile/verifier.hpp"
3069408Sache#include "classfile/vmSymbols.hpp"
3169408Sache#include "interpreter/linkResolver.hpp"
3269408Sache#include "memory/oopFactory.hpp"
33195609Smp#include "memory/resourceArea.hpp"
34100616Smp#include "memory/universe.inline.hpp"
35231990Smp#include "oops/instanceKlass.hpp"
36100616Smp#include "oops/objArrayKlass.hpp"
3769408Sache#include "oops/objArrayOop.hpp"
3869408Sache#include "prims/jvm.h"
3969408Sache#include "runtime/arguments.hpp"
4069408Sache#include "runtime/handles.inline.hpp"
4169408Sache#include "runtime/javaCalls.hpp"
42231990Smp#include "runtime/reflection.hpp"
43231990Smp#include "runtime/reflectionUtils.hpp"
44231990Smp#include "runtime/signature.hpp"
4569408Sache#include "runtime/vframe.hpp"
4669408Sache
4769408Sache#define JAVA_1_5_VERSION                  49
4869408Sache
4969408Sachestatic void trace_class_resolution(Klass* to_class) {
5069408Sache  ResourceMark rm;
5169408Sache  int line_number = -1;
5269408Sache  const char * source_file = NULL;
5369408Sache  Klass* caller = NULL;
5469408Sache  JavaThread* jthread = JavaThread::current();
5569408Sache  if (jthread->has_last_Java_frame()) {
5669408Sache    vframeStream vfst(jthread);
5769408Sache    // skip over any frames belonging to java.lang.Class
5869408Sache    while (!vfst.at_end() &&
5969408Sache           InstanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class()) {
60100616Smp      vfst.next();
6169408Sache    }
62100616Smp    if (!vfst.at_end()) {
63100616Smp      // this frame is a likely suspect
64100616Smp      caller = vfst.method()->method_holder();
65100616Smp      line_number = vfst.method()->line_number_from_bci(vfst.bci());
66100616Smp      Symbol* s = InstanceKlass::cast(vfst.method()->method_holder())->source_file_name();
67100616Smp      if (s != NULL) {
68100616Smp        source_file = s->as_C_string();
69100616Smp      }
70100616Smp    }
71100616Smp  }
72100616Smp  if (caller != NULL) {
73100616Smp    const char * from = Klass::cast(caller)->external_name();
74100616Smp    const char * to = Klass::cast(to_class)->external_name();
75100616Smp    // print in a single call to reduce interleaving between threads
76100616Smp    if (source_file != NULL) {
77100616Smp      tty->print("RESOLVE %s %s %s:%d (reflection)\n", from, to, source_file, line_number);
78231990Smp    } else {
79231990Smp      tty->print("RESOLVE %s %s (reflection)\n", from, to);
80231990Smp    }
81100616Smp  }
82100616Smp}
83100616Smp
84100616Smp
85100616Smpoop Reflection::box(jvalue* value, BasicType type, TRAPS) {
86100616Smp  if (type == T_VOID) {
87100616Smp    return NULL;
88100616Smp  }
89100616Smp  if (type == T_OBJECT || type == T_ARRAY) {
90100616Smp    // regular objects are not boxed
91100616Smp    return (oop) value->l;
92195609Smp  }
93100616Smp  oop result = java_lang_boxing_object::create(type, value, CHECK_NULL);
94195609Smp  if (result == NULL) {
95100616Smp    THROW_(vmSymbols::java_lang_IllegalArgumentException(), result);
96195609Smp  }
97100616Smp  return result;
98100616Smp}
99100616Smp
100100616Smp
101100616SmpBasicType Reflection::unbox_for_primitive(oop box, jvalue* value, TRAPS) {
102100616Smp  if (box == NULL) {
103100616Smp    THROW_(vmSymbols::java_lang_IllegalArgumentException(), T_ILLEGAL);
104100616Smp  }
105100616Smp  return java_lang_boxing_object::get_value(box, value);
106100616Smp}
107100616Smp
108195609SmpBasicType Reflection::unbox_for_regular_object(oop box, jvalue* value) {
109100616Smp  // Note:  box is really the unboxed oop.  It might even be a Short, etc.!
110100616Smp  value->l = (jobject) box;
111100616Smp  return T_OBJECT;
112100616Smp}
113100616Smp
114100616Smp
115100616Smpvoid Reflection::widen(jvalue* value, BasicType current_type, BasicType wide_type, TRAPS) {
116100616Smp  assert(wide_type != current_type, "widen should not be called with identical types");
117100616Smp  switch (wide_type) {
118100616Smp    case T_BOOLEAN:
119100616Smp    case T_BYTE:
120100616Smp    case T_CHAR:
12169408Sache      break;  // fail
12269408Sache    case T_SHORT:
12369408Sache      switch (current_type) {
12469408Sache        case T_BYTE:
12569408Sache          value->s = (jshort) value->b;
12669408Sache          return;
127195609Smp      }
128195609Smp      break;  // fail
129195609Smp    case T_INT:
130195609Smp      switch (current_type) {
13169408Sache        case T_BYTE:
13269408Sache          value->i = (jint) value->b;
13369408Sache          return;
13469408Sache        case T_CHAR:
13569408Sache          value->i = (jint) value->c;
13669408Sache          return;
13769408Sache        case T_SHORT:
13869408Sache          value->i = (jint) value->s;
13969408Sache          return;
14069408Sache      }
14169408Sache      break;  // fail
14269408Sache    case T_LONG:
14369408Sache      switch (current_type) {
14469408Sache        case T_BYTE:
14569408Sache          value->j = (jlong) value->b;
14669408Sache          return;
14769408Sache        case T_CHAR:
14869408Sache          value->j = (jlong) value->c;
14969408Sache          return;
15069408Sache        case T_SHORT:
15169408Sache          value->j = (jlong) value->s;
15269408Sache          return;
15369408Sache        case T_INT:
15469408Sache          value->j = (jlong) value->i;
15569408Sache          return;
156231990Smp      }
15769408Sache      break;  // fail
15869408Sache    case T_FLOAT:
15969408Sache      switch (current_type) {
160195609Smp        case T_BYTE:
161195609Smp          value->f = (jfloat) value->b;
162195609Smp          return;
16383098Smp        case T_CHAR:
16483098Smp          value->f = (jfloat) value->c;
16583098Smp          return;
16683098Smp        case T_SHORT:
16783098Smp          value->f = (jfloat) value->s;
16883098Smp          return;
16983098Smp        case T_INT:
17083098Smp          value->f = (jfloat) value->i;
17183098Smp          return;
17283098Smp        case T_LONG:
173100616Smp          value->f = (jfloat) value->j;
174100616Smp          return;
175100616Smp      }
176100616Smp      break;  // fail
177100616Smp    case T_DOUBLE:
178100616Smp      switch (current_type) {
179100616Smp        case T_BYTE:
180100616Smp          value->d = (jdouble) value->b;
18169408Sache          return;
18269408Sache        case T_CHAR:
18369408Sache          value->d = (jdouble) value->c;
184195609Smp          return;
185195609Smp        case T_SHORT:
186195609Smp          value->d = (jdouble) value->s;
187195609Smp          return;
18869408Sache        case T_INT:
18983098Smp          value->d = (jdouble) value->i;
19069408Sache          return;
19169408Sache        case T_FLOAT:
19269408Sache          value->d = (jdouble) value->f;
19369408Sache          return;
19469408Sache        case T_LONG:
19569408Sache          value->d = (jdouble) value->j;
19669408Sache          return;
19769408Sache      }
19869408Sache      break;  // fail
19969408Sache    default:
20069408Sache      break;  // fail
20169408Sache  }
20269408Sache  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
20369408Sache}
204195609Smp
205195609Smp
206195609SmpBasicType Reflection::array_get(jvalue* value, arrayOop a, int index, TRAPS) {
207195609Smp  if (!a->is_within_bounds(index)) {
20869408Sache    THROW_(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), T_ILLEGAL);
20969408Sache  }
21069408Sache  if (a->is_objArray()) {
21169408Sache    value->l = (jobject) objArrayOop(a)->obj_at(index);
21283098Smp    return T_OBJECT;
21383098Smp  } else {
21483098Smp    assert(a->is_typeArray(), "just checking");
21569408Sache    BasicType type = typeArrayKlass::cast(a->klass())->element_type();
21669408Sache    switch (type) {
21769408Sache      case T_BOOLEAN:
21869408Sache        value->z = typeArrayOop(a)->bool_at(index);
21969408Sache        break;
22069408Sache      case T_CHAR:
22169408Sache        value->c = typeArrayOop(a)->char_at(index);
22269408Sache        break;
22369408Sache      case T_FLOAT:
22469408Sache        value->f = typeArrayOop(a)->float_at(index);
22569408Sache        break;
22669408Sache      case T_DOUBLE:
22769408Sache        value->d = typeArrayOop(a)->double_at(index);
22869408Sache        break;
22969408Sache      case T_BYTE:
23069408Sache        value->b = typeArrayOop(a)->byte_at(index);
23169408Sache        break;
23269408Sache      case T_SHORT:
23369408Sache        value->s = typeArrayOop(a)->short_at(index);
23469408Sache        break;
23569408Sache      case T_INT:
23669408Sache        value->i = typeArrayOop(a)->int_at(index);
23783098Smp        break;
23883098Smp      case T_LONG:
23983098Smp        value->j = typeArrayOop(a)->long_at(index);
24083098Smp        break;
24169408Sache      default:
24269408Sache        return T_ILLEGAL;
24369408Sache    }
24469408Sache    return type;
24569408Sache  }
24669408Sache}
247100616Smp
248100616Smp
249100616Smpvoid Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value_type, TRAPS) {
250100616Smp  if (!a->is_within_bounds(index)) {
251195609Smp    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
252195609Smp  }
253195609Smp  if (a->is_objArray()) {
254100616Smp    if (value_type == T_OBJECT) {
255100616Smp      oop obj = (oop) value->l;
256195609Smp      if (obj != NULL) {
257100616Smp        Klass* element_klass = objArrayKlass::cast(a->klass())->element_klass();
258100616Smp        if (!obj->is_a(element_klass)) {
259195609Smp          THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array element type mismatch");
260195609Smp        }
261195609Smp      }
262195609Smp      objArrayOop(a)->obj_at_put(index, obj);
263100616Smp    }
264100616Smp  } else {
265100616Smp    assert(a->is_typeArray(), "just checking");
266195609Smp    BasicType array_type = typeArrayKlass::cast(a->klass())->element_type();
267100616Smp    if (array_type != value_type) {
268195609Smp      // The widen operation can potentially throw an exception, but cannot block,
269195609Smp      // so typeArrayOop a is safe if the call succeeds.
270100616Smp      widen(value, value_type, array_type, CHECK);
271100616Smp    }
272100616Smp    switch (array_type) {
273195609Smp      case T_BOOLEAN:
274100616Smp        typeArrayOop(a)->bool_at_put(index, value->z);
275195609Smp        break;
276100616Smp      case T_CHAR:
277195609Smp        typeArrayOop(a)->char_at_put(index, value->c);
278100616Smp        break;
279195609Smp      case T_FLOAT:
280100616Smp        typeArrayOop(a)->float_at_put(index, value->f);
281100616Smp        break;
282195609Smp      case T_DOUBLE:
283195609Smp        typeArrayOop(a)->double_at_put(index, value->d);
284195609Smp        break;
285195609Smp      case T_BYTE:
286100616Smp        typeArrayOop(a)->byte_at_put(index, value->b);
287195609Smp        break;
288100616Smp      case T_SHORT:
289100616Smp        typeArrayOop(a)->short_at_put(index, value->s);
290100616Smp        break;
291231990Smp      case T_INT:
292195609Smp        typeArrayOop(a)->int_at_put(index, value->i);
293195609Smp        break;
294100616Smp      case T_LONG:
295195609Smp        typeArrayOop(a)->long_at_put(index, value->j);
296195609Smp        break;
297195609Smp      default:
298195609Smp        THROW(vmSymbols::java_lang_IllegalArgumentException());
299231990Smp    }
300100616Smp  }
301100616Smp}
302195609Smp
303195609Smp
30469408SacheKlass* Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) {
30569408Sache  assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
306231990Smp  BasicType type = java_lang_Class::primitive_type(basic_type_mirror);
307100616Smp  if (type == T_VOID) {
308100616Smp    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
309100616Smp  } else {
31083098Smp    return Universe::typeArrayKlassObj(type);
311100616Smp  }
312100616Smp}
313195609Smp
314195609Smp
315195609Smpoop Reflection:: basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS) {
31683098Smp  BasicType type = typeArrayKlass::cast(basic_type_arrayklass)->element_type();
31769408Sache  return Universe::java_mirror(type);
31869408Sache}
31969408Sache
320100616Smp
32169408SachearrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
32269408Sache  if (element_mirror == NULL) {
32369408Sache    THROW_0(vmSymbols::java_lang_NullPointerException());
32469408Sache  }
32569408Sache  if (length < 0) {
32669408Sache    THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
32769408Sache  }
32869408Sache  if (java_lang_Class::is_primitive(element_mirror)) {
329100616Smp    Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
330100616Smp    return typeArrayKlass::cast(tak)->allocate(length, THREAD);
331100616Smp  } else {
332100616Smp    Klass* k = java_lang_Class::as_Klass(element_mirror);
333100616Smp    if (Klass::cast(k)->oop_is_array() && arrayKlass::cast(k)->dimension() >= MAX_DIM) {
334100616Smp      THROW_0(vmSymbols::java_lang_IllegalArgumentException());
335195609Smp    }
336195609Smp    return oopFactory::new_objArray(k, length, THREAD);
337195609Smp  }
338195609Smp}
339100616Smp
340100616Smp
341195609SmparrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {
342100616Smp  assert(dim_array->is_typeArray(), "just checking");
343100616Smp  assert(typeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking");
344100616Smp
345195609Smp  if (element_mirror == NULL) {
346195609Smp    THROW_0(vmSymbols::java_lang_NullPointerException());
347195609Smp  }
348100616Smp
349231990Smp  int len = dim_array->length();
350100616Smp  if (len <= 0 || len > MAX_DIM) {
351100616Smp    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
352100616Smp  }
353195609Smp
354100616Smp  jint dimensions[MAX_DIM];   // C array copy of intArrayOop
355195609Smp  for (int i = 0; i < len; i++) {
356195609Smp    int d = dim_array->int_at(i);
357100616Smp    if (d < 0) {
358100616Smp      THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
359100616Smp    }
360195609Smp    dimensions[i] = d;
361100616Smp  }
362195609Smp
363100616Smp  Klass* klass;
364195609Smp  int dim = len;
365100616Smp  if (java_lang_Class::is_primitive(element_mirror)) {
366195609Smp    klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
367195609Smp  } else {
368195609Smp    klass = java_lang_Class::as_Klass(element_mirror);
369195609Smp    if (Klass::cast(klass)->oop_is_array()) {
370195609Smp      int k_dim = arrayKlass::cast(klass)->dimension();
371195609Smp      if (k_dim + len > MAX_DIM) {
372100616Smp        THROW_0(vmSymbols::java_lang_IllegalArgumentException());
373100616Smp      }
374100616Smp      dim += k_dim;
375100616Smp    }
376100616Smp  }
377231990Smp  klass = Klass::cast(klass)->array_klass(dim, CHECK_NULL);
378195609Smp  oop obj = arrayKlass::cast(klass)->multi_allocate(len, dimensions, THREAD);
379100616Smp  assert(obj->is_array(), "just checking");
380195609Smp  return arrayOop(obj);
381195609Smp}
382195609Smp
383195609Smp
384195609Smpoop Reflection::array_component_type(oop mirror, TRAPS) {
385195609Smp  if (java_lang_Class::is_primitive(mirror)) {
386231990Smp    return NULL;
387100616Smp  }
388100616Smp
389195609Smp  Klass* klass = java_lang_Class::as_Klass(mirror);
390195609Smp  if (!Klass::cast(klass)->oop_is_array()) {
391100616Smp    return NULL;
392195609Smp  }
39369408Sache
394195609Smp  oop result = arrayKlass::cast(klass)->component_mirror();
395195609Smp#ifdef ASSERT
396195609Smp  oop result2 = NULL;
397195609Smp  if (arrayKlass::cast(klass)->dimension() == 1) {
39869408Sache    if (Klass::cast(klass)->oop_is_typeArray()) {
39969408Sache      result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL);
40083098Smp    } else {
40183098Smp      result2 = Klass::cast(objArrayKlass::cast(klass)->element_klass())->java_mirror();
40283098Smp    }
40383098Smp  } else {
40469408Sache    Klass* lower_dim = arrayKlass::cast(klass)->lower_dimension();
40569408Sache    assert(Klass::cast(lower_dim)->oop_is_array(), "just checking");
40669408Sache    result2 = Klass::cast(lower_dim)->java_mirror();
40769408Sache  }
40869408Sache  assert(result == result2, "results must be consistent");
40969408Sache#endif //ASSERT
41083098Smp  return result;
41183098Smp}
41283098Smp
41383098Smp
414195609Smpbool Reflection::reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS) {
415195609Smp  // field_class  : declaring class
416195609Smp  // acc          : declared field access
41783098Smp  // target_class : for protected
41883098Smp
41983098Smp  // Check if field or method is accessible to client.  Throw an
42083098Smp  // IllegalAccessException and return false if not.
42169408Sache
42269408Sache  // The "client" is the class associated with the nearest real frame
42369408Sache  // getCallerClass already skips Method.invoke frames, so pass 0 in
42469408Sache  // that case (same as classic).
42569408Sache  ResourceMark rm(THREAD);
42669408Sache  assert(THREAD->is_Java_thread(), "sanity check");
42769408Sache  Klass* client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1);
42869408Sache
42969408Sache  if (client_class != field_class) {
43069408Sache    if (!verify_class_access(client_class, field_class, false)
431195609Smp        || !verify_field_access(client_class,
432195609Smp                                field_class,
433195609Smp                                field_class,
434195609Smp                                acc,
435195609Smp                                false)) {
436195609Smp      THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
43769408Sache    }
43869408Sache  }
43969408Sache
44069408Sache  // Additional test for protected members: JLS 6.6.2
44169408Sache
442100616Smp  if (acc.is_protected()) {
44369408Sache    if (target_class != client_class) {
44469408Sache      if (!is_same_class_package(client_class, field_class)) {
445100616Smp        if (!Klass::cast(target_class)->is_subclass_of(client_class)) {
44669408Sache          THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
44769408Sache        }
44869408Sache      }
449100616Smp    }
45069408Sache  }
45169408Sache
45269408Sache  // Passed all tests
45369408Sache  return true;
45469408Sache}
45569408Sache
45683098Smp
45783098Smpbool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) {
45883098Smp  // Verify that current_class can access new_class.  If the classloader_only
45983098Smp  // flag is set, we automatically allow any accesses in which current_class
460195609Smp  // doesn't have a classloader.
461195609Smp  if ((current_class == NULL) ||
462195609Smp      (current_class == new_class) ||
463195609Smp      (InstanceKlass::cast(new_class)->is_public()) ||
46469408Sache      is_same_class_package(current_class, new_class)) {
46569408Sache    return true;
46669408Sache  }
46769408Sache  // New (1.4) reflection implementation. Allow all accesses from
46869408Sache  // sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
46969408Sache  if (   JDK_Version::is_gte_jdk14x_version()
47069408Sache      && UseNewReflection
47169408Sache      && Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
472195609Smp    return true;
473195609Smp  }
474195609Smp
475195609Smp  return can_relax_access_check_for(current_class, new_class, classloader_only);
476195609Smp}
477195609Smp
478195609Smpstatic bool under_host_klass(InstanceKlass* ik, Klass* host_klass) {
479195609Smp  DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
480195609Smp  for (;;) {
481195609Smp    Klass* hc = (Klass*) ik->host_klass();
482195609Smp    if (hc == NULL)        return false;
483195609Smp    if (hc == host_klass)  return true;
484100616Smp    ik = InstanceKlass::cast(hc);
485100616Smp
486100616Smp    // There's no way to make a host class loop short of patching memory.
487100616Smp    // Therefore there cannot be a loop here unles there's another bug.
488195609Smp    // Still, let's check for it.
489195609Smp    assert(--inf_loop_check > 0, "no host_klass loop");
490195609Smp  }
491195609Smp}
49269408Sache
49369408Sachebool Reflection::can_relax_access_check_for(
49469408Sache    Klass* accessor, Klass* accessee, bool classloader_only) {
49569408Sache  InstanceKlass* accessor_ik = InstanceKlass::cast(accessor);
49669408Sache  InstanceKlass* accessee_ik  = InstanceKlass::cast(accessee);
49769408Sache
49869408Sache  // If either is on the other's host_klass chain, access is OK,
49969408Sache  // because one is inside the other.
50069408Sache  if (under_host_klass(accessor_ik, accessee) ||
50169408Sache      under_host_klass(accessee_ik, accessor))
50269408Sache    return true;
50369408Sache
50469408Sache  if (RelaxAccessControlCheck ||
50569408Sache      (accessor_ik->major_version() < JAVA_1_5_VERSION &&
50669408Sache       accessee_ik->major_version() < JAVA_1_5_VERSION)) {
50769408Sache    return classloader_only &&
50869408Sache      Verifier::relax_verify_for(accessor_ik->class_loader()) &&
50969408Sache      accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
51069408Sache      accessor_ik->class_loader() == accessee_ik->class_loader();
51169408Sache  } else {
512100616Smp    return false;
513100616Smp  }
51469408Sache}
51569408Sache
516195609Smpbool Reflection::verify_field_access(Klass* current_class,
517195609Smp                                     Klass* resolved_class,
518195609Smp                                     Klass* field_class,
519195609Smp                                     AccessFlags access,
520195609Smp                                     bool classloader_only,
521195609Smp                                     bool protected_restriction) {
522195609Smp  // Verify that current_class can access a field of field_class, where that
523195609Smp  // field's access bits are "access".  We assume that we've already verified
52469408Sache  // that current_class can access field_class.
52569408Sache  //
52669408Sache  // If the classloader_only flag is set, we automatically allow any accesses
527195609Smp  // in which current_class doesn't have a classloader.
528195609Smp  //
529195609Smp  // "resolved_class" is the runtime type of "field_class". Sometimes we don't
530100616Smp  // need this distinction (e.g. if all we have is the runtime type, or during
531100616Smp  // class file parsing when we only care about the static type); in that case
532100616Smp  // callers should ensure that resolved_class == field_class.
533195609Smp  //
534195609Smp  if ((current_class == NULL) ||
535195609Smp      (current_class == field_class) ||
536195609Smp      access.is_public()) {
53769408Sache    return true;
53869408Sache  }
53969408Sache
54069408Sache  if (access.is_protected()) {
54169408Sache    if (!protected_restriction) {
54269408Sache      // See if current_class is a subclass of field_class
543100616Smp      if (Klass::cast(current_class)->is_subclass_of(field_class)) {
544100616Smp        if (access.is_static() || // static fields are ok, see 6622385
545100616Smp            current_class == resolved_class ||
546100616Smp            field_class == resolved_class ||
547100616Smp            Klass::cast(current_class)->is_subclass_of(resolved_class) ||
548100616Smp            Klass::cast(resolved_class)->is_subclass_of(current_class)) {
549100616Smp          return true;
550100616Smp        }
55169408Sache      }
55269408Sache    }
55369408Sache  }
55469408Sache
55569408Sache  if (!access.is_private() && is_same_class_package(current_class, field_class)) {
55669408Sache    return true;
55769408Sache  }
55869408Sache
559195609Smp  // New (1.4) reflection implementation. Allow all accesses from
560195609Smp  // sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
561195609Smp  if (   JDK_Version::is_gte_jdk14x_version()
562195609Smp      && UseNewReflection
563195609Smp      && Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
564195609Smp    return true;
565195609Smp  }
566195609Smp
56769408Sache  return can_relax_access_check_for(
56869408Sache    current_class, field_class, classloader_only);
56969408Sache}
57069408Sache
57169408Sache
57269408Sachebool Reflection::is_same_class_package(Klass* class1, Klass* class2) {
57369408Sache  return InstanceKlass::cast(class1)->is_same_class_package(class2);
57469408Sache}
57569408Sache
57669408Sachebool Reflection::is_same_package_member(Klass* class1, Klass* class2, TRAPS) {
57769408Sache  return InstanceKlass::cast(class1)->is_same_package_member(class2, THREAD);
57869408Sache}
57969408Sache
58069408Sache
58169408Sache// Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
58269408Sache// throw an incompatible class change exception
58369408Sache// If inner_is_member, require the inner to be a member of the outer.
58469408Sache// If !inner_is_member, require the inner to be anonymous (a non-member).
58569408Sache// Caller is responsible for figuring out in advance which case must be true.
58683098Smpvoid Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
58783098Smp                                       bool inner_is_member, TRAPS) {
58883098Smp  InnerClassesIterator iter(outer);
58983098Smp  constantPoolHandle cp   (THREAD, outer->constants());
59069408Sache  for (; !iter.done(); iter.next()) {
59169408Sache     int ioff = iter.inner_class_info_index();
59269408Sache     int ooff = iter.outer_class_info_index();
59369408Sache
59469408Sache     if (inner_is_member && ioff != 0 && ooff != 0) {
59569408Sache        Klass* o = cp->klass_at(ooff, CHECK);
59669408Sache        if (o == outer()) {
59769408Sache          Klass* i = cp->klass_at(ioff, CHECK);
59869408Sache          if (i == inner()) {
59969408Sache            return;
600100616Smp          }
601100616Smp        }
602100616Smp     }
603100616Smp     if (!inner_is_member && ioff != 0 && ooff == 0 &&
60469408Sache         cp->klass_name_at_matches(inner, ioff)) {
60569408Sache        Klass* i = cp->klass_at(ioff, CHECK);
60669408Sache        if (i == inner()) {
60769408Sache          return;
60869408Sache        }
60969408Sache     }
61069408Sache  }
61169408Sache
61283098Smp  // 'inner' not declared as an inner klass in outer
61383098Smp  ResourceMark rm(THREAD);
61483098Smp  Exceptions::fthrow(
61583098Smp    THREAD_AND_LOCATION,
61683098Smp    vmSymbols::java_lang_IncompatibleClassChangeError(),
61783098Smp    "%s and %s disagree on InnerClasses attribute",
61883098Smp    outer->external_name(),
61983098Smp    inner->external_name()
62069408Sache  );
62169408Sache}
62269408Sache
62369408Sache// Utility method converting a single SignatureStream element into java.lang.Class instance
62469408Sache
62569408Sacheoop get_mirror_from_signature(methodHandle method, SignatureStream* ss, TRAPS) {
62669408Sache  switch (ss->type()) {
62769408Sache    default:
62869408Sache      assert(ss->type() != T_VOID || ss->at_return_type(), "T_VOID should only appear as return type");
62969408Sache      return java_lang_Class::primitive_mirror(ss->type());
63069408Sache    case T_OBJECT:
63169408Sache    case T_ARRAY:
63269408Sache      Symbol* name        = ss->as_symbol(CHECK_NULL);
63369408Sache      oop loader            = InstanceKlass::cast(method->method_holder())->class_loader();
63469408Sache      oop protection_domain = InstanceKlass::cast(method->method_holder())->protection_domain();
63583098Smp      Klass* k = SystemDictionary::resolve_or_fail(
63683098Smp                                       name,
63783098Smp                                       Handle(THREAD, loader),
63869408Sache                                       Handle(THREAD, protection_domain),
63969408Sache                                       true, CHECK_NULL);
64069408Sache      if (TraceClassResolution) {
64169408Sache        trace_class_resolution(k);
64269408Sache      }
64369408Sache      return k->java_mirror();
64483098Smp  };
64583098Smp}
64683098Smp
64783098Smp
64869408SacheobjArrayHandle Reflection::get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS) {
64969408Sache  // Allocate array holding parameter types (java.lang.Class instances)
65083098Smp  objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
65183098Smp  objArrayHandle mirrors (THREAD, m);
65283098Smp  int index = 0;
65383098Smp  // Collect parameter types
65483098Smp  ResourceMark rm(THREAD);
65583098Smp  Symbol*  signature  = method->signature();
65683098Smp  SignatureStream ss(signature);
65783098Smp  while (!ss.at_return_type()) {
65883098Smp    oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
65983098Smp    mirrors->obj_at_put(index++, mirror);
66083098Smp    ss.next();
66169408Sache  }
66269408Sache  assert(index == parameter_count, "invalid parameter count");
66369408Sache  if (return_type != NULL) {
66469408Sache    // Collect return type as well
66569408Sache    assert(ss.at_return_type(), "return type should be present");
66669408Sache    *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
66783098Smp  }
66883098Smp  return mirrors;
66983098Smp}
67083098Smp
67183098SmpobjArrayHandle Reflection::get_exception_types(methodHandle method, TRAPS) {
67283098Smp  return method->resolved_checked_exceptions(CHECK_(objArrayHandle()));
67383098Smp}
67483098Smp
67569408Sache
67669408SacheHandle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) {
67769408Sache  // Basic types
67869408Sache  BasicType type = vmSymbols::signature_type(signature);
679100616Smp  if (type != T_OBJECT) {
68069408Sache    return Handle(THREAD, Universe::java_mirror(type));
68169408Sache  }
68269408Sache
683100616Smp  oop loader = InstanceKlass::cast(k())->class_loader();
68469408Sache  oop protection_domain = Klass::cast(k())->protection_domain();
68569408Sache  Klass* result = SystemDictionary::resolve_or_fail(signature,
68669408Sache                                    Handle(THREAD, loader),
687100616Smp                                    Handle(THREAD, protection_domain),
68869408Sache                                    true, CHECK_(Handle()));
68969408Sache
69069408Sache  if (TraceClassResolution) {
691100616Smp    trace_class_resolution(result);
69269408Sache  }
69369408Sache
69469408Sache  oop nt = Klass::cast(result)->java_mirror();
69583098Smp  return Handle(THREAD, nt);
69683098Smp}
69783098Smp
69883098Smp
69983098Smpoop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) {
70083098Smp  // In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert.
70183098Smp  // Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
70283098Smp  assert(!method()->is_initializer() ||
70369408Sache         (for_constant_pool_access && method()->is_static()) ||
70469408Sache         (method()->name() == vmSymbols::class_initializer_name()
70569408Sache    && Klass::cast(method()->method_holder())->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead");
70669408Sache  instanceKlassHandle holder (THREAD, method->method_holder());
70769408Sache  int slot = method->method_idnum();
70869408Sache
70969408Sache  Symbol*  signature  = method->signature();
71069408Sache  int parameter_count = ArgumentCount(signature).size();
71169408Sache  oop return_type_oop = NULL;
71269408Sache  objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
71369408Sache  if (parameter_types.is_null() || return_type_oop == NULL) return NULL;
71469408Sache
71569408Sache  Handle return_type(THREAD, return_type_oop);
71669408Sache
717195609Smp  objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
718195609Smp
719195609Smp  if (exception_types.is_null()) return NULL;
720195609Smp
721195609Smp  Symbol*  method_name = method->name();
722195609Smp  Handle name;
723195609Smp  if (intern_name) {
724195609Smp    // intern_name is only true with UseNewReflection
72569408Sache    oop name_oop = StringTable::intern(method_name, CHECK_NULL);
72669408Sache    name = Handle(THREAD, name_oop);
72769408Sache  } else {
72869408Sache    name = java_lang_String::create_from_symbol(method_name, CHECK_NULL);
72969408Sache  }
73069408Sache  if (name == NULL) return NULL;
73169408Sache
73269408Sache  int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
73369408Sache
73469408Sache  Handle mh = java_lang_reflect_Method::create(CHECK_NULL);
73569408Sache
736231990Smp  java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror());
737231990Smp  java_lang_reflect_Method::set_slot(mh(), slot);
738231990Smp  java_lang_reflect_Method::set_name(mh(), name());
739100616Smp  java_lang_reflect_Method::set_return_type(mh(), return_type());
740100616Smp  java_lang_reflect_Method::set_parameter_types(mh(), parameter_types());
741100616Smp  java_lang_reflect_Method::set_exception_types(mh(), exception_types());
742100616Smp  java_lang_reflect_Method::set_modifiers(mh(), modifiers);
743195609Smp  java_lang_reflect_Method::set_override(mh(), false);
744195609Smp  if (java_lang_reflect_Method::has_signature_field() &&
745195609Smp      method->generic_signature() != NULL) {
746195609Smp    Symbol*  gs = method->generic_signature();
74769408Sache    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
74869408Sache    java_lang_reflect_Method::set_signature(mh(), sig());
74969408Sache  }
75083098Smp  if (java_lang_reflect_Method::has_annotations_field()) {
75183098Smp    typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
75283098Smp    java_lang_reflect_Method::set_annotations(mh(), an_oop);
75383098Smp  }
75469408Sache  if (java_lang_reflect_Method::has_parameter_annotations_field()) {
75569408Sache    typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
75669408Sache    java_lang_reflect_Method::set_parameter_annotations(mh(), an_oop);
75769408Sache  }
75869408Sache  if (java_lang_reflect_Method::has_annotation_default_field()) {
75969408Sache    typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL);
76083098Smp    java_lang_reflect_Method::set_annotation_default(mh(), an_oop);
76183098Smp  }
76283098Smp  return mh();
76383098Smp}
764100616Smp
765100616Smp
766100616Smpoop Reflection::new_constructor(methodHandle method, TRAPS) {
767100616Smp  assert(method()->is_initializer(), "should call new_method instead");
76883098Smp
769100616Smp  instanceKlassHandle  holder (THREAD, method->method_holder());
77083098Smp  int slot = method->method_idnum();
77183098Smp
772195609Smp  Symbol*  signature  = method->signature();
773195609Smp  int parameter_count = ArgumentCount(signature).size();
774195609Smp  objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL);
77583098Smp  if (parameter_types.is_null()) return NULL;
77683098Smp
77783098Smp  objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
77883098Smp  if (exception_types.is_null()) return NULL;
77969408Sache
78069408Sache  int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
78169408Sache
78269408Sache  Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL);
78383098Smp
78483098Smp  java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror());
78583098Smp  java_lang_reflect_Constructor::set_slot(ch(), slot);
78683098Smp  java_lang_reflect_Constructor::set_parameter_types(ch(), parameter_types());
78783098Smp  java_lang_reflect_Constructor::set_exception_types(ch(), exception_types());
78883098Smp  java_lang_reflect_Constructor::set_modifiers(ch(), modifiers);
78983098Smp  java_lang_reflect_Constructor::set_override(ch(), false);
79083098Smp  if (java_lang_reflect_Constructor::has_signature_field() &&
79169408Sache      method->generic_signature() != NULL) {
79269408Sache    Symbol*  gs = method->generic_signature();
79369408Sache    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
79469408Sache    java_lang_reflect_Constructor::set_signature(ch(), sig());
79569408Sache  }
79669408Sache  if (java_lang_reflect_Constructor::has_annotations_field()) {
79769408Sache    typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
79869408Sache    java_lang_reflect_Constructor::set_annotations(ch(), an_oop);
79969408Sache  }
80069408Sache  if (java_lang_reflect_Constructor::has_parameter_annotations_field()) {
80169408Sache    typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
80269408Sache    java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
80383098Smp  }
80483098Smp  return ch();
80583098Smp}
80683098Smp
80769408Sache
80869408Sacheoop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
80969408Sache  Symbol*  field_name = fd->name();
81069408Sache  Handle name;
81169408Sache  if (intern_name) {
81269408Sache    // intern_name is only true with UseNewReflection
81369408Sache    oop name_oop = StringTable::intern(field_name, CHECK_NULL);
81469408Sache    name = Handle(THREAD, name_oop);
81569408Sache  } else {
81669408Sache    name = java_lang_String::create_from_symbol(field_name, CHECK_NULL);
81769408Sache  }
81869408Sache  Symbol*  signature  = fd->signature();
81969408Sache  instanceKlassHandle  holder    (THREAD, fd->field_holder());
82069408Sache  Handle type = new_type(signature, holder, CHECK_NULL);
82169408Sache  Handle rh  = java_lang_reflect_Field::create(CHECK_NULL);
82269408Sache
82369408Sache  java_lang_reflect_Field::set_clazz(rh(), Klass::cast(fd->field_holder())->java_mirror());
82469408Sache  java_lang_reflect_Field::set_slot(rh(), fd->index());
82569408Sache  java_lang_reflect_Field::set_name(rh(), name());
82669408Sache  java_lang_reflect_Field::set_type(rh(), type());
82769408Sache  // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
82869408Sache  java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
82969408Sache  java_lang_reflect_Field::set_override(rh(), false);
83069408Sache  if (java_lang_reflect_Field::has_signature_field() &&
83169408Sache      fd->has_generic_signature()) {
83283098Smp    Symbol*  gs = fd->generic_signature();
83383098Smp    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
83483098Smp    java_lang_reflect_Field::set_signature(rh(), sig());
83583098Smp  }
836100616Smp  if (java_lang_reflect_Field::has_annotations_field()) {
837100616Smp    typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
838100616Smp    java_lang_reflect_Field::set_annotations(rh(), an_oop);
839100616Smp  }
84069408Sache  return rh();
84169408Sache}
84269408Sache
843100616Smp
844100616SmpmethodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
845100616Smp                                                KlassHandle recv_klass, Handle receiver, TRAPS) {
84683098Smp  assert(!method.is_null() , "method should not be null");
84783098Smp
84883098Smp  CallInfo info;
84983098Smp  Symbol*  signature  = method->signature();
850195609Smp  Symbol*  name       = method->name();
851100616Smp  LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass,
852100616Smp                                       name, signature,
853195609Smp                                       KlassHandle(), false, true,
854195609Smp                                       CHECK_(methodHandle()));
855195609Smp  return info.selected_method();
856195609Smp}
85783098Smp
85883098Smp
85983098Smpoop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
86083098Smp                       Handle receiver, bool override, objArrayHandle ptypes,
86183098Smp                       BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) {
86283098Smp  ResourceMark rm(THREAD);
86383098Smp
86483098Smp  methodHandle method;      // actual method to invoke
86569408Sache  KlassHandle target_klass; // target klass, receiver's klass for non-static
86669408Sache
86769408Sache  // Ensure klass is initialized
86869408Sache  klass->initialize(CHECK_NULL);
86969408Sache
87069408Sache  bool is_static = reflected_method->is_static();
87169408Sache  if (is_static) {
87269408Sache    // ignore receiver argument
873195609Smp    method = reflected_method;
874195609Smp    target_klass = klass;
875195609Smp  } else {
876195609Smp    // check for null receiver
877195609Smp    if (receiver.is_null()) {
878195609Smp      THROW_0(vmSymbols::java_lang_NullPointerException());
879195609Smp    }
880195609Smp    // Check class of receiver against class declaring method
88169408Sache    if (!receiver->is_a(klass())) {
88269408Sache      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
88369408Sache    }
88469408Sache    // target klass is receiver's klass
88569408Sache    target_klass = KlassHandle(THREAD, receiver->klass());
88669408Sache    // no need to resolve if method is private or <init>
887195609Smp    if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
88869408Sache      method = reflected_method;
88969408Sache    } else {
890195609Smp      // resolve based on the receiver
891195609Smp      if (InstanceKlass::cast(reflected_method->method_holder())->is_interface()) {
892195609Smp        // resolve interface call
893195609Smp        if (ReflectionWrapResolutionErrors) {
894195609Smp          // new default: 6531596
895195609Smp          // Match resolution errors with those thrown due to reflection inlining
896100616Smp          // Linktime resolution & IllegalAccessCheck already done by Class.getMethod()
89769408Sache          method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD);
89869408Sache          if (HAS_PENDING_EXCEPTION) {
899195609Smp          // Method resolution threw an exception; wrap it in an InvocationTargetException
90069408Sache            oop resolution_exception = PENDING_EXCEPTION;
90169408Sache            CLEAR_PENDING_EXCEPTION;
902195609Smp            JavaCallArguments args(Handle(THREAD, resolution_exception));
903100616Smp            THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
90469408Sache                vmSymbols::throwable_void_signature(),
905195609Smp                &args);
906195609Smp          }
907195609Smp        } else {
908100616Smp          method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL));
90969408Sache        }
91069408Sache      }  else {
911100616Smp        // if the method can be overridden, we resolve using the vtable index.
91269408Sache        int index  = reflected_method->vtable_index();
91369408Sache        method = reflected_method;
914195609Smp        if (index != Method::nonvirtual_vtable_index) {
915100616Smp          // target_klass might be an arrayKlassOop but all vtables start at
91669408Sache          // the same place. The cast is to avoid virtual call and assertion.
917195609Smp          InstanceKlass* inst = (InstanceKlass*)target_klass();
918195609Smp          method = methodHandle(THREAD, inst->method_at_vtable(index));
919195609Smp        }
92069408Sache        if (!method.is_null()) {
92169408Sache          // Check for abstract methods as well
92269408Sache          if (method->is_abstract()) {
923100616Smp            // new default: 6531596
92469408Sache            if (ReflectionWrapResolutionErrors) {
92569408Sache              ResourceMark rm(THREAD);
926195609Smp              Handle h_origexception = Exceptions::new_exception(THREAD,
92769408Sache                     vmSymbols::java_lang_AbstractMethodError(),
92869408Sache                     Method::name_and_sig_as_C_string(Klass::cast(target_klass()),
92969408Sache                     method->name(),
93069408Sache                     method->signature()));
931195609Smp              JavaCallArguments args(h_origexception);
93269408Sache              THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
93369408Sache                vmSymbols::throwable_void_signature(),
93469408Sache                &args);
935100616Smp            } else {
936195609Smp              ResourceMark rm(THREAD);
937100616Smp              THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(),
938100616Smp                        Method::name_and_sig_as_C_string(Klass::cast(target_klass()),
939100616Smp                                                                method->name(),
940100616Smp                                                                method->signature()));
941195609Smp            }
942100616Smp          }
943100616Smp        }
944100616Smp      }
94569408Sache    }
94669408Sache  }
94769408Sache
948100616Smp  // I believe this is a ShouldNotGetHere case which requires
949100616Smp  // an internal vtable bug. If you ever get this please let Karen know.
950100616Smp  if (method.is_null()) {
951100616Smp    ResourceMark rm(THREAD);
952195609Smp    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
953195609Smp                Method::name_and_sig_as_C_string(Klass::cast(klass()),
954195609Smp                                                        reflected_method->name(),
955195609Smp                                                        reflected_method->signature()));
95683098Smp  }
95783098Smp
95883098Smp  // In the JDK 1.4 reflection implementation, the security check is
95983098Smp  // done at the Java level
96069408Sache  if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) {
96169408Sache
96269408Sache  // Access checking (unless overridden by Method)
96369408Sache  if (!override) {
96469408Sache    if (!(klass->is_public() && reflected_method->is_public())) {
96569408Sache      bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL);
966100616Smp      if (!access) {
967100616Smp        return NULL; // exception
968100616Smp      }
969100616Smp    }
970100616Smp  }
971100616Smp
97283098Smp  } // !(Universe::is_gte_jdk14x_version() && UseNewReflection)
97383098Smp
97483098Smp  assert(ptypes->is_objArray(), "just checking");
97583098Smp  int args_len = args.is_null() ? 0 : args->length();
976195609Smp  // Check number of arguments
977195609Smp  if (ptypes->length() != args_len) {
978195609Smp    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments");
979195609Smp  }
980195609Smp
981195609Smp  // Create object to contain parameters for the JavaCall
982195609Smp  JavaCallArguments java_args(method->size_of_parameters());
983195609Smp
984195609Smp  if (!is_static) {
985195609Smp    java_args.push_oop(receiver);
986195609Smp  }
987195609Smp
988195609Smp  for (int i = 0; i < args_len; i++) {
989195609Smp    oop type_mirror = ptypes->obj_at(i);
99069408Sache    oop arg = args->obj_at(i);
99169408Sache    if (java_lang_Class::is_primitive(type_mirror)) {
99269408Sache      jvalue value;
99369408Sache      BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL);
99469408Sache      BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL);
99569408Sache      if (ptype != atype) {
99669408Sache        widen(&value, atype, ptype, CHECK_NULL);
997195609Smp      }
998195609Smp      switch (ptype) {
999195609Smp        case T_BOOLEAN:     java_args.push_int(value.z);    break;
1000195609Smp        case T_CHAR:        java_args.push_int(value.c);    break;
1001195609Smp        case T_BYTE:        java_args.push_int(value.b);    break;
1002195609Smp        case T_SHORT:       java_args.push_int(value.s);    break;
1003100616Smp        case T_INT:         java_args.push_int(value.i);    break;
100483098Smp        case T_LONG:        java_args.push_long(value.j);   break;
100583098Smp        case T_FLOAT:       java_args.push_float(value.f);  break;
100683098Smp        case T_DOUBLE:      java_args.push_double(value.d); break;
100769408Sache        default:
100869408Sache          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
100969408Sache      }
101069408Sache    } else {
101169408Sache      if (arg != NULL) {
101269408Sache        Klass* k = java_lang_Class::as_Klass(type_mirror);
101369408Sache        if (!arg->is_a(k)) {
101483098Smp          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
101583098Smp        }
101683098Smp      }
101783098Smp      Handle arg_handle(THREAD, arg);         // Create handle for argument
101883098Smp      java_args.push_oop(arg_handle); // Push handle
101983098Smp    }
102083098Smp  }
102169408Sache
102269408Sache  assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking");
102369408Sache
102469408Sache  // All oops (including receiver) is passed in as Handles. An potential oop is returned as an
102569408Sache  // oop (i.e., NOT as an handle)
102669408Sache  JavaValue result(rtype);
102769408Sache  JavaCalls::call(&result, method, &java_args, THREAD);
102869408Sache
102969408Sache  if (HAS_PENDING_EXCEPTION) {
103069408Sache    // Method threw an exception; wrap it in an InvocationTargetException
103169408Sache    oop target_exception = PENDING_EXCEPTION;
103269408Sache    CLEAR_PENDING_EXCEPTION;
103369408Sache    JavaCallArguments args(Handle(THREAD, target_exception));
103469408Sache    THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
103569408Sache                vmSymbols::throwable_void_signature(),
103669408Sache                &args);
103769408Sache  } else {
103869408Sache    if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT)
103969408Sache      narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
104069408Sache    return box((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
104169408Sache  }
104269408Sache}
104369408Sache
104469408Sache
104569408Sachevoid Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) {
104669408Sache  switch (narrow_type) {
104769408Sache    case T_BOOLEAN:
104869408Sache     value->z = (jboolean) value->i;
104969408Sache     return;
105069408Sache    case T_BYTE:
105169408Sache     value->b = (jbyte) value->i;
105269408Sache     return;
105369408Sache    case T_CHAR:
105469408Sache     value->c = (jchar) value->i;
105569408Sache     return;
105669408Sache    case T_SHORT:
105769408Sache     value->s = (jshort) value->i;
105869408Sache     return;
105969408Sache    default:
106069408Sache      break; // fail
1061195609Smp   }
1062100616Smp  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
1063100616Smp}
1064100616Smp
106569408Sache
106669408SacheBasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) {
106769408Sache  assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
106869408Sache  return java_lang_Class::primitive_type(basic_type_mirror);
106983098Smp}
1070100616Smp
107183098Smp// This would be nicer if, say, java.lang.reflect.Method was a subclass
107283098Smp// of java.lang.reflect.Constructor
1073100616Smp
1074100616Smpoop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
1075100616Smp  oop mirror             = java_lang_reflect_Method::clazz(method_mirror);
1076100616Smp  int slot               = java_lang_reflect_Method::slot(method_mirror);
1077100616Smp  bool override          = java_lang_reflect_Method::override(method_mirror) != 0;
1078100616Smp  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror)));
1079100616Smp
1080100616Smp  oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror);
1081195609Smp  BasicType rtype;
1082195609Smp  if (java_lang_Class::is_primitive(return_type_mirror)) {
1083195609Smp    rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
1084195609Smp  } else {
1085195609Smp    rtype = T_OBJECT;
1086195609Smp  }
1087195609Smp
1088195609Smp  instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
1089195609Smp  Method* m = klass->method_with_idnum(slot);
1090195609Smp  if (m == NULL) {
1091195609Smp    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
1092195609Smp  }
109369408Sache  methodHandle method(THREAD, m);
109469408Sache
109569408Sache  return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
109669408Sache}
109769408Sache
109869408Sache
1099100616Smpoop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) {
1100100616Smp  oop mirror             = java_lang_reflect_Constructor::clazz(constructor_mirror);
1101100616Smp  int slot               = java_lang_reflect_Constructor::slot(constructor_mirror);
1102100616Smp  bool override          = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
110369408Sache  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
110469408Sache
110569408Sache  instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
1106195609Smp  Method* m = klass->method_with_idnum(slot);
1107195609Smp  if (m == NULL) {
1108195609Smp    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
1109195609Smp  }
111069408Sache  methodHandle method(THREAD, m);
111169408Sache  assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
111269408Sache
111369408Sache  // Make sure klass gets initialize
111469408Sache  klass->initialize(CHECK_NULL);
111569408Sache
111669408Sache  // Create new instance (the receiver)
111769408Sache  klass->check_valid_for_instantiation(false, CHECK_NULL);
111883098Smp  Handle receiver = klass->allocate_instance_handle(CHECK_NULL);
111983098Smp
112083098Smp  // Ignore result from call and return receiver
112183098Smp  invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
112269408Sache  return receiver();
112369408Sache}
112469408Sache