jpvar.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2011 by Jonas Maebe,
  4. members of the Free Pascal development team.
  5. This file implements support infrastructure for procvars under the JVM
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. constructor FpcBaseProcVarType.create(inst: jlobject; const methodName: unicodestring; const argTypes: array of JLClass);
  13. begin
  14. method.data:=inst;
  15. setFpcBaseProcVarTypeBySignature(methodName,argtypes);
  16. end;
  17. constructor FpcBaseProcVarType.create(const meth: tmethod);
  18. begin
  19. method:=meth;
  20. end;
  21. procedure FpcBaseProcVarType.setFpcBaseProcVarTypeBySignature(const methodName: unicodestring; const argTypes: array of JLClass);
  22. var
  23. owningClass: JLClass;
  24. begin
  25. { class method or instance method }
  26. if method.data is JLClass then
  27. owningClass:=JLClass(method.data)
  28. else
  29. owningClass:=method.data.getClass;
  30. method.code:=nil;
  31. { getDeclaredMethod does not search superclasses -> manually traverse
  32. until found. If we don't find it anywhere, we'll traverse up to the
  33. parent of java.lang.Object = null and throw a NullPointerException }
  34. repeat
  35. try
  36. method.code:=owningClass.getDeclaredMethod(methodName,argTypes);
  37. except
  38. on JLNoSuchMethodException do
  39. owningClass:=owningClass.getSuperClass;
  40. end;
  41. until assigned(method.code);
  42. { required to enable calling private methods in one class from another
  43. class -- can cause security exceptions if the security manager doesn't
  44. allow this though... }
  45. if not method.code.isAccessible then
  46. method.code.setAccessible(true);
  47. end;
  48. function FpcBaseProcVarType.getClassProcArgs(const args: array of jlobject): TJLObjectDynArray;
  49. var
  50. arglen: longint;
  51. begin
  52. { add the self pointer as first argument (Java class methods don't take an
  53. implicit self parameters, Pascal ones do) }
  54. arglen:=length(args);
  55. setlength(result,arglen+1);
  56. JLSystem.ArrayCopy(JLObject(@args),0,JLObject(result),1,arglen);
  57. result[0]:=method.data;
  58. end;
  59. procedure FpcBaseProcVarType.fpcDeepCopy(result: FpcBaseProcVarType);
  60. begin
  61. result.method:=method;
  62. end;
  63. function FpcBaseProcVarType.clone: JLObject;
  64. var
  65. field: JLRField;
  66. newmethodrec: tmethod;
  67. begin
  68. result:=inherited;
  69. { replace the method record pointer (the inherited clone will have copied
  70. it, and there is no way we can change it using Pascal code since it's
  71. not a pointer at the Pascal level) }
  72. newmethodrec:=method;
  73. field:=getClass.getField('method');
  74. { doesn't matter that it's a local variable, everything is garbage
  75. collected }
  76. field.&set(result,JLObject(@newmethodrec));
  77. end;
  78. procedure FpcBaseProcVarType.invokeProc(const args: array of jlobject);
  79. begin
  80. { caching the length would be faster, but that would have to be done
  81. in a synchronised way. Doing it at construction time and in fpcDeepCopy/
  82. clone is not enough, because the method field can be manipulated
  83. directly }
  84. try
  85. if length(method.code.getParameterTypes)=length(args) then
  86. method.code.invoke(method.data,args)
  87. else
  88. method.code.invoke(method.data,getClassProcArgs(args));
  89. except
  90. on e: JLRInvocationTargetException do
  91. raise e.getCause
  92. end;
  93. end;
  94. function FpcBaseProcVarType.invokeBooleanFunc(const args: array of jlobject): jboolean;
  95. begin
  96. try
  97. if length(method.code.getParameterTypes)=length(args) then
  98. result:=JLBoolean(method.code.invoke(method.data,args)).booleanValue
  99. else
  100. result:=JLBoolean(method.code.invoke(method.data,getClassProcArgs(args))).booleanValue
  101. except
  102. on e: JLRInvocationTargetException do
  103. raise e.getCause
  104. end;
  105. end;
  106. function FpcBaseProcVarType.invokeCharFunc(const args: array of jlobject): jchar;
  107. begin
  108. try
  109. if length(method.code.getParameterTypes)=length(args) then
  110. result:=JLCharacter(method.code.invoke(method.data,args)).charValue
  111. else
  112. result:=JLCharacter(method.code.invoke(method.data,getClassProcArgs(args))).charValue;
  113. except
  114. on e: JLRInvocationTargetException do
  115. raise e.getCause
  116. end;
  117. end;
  118. function FpcBaseProcVarType.invokeByteFunc(const args: array of jlobject): jbyte;
  119. begin
  120. try
  121. if length(method.code.getParameterTypes)=length(args) then
  122. result:=JLByte(method.code.invoke(method.data,args)).byteValue
  123. else
  124. result:=JLByte(method.code.invoke(method.data,getClassProcArgs(args))).byteValue
  125. except
  126. on e: JLRInvocationTargetException do
  127. raise e.getCause
  128. end;
  129. end;
  130. function FpcBaseProcVarType.invokeShortFunc(const args: array of jlobject): jshort;
  131. begin
  132. try
  133. if length(method.code.getParameterTypes)=length(args) then
  134. result:=JLShort(method.code.invoke(method.data,args)).shortValue
  135. else
  136. result:=JLShort(method.code.invoke(method.data,getClassProcArgs(args))).shortValue
  137. except
  138. on e: JLRInvocationTargetException do
  139. raise e.getCause
  140. end;
  141. end;
  142. function FpcBaseProcVarType.invokeIntFunc(const args: array of jlobject): jint;
  143. begin
  144. try
  145. if length(method.code.getParameterTypes)=length(args) then
  146. result:=JLInteger(method.code.invoke(method.data,args)).intValue
  147. else
  148. result:=JLInteger(method.code.invoke(method.data,getClassProcArgs(args))).intValue
  149. except
  150. on e: JLRInvocationTargetException do
  151. raise e.getCause
  152. end;
  153. end;
  154. function FpcBaseProcVarType.invokeLongFunc(const args: array of jlobject): jlong;
  155. begin
  156. try
  157. if length(method.code.getParameterTypes)=length(args) then
  158. result:=JLLong(method.code.invoke(method.data,args)).longValue
  159. else
  160. result:=JLLong(method.code.invoke(method.data,getClassProcArgs(args))).longValue;
  161. except
  162. on e: JLRInvocationTargetException do
  163. raise e.getCause
  164. end;
  165. end;
  166. function FpcBaseProcVarType.invokeSingleFunc(const args: array of jlobject): jfloat;
  167. begin
  168. try
  169. if length(method.code.getParameterTypes)=length(args) then
  170. result:=JLFloat(method.code.invoke(method.data,args)).floatValue
  171. else
  172. result:=JLFloat(method.code.invoke(method.data,getClassProcArgs(args))).floatValue
  173. except
  174. on e: JLRInvocationTargetException do
  175. raise e.getCause
  176. end;
  177. end;
  178. function FpcBaseProcVarType.invokeDoubleFunc(const args: array of jlobject): jdouble;
  179. begin
  180. try
  181. if length(method.code.getParameterTypes)=length(args) then
  182. result:=JLDouble(method.code.invoke(method.data,args)).doubleValue
  183. else
  184. result:=JLDouble(method.code.invoke(method.data,getClassProcArgs(args))).doubleValue
  185. except
  186. on e: JLRInvocationTargetException do
  187. raise e.getCause
  188. end;
  189. end;
  190. function FpcBaseProcVarType.invokeObjectFunc(const args: array of jlobject): jlobject;
  191. begin
  192. try
  193. if length(method.code.getParameterTypes)=length(args) then
  194. result:=method.code.invoke(method.data,args)
  195. else
  196. result:=method.code.invoke(method.data,getClassProcArgs(args))
  197. except
  198. on e: JLRInvocationTargetException do
  199. raise e.getCause
  200. end;
  201. end;
  202. function FpcBaseNestedProcVarType.getNestedArgs(const args: array of jlobject): TJLObjectDynArray;
  203. var
  204. arglen: longint;
  205. begin
  206. { add the parentfp struct pointer as last argument (delphi nested cc
  207. "calling convention") }
  208. arglen:=length(args);
  209. setlength(result,arglen+1);
  210. JLSystem.ArrayCopy(JLObject(@args),0,JLObject(result),0,arglen);
  211. result[arglen]:=nestedfpstruct;
  212. end;
  213. constructor FpcBaseNestedProcVarType.create(inst, context: jlobject; const methodName: unicodestring; const argTypes: array of JLClass);
  214. begin
  215. inherited create(inst,methodName,argTypes);
  216. nestedfpstruct:=context;
  217. end;
  218. procedure FpcBaseNestedProcVarType.fpcDeepCopy(result: FpcBaseProcVarType);
  219. begin
  220. inherited fpcDeepCopy(result);
  221. FpcBaseNestedProcVarType(result).nestedfpstruct:=nestedfpstruct;
  222. end;
  223. function FpcBaseNestedProcVarType.clone: JLObject;
  224. begin
  225. result:=inherited;
  226. FpcBaseNestedProcVarType(result).nestedfpstruct:=nestedfpstruct;
  227. end;
  228. procedure FpcBaseNestedProcVarType.invokeProc(const args: array of jlobject);
  229. begin
  230. inherited invokeProc(getNestedArgs(args));
  231. end;
  232. function FpcBaseNestedProcVarType.invokeBooleanFunc(const args: array of jlobject): jboolean;
  233. begin
  234. result:=inherited invokeBooleanFunc(getNestedArgs(args));
  235. end;
  236. function FpcBaseNestedProcVarType.invokeCharFunc(const args: array of jlobject): jchar;
  237. begin
  238. result:=inherited invokeCharFunc(getNestedArgs(args));
  239. end;
  240. function FpcBaseNestedProcVarType.invokeByteFunc(const args: array of jlobject): jbyte;
  241. begin
  242. result:=inherited invokeByteFunc(getNestedArgs(args));
  243. end;
  244. function FpcBaseNestedProcVarType.invokeShortFunc(const args: array of jlobject): jshort;
  245. begin
  246. result:=inherited invokeShortFunc(getNestedArgs(args));
  247. end;
  248. function FpcBaseNestedProcVarType.invokeIntFunc(const args: array of jlobject): jint;
  249. begin
  250. result:=inherited invokeIntFunc(getNestedArgs(args));
  251. end;
  252. function FpcBaseNestedProcVarType.invokeLongFunc(const args: array of jlobject): jlong;
  253. begin
  254. result:=inherited invokeLongFunc(getNestedArgs(args));
  255. end;
  256. function FpcBaseNestedProcVarType.invokeSingleFunc(const args: array of jlobject): jfloat;
  257. begin
  258. result:=inherited invokeSingleFunc(getNestedArgs(args));
  259. end;
  260. function FpcBaseNestedProcVarType.invokeDoubleFunc(const args: array of jlobject): jdouble;
  261. begin
  262. result:=inherited invokeDoubleFunc(getNestedArgs(args));
  263. end;
  264. function FpcBaseNestedProcVarType.invokeObjectFunc(const args: array of jlobject): jlobject;
  265. begin
  266. result:=inherited invokeObjectFunc(getNestedArgs(args));
  267. end;