Runtime.hx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. /*
  2. * Copyright (C)2005-2017 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, java.lang.Object[] 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. public static function toBool(obj:java.lang.Boolean):Bool
  115. {
  116. return obj == null ? false : obj.booleanValue();
  117. }
  118. @:functionCode('
  119. return (obj == null) ? 0 : ((java.lang.Number) obj).intValue();
  120. ')
  121. public static function toInt(obj:Dynamic):Int
  122. {
  123. return 0;
  124. }
  125. public static function toLong(obj:Dynamic):haxe.Int64
  126. {
  127. return obj == null ? 0 : (obj : java.lang.Number).longValue();
  128. }
  129. @:functionCode('
  130. if (obj != null && obj instanceof java.lang.Number)
  131. {
  132. return true;
  133. } else {
  134. return false;
  135. }
  136. ')
  137. public static function isDouble(obj:Dynamic):Bool
  138. {
  139. return false;
  140. }
  141. @:overload public static function isInt(obj:Dynamic):Bool
  142. {
  143. if (Std.is(obj, java.lang.Number)) {
  144. var n:java.lang.Number = obj;
  145. return n.doubleValue() == n.intValue();
  146. } else {
  147. return false;
  148. }
  149. }
  150. @:overload public static function isInt(num:java.lang.Number):Bool {
  151. return num != null && num.doubleValue() == num.intValue();
  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 == null) return -1;
  191. if (v2 == null) return 1;
  192. if (v1 instanceof java.lang.Number || v2 instanceof java.lang.Number)
  193. {
  194. java.lang.Number v1c = (java.lang.Number) v1;
  195. java.lang.Number v2c = (java.lang.Number) v2;
  196. if (v1 instanceof java.lang.Long || v2 instanceof java.lang.Long)
  197. {
  198. long l1 = (v1 == null) ? 0L : v1c.longValue();
  199. long l2 = (v2 == null) ? 0L : v2c.longValue();
  200. return (l1 < l2) ? -1 : (l1 > l2) ? 1 : 0;
  201. } else {
  202. double d1 = (v1 == null) ? 0.0 : v1c.doubleValue();
  203. double d2 = (v2 == null) ? 0.0 : v2c.doubleValue();
  204. return (d1 < d2) ? -1 : (d1 > d2) ? 1 : 0;
  205. }
  206. }
  207. //if it\'s not a number it must be a String
  208. return ((java.lang.String) v1).compareTo((java.lang.String) v2);
  209. ')
  210. public static function compare(v1:Dynamic, v2:Dynamic):Int
  211. {
  212. return 0;
  213. }
  214. @:functionCode('
  215. if (v1 instanceof java.lang.String || v2 instanceof java.lang.String)
  216. return toString(v1) + toString(v2);
  217. if (v1 instanceof java.lang.Number || v2 instanceof java.lang.Number)
  218. {
  219. java.lang.Number v1c = (java.lang.Number) v1;
  220. java.lang.Number v2c = (java.lang.Number) v2;
  221. double d1 = (v1 == null) ? 0.0 : v1c.doubleValue();
  222. double d2 = (v2 == null) ? 0.0 : v2c.doubleValue();
  223. return d1 + d2;
  224. }
  225. throw new java.lang.IllegalArgumentException("Cannot dynamically add " + v1 + " and " + v2);
  226. ')
  227. public static function plus(v1:Dynamic, v2:Dynamic):Dynamic
  228. {
  229. return null;
  230. }
  231. @:functionCode('
  232. if (obj == null)
  233. if (throwErrors)
  234. throw new java.lang.NullPointerException("Cannot access field \'" + field + "\' of null.");
  235. else
  236. return null;
  237. java.lang.Class cl = null;
  238. try
  239. {
  240. if (obj instanceof java.lang.Class)
  241. {
  242. if (obj == java.lang.String.class && field.equals("fromCharCode"))
  243. return new haxe.lang.Closure(haxe.lang.StringExt.class, field);
  244. cl = (java.lang.Class) obj;
  245. obj = null;
  246. } else if (obj instanceof java.lang.String) {
  247. return haxe.lang.StringRefl.handleGetField((java.lang.String) obj, field, throwErrors);
  248. } else {
  249. cl = obj.getClass();
  250. }
  251. java.lang.reflect.Field f = cl.getField(field);
  252. f.setAccessible(true);
  253. return f.get(obj);
  254. } catch (Throwable t)
  255. {
  256. try
  257. {
  258. java.lang.reflect.Method[] ms = cl.getMethods();
  259. for (int i = 0; i < ms.length; i++)
  260. {
  261. if (ms[i].getName().equals(field))
  262. {
  263. return new haxe.lang.Closure(obj != null ? obj : cl, field);
  264. }
  265. }
  266. } catch (Throwable t2)
  267. {
  268. }
  269. if (throwErrors)
  270. throw HaxeException.wrap(t);
  271. return null;
  272. }
  273. ')
  274. public static function slowGetField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic
  275. {
  276. return null;
  277. }
  278. @:functionCode('
  279. java.lang.Class cl = null;
  280. if (obj instanceof java.lang.Class)
  281. {
  282. cl = (java.lang.Class) obj;
  283. obj = null;
  284. } else {
  285. cl = obj.getClass();
  286. }
  287. try {
  288. java.lang.reflect.Field f = cl.getField(field);
  289. f.setAccessible(true);
  290. //FIXME we must evaluate if field to be set receives either int or double
  291. if (isInt(value))
  292. {
  293. f.setInt(obj, toInt(value));
  294. } else if (isDouble(value)) {
  295. f.setDouble(obj, toDouble(value));
  296. } else {
  297. f.set(obj, value);
  298. }
  299. return value;
  300. }
  301. catch (Throwable t)
  302. {
  303. throw HaxeException.wrap(t);
  304. }
  305. ')
  306. public static function slowSetField(obj:Dynamic, field:String, value:Dynamic):Dynamic
  307. {
  308. return null;
  309. }
  310. @:functionCode('
  311. java.lang.Class cl = null;
  312. if (obj instanceof java.lang.Class)
  313. {
  314. if (obj == java.lang.String.class && field.equals("fromCharCode"))
  315. return haxe.lang.StringExt.fromCharCode(toInt(args[0]));
  316. cl = (java.lang.Class) obj;
  317. obj = null;
  318. } else if (obj instanceof java.lang.String) {
  319. return haxe.lang.StringRefl.handleCallField((java.lang.String) obj, field, args);
  320. } else {
  321. cl = obj.getClass();
  322. }
  323. if (args == null) args = new java.lang.Object[0];
  324. int len = args.length;
  325. java.lang.Class[] cls = new java.lang.Class[len];
  326. java.lang.Object[] objs = new java.lang.Object[len];
  327. java.lang.reflect.Method[] ms = cl.getMethods();
  328. int msl = ms.length;
  329. int realMsl = 0;
  330. for(int i =0; i < msl; i++)
  331. {
  332. if (!ms[i].getName().equals(field) || (!ms[i].isVarArgs() && ms[i].getParameterTypes().length != len))
  333. {
  334. ms[i] = null;
  335. } else {
  336. ms[realMsl] = ms[i];
  337. if (realMsl != i)
  338. ms[i] = null;
  339. realMsl++;
  340. }
  341. }
  342. boolean hasNumber = false;
  343. for (int i = 0; i < len; i++)
  344. {
  345. Object o = args[i];
  346. if (o == null)
  347. {
  348. continue; //can be anything
  349. }
  350. objs[i]= o;
  351. cls[i] = o.getClass();
  352. boolean isNum = false;
  353. if (o instanceof java.lang.Number)
  354. {
  355. cls[i] = java.lang.Number.class;
  356. isNum = hasNumber = true;
  357. } else if (o instanceof java.lang.Boolean) {
  358. cls[i] = java.lang.Boolean.class;
  359. isNum = true;
  360. }
  361. msl = realMsl;
  362. realMsl = 0;
  363. for (int j = 0; j < msl; j++)
  364. {
  365. java.lang.Class[] allcls = ms[j].getParameterTypes();
  366. if (i < allcls.length)
  367. {
  368. if (! ((isNum && allcls[i].isPrimitive()) || allcls[i].isAssignableFrom(cls[i])) )
  369. {
  370. ms[j] = null;
  371. } else {
  372. ms[realMsl] = ms[j];
  373. if (realMsl != j)
  374. ms[j] = null;
  375. realMsl++;
  376. }
  377. }
  378. }
  379. }
  380. java.lang.reflect.Method found;
  381. if (ms.length == 0 || (found = ms[0]) == null)
  382. throw haxe.lang.HaxeException.wrap("No compatible method found for: " + field);
  383. if (hasNumber)
  384. {
  385. java.lang.Class[] allcls = found.getParameterTypes();
  386. for (int i = 0; i < len; i++)
  387. {
  388. java.lang.Object o = objs[i];
  389. if (o instanceof java.lang.Number)
  390. {
  391. java.lang.Class curCls = null;
  392. if (i < allcls.length)
  393. {
  394. curCls = allcls[i];
  395. if (!curCls.isAssignableFrom(o.getClass()))
  396. {
  397. String name = curCls.getName();
  398. if (name.equals("double") || name.equals("java.lang.Double"))
  399. {
  400. objs[i] = ((java.lang.Number)o).doubleValue();
  401. } else if (name.equals("int") || name.equals("java.lang.Integer"))
  402. {
  403. objs[i] = ((java.lang.Number)o).intValue();
  404. } else if (name.equals("float") || name.equals("java.lang.Float"))
  405. {
  406. objs[i] = ((java.lang.Number)o).floatValue();
  407. } else if (name.equals("byte") || name.equals("java.lang.Byte"))
  408. {
  409. objs[i] = ((java.lang.Number)o).byteValue();
  410. } else if (name.equals("short") || name.equals("java.lang.Short"))
  411. {
  412. objs[i] = ((java.lang.Number)o).shortValue();
  413. } else if (name.equals("long") || name.equals("java.lang.Long"))
  414. {
  415. objs[i] = ((java.lang.Number)o).longValue();
  416. }
  417. }
  418. } //else varargs not handled TODO
  419. }
  420. }
  421. }
  422. try {
  423. found.setAccessible(true);
  424. return found.invoke(obj, objs);
  425. }
  426. catch (java.lang.reflect.InvocationTargetException e)
  427. {
  428. throw haxe.lang.HaxeException.wrap(e.getCause());
  429. }
  430. catch (Throwable t)
  431. {
  432. throw haxe.lang.HaxeException.wrap(t);
  433. }
  434. ')
  435. public static function slowCallField(obj:Dynamic, field:String, args:java.NativeArray<Dynamic>):Dynamic
  436. {
  437. return null;
  438. }
  439. @:functionCode('
  440. if (obj instanceof haxe.lang.IHxObject)
  441. {
  442. return ((haxe.lang.IHxObject) obj).__hx_invokeField(field, args);
  443. }
  444. return slowCallField(obj, field, args);
  445. ')
  446. public static function callField(obj:Dynamic, field:String, args:java.NativeArray<Dynamic>):Dynamic
  447. {
  448. return null;
  449. }
  450. @:functionCode('
  451. if (obj instanceof haxe.lang.IHxObject)
  452. return ((haxe.lang.IHxObject) obj).__hx_getField(field, throwErrors, false, false);
  453. return slowGetField(obj, field, throwErrors);
  454. ')
  455. public static function getField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic
  456. {
  457. return null;
  458. }
  459. @:functionCode('
  460. if (obj instanceof haxe.lang.IHxObject)
  461. return ((haxe.lang.IHxObject) obj).__hx_getField_f(field, throwErrors, false);
  462. return toDouble(slowGetField(obj, field, throwErrors));
  463. ')
  464. public static function getField_f(obj:Dynamic, field:String, throwErrors:Bool):Float
  465. {
  466. return 0.0;
  467. }
  468. @:functionCode('
  469. if (obj instanceof haxe.lang.IHxObject)
  470. return ((haxe.lang.IHxObject) obj).__hx_setField(field, value, false);
  471. return slowSetField(obj, field, value);
  472. ')
  473. public static function setField(obj:Dynamic, field:String, value:Dynamic):Dynamic
  474. {
  475. return null;
  476. }
  477. @:functionCode('
  478. if (obj instanceof haxe.lang.IHxObject)
  479. return ((haxe.lang.IHxObject) obj).__hx_setField_f(field, value, false);
  480. return toDouble(slowSetField(obj, field, value));
  481. ')
  482. public static function setField_f(obj:Dynamic, field:String, value:Float):Float
  483. {
  484. return 0.0;
  485. }
  486. public static function toString(obj:Dynamic):String
  487. {
  488. if (obj == null)
  489. return null;
  490. if (Std.is(obj, java.lang.Number) && !Std.is(obj, java.lang.Integer.IntegerClass) && isInt( (obj : java.lang.Number) ))
  491. return java.lang.Integer._toString(toInt(obj));
  492. return untyped obj.toString();
  493. }
  494. public static function isFinite(v:Float):Bool
  495. {
  496. return (v == v) && !java.lang.Double.DoubleClass._isInfinite(v);
  497. }
  498. public static function getIntFromNumber(n:java.lang.Number):Int {
  499. return n == null ? 0 : n.intValue();
  500. }
  501. public static function getFloatFromNumber(n:java.lang.Number):Float {
  502. return n == null ? 0.0 : n.doubleValue();
  503. }
  504. public static function getInt64FromNumber(n:java.lang.Number):java.StdTypes.Int64 {
  505. return n == null ? 0.0 : n.longValue();
  506. }
  507. public static function numToInteger(num:java.lang.Number):java.lang.Integer {
  508. return num == null ? null : (Std.is(num, java.lang.Integer.IntegerClass) ? cast num : java.lang.Integer.valueOf(num.intValue()));
  509. }
  510. public static function numToDouble(num:java.lang.Number):java.lang.Double {
  511. return num == null ? null : (Std.is(num, java.lang.Double.DoubleClass) ? cast num : java.lang.Double.valueOf(num.doubleValue()));
  512. }
  513. public static function numToFloat(num:java.lang.Number):java.lang.Float {
  514. return num == null ? null : (Std.is(num, java.lang.Float.FloatClass) ? cast num : java.lang.Float.valueOf(num.floatValue()));
  515. }
  516. public static function numToByte(num:java.lang.Number):java.lang.Byte {
  517. return num == null ? null : (Std.is(num, java.lang.Byte.ByteClass) ? cast num : java.lang.Byte.valueOf(num.byteValue()));
  518. }
  519. public static function numToLong(num:java.lang.Number):java.lang.Long {
  520. return num == null ? null : (Std.is(num, java.lang.Long.LongClass) ? cast num : java.lang.Long.valueOf(num.longValue()));
  521. }
  522. public static function numToShort(num:java.lang.Number):java.lang.Short {
  523. return num == null ? null : (Std.is(num, java.lang.Short.ShortClass) ? cast num : java.lang.Short.valueOf(num.shortValue()));
  524. }
  525. }
  526. @:keep @:native("haxe.lang.EmptyObject") enum EmptyObject
  527. {
  528. EMPTY;
  529. }