jpvar.inc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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. begin
  65. result:=inherited;
  66. FpcBaseProcVarType(result).method:=method;
  67. end;
  68. procedure FpcBaseProcVarType.invokeProc(const args: array of jlobject);
  69. begin
  70. { caching the length would be faster, but that would have to be done
  71. in a synchronised way. Doing it at construction time and in fpcDeepCopy/
  72. clone is not enough, because the method field can be manipulated
  73. directly }
  74. if length(method.code.getParameterTypes)=length(args) then
  75. method.code.invoke(method.data,args)
  76. else
  77. method.code.invoke(method.data,getClassProcArgs(args));
  78. end;
  79. function FpcBaseProcVarType.invokeBooleanFunc(const args: array of jlobject): jboolean;
  80. begin
  81. if length(method.code.getParameterTypes)=length(args) then
  82. result:=JLBoolean(method.code.invoke(method.data,args)).booleanValue
  83. else
  84. result:=JLBoolean(method.code.invoke(method.data,getClassProcArgs(args))).booleanValue
  85. end;
  86. function FpcBaseProcVarType.invokeCharFunc(const args: array of jlobject): jchar;
  87. begin
  88. if length(method.code.getParameterTypes)=length(args) then
  89. result:=JLCharacter(method.code.invoke(method.data,args)).charValue
  90. else
  91. result:=JLCharacter(method.code.invoke(method.data,getClassProcArgs(args))).charValue;
  92. end;
  93. function FpcBaseProcVarType.invokeByteFunc(const args: array of jlobject): jbyte;
  94. begin
  95. if length(method.code.getParameterTypes)=length(args) then
  96. result:=JLByte(method.code.invoke(method.data,args)).byteValue
  97. else
  98. result:=JLByte(method.code.invoke(method.data,getClassProcArgs(args))).byteValue
  99. end;
  100. function FpcBaseProcVarType.invokeShortFunc(const args: array of jlobject): jshort;
  101. begin
  102. if length(method.code.getParameterTypes)=length(args) then
  103. result:=JLShort(method.code.invoke(method.data,args)).shortValue
  104. else
  105. result:=JLShort(method.code.invoke(method.data,getClassProcArgs(args))).shortValue
  106. end;
  107. function FpcBaseProcVarType.invokeIntFunc(const args: array of jlobject): jint;
  108. begin
  109. if length(method.code.getParameterTypes)=length(args) then
  110. result:=JLInteger(method.code.invoke(method.data,args)).intValue
  111. else
  112. result:=JLInteger(method.code.invoke(method.data,getClassProcArgs(args))).intValue
  113. end;
  114. function FpcBaseProcVarType.invokeLongFunc(const args: array of jlobject): jlong;
  115. begin
  116. if length(method.code.getParameterTypes)=length(args) then
  117. result:=JLLong(method.code.invoke(method.data,args)).longValue
  118. else
  119. result:=JLLong(method.code.invoke(method.data,getClassProcArgs(args))).longValue;
  120. end;
  121. function FpcBaseProcVarType.invokeSingleFunc(const args: array of jlobject): jfloat;
  122. begin
  123. if length(method.code.getParameterTypes)=length(args) then
  124. result:=JLFloat(method.code.invoke(method.data,args)).floatValue
  125. else
  126. result:=JLFloat(method.code.invoke(method.data,getClassProcArgs(args))).floatValue
  127. end;
  128. function FpcBaseProcVarType.invokeDoubleFunc(const args: array of jlobject): jdouble;
  129. begin
  130. if length(method.code.getParameterTypes)=length(args) then
  131. result:=JLDouble(method.code.invoke(method.data,args)).doubleValue
  132. else
  133. result:=JLDouble(method.code.invoke(method.data,getClassProcArgs(args))).doubleValue
  134. end;
  135. function FpcBaseProcVarType.invokeObjectFunc(const args: array of jlobject): jlobject;
  136. begin
  137. if length(method.code.getParameterTypes)=length(args) then
  138. result:=method.code.invoke(method.data,args)
  139. else
  140. result:=method.code.invoke(method.data,getClassProcArgs(args))
  141. end;
  142. function FpcBaseNestedProcVarType.getNestedArgs(const args: array of jlobject): TJLObjectDynArray;
  143. var
  144. arglen: longint;
  145. begin
  146. { add the parentfp struct pointer as last argument (delphi nested cc
  147. "calling convention") }
  148. arglen:=length(args);
  149. setlength(result,arglen+1);
  150. JLSystem.ArrayCopy(JLObject(@args),0,JLObject(result),0,arglen);
  151. result[arglen]:=nestedfpstruct;
  152. end;
  153. constructor FpcBaseNestedProcVarType.create(inst, context: jlobject; const methodName: unicodestring; const argTypes: array of JLClass);
  154. begin
  155. inherited create(inst,methodName,argTypes);
  156. nestedfpstruct:=context;
  157. end;
  158. procedure FpcBaseNestedProcVarType.fpcDeepCopy(result: FpcBaseProcVarType);
  159. begin
  160. inherited fpcDeepCopy(result);
  161. FpcBaseNestedProcVarType(result).nestedfpstruct:=nestedfpstruct;
  162. end;
  163. function FpcBaseNestedProcVarType.clone: JLObject;
  164. begin
  165. result:=inherited;
  166. FpcBaseNestedProcVarType(result).nestedfpstruct:=nestedfpstruct;
  167. end;
  168. procedure FpcBaseNestedProcVarType.invokeProc(const args: array of jlobject);
  169. begin
  170. inherited invokeProc(getNestedArgs(args));
  171. end;
  172. function FpcBaseNestedProcVarType.invokeBooleanFunc(const args: array of jlobject): jboolean;
  173. begin
  174. result:=inherited invokeBooleanFunc(getNestedArgs(args));
  175. end;
  176. function FpcBaseNestedProcVarType.invokeCharFunc(const args: array of jlobject): jchar;
  177. begin
  178. result:=inherited invokeCharFunc(getNestedArgs(args));
  179. end;
  180. function FpcBaseNestedProcVarType.invokeByteFunc(const args: array of jlobject): jbyte;
  181. begin
  182. result:=inherited invokeByteFunc(getNestedArgs(args));
  183. end;
  184. function FpcBaseNestedProcVarType.invokeShortFunc(const args: array of jlobject): jshort;
  185. begin
  186. result:=inherited invokeShortFunc(getNestedArgs(args));
  187. end;
  188. function FpcBaseNestedProcVarType.invokeIntFunc(const args: array of jlobject): jint;
  189. begin
  190. result:=inherited invokeIntFunc(getNestedArgs(args));
  191. end;
  192. function FpcBaseNestedProcVarType.invokeLongFunc(const args: array of jlobject): jlong;
  193. begin
  194. result:=inherited invokeLongFunc(getNestedArgs(args));
  195. end;
  196. function FpcBaseNestedProcVarType.invokeSingleFunc(const args: array of jlobject): jfloat;
  197. begin
  198. result:=inherited invokeSingleFunc(getNestedArgs(args));
  199. end;
  200. function FpcBaseNestedProcVarType.invokeDoubleFunc(const args: array of jlobject): jdouble;
  201. begin
  202. result:=inherited invokeDoubleFunc(getNestedArgs(args));
  203. end;
  204. function FpcBaseNestedProcVarType.invokeObjectFunc(const args: array of jlobject): jlobject;
  205. begin
  206. result:=inherited invokeObjectFunc(getNestedArgs(args));
  207. end;