jpvar.inc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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. if length(method.code.getParameterTypes)=length(args) then
  85. method.code.invoke(method.data,args)
  86. else
  87. method.code.invoke(method.data,getClassProcArgs(args));
  88. end;
  89. function FpcBaseProcVarType.invokeBooleanFunc(const args: array of jlobject): jboolean;
  90. begin
  91. if length(method.code.getParameterTypes)=length(args) then
  92. result:=JLBoolean(method.code.invoke(method.data,args)).booleanValue
  93. else
  94. result:=JLBoolean(method.code.invoke(method.data,getClassProcArgs(args))).booleanValue
  95. end;
  96. function FpcBaseProcVarType.invokeCharFunc(const args: array of jlobject): jchar;
  97. begin
  98. if length(method.code.getParameterTypes)=length(args) then
  99. result:=JLCharacter(method.code.invoke(method.data,args)).charValue
  100. else
  101. result:=JLCharacter(method.code.invoke(method.data,getClassProcArgs(args))).charValue;
  102. end;
  103. function FpcBaseProcVarType.invokeByteFunc(const args: array of jlobject): jbyte;
  104. begin
  105. if length(method.code.getParameterTypes)=length(args) then
  106. result:=JLByte(method.code.invoke(method.data,args)).byteValue
  107. else
  108. result:=JLByte(method.code.invoke(method.data,getClassProcArgs(args))).byteValue
  109. end;
  110. function FpcBaseProcVarType.invokeShortFunc(const args: array of jlobject): jshort;
  111. begin
  112. if length(method.code.getParameterTypes)=length(args) then
  113. result:=JLShort(method.code.invoke(method.data,args)).shortValue
  114. else
  115. result:=JLShort(method.code.invoke(method.data,getClassProcArgs(args))).shortValue
  116. end;
  117. function FpcBaseProcVarType.invokeIntFunc(const args: array of jlobject): jint;
  118. begin
  119. if length(method.code.getParameterTypes)=length(args) then
  120. result:=JLInteger(method.code.invoke(method.data,args)).intValue
  121. else
  122. result:=JLInteger(method.code.invoke(method.data,getClassProcArgs(args))).intValue
  123. end;
  124. function FpcBaseProcVarType.invokeLongFunc(const args: array of jlobject): jlong;
  125. begin
  126. if length(method.code.getParameterTypes)=length(args) then
  127. result:=JLLong(method.code.invoke(method.data,args)).longValue
  128. else
  129. result:=JLLong(method.code.invoke(method.data,getClassProcArgs(args))).longValue;
  130. end;
  131. function FpcBaseProcVarType.invokeSingleFunc(const args: array of jlobject): jfloat;
  132. begin
  133. if length(method.code.getParameterTypes)=length(args) then
  134. result:=JLFloat(method.code.invoke(method.data,args)).floatValue
  135. else
  136. result:=JLFloat(method.code.invoke(method.data,getClassProcArgs(args))).floatValue
  137. end;
  138. function FpcBaseProcVarType.invokeDoubleFunc(const args: array of jlobject): jdouble;
  139. begin
  140. if length(method.code.getParameterTypes)=length(args) then
  141. result:=JLDouble(method.code.invoke(method.data,args)).doubleValue
  142. else
  143. result:=JLDouble(method.code.invoke(method.data,getClassProcArgs(args))).doubleValue
  144. end;
  145. function FpcBaseProcVarType.invokeObjectFunc(const args: array of jlobject): jlobject;
  146. begin
  147. if length(method.code.getParameterTypes)=length(args) then
  148. result:=method.code.invoke(method.data,args)
  149. else
  150. result:=method.code.invoke(method.data,getClassProcArgs(args))
  151. end;
  152. function FpcBaseNestedProcVarType.getNestedArgs(const args: array of jlobject): TJLObjectDynArray;
  153. var
  154. arglen: longint;
  155. begin
  156. { add the parentfp struct pointer as last argument (delphi nested cc
  157. "calling convention") }
  158. arglen:=length(args);
  159. setlength(result,arglen+1);
  160. JLSystem.ArrayCopy(JLObject(@args),0,JLObject(result),0,arglen);
  161. result[arglen]:=nestedfpstruct;
  162. end;
  163. constructor FpcBaseNestedProcVarType.create(inst, context: jlobject; const methodName: unicodestring; const argTypes: array of JLClass);
  164. begin
  165. inherited create(inst,methodName,argTypes);
  166. nestedfpstruct:=context;
  167. end;
  168. procedure FpcBaseNestedProcVarType.fpcDeepCopy(result: FpcBaseProcVarType);
  169. begin
  170. inherited fpcDeepCopy(result);
  171. FpcBaseNestedProcVarType(result).nestedfpstruct:=nestedfpstruct;
  172. end;
  173. function FpcBaseNestedProcVarType.clone: JLObject;
  174. begin
  175. result:=inherited;
  176. FpcBaseNestedProcVarType(result).nestedfpstruct:=nestedfpstruct;
  177. end;
  178. procedure FpcBaseNestedProcVarType.invokeProc(const args: array of jlobject);
  179. begin
  180. inherited invokeProc(getNestedArgs(args));
  181. end;
  182. function FpcBaseNestedProcVarType.invokeBooleanFunc(const args: array of jlobject): jboolean;
  183. begin
  184. result:=inherited invokeBooleanFunc(getNestedArgs(args));
  185. end;
  186. function FpcBaseNestedProcVarType.invokeCharFunc(const args: array of jlobject): jchar;
  187. begin
  188. result:=inherited invokeCharFunc(getNestedArgs(args));
  189. end;
  190. function FpcBaseNestedProcVarType.invokeByteFunc(const args: array of jlobject): jbyte;
  191. begin
  192. result:=inherited invokeByteFunc(getNestedArgs(args));
  193. end;
  194. function FpcBaseNestedProcVarType.invokeShortFunc(const args: array of jlobject): jshort;
  195. begin
  196. result:=inherited invokeShortFunc(getNestedArgs(args));
  197. end;
  198. function FpcBaseNestedProcVarType.invokeIntFunc(const args: array of jlobject): jint;
  199. begin
  200. result:=inherited invokeIntFunc(getNestedArgs(args));
  201. end;
  202. function FpcBaseNestedProcVarType.invokeLongFunc(const args: array of jlobject): jlong;
  203. begin
  204. result:=inherited invokeLongFunc(getNestedArgs(args));
  205. end;
  206. function FpcBaseNestedProcVarType.invokeSingleFunc(const args: array of jlobject): jfloat;
  207. begin
  208. result:=inherited invokeSingleFunc(getNestedArgs(args));
  209. end;
  210. function FpcBaseNestedProcVarType.invokeDoubleFunc(const args: array of jlobject): jdouble;
  211. begin
  212. result:=inherited invokeDoubleFunc(getNestedArgs(args));
  213. end;
  214. function FpcBaseNestedProcVarType.invokeObjectFunc(const args: array of jlobject): jlobject;
  215. begin
  216. result:=inherited invokeObjectFunc(getNestedArgs(args));
  217. end;