Runtime.hx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /*
  2. * Copyright (C)2005-2012 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. package java.internal;
  23. /**
  24. This class is meant for internal compiler use only. It provides the Haxe runtime
  25. compatibility to the host language. Do not access it directly.
  26. **/
  27. @:native('haxe.lang.Runtime')
  28. @:nativeGen
  29. @:classCode('
  30. public static java.lang.Object getField(haxe.lang.IHxObject obj, java.lang.String field, boolean throwErrors)
  31. {
  32. if (obj == null && !throwErrors) return null;
  33. return obj.__hx_getField(field, throwErrors, false, false);
  34. }
  35. public static double getField_f(haxe.lang.IHxObject obj, java.lang.String field, boolean throwErrors)
  36. {
  37. if (obj == null && !throwErrors) return 0.0;
  38. return obj.__hx_getField_f(field, throwErrors, false);
  39. }
  40. public static java.lang.Object setField(haxe.lang.IHxObject obj, java.lang.String field, java.lang.Object value)
  41. {
  42. return obj.__hx_setField(field, value, false);
  43. }
  44. public static double setField_f(haxe.lang.IHxObject obj, java.lang.String field, double value)
  45. {
  46. return obj.__hx_setField_f(field, value, false);
  47. }
  48. public static java.lang.Object callField(haxe.lang.IHxObject obj, java.lang.String field, Array<?> args)
  49. {
  50. return obj.__hx_invokeField(field, args);
  51. }
  52. ')
  53. @:keep class Runtime
  54. {
  55. public static var undefined:Dynamic = { };
  56. @:functionCode('
  57. return new haxe.lang.Closure(obj, field);
  58. ')
  59. public static function closure(obj:Dynamic, field:String):Dynamic
  60. {
  61. return null;
  62. }
  63. @:functionCode('
  64. if (v1 == v2)
  65. return true;
  66. if (v1 == null || v2 == null)
  67. return false;
  68. if (v1 instanceof java.lang.Number)
  69. {
  70. if (!(v2 instanceof java.lang.Number))
  71. return false;
  72. java.lang.Number v1c = (java.lang.Number) v1;
  73. java.lang.Number v2c = (java.lang.Number) v2;
  74. if (v1 instanceof java.lang.Long || v2 instanceof java.lang.Long)
  75. return v1c.longValue() == v2c.longValue();
  76. return v1c.doubleValue() == v2c.doubleValue();
  77. } else if (v1 instanceof java.lang.String || v1 instanceof haxe.lang.IEquatable) { //TODO see what happens with Boolean cases
  78. return v1.equals(v2);
  79. }
  80. return false;
  81. ')
  82. public static function eq(v1:Dynamic, v2:Dynamic):Bool
  83. {
  84. return false;
  85. }
  86. @:functionCode('
  87. if (v1 == v2)
  88. return true;
  89. if (v1 instanceof java.lang.String || v1 instanceof haxe.lang.IEquatable)
  90. {
  91. return v1 != null && v1.equals(v2);
  92. } else {
  93. return v1 == v2;
  94. }
  95. ')
  96. public static function refEq(v1: { }, v2: { } ):Bool
  97. {
  98. return false;
  99. }
  100. @:functionCode('
  101. return v1 == v2 || (v1 != null && v1.equals(v2));
  102. ')
  103. public static function valEq(v1: { }, v2: { } ):Bool
  104. {
  105. return false;
  106. }
  107. @:functionCode('
  108. return (obj == null) ? 0.0 : ((java.lang.Number) obj).doubleValue();
  109. ')
  110. public static function toDouble(obj:Dynamic):Float
  111. {
  112. return 0.0;
  113. }
  114. @:functionCode('
  115. return (obj == null) ? false : ((java.lang.Boolean) obj).booleanValue();
  116. ')
  117. public static function toBool(obj:Dynamic):Bool
  118. {
  119. return false;
  120. }
  121. @:functionCode('
  122. return (obj == null) ? 0 : ((java.lang.Number) obj).intValue();
  123. ')
  124. public static function toInt(obj:Dynamic):Int
  125. {
  126. return 0;
  127. }
  128. @:functionCode('
  129. if (obj != null && obj instanceof java.lang.Number)
  130. {
  131. return true;
  132. } else {
  133. return false;
  134. }
  135. ')
  136. public static function isDouble(obj:Dynamic):Bool
  137. {
  138. return false;
  139. }
  140. @:functionCode('
  141. if (obj != null && obj instanceof java.lang.Number)
  142. {
  143. java.lang.Number n = (java.lang.Number) obj;
  144. return n.doubleValue() == n.intValue();
  145. } else {
  146. return false;
  147. }
  148. ')
  149. public static function isInt(obj:Dynamic):Bool
  150. {
  151. return false;
  152. }
  153. @:functionCode('
  154. java.lang.Class cl = null;
  155. if (o instanceof java.lang.Class)
  156. {
  157. if (o == java.lang.String.class)
  158. return field.equals("fromCharCode");
  159. cl = (java.lang.Class) o;
  160. } else if (o instanceof java.lang.String) {
  161. return haxe.lang.StringRefl.handleGetField( (java.lang.String) o, field, false) != null;
  162. } else {
  163. cl = o.getClass();
  164. }
  165. try
  166. {
  167. java.lang.reflect.Field f = cl.getField(field);
  168. return true;
  169. }
  170. catch(Throwable t)
  171. {
  172. java.lang.reflect.Method[] ms = cl.getMethods();
  173. for (int i = 0; i < ms.length; i++)
  174. {
  175. if (ms[i].getName().equals(field))
  176. {
  177. return true;
  178. }
  179. }
  180. }
  181. return false;
  182. ')
  183. public static function slowHasField(o:Dynamic, field:String):Bool
  184. {
  185. return false;
  186. }
  187. @:functionCode('
  188. if (v1 == v2)
  189. return 0;
  190. if (v1 instanceof java.lang.Number || v2 instanceof java.lang.Number)
  191. {
  192. java.lang.Number v1c = (java.lang.Number) v1;
  193. java.lang.Number v2c = (java.lang.Number) v2;
  194. if (v1 instanceof java.lang.Long || v2 instanceof java.lang.Long)
  195. {
  196. long l1 = (v1 == null) ? 0L : v1c.longValue();
  197. long l2 = (v2 == null) ? 0L : v2c.longValue();
  198. return (int) (l1 - l2);
  199. } else {
  200. double d1 = (v1 == null) ? 0.0 : v1c.doubleValue();
  201. double d2 = (v2 == null) ? 0.0 : v2c.doubleValue();
  202. return (int) (d1 - d2);
  203. }
  204. }
  205. //if it\'s not a number it must be a String
  206. return ((java.lang.String) v1).compareTo((java.lang.String) v2);
  207. ')
  208. public static function compare(v1:Dynamic, v2:Dynamic):Int
  209. {
  210. return 0;
  211. }
  212. @:functionCode('
  213. if (v1 instanceof java.lang.String || v2 instanceof java.lang.String)
  214. return toString(v1) + toString(v2);
  215. if (v1 instanceof java.lang.Number || v2 instanceof java.lang.Number)
  216. {
  217. java.lang.Number v1c = (java.lang.Number) v1;
  218. java.lang.Number v2c = (java.lang.Number) v2;
  219. double d1 = (v1 == null) ? 0.0 : v1c.doubleValue();
  220. double d2 = (v2 == null) ? 0.0 : v2c.doubleValue();
  221. return d1 + d2;
  222. }
  223. throw new java.lang.IllegalArgumentException("Cannot dynamically add " + v1 + " and " + v2);
  224. ')
  225. public static function plus(v1:Dynamic, v2:Dynamic):Dynamic
  226. {
  227. return null;
  228. }
  229. @:functionCode('
  230. if (obj == null)
  231. if (throwErrors)
  232. throw new java.lang.NullPointerException("Cannot access field \'" + field + "\' of null.");
  233. else
  234. return null;
  235. java.lang.Class cl = null;
  236. try
  237. {
  238. if (obj instanceof java.lang.Class)
  239. {
  240. if (obj == java.lang.String.class && field.equals("fromCharCode"))
  241. return new haxe.lang.Closure(haxe.lang.StringExt.class, field);
  242. cl = (java.lang.Class) obj;
  243. obj = null;
  244. } else if (obj instanceof java.lang.String) {
  245. return haxe.lang.StringRefl.handleGetField((java.lang.String) obj, field, throwErrors);
  246. } else {
  247. cl = obj.getClass();
  248. }
  249. java.lang.reflect.Field f = cl.getField(field);
  250. f.setAccessible(true);
  251. return f.get(obj);
  252. } catch (Throwable t)
  253. {
  254. try
  255. {
  256. java.lang.reflect.Method[] ms = cl.getMethods();
  257. for (int i = 0; i < ms.length; i++)
  258. {
  259. if (ms[i].getName().equals(field))
  260. {
  261. return new haxe.lang.Closure(obj != null ? obj : cl, field);
  262. }
  263. }
  264. } catch (Throwable t2)
  265. {
  266. }
  267. if (throwErrors)
  268. throw HaxeException.wrap(t);
  269. return null;
  270. }
  271. ')
  272. public static function slowGetField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic
  273. {
  274. return null;
  275. }
  276. @:functionCode('
  277. java.lang.Class cl = null;
  278. if (obj instanceof java.lang.Class)
  279. {
  280. cl = (java.lang.Class) obj;
  281. obj = null;
  282. } else {
  283. cl = obj.getClass();
  284. }
  285. try {
  286. java.lang.reflect.Field f = cl.getField(field);
  287. f.setAccessible(true);
  288. //FIXME we must evaluate if field to be set receives either int or double
  289. if (isInt(value))
  290. {
  291. f.setInt(obj, toInt(value));
  292. } else if (isDouble(value)) {
  293. f.setDouble(obj, toDouble(value));
  294. } else {
  295. f.set(obj, value);
  296. }
  297. return value;
  298. }
  299. catch (Throwable t)
  300. {
  301. throw HaxeException.wrap(t);
  302. }
  303. ')
  304. public static function slowSetField(obj:Dynamic, field:String, value:Dynamic):Dynamic
  305. {
  306. return null;
  307. }
  308. @:functionCode('
  309. java.lang.Class cl = null;
  310. if (obj instanceof java.lang.Class)
  311. {
  312. if (obj == java.lang.String.class && field.equals("fromCharCode"))
  313. return haxe.lang.StringExt.fromCharCode(toInt(args.__get(0)));
  314. cl = (java.lang.Class) obj;
  315. obj = null;
  316. } else if (obj instanceof java.lang.String) {
  317. return haxe.lang.StringRefl.handleCallField((java.lang.String) obj, field, args);
  318. } else {
  319. cl = obj.getClass();
  320. }
  321. if (args == null) args = new Array();
  322. int len = args.length;
  323. java.lang.Class[] cls = new java.lang.Class[len];
  324. java.lang.Object[] objs = new java.lang.Object[len];
  325. java.lang.reflect.Method[] ms = cl.getDeclaredMethods();
  326. int msl = ms.length;
  327. int realMsl = 0;
  328. for(int i =0; i < msl; i++)
  329. {
  330. if (!ms[i].getName().equals(field) || (!ms[i].isVarArgs() && ms[i].getParameterTypes().length != len))
  331. {
  332. ms[i] = null;
  333. } else {
  334. ms[realMsl] = ms[i];
  335. if (realMsl != i)
  336. ms[i] = null;
  337. realMsl++;
  338. }
  339. }
  340. boolean hasNumber = false;
  341. for (int i = 0; i < len; i++)
  342. {
  343. Object o = args.__get(i);
  344. objs[i]= o;
  345. cls[i] = o.getClass();
  346. boolean isNum = false;
  347. if (o instanceof java.lang.Number)
  348. {
  349. cls[i] = java.lang.Number.class;
  350. isNum = hasNumber = true;
  351. }
  352. msl = realMsl;
  353. realMsl = 0;
  354. for (int j = 0; j < msl; j++)
  355. {
  356. java.lang.Class[] allcls = ms[j].getParameterTypes();
  357. if (i < allcls.length)
  358. {
  359. if (! ((isNum && allcls[i].isPrimitive()) || allcls[i].isAssignableFrom(cls[i])) )
  360. {
  361. ms[j] = null;
  362. } else {
  363. ms[realMsl] = ms[j];
  364. if (realMsl != j)
  365. ms[j] = null;
  366. realMsl++;
  367. }
  368. }
  369. }
  370. }
  371. java.lang.reflect.Method found;
  372. if (ms.length == 0 || (found = ms[0]) == null)
  373. throw haxe.lang.HaxeException.wrap("No compatible method found for: " + field);
  374. if (hasNumber)
  375. {
  376. java.lang.Class[] allcls = found.getParameterTypes();
  377. for (int i = 0; i < len; i++)
  378. {
  379. java.lang.Object o = objs[i];
  380. if (o instanceof java.lang.Number)
  381. {
  382. java.lang.Class curCls = null;
  383. if (i < allcls.length)
  384. {
  385. curCls = allcls[i];
  386. if (!curCls.isAssignableFrom(o.getClass()))
  387. {
  388. String name = curCls.getName();
  389. if (name.equals("double") || name.equals("java.lang.Double"))
  390. {
  391. objs[i] = ((java.lang.Number)o).doubleValue();
  392. } else if (name.equals("int") || name.equals("java.lang.Integer"))
  393. {
  394. objs[i] = ((java.lang.Number)o).intValue();
  395. } else if (name.equals("float") || name.equals("java.lang.Float"))
  396. {
  397. objs[i] = ((java.lang.Number)o).floatValue();
  398. } else if (name.equals("byte") || name.equals("java.lang.Byte"))
  399. {
  400. objs[i] = ((java.lang.Number)o).byteValue();
  401. } else if (name.equals("short") || name.equals("java.lang.Short"))
  402. {
  403. objs[i] = ((java.lang.Number)o).shortValue();
  404. }
  405. }
  406. } //else varargs not handled TODO
  407. }
  408. }
  409. }
  410. try {
  411. found.setAccessible(true);
  412. return found.invoke(obj, objs);
  413. }
  414. catch (java.lang.reflect.InvocationTargetException e)
  415. {
  416. throw haxe.lang.HaxeException.wrap(e.getCause());
  417. }
  418. catch (Throwable t)
  419. {
  420. throw haxe.lang.HaxeException.wrap(t);
  421. }
  422. ')
  423. public static function slowCallField(obj:Dynamic, field:String, args:Array<Dynamic>):Dynamic
  424. {
  425. return null;
  426. }
  427. @:functionCode('
  428. if (obj instanceof haxe.lang.IHxObject)
  429. {
  430. return ((haxe.lang.IHxObject) obj).__hx_invokeField(field, args);
  431. }
  432. return slowCallField(obj, field, args);
  433. ')
  434. public static function callField(obj:Dynamic, field:String, args:Array<Dynamic>):Dynamic
  435. {
  436. return null;
  437. }
  438. @:functionCode('
  439. if (obj instanceof haxe.lang.IHxObject)
  440. return ((haxe.lang.IHxObject) obj).__hx_getField(field, throwErrors, false, false);
  441. return slowGetField(obj, field, throwErrors);
  442. ')
  443. public static function getField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic
  444. {
  445. return null;
  446. }
  447. @:functionCode('
  448. if (obj instanceof haxe.lang.IHxObject)
  449. return ((haxe.lang.IHxObject) obj).__hx_getField_f(field, throwErrors, false);
  450. return toDouble(slowGetField(obj, field, throwErrors));
  451. ')
  452. public static function getField_f(obj:Dynamic, field:String, throwErrors:Bool):Float
  453. {
  454. return 0.0;
  455. }
  456. @:functionCode('
  457. if (obj instanceof haxe.lang.IHxObject)
  458. return ((haxe.lang.IHxObject) obj).__hx_setField(field, value, false);
  459. return slowSetField(obj, field, value);
  460. ')
  461. public static function setField(obj:Dynamic, field:String, value:Dynamic):Dynamic
  462. {
  463. return null;
  464. }
  465. @:functionCode('
  466. if (obj instanceof haxe.lang.IHxObject)
  467. return ((haxe.lang.IHxObject) obj).__hx_setField_f(field, value, false);
  468. return toDouble(slowSetField(obj, field, value));
  469. ')
  470. public static function setField_f(obj:Dynamic, field:String, value:Float):Float
  471. {
  472. return 0.0;
  473. }
  474. public static function toString(obj:Dynamic):String
  475. {
  476. if (obj == null)
  477. return null;
  478. if (isInt(obj))
  479. return (cast(obj, Int)) + "";
  480. return untyped obj.toString();
  481. }
  482. public static function isFinite(v:Float):Bool
  483. {
  484. return (v == v) && !java.lang.Double._isInfinite(v);
  485. }
  486. }
  487. @:keep @:native("haxe.lang.EmptyObject") private enum EmptyObject
  488. {
  489. EMPTY;
  490. }