Runtime.hx 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  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 cs.internal;
  23. import cs.Lib;
  24. import cs.Lib.*;
  25. import cs.NativeArray;
  26. import cs.NativeArray;
  27. import cs.system.Activator;
  28. import cs.system.IConvertible;
  29. import cs.system.IComparable;
  30. import cs.system.reflection.MethodBase;
  31. import cs.system.reflection.MethodInfo;
  32. import cs.system.Type;
  33. import cs.system.Object;
  34. /**
  35. This class is meant for internal compiler use only. It provides the Haxe runtime
  36. compatibility to the host language.
  37. **/
  38. @:nativeGen
  39. @:native('haxe.lang.Runtime')
  40. @:access(String)
  41. @:classCode('
  42. public static object getField(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
  43. {
  44. if (obj == null && !throwErrors) return null;
  45. return obj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false, false);
  46. }
  47. public static double getField_f(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
  48. {
  49. if (obj == null && !throwErrors) return 0.0;
  50. return obj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
  51. }
  52. public static object setField(haxe.lang.HxObject obj, string field, int fieldHash, object value)
  53. {
  54. return obj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
  55. }
  56. public static double setField_f(haxe.lang.HxObject obj, string field, int fieldHash, double value)
  57. {
  58. return obj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
  59. }
  60. public static object callField(haxe.lang.HxObject obj, string field, int fieldHash, Array args)
  61. {
  62. return obj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, args);
  63. }
  64. ')
  65. @:keep class Runtime
  66. {
  67. public static var undefined(default, never):Dynamic = { };
  68. @:functionCode('
  69. return new haxe.lang.Closure(obj, field, hash);
  70. ')
  71. public static function closure(obj:Dynamic, hash:Int, field:String):Dynamic
  72. {
  73. return null;
  74. }
  75. public static function eq(v1:Dynamic, v2:Dynamic):Bool
  76. {
  77. if (Object.ReferenceEquals(v1, v2))
  78. return true;
  79. if (Object.ReferenceEquals(v1,null) || Object.ReferenceEquals(v2,null))
  80. return false;
  81. var v1c = Lib.as(v1, IConvertible);
  82. if (v1c != null)
  83. {
  84. var v2c = Lib.as(v2, IConvertible);
  85. if (v2c == null)
  86. {
  87. return false;
  88. }
  89. var t1 = v1c.GetTypeCode(),
  90. t2 = v2c.GetTypeCode();
  91. if (t1 == t2)
  92. return Object._Equals(v1c,v2c);
  93. if (t1 == cs.system.TypeCode.String || t2 == cs.system.TypeCode.String)
  94. return false;
  95. switch(t1)
  96. {
  97. case Decimal:
  98. return v1c.ToDecimal(null) == v2c.ToDecimal(null);
  99. case UInt64 | Int64:
  100. if (t2 == Decimal)
  101. return v1c.ToDecimal(null) == v2c.ToDecimal(null);
  102. else
  103. return v1c.ToUInt64(null) == v2c.ToUInt64(null);
  104. default:
  105. switch(t2)
  106. {
  107. case Decimal:
  108. return v1c.ToDecimal(null) == v2c.ToDecimal(null);
  109. case UInt64 | Int64:
  110. if (t2 == Decimal)
  111. return v1c.ToDecimal(null) == v2c.ToDecimal(null);
  112. else
  113. return v1c.ToUInt64(null) == v2c.ToUInt64(null);
  114. default:
  115. return v1c.ToDouble(null) == v2c.ToDouble(null);
  116. }
  117. }
  118. }
  119. var v1v = Lib.as(v1, cs.system.ValueType);
  120. if (v1v != null)
  121. {
  122. return v1.Equals(v2);
  123. } else {
  124. var v1t = Lib.as(v1, Type);
  125. if (v1t != null)
  126. {
  127. var v2t = Lib.as(v2, Type);
  128. if (v2t != null)
  129. return typeEq(v1t, v2t);
  130. return false;
  131. }
  132. }
  133. return false;
  134. }
  135. public static function refEq(v1: { }, v2: { } ):Bool
  136. {
  137. if (Std.is(v1, Type))
  138. return typeEq(Lib.as(v1,Type), Lib.as(v2,Type));
  139. return Object.ReferenceEquals(v1,v2);
  140. }
  141. public static function toDouble(obj:Dynamic):Float
  142. {
  143. return (obj == null) ? .0 : Std.is(obj,Float) ? cast obj : Lib.as(obj,IConvertible).ToDouble(null);
  144. }
  145. public static function toInt(obj:Dynamic):Int
  146. {
  147. return (obj == null) ? 0 : Std.is(obj,Int) ? cast obj : Lib.as(obj,IConvertible).ToInt32(null);
  148. }
  149. public static function isInt(obj:Dynamic):Bool
  150. {
  151. var cv1 = Lib.as(obj, IConvertible);
  152. if (cv1 != null)
  153. {
  154. switch (cv1.GetTypeCode())
  155. {
  156. case Double:
  157. var d:Float = cast obj;
  158. return d >= cs.system.Int32.MinValue && d <= cs.system.Int32.MaxValue && d == ( cast(d,Int) );
  159. case UInt32, Int32:
  160. return true;
  161. default:
  162. return false;
  163. }
  164. }
  165. return false;
  166. }
  167. public static function isUInt(obj:Dynamic):Bool
  168. {
  169. var cv1 = Lib.as(obj, IConvertible);
  170. if (cv1 != null)
  171. {
  172. switch (cv1.GetTypeCode())
  173. {
  174. case Double:
  175. var d:Float = cast obj;
  176. return d >= cs.system.UInt32.MinValue && d <= cs.system.UInt32.MaxValue && d == ( cast(d,UInt) );
  177. case UInt32:
  178. return true;
  179. default:
  180. return false;
  181. }
  182. }
  183. return false;
  184. }
  185. public static function compare(v1:Dynamic, v2:Dynamic):Int
  186. {
  187. if (Object.ReferenceEquals(v1,v2)) return 0;
  188. if (Object.ReferenceEquals(v1,null)) return -1;
  189. if (Object.ReferenceEquals(v2,null)) return 1;
  190. var cv1 = Lib.as(v1, IConvertible);
  191. if (cv1 != null)
  192. {
  193. var cv2 = Lib.as(v2, IConvertible);
  194. if (cv2 == null)
  195. {
  196. throw new cs.system.ArgumentException("Cannot compare " + nativeType(v1).ToString() + " and " + nativeType(v2).ToString());
  197. }
  198. switch(cv1.GetTypeCode())
  199. {
  200. case cs.system.TypeCode.String:
  201. if (cv2.GetTypeCode() != cs.system.TypeCode.String)
  202. throw new cs.system.ArgumentException("Cannot compare " + nativeType(v1).ToString() + " and " + nativeType(v2).ToString());
  203. var s1 = Lib.as(v1,String);
  204. var s2 = Lib.as(v2,String);
  205. return String.Compare(s1,s2, cs.system.StringComparison.Ordinal);
  206. case cs.system.TypeCode.Double:
  207. var d1:Float = cast v1,
  208. d2:Float = cv2.ToDouble(null);
  209. return (d1 < d2) ? -1 : (d1 > d2) ? 1 : 0;
  210. default:
  211. var d1d = cv1.ToDouble(null);
  212. var d2d = cv2.ToDouble(null);
  213. return (d1d < d2d) ? -1 : (d1d > d2d) ? 1 : 0;
  214. }
  215. }
  216. var c1 = Lib.as(v1, IComparable);
  217. var c2 = Lib.as(v2, IComparable);
  218. if (c1 == null || c2 == null)
  219. {
  220. throw new cs.system.ArgumentException("Cannot compare " + nativeType(v1).ToString() + " and " + nativeType(v2).ToString());
  221. }
  222. return c1.CompareTo(c2);
  223. }
  224. public static function plus(v1:Dynamic, v2:Dynamic):Dynamic
  225. {
  226. if (Std.is(v1,String) || Std.is(v2,String))
  227. return Std.string(v1) + Std.string(v2);
  228. var cv1 = Lib.as(v1, IConvertible);
  229. if (cv1 != null)
  230. {
  231. var cv2 = Lib.as(v2, IConvertible);
  232. if (cv2 == null)
  233. {
  234. throw new cs.system.ArgumentException("Cannot dynamically add " + cs.Lib.nativeType(v1).ToString() + " and " + cs.Lib.nativeType(v2).ToString());
  235. }
  236. return cv1.ToDouble(null) + cv2.ToDouble(null);
  237. }
  238. throw new cs.system.ArgumentException("Cannot dynamically add " + v1 + " and " + v2);
  239. }
  240. @:functionCode('
  241. if (obj == null)
  242. if (throwErrors)
  243. throw new System.NullReferenceException("Cannot access field \'" + field + "\' of null.");
  244. else
  245. return null;
  246. System.Type t = obj as System.Type;
  247. System.Reflection.BindingFlags bf;
  248. if (t == null)
  249. {
  250. string s = obj as string;
  251. if (s != null)
  252. return haxe.lang.StringRefl.handleGetField(s, field, throwErrors);
  253. t = obj.GetType();
  254. bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
  255. } else {
  256. if (t == typeof(string) && field.Equals("fromCharCode"))
  257. return new haxe.lang.Closure(typeof(haxe.lang.StringExt), field, 0);
  258. obj = null;
  259. bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
  260. }
  261. System.Reflection.FieldInfo f = t.GetField(field, bf);
  262. if (f != null)
  263. {
  264. return haxe.lang.Runtime.unbox(f.GetValue(obj));
  265. } else {
  266. System.Reflection.PropertyInfo prop = t.GetProperty(field, bf);
  267. if (prop == null)
  268. {
  269. System.Reflection.MemberInfo[] m = t.GetMember(field, bf);
  270. if (m.Length == 0 && (field == "__get" || field == "__set"))
  271. m = t.GetMember(field == "__get" ? "get_Item" : "set_Item", bf);
  272. if (m.Length > 0)
  273. {
  274. return new haxe.lang.Closure(obj != null ? obj : t, field, 0);
  275. } else {
  276. // COM object handling
  277. if (t.IsCOMObject)
  278. {
  279. try
  280. {
  281. return t.InvokeMember(field, System.Reflection.BindingFlags.GetProperty, null, obj, new object[0]);
  282. }
  283. catch (System.Exception e)
  284. {
  285. //Closures of COM objects not supported currently
  286. }
  287. }
  288. if (throwErrors)
  289. throw HaxeException.wrap("Cannot access field \'" + field + "\'.");
  290. else
  291. return null;
  292. }
  293. }
  294. return haxe.lang.Runtime.unbox(prop.GetValue(obj, null));
  295. }
  296. ')
  297. public static function slowGetField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic
  298. {
  299. return null;
  300. }
  301. @:functionCode('
  302. if (obj == null) return false;
  303. System.Type t = obj as System.Type;
  304. System.Reflection.BindingFlags bf;
  305. if (t == null)
  306. {
  307. string s = obj as string;
  308. if (s != null)
  309. return haxe.lang.StringRefl.handleGetField(s, field, false) != null;
  310. t = obj.GetType();
  311. bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
  312. } else {
  313. if (t == typeof(string))
  314. return field.Equals("fromCharCode");
  315. obj = null;
  316. bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
  317. }
  318. System.Reflection.MemberInfo[] mi = t.GetMember(field, bf);
  319. return mi != null && mi.Length > 0;
  320. ')
  321. public static function slowHasField(obj:Dynamic, field:String):Bool
  322. {
  323. return false;
  324. }
  325. @:functionCode('
  326. if (obj == null)
  327. throw new System.NullReferenceException("Cannot access field \'" + field + "\' of null.");
  328. System.Type t = obj as System.Type;
  329. System.Reflection.BindingFlags bf;
  330. if (t == null)
  331. {
  332. t = obj.GetType();
  333. bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
  334. } else {
  335. obj = null;
  336. bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
  337. }
  338. System.Reflection.FieldInfo f = t.GetField(field, bf);
  339. if (f != null)
  340. {
  341. if (f.FieldType.ToString().StartsWith("haxe.lang.Null"))
  342. {
  343. @value = haxe.lang.Runtime.mkNullable(@value, f.FieldType);
  344. }
  345. f.SetValue(obj, @value);
  346. return @value;
  347. } else {
  348. System.Reflection.PropertyInfo prop = t.GetProperty(field, bf);
  349. if (prop == null)
  350. {
  351. // COM object handling
  352. if (t.IsCOMObject)
  353. {
  354. try
  355. {
  356. return t.InvokeMember(field, System.Reflection.BindingFlags.SetProperty, null, obj, new object[] { value });
  357. }
  358. catch (System.Exception e)
  359. {
  360. //Closures of COM objects not supported currently
  361. }
  362. }
  363. throw haxe.lang.HaxeException.wrap("Field \'" + field + "\' not found for writing from Class " + t);
  364. }
  365. if (prop.PropertyType.ToString().StartsWith("haxe.lang.Null"))
  366. {
  367. @value = haxe.lang.Runtime.mkNullable(@value, prop.PropertyType);
  368. }
  369. prop.SetValue(obj, @value, null);
  370. return @value;
  371. }
  372. ')
  373. public static function slowSetField(obj:Dynamic, field:String, value:Dynamic):Dynamic
  374. {
  375. //not implemented yet;
  376. throw "Not implemented";
  377. }
  378. public static function callMethod(obj:Dynamic, methods:NativeArray<MethodBase>, methodLength:Int, args:Array<Dynamic>):Dynamic
  379. {
  380. if (methodLength == 0) throw "No available methods";
  381. var length = args.length;
  382. var oargs:NativeArray<Dynamic> = new NativeArray(length);
  383. var ts:NativeArray<Type> = new NativeArray(length);
  384. var rates:NativeArray<Int> = new NativeArray(methods.Length);
  385. for (i in 0...length)
  386. {
  387. oargs[i] = args[i];
  388. if (args[i] != null)
  389. ts[i] = Lib.nativeType(args[i]);
  390. }
  391. var last = 0;
  392. //first filter by number of parameters and if it is assignable
  393. if (methodLength > 1)
  394. {
  395. for (i in 0...methodLength)
  396. {
  397. var params = methods[i].GetParameters();
  398. if (params.Length != length) {
  399. continue;
  400. } else {
  401. var fits = true, crate = 0;
  402. for (i in 0...params.Length)
  403. {
  404. var param = params[i].ParameterType;
  405. var strParam = param + "";
  406. if (param.IsAssignableFrom(ts[i]) || (ts[i] == null && !param.IsValueType))
  407. {
  408. //if it is directly assignable, we'll give it top rate
  409. continue;
  410. } else if (untyped strParam.StartsWith("haxe.lang.Null") || ( (oargs[i] == null || Std.is(oargs[i], IConvertible) ) && cast(untyped __typeof__(IConvertible), Type).IsAssignableFrom(param) ))
  411. {
  412. //if it needs conversion, give a penalty. TODO rate penalty
  413. crate++;
  414. continue;
  415. } else if (!param.ContainsGenericParameters) { //generics don't appear as assignable, but may be in the end. no rate there.
  416. fits = false;
  417. break;
  418. }
  419. }
  420. if (fits)
  421. {
  422. rates[last] = crate;
  423. methods[last++] = methods[i];
  424. }
  425. }
  426. }
  427. methodLength = last;
  428. } else if (methodLength == 1 && methods[0].GetParameters().Length != length) {
  429. methodLength = 0;
  430. }
  431. //At this time, we should be left with only one method.
  432. //Of course, realistically, we can be left with plenty of methods, if there are lots of variants with IConvertible
  433. //But at this time we still aren't rating the best methods
  434. //FIXME rate best methods
  435. if (methodLength == 0)
  436. throw "Invalid calling parameters for method " + methods[0].Name;
  437. var best = Math.POSITIVE_INFINITY;
  438. var bestMethod = 0;
  439. for(i in 0...methodLength)
  440. {
  441. if (rates[i] < best)
  442. {
  443. bestMethod = i;
  444. best = rates[i];
  445. }
  446. }
  447. methods[0] = methods[bestMethod];
  448. var params = methods[0].GetParameters();
  449. for (i in 0...params.Length)
  450. {
  451. var param = params[i].ParameterType;
  452. var strParam = param + "",
  453. arg = oargs[i];
  454. if (StringTools.startsWith(strParam, "haxe.lang.Null"))
  455. {
  456. oargs[i] = mkNullable(arg, param);
  457. } else if (cast(untyped __typeof__(IConvertible), Type).IsAssignableFrom(param)) {
  458. if (arg == null) {
  459. if (param.IsValueType)
  460. oargs[i] = Activator.CreateInstance(param);
  461. } else if (!cs.Lib.nativeType(arg).IsAssignableFrom(param)) {
  462. oargs[i] = cast(arg, IConvertible).ToType(param, null);
  463. }
  464. }
  465. }
  466. if (methods[0].ContainsGenericParameters && Std.is(methods[0], cs.system.reflection.MethodInfo))
  467. {
  468. var m:MethodInfo = cast methods[0];
  469. var tgs = m.GetGenericArguments();
  470. for (i in 0...tgs.Length)
  471. {
  472. tgs[i] = untyped __typeof__(Dynamic);
  473. }
  474. m = m.MakeGenericMethod(tgs);
  475. var retg = m.Invoke(obj, oargs);
  476. return cs.internal.Runtime.unbox(retg);
  477. }
  478. var m = methods[0];
  479. if (obj == null && Std.is(m, cs.system.reflection.ConstructorInfo))
  480. {
  481. var ret = cast(m, cs.system.reflection.ConstructorInfo).Invoke(oargs);
  482. return unbox(ret);
  483. }
  484. var ret = m.Invoke(obj, oargs);
  485. return unbox(ret);
  486. }
  487. public static function unbox(dyn:Dynamic):Dynamic
  488. {
  489. if (dyn != null && untyped (Lib.nativeType(dyn) + "").StartsWith("haxe.lang.Null"))
  490. {
  491. return dyn.toDynamic();
  492. } else {
  493. return dyn;
  494. }
  495. }
  496. @:functionCode('
  497. if (nullableType.ContainsGenericParameters)
  498. return haxe.lang.Null<object>.ofDynamic<object>(obj);
  499. return nullableType.GetMethod("_ofDynamic").Invoke(null, new object[] { obj });
  500. ')
  501. public static function mkNullable(obj:Dynamic, nullableType:Type):Dynamic
  502. {
  503. return null;
  504. }
  505. @:functionCode('
  506. if (field == "toString")
  507. {
  508. if (args == null)
  509. return obj.ToString();
  510. field = "ToString";
  511. }
  512. if (args == null) args = new Array<object>();
  513. System.Reflection.BindingFlags bf;
  514. System.Type t = obj as System.Type;
  515. if (t == null)
  516. {
  517. string s = obj as string;
  518. if (s != null)
  519. return haxe.lang.StringRefl.handleCallField(s, field, args);
  520. t = obj.GetType();
  521. bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
  522. } else {
  523. if (t == typeof(string) && field.Equals("fromCharCode"))
  524. return haxe.lang.StringExt.fromCharCode(toInt(args[0]));
  525. obj = null;
  526. bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
  527. }
  528. System.Reflection.MethodInfo[] mis = t.GetMethods(bf);
  529. int last = 0;
  530. for (int i = 0; i < mis.Length; i++)
  531. {
  532. string name = mis[i].Name;
  533. if (name.Equals(field))
  534. {
  535. mis[last++] = mis[i];
  536. }
  537. }
  538. if (last == 0 && (field == "__get" || field == "__set"))
  539. {
  540. field = field == "__get" ? "get_Item" : "set_Item";
  541. for (int i = 0; i < mis.Length; i++)
  542. {
  543. string name = mis[i].Name;
  544. if (name.Equals(field))
  545. {
  546. mis[last++] = mis[i];
  547. }
  548. }
  549. }
  550. if (last == 0 && t.IsCOMObject)
  551. {
  552. object[] oargs = new object[arrLen(args)];
  553. for (int i = 0; i < oargs.Length; i++)
  554. {
  555. oargs[i] = args[i];
  556. }
  557. return t.InvokeMember(field, System.Reflection.BindingFlags.InvokeMethod, null, obj, oargs);
  558. }
  559. if (last == 0)
  560. {
  561. throw haxe.lang.HaxeException.wrap("Method \'" + field + "\' not found on type " + t);
  562. }
  563. return haxe.lang.Runtime.callMethod(obj, mis, last, args);
  564. ')
  565. public static function slowCallField(obj:Dynamic, field:String, args:Array<Dynamic>):Dynamic
  566. {
  567. throw "not implemented";
  568. }
  569. @:private static function arrLen(arr:Array<Dynamic>):Int
  570. {
  571. return arr.length;
  572. }
  573. @:functionCode('
  574. haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
  575. if (hxObj != null)
  576. return hxObj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, args);
  577. return slowCallField(obj, field, args);
  578. ')
  579. public static function callField(obj:Dynamic, field:String, fieldHash:Int, args:Array<Dynamic>):Dynamic
  580. {
  581. return null;
  582. }
  583. @:functionCode('
  584. haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
  585. if (hxObj != null)
  586. return hxObj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false, false);
  587. return slowGetField(obj, field, throwErrors);
  588. ')
  589. public static function getField(obj:Dynamic, field:String, fieldHash:Int, throwErrors:Bool):Dynamic
  590. {
  591. return null;
  592. }
  593. @:functionCode('
  594. haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
  595. if (hxObj != null)
  596. return hxObj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
  597. return toDouble(slowGetField(obj, field, throwErrors));
  598. ')
  599. public static function getField_f(obj:Dynamic, field:String, fieldHash:Int, throwErrors:Bool):Float
  600. {
  601. return 0.0;
  602. }
  603. @:functionCode('
  604. haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
  605. if (hxObj != null)
  606. return hxObj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
  607. return slowSetField(obj, field, value);
  608. ')
  609. public static function setField(obj:Dynamic, field:String, fieldHash:Int, value:Dynamic):Dynamic
  610. {
  611. return null;
  612. }
  613. @:functionCode('
  614. haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
  615. if (hxObj != null)
  616. return hxObj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
  617. return toDouble(slowSetField(obj, field, value));
  618. ')
  619. public static function setField_f(obj:Dynamic, field:String, fieldHash:Int, value:Float):Float
  620. {
  621. return 0.0;
  622. }
  623. public static function toString(obj:Dynamic):String
  624. {
  625. if (obj == null)
  626. return null;
  627. if (Std.is(obj, Bool))
  628. if(obj)
  629. return "true";
  630. else
  631. return "false";
  632. return untyped obj.ToString();
  633. }
  634. @:functionCode('
  635. if (t1 == null || t2 == null)
  636. return t1 == t2;
  637. string n1 = Type.getClassName(t1);
  638. string n2 = Type.getClassName(t2);
  639. return n1.Equals(n2);
  640. ')
  641. public static function typeEq(t1:Type, t2:Type):Bool
  642. {
  643. return false;
  644. }
  645. @:functionCode('
  646. if (obj is To)
  647. return (To) obj;
  648. else if (obj == null)
  649. return default(To);
  650. if (typeof(To) == typeof(double))
  651. return (To)(object) toDouble(obj);
  652. else if (typeof(To) == typeof(int))
  653. return (To)(object) toInt(obj);
  654. else if (typeof(To) == typeof(float))
  655. return (To)(object)(float)toDouble(obj);
  656. else if (typeof(To) == typeof(long))
  657. return (To)(object)(long)toDouble(obj);
  658. else
  659. return (To) obj;
  660. ')
  661. public static function genericCast<To>(obj:Dynamic):To
  662. {
  663. return null;
  664. }
  665. @:functionCode('
  666. return (s1 == null ? "null" : s1) + (s2 == null ? "null" : s2);
  667. ')
  668. public static function concat(s1:String, s2:String):String
  669. {
  670. return null;
  671. }
  672. @:functionCode('
  673. return dyn == null ? false : ((bool) dyn);
  674. ')
  675. public static function toBool(dyn:Dynamic):Bool
  676. {
  677. return false;
  678. }
  679. //TODO: change from genericCast to getConverter, so we don't need to handle extra boxing associated with it
  680. /*@:functionCode('
  681. if (typeof(To).TypeHandle == typeof(double).TypeHandle)
  682. return (System.Converter<object,To>) new System.Converter<object,double>(toDouble);
  683. else if (typeof(To).TypeHandle == typeof(double).TypeHandle)
  684. return (System.Converter<object,To>) new System.Converter<object,double>(toDouble);
  685. else
  686. return (System.Converter<object, To>) delegate(object obj) { return (To) obj; };
  687. ')
  688. public static function getConverter<To>():cs.system.Converter<Dynamic,To>
  689. {
  690. return null;
  691. }*/
  692. }
  693. @:keep @:native("haxe.lang.EmptyObject") private enum EmptyObject
  694. {
  695. EMPTY;
  696. }