natField.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. // natField.cc - Implementation of java.lang.reflect.Field native methods.
  2. /* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006 Free Software Foundation
  3. This file is part of libgcj.
  4. This software is copyrighted work licensed under the terms of the
  5. Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
  6. details. */
  7. #include <config.h>
  8. #include <stdlib.h>
  9. #include <jvm.h>
  10. #include <java-stack.h>
  11. #include <java/lang/reflect/Field.h>
  12. #include <java/lang/reflect/Modifier.h>
  13. #include <java/lang/ArrayIndexOutOfBoundsException.h>
  14. #include <java/lang/IllegalArgumentException.h>
  15. #include <java/lang/IllegalAccessException.h>
  16. #include <java/lang/NullPointerException.h>
  17. #include <java/lang/Byte.h>
  18. #include <java/lang/Short.h>
  19. #include <java/lang/Integer.h>
  20. #include <java/lang/Long.h>
  21. #include <java/lang/Float.h>
  22. #include <java/lang/Double.h>
  23. #include <java/lang/Boolean.h>
  24. #include <java/lang/Character.h>
  25. typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
  26. jint
  27. java::lang::reflect::Field::getModifiersInternal ()
  28. {
  29. return _Jv_FromReflectedField (this)->flags;
  30. }
  31. jstring
  32. java::lang::reflect::Field::getSignature()
  33. {
  34. return declaringClass->getReflectionSignature (this);
  35. }
  36. anno_a_t
  37. java::lang::reflect::Field::getDeclaredAnnotationsInternal()
  38. {
  39. return (anno_a_t) declaringClass->getDeclaredAnnotations(this);
  40. }
  41. jstring
  42. java::lang::reflect::Field::getName ()
  43. {
  44. if (name == NULL)
  45. name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
  46. return name;
  47. }
  48. jclass
  49. java::lang::reflect::Field::getType ()
  50. {
  51. if (type == NULL)
  52. {
  53. jfieldID fld = _Jv_FromReflectedField (this);
  54. JvSynchronize sync (declaringClass);
  55. _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
  56. type = fld->type;
  57. }
  58. return type;
  59. }
  60. static void*
  61. getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj,
  62. jboolean checkFinal)
  63. {
  64. using namespace java::lang::reflect;
  65. jfieldID fld = _Jv_FromReflectedField (field);
  66. _Jv_ushort flags = fld->getModifiers();
  67. // Setting a final field is usually not allowed.
  68. if (checkFinal
  69. // As of 1.5, you can set a non-static final field if it is
  70. // accessible.
  71. && (! field->isAccessible()
  72. || (field->getModifiers() & java::lang::reflect::Modifier::STATIC))
  73. && (field->getModifiers() & java::lang::reflect::Modifier::FINAL))
  74. throw new java::lang::IllegalAccessException(JvNewStringUTF
  75. ("Field is final"));
  76. // Check accessibility, if required.
  77. if (! (Modifier::isPublic (flags) || field->isAccessible()))
  78. {
  79. if (! caller)
  80. caller = _Jv_StackTrace::GetCallingClass (&Field::class$);
  81. if (! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags))
  82. throw new java::lang::IllegalAccessException;
  83. }
  84. if (flags & Modifier::STATIC)
  85. {
  86. jclass fldClass = field->getDeclaringClass ();
  87. JvInitClass(fldClass);
  88. return fld->u.addr;
  89. }
  90. else
  91. {
  92. if (obj == NULL)
  93. throw new java::lang::NullPointerException;
  94. if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass()))
  95. throw new java::lang::IllegalArgumentException;
  96. return (void*) ((char*) obj + fld->getOffset ());
  97. }
  98. }
  99. static jboolean
  100. getBoolean (jclass cls, void* addr)
  101. {
  102. if (cls == JvPrimClass (boolean))
  103. return * (jboolean *) addr;
  104. throw new java::lang::IllegalArgumentException;
  105. }
  106. static jchar
  107. getChar (jclass cls, void* addr)
  108. {
  109. if (cls == JvPrimClass (char))
  110. return * (jchar *) addr;
  111. throw new java::lang::IllegalArgumentException;
  112. }
  113. static jbyte
  114. getByte (jclass cls, void* addr)
  115. {
  116. if (cls == JvPrimClass (byte))
  117. return * (jbyte *) addr;
  118. throw new java::lang::IllegalArgumentException;
  119. }
  120. static jshort
  121. getShort (jclass cls, void* addr)
  122. {
  123. if (cls == JvPrimClass (short))
  124. return * (jshort *) addr;
  125. if (cls == JvPrimClass (byte))
  126. return * (jbyte *) addr;
  127. throw new java::lang::IllegalArgumentException;
  128. }
  129. static jint
  130. getInt (jclass cls, void* addr)
  131. {
  132. if (cls == JvPrimClass (int))
  133. return * (jint *) addr;
  134. if (cls == JvPrimClass (short))
  135. return * (jshort *) addr;
  136. if (cls == JvPrimClass (char))
  137. return * (jchar *) addr;
  138. if (cls == JvPrimClass (byte))
  139. return * (jbyte *) addr;
  140. throw new java::lang::IllegalArgumentException;
  141. }
  142. static jlong
  143. getLong (jclass cls, void* addr)
  144. {
  145. if (cls == JvPrimClass (long))
  146. return * (jlong *) addr;
  147. return ::getInt(cls, addr);
  148. }
  149. static jfloat
  150. getFloat (jclass cls, void* addr)
  151. {
  152. if (cls == JvPrimClass (float))
  153. return * (jfloat *) addr;
  154. if (cls == JvPrimClass (long))
  155. return * (jlong *) addr;
  156. return ::getInt(cls, addr);
  157. }
  158. static jdouble
  159. getDouble (jclass cls, void* addr)
  160. {
  161. if (cls == JvPrimClass (double))
  162. return * (jdouble *) addr;
  163. if (cls == JvPrimClass (float))
  164. return * (jfloat *) addr;
  165. if (cls == JvPrimClass (long))
  166. return * (jlong *) addr;
  167. return ::getInt(cls, addr);
  168. }
  169. jboolean
  170. java::lang::reflect::Field::getBoolean (jclass caller, jobject obj)
  171. {
  172. return ::getBoolean (this->getType(), getAddr (this, caller, obj, false));
  173. }
  174. jchar
  175. java::lang::reflect::Field::getChar (jclass caller, jobject obj)
  176. {
  177. return ::getChar (this->getType(), getAddr (this, caller, obj, false));
  178. }
  179. jbyte
  180. java::lang::reflect::Field::getByte (jclass caller, jobject obj)
  181. {
  182. return ::getByte (this->getType(), getAddr (this, caller, obj, false));
  183. }
  184. jshort
  185. java::lang::reflect::Field::getShort (jclass caller, jobject obj)
  186. {
  187. return ::getShort (this->getType(), getAddr (this, caller, obj, false));
  188. }
  189. jint
  190. java::lang::reflect::Field::getInt (jclass caller, jobject obj)
  191. {
  192. return ::getInt (this->getType(), getAddr (this, caller, obj, false));
  193. }
  194. jlong
  195. java::lang::reflect::Field::getLong (jclass caller, jobject obj)
  196. {
  197. return ::getLong (this->getType(), getAddr (this, caller, obj, false));
  198. }
  199. jfloat
  200. java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
  201. {
  202. return ::getFloat (this->getType(), getAddr (this, caller, obj, false));
  203. }
  204. jdouble
  205. java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
  206. {
  207. return ::getDouble (this->getType(), getAddr (this, caller, obj, false));
  208. }
  209. jobject
  210. java::lang::reflect::Field::get (jclass caller, jobject obj)
  211. {
  212. jclass type = this->getType();
  213. void* addr = getAddr (this, caller, obj, false);
  214. if (! type->isPrimitive ())
  215. return * (jobject*) addr;
  216. if (type == JvPrimClass (double))
  217. return new java::lang::Double (* (jdouble*) addr);
  218. if (type == JvPrimClass (float))
  219. return new java::lang::Float (* (jfloat*) addr);
  220. if (type == JvPrimClass (long))
  221. return new java::lang::Long (* (jlong*) addr);
  222. if (type == JvPrimClass (int))
  223. return new java::lang::Integer (* (jint*) addr);
  224. if (type == JvPrimClass (short))
  225. return new java::lang::Short (* (jshort*) addr);
  226. if (type == JvPrimClass (byte))
  227. return new java::lang::Byte (* (jbyte*) addr);
  228. if (type == JvPrimClass (char))
  229. return new java::lang::Character (* (jchar*) addr);
  230. if (type == JvPrimClass (boolean))
  231. {
  232. _Jv_InitClass (&java::lang::Boolean::class$);
  233. if (* (jboolean*) addr)
  234. return java::lang::Boolean::TRUE;
  235. else
  236. return java::lang::Boolean::FALSE;
  237. }
  238. throw new java::lang::IllegalArgumentException;
  239. }
  240. static void
  241. setBoolean (jclass type, void *addr, jboolean value)
  242. {
  243. if (type == JvPrimClass (boolean))
  244. * (jboolean *) addr = value;
  245. else
  246. throw new java::lang::IllegalArgumentException;
  247. }
  248. static void
  249. setChar (jclass type, void *addr, jchar value)
  250. {
  251. if (type == JvPrimClass (char))
  252. * (jchar *) addr = value;
  253. else if (type == JvPrimClass (int))
  254. * (jint *) addr = value;
  255. else if (type == JvPrimClass (long))
  256. * (jlong *) addr = value;
  257. else if (type == JvPrimClass (float))
  258. * (jfloat *) addr = value;
  259. else if (type == JvPrimClass (double))
  260. * (jdouble *) addr = value;
  261. else
  262. throw new java::lang::IllegalArgumentException;
  263. }
  264. static void
  265. setByte (jclass type, void *addr, jbyte value)
  266. {
  267. if (type == JvPrimClass (byte))
  268. * (jbyte *) addr = value;
  269. else if (type == JvPrimClass (short))
  270. * (jshort *) addr = value;
  271. else if (type == JvPrimClass (int))
  272. * (jint *) addr = value;
  273. else if (type == JvPrimClass (long))
  274. * (jlong *) addr = value;
  275. else if (type == JvPrimClass (float))
  276. * (jfloat *) addr = value;
  277. else if (type == JvPrimClass (double))
  278. * (jdouble *) addr = value;
  279. else
  280. throw new java::lang::IllegalArgumentException;
  281. }
  282. static void
  283. setShort (jclass type, void *addr, jshort value)
  284. {
  285. if (type == JvPrimClass (short))
  286. * (jshort *) addr = value;
  287. else if (type == JvPrimClass (int))
  288. * (jint *) addr = value;
  289. else if (type == JvPrimClass (long))
  290. * (jlong *) addr = value;
  291. else if (type == JvPrimClass (float))
  292. * (jfloat *) addr = value;
  293. else if (type == JvPrimClass (double))
  294. * (jdouble *) addr = value;
  295. else
  296. throw new java::lang::IllegalArgumentException;
  297. }
  298. static void
  299. setInt (jclass type, void *addr, jint value)
  300. {
  301. if (type == JvPrimClass (int))
  302. * (jint *) addr = value;
  303. else if (type == JvPrimClass (long))
  304. * (jlong *) addr = value;
  305. else if (type == JvPrimClass (float))
  306. * (jfloat *) addr = value;
  307. else if (type == JvPrimClass (double))
  308. * (jdouble *) addr = value;
  309. else
  310. throw new java::lang::IllegalArgumentException;
  311. }
  312. static void
  313. setLong (jclass type, void *addr, jlong value)
  314. {
  315. if (type == JvPrimClass (long))
  316. * (jlong *) addr = value;
  317. else if (type == JvPrimClass (float))
  318. * (jfloat *) addr = value;
  319. else if (type == JvPrimClass (double))
  320. * (jdouble *) addr = value;
  321. else
  322. throw new java::lang::IllegalArgumentException;
  323. }
  324. static void
  325. setFloat (jclass type, void *addr, jfloat value)
  326. {
  327. if (type == JvPrimClass (float))
  328. * (jfloat *) addr = value;
  329. else if (type == JvPrimClass (double))
  330. * (jdouble *) addr = value;
  331. else
  332. throw new java::lang::IllegalArgumentException;
  333. }
  334. static void
  335. setDouble (jclass type, void *addr, jdouble value)
  336. {
  337. if (type == JvPrimClass (double))
  338. * (jdouble *) addr = value;
  339. else
  340. throw new java::lang::IllegalArgumentException;
  341. }
  342. void
  343. java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b,
  344. jboolean checkFinal)
  345. {
  346. ::setBoolean (this->getType(), getAddr (this, caller, obj, checkFinal), b);
  347. }
  348. void
  349. java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c,
  350. jboolean checkFinal)
  351. {
  352. ::setChar (this->getType(), getAddr (this, caller, obj, checkFinal), c);
  353. }
  354. void
  355. java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b,
  356. jboolean checkFinal)
  357. {
  358. ::setByte (this->getType(), getAddr (this, caller, obj, checkFinal), b);
  359. }
  360. void
  361. java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s,
  362. jboolean checkFinal)
  363. {
  364. ::setShort (this->getType(), getAddr (this, caller, obj, checkFinal), s);
  365. }
  366. void
  367. java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i,
  368. jboolean checkFinal)
  369. {
  370. ::setInt (this->getType(), getAddr (this, caller, obj, checkFinal), i);
  371. }
  372. void
  373. java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l,
  374. jboolean checkFinal)
  375. {
  376. ::setLong (this->getType(), getAddr (this, caller, obj, checkFinal), l);
  377. }
  378. void
  379. java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f,
  380. jboolean checkFinal)
  381. {
  382. ::setFloat (this->getType(), getAddr (this, caller, obj, checkFinal), f);
  383. }
  384. void
  385. java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d,
  386. jboolean checkFinal)
  387. {
  388. ::setDouble (this->getType(), getAddr (this, caller, obj, checkFinal), d);
  389. }
  390. void
  391. java::lang::reflect::Field::set (jclass caller, jobject object, jobject value,
  392. jclass type, jboolean checkFinal)
  393. {
  394. void* addr = getAddr (this, caller, object, checkFinal);
  395. if (value != NULL && ! _Jv_IsInstanceOf (value, type))
  396. throw new java::lang::IllegalArgumentException;
  397. * (jobject*) addr = value;
  398. }