MethodBindingGenerator.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using System.Linq;
  5. using System.Text;
  6. using ILRuntime.Runtime.Enviorment;
  7. using ILRuntime.CLR.Utils;
  8. namespace ILRuntime.Runtime.CLRBinding
  9. {
  10. static class MethodBindingGenerator
  11. {
  12. static string GenerateParameterTypes(MethodInfo i, bool needBracket)
  13. {
  14. string clsName, realClsName;
  15. bool isByRef;
  16. var param = i.GetParameters();
  17. StringBuilder sb2 = new StringBuilder();
  18. if (needBracket)
  19. sb2.Append("{");
  20. bool first = true;
  21. foreach (var j in param)
  22. {
  23. if (first)
  24. first = false;
  25. else
  26. sb2.Append(", ");
  27. sb2.Append("typeof(");
  28. j.ParameterType.GetClassName(out clsName, out realClsName, out isByRef);
  29. sb2.Append(realClsName);
  30. sb2.Append(")");
  31. if (isByRef)
  32. sb2.Append(".MakeByRefType()");
  33. }
  34. if (needBracket)
  35. sb2.Append("}");
  36. return sb2.ToString();
  37. }
  38. internal static string GenerateMethodRegisterCode(this Type type, MethodInfo[] methods, HashSet<MethodBase> excludes, out bool needMethods)
  39. {
  40. needMethods = false;
  41. MethodInfo[] allMethods = type.GetMethods();
  42. StringBuilder sb = new StringBuilder();
  43. int idx = 0;
  44. bool isMethodsGot = false;
  45. foreach (var i in methods)
  46. {
  47. if (excludes != null && excludes.Contains(i))
  48. continue;
  49. if (type.ShouldSkipMethod(i))
  50. continue;
  51. if (i.IsGenericMethod)
  52. {
  53. if (!isMethodsGot)
  54. {
  55. sb.AppendLine(@" Dictionary<string, List<MethodInfo>> genericMethods = new Dictionary<string, List<MethodInfo>>();
  56. List<MethodInfo> lst = null;
  57. foreach(var m in type.GetMethods())
  58. {
  59. if(m.IsGenericMethodDefinition)
  60. {
  61. if (!genericMethods.TryGetValue(m.Name, out lst))
  62. {
  63. lst = new List<MethodInfo>();
  64. genericMethods[m.Name] = lst;
  65. }
  66. lst.Add(m);
  67. }
  68. }");
  69. isMethodsGot = true;
  70. }
  71. var param = i.GetGenericArguments();
  72. StringBuilder sb2 = new StringBuilder();
  73. sb2.Append("{");
  74. bool first = true;
  75. string clsName, realClsName;
  76. bool isByRef;
  77. foreach (var j in param)
  78. {
  79. if (first)
  80. first = false;
  81. else
  82. sb2.Append(", ");
  83. sb2.Append("typeof(");
  84. j.GetClassName(out clsName, out realClsName, out isByRef);
  85. sb2.Append(realClsName);
  86. sb2.Append(")");
  87. if (isByRef)
  88. sb2.Append(".MakeByRefType()");
  89. }
  90. sb2.Append("}");
  91. sb.AppendLine(string.Format(" args = new Type[]{0};", sb2));
  92. sb.AppendLine(string.Format(" if (genericMethods.TryGetValue(\"{0}\", out lst))", i.Name));
  93. sb.Append(@" {
  94. foreach(var m in lst)
  95. {
  96. if(m.MatchGenericParameters(args, ");
  97. if (i.ReturnType != typeof(void))
  98. {
  99. sb.Append("typeof(");
  100. i.ReturnType.GetClassName(out clsName, out realClsName, out isByRef);
  101. sb.Append(realClsName);
  102. sb.Append(")");
  103. }
  104. else
  105. sb.Append("typeof(void)");
  106. if (i.GetParameters().Length > 0)
  107. {
  108. sb.Append(", ");
  109. sb.Append(GenerateParameterTypes(i, false));
  110. }
  111. sb.Append(@"))
  112. {
  113. method = m.MakeGenericMethod(args);
  114. app.RegisterCLRMethodRedirection(method, ");
  115. sb.AppendLine(string.Format("{0}_{1});", i.Name, idx));
  116. sb.AppendLine(@"
  117. break;
  118. }
  119. }
  120. }");
  121. }
  122. else
  123. {
  124. string clsName, realClsName;
  125. bool isByRef;
  126. var param = i.GetParameters();
  127. string sb2 = GenerateParameterTypes(i, true);
  128. sb.AppendLine(string.Format(" args = new Type[]{0};", sb2));
  129. i.ReturnType.GetClassName(out clsName, out realClsName, out isByRef);
  130. if ((i.Name.Equals("op_Implicit") || i.Name.Equals("op_Explicit")) && allMethods.Count(m => m.Name.Equals(i.Name)) > 1)
  131. {
  132. // Type conversions can have different return types
  133. needMethods = true;
  134. sb.AppendLine(string.Format(" method = methods.Where(t => t.Name.Equals(\"{0}\") && t.ReturnType == typeof({1}) && t.CheckMethodParams(args)).Single();", i.Name, realClsName));
  135. }
  136. else if (allMethods.Any(m => m.IsGenericMethod && m.Name.Equals(i.Name) && m.CheckMethodParams(param)))
  137. {
  138. // Check for a generic method with the same name and params
  139. needMethods = true;
  140. sb.AppendLine(string.Format(" method = methods.Where(t => t.Name.Equals(\"{0}\") && t.CheckMethodParams(args)).Single();", i.Name));
  141. } else
  142. sb.AppendLine(string.Format(" method = type.GetMethod(\"{0}\", flag, null, args, null);", i.Name));
  143. sb.AppendLine(string.Format(" app.RegisterCLRMethodRedirection(method, {0}_{1});", i.Name, idx));
  144. }
  145. idx++;
  146. }
  147. return sb.ToString();
  148. }
  149. internal static string GenerateMethodWraperCode(this Type type, MethodInfo[] methods, string typeClsName, HashSet<MethodBase> excludes, List<Type> valueTypeBinders, Enviorment.AppDomain domain)
  150. {
  151. StringBuilder sb = new StringBuilder();
  152. bool isMultiArr = type.IsArray && type.GetArrayRank() > 1;
  153. int idx = 0;
  154. foreach (var i in methods)
  155. {
  156. if (excludes != null && excludes.Contains(i))
  157. continue;
  158. if (type.ShouldSkipMethod(i))
  159. continue;
  160. bool isProperty = i.IsSpecialName;
  161. var param = i.GetParameters();
  162. int paramCnt = param.Length;
  163. if (!i.IsStatic)
  164. paramCnt++;
  165. sb.AppendLine(string.Format(" static StackObject* {0}_{1}(ILIntepreter __intp, StackObject* __esp, IList<object> __mStack, CLRMethod __method, bool isNewObj)", i.Name, idx));
  166. sb.AppendLine(" {");
  167. sb.AppendLine(" ILRuntime.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;");
  168. if (param.Length != 0 || !i.IsStatic)
  169. sb.AppendLine(" StackObject* ptr_of_this_method;");
  170. sb.AppendLine(string.Format(" StackObject* __ret = ILIntepreter.Minus(__esp, {0});", paramCnt));
  171. sb.AppendLine();
  172. bool hasByRef = param.HasByRefParam();
  173. string shouldFreeParam = hasByRef ? "false" : "true";
  174. for (int j = param.Length; j > 0; j--)
  175. {
  176. var p = param[j - 1];
  177. sb.AppendLine(string.Format(" ptr_of_this_method = ILIntepreter.Minus(__esp, {0});", param.Length - j + 1));
  178. p.ParameterType.AppendArgumentCode(sb, j, p.Name, valueTypeBinders, isMultiArr, hasByRef, true);
  179. sb.AppendLine();
  180. }
  181. bool noUnbox = (type.Name.Contains("AsyncTaskMethodBuilder") || type.FullName.StartsWith("System.Runtime.CompilerServices.AsyncVoidMethodBuilder")) && i.Name == "Start";
  182. if (!i.IsStatic)
  183. {
  184. sb.AppendLine(string.Format(" ptr_of_this_method = ILIntepreter.Minus(__esp, {0});", paramCnt));
  185. if (type.IsPrimitive)
  186. sb.AppendLine(string.Format(" {0} instance_of_this_method = GetInstance(__domain, ptr_of_this_method, __mStack);", typeClsName));
  187. else if (type.IsValueType && !type.IsPrimitive && valueTypeBinders != null && valueTypeBinders.Contains(type))
  188. {
  189. string clsName, realClsName;
  190. bool isByRef;
  191. type.GetClassName(out clsName, out realClsName, out isByRef);
  192. sb.AppendLine(string.Format(" {0} instance_of_this_method = new {0}();", realClsName));
  193. sb.AppendLine(string.Format(" if (ILRuntime.Runtime.Generated.CLRBindings.s_{0}_Binder != null) {{", clsName));
  194. sb.AppendLine(string.Format(" ILRuntime.Runtime.Generated.CLRBindings.s_{0}_Binder.ParseValue(ref instance_of_this_method, __intp, ptr_of_this_method, __mStack, false);", clsName));
  195. sb.AppendLine(" } else {");
  196. if (type.IsValueType)
  197. sb.AppendLine(" ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);");
  198. sb.AppendLine(string.Format(" instance_of_this_method = {0};", type.GetRetrieveValueCode(typeClsName)));
  199. if (!type.IsValueType && !hasByRef)
  200. sb.AppendLine(" __intp.Free(ptr_of_this_method);");
  201. sb.AppendLine(" }");
  202. }
  203. else
  204. {
  205. if (type.IsValueType && !type.IsPrimitive)
  206. {
  207. sb.AppendLine(" ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);");
  208. }
  209. if (noUnbox)
  210. sb.AppendLine(string.Format(" object instance_of_this_method = {0};", type.GetRetrieveValueCode(typeClsName)));
  211. else
  212. sb.AppendLine(string.Format(" {0} instance_of_this_method = {1};", typeClsName, type.GetRetrieveValueCode(typeClsName)));
  213. if (!type.IsValueType && !hasByRef)
  214. sb.AppendLine(" __intp.Free(ptr_of_this_method);");
  215. }
  216. }
  217. sb.AppendLine();
  218. if (i.ReturnType != typeof(void))
  219. {
  220. sb.Append(" var result_of_this_method = ");
  221. }
  222. else
  223. sb.Append(" ");
  224. string genericArguments = "";
  225. if (i.IsGenericMethod)
  226. {
  227. var p = i.GetGenericArguments();
  228. StringBuilder sb2 = new StringBuilder();
  229. bool first = true;
  230. sb2.Append('<');
  231. foreach (var j in p)
  232. {
  233. if (first)
  234. first = false;
  235. else
  236. sb2.Append(", ");
  237. string clsName, realClsName;
  238. bool isByRef;
  239. j.GetClassName(out clsName, out realClsName, out isByRef);
  240. sb2.Append(realClsName);
  241. }
  242. sb2.Append('>');
  243. genericArguments = sb2.ToString();
  244. }
  245. if (i.IsStatic)
  246. {
  247. if (isProperty)
  248. {
  249. string[] t = new string[2];
  250. int firstUnderlineIndex = i.Name.IndexOf("_");
  251. t[0] = i.Name.Substring(0, firstUnderlineIndex);
  252. t[1] = i.Name.Substring(firstUnderlineIndex + 1);
  253. string propType = t[0];
  254. if (propType == "get")
  255. {
  256. bool isIndexer = param.Length > 0;
  257. if (isIndexer)
  258. {
  259. sb.AppendLine(string.Format("{1}[{0}];", param[0].Name, typeClsName));
  260. }
  261. else
  262. sb.AppendLine(string.Format("{1}.{0};", t[1], typeClsName));
  263. }
  264. else if (propType == "set")
  265. {
  266. bool isIndexer = param.Length > 1;
  267. if (isIndexer)
  268. {
  269. sb.AppendLine(string.Format("{2}[{0}] = {1};", param[0].Name, param[1].Name, typeClsName));
  270. }
  271. else
  272. sb.AppendLine(string.Format("{2}.{0} = {1};", t[1], param[0].Name, typeClsName));
  273. }
  274. else if (propType == "op")
  275. {
  276. switch (t[1])
  277. {
  278. case "Equality":
  279. sb.AppendLine(string.Format("{0} == {1};", param[0].Name, param[1].Name));
  280. break;
  281. case "Inequality":
  282. sb.AppendLine(string.Format("{0} != {1};", param[0].Name, param[1].Name));
  283. break;
  284. case "Addition":
  285. sb.AppendLine(string.Format("{0} + {1};", param[0].Name, param[1].Name));
  286. break;
  287. case "Subtraction":
  288. sb.AppendLine(string.Format("{0} - {1};", param[0].Name, param[1].Name));
  289. break;
  290. case "Multiply":
  291. sb.AppendLine(string.Format("{0} * {1};", param[0].Name, param[1].Name));
  292. break;
  293. case "Division":
  294. sb.AppendLine(string.Format("{0} / {1};", param[0].Name, param[1].Name));
  295. break;
  296. case "GreaterThan":
  297. sb.AppendLine(string.Format("{0} > {1};", param[0].Name, param[1].Name));
  298. break;
  299. case "GreaterThanOrEqual":
  300. sb.AppendLine(string.Format("{0} >= {1};", param[0].Name, param[1].Name));
  301. break;
  302. case "LessThan":
  303. sb.AppendLine(string.Format("{0} < {1};", param[0].Name, param[1].Name));
  304. break;
  305. case "LessThanOrEqual":
  306. sb.AppendLine(string.Format("{0} <= {1};", param[0].Name, param[1].Name));
  307. break;
  308. case "UnaryNegation":
  309. sb.AppendLine(string.Format("-{0};", param[0].Name));
  310. break;
  311. case "LogicalNot":
  312. sb.AppendLine(string.Format("!{0};", param[0].Name));
  313. break;
  314. case "Modulus":
  315. sb.AppendLine(string.Format("{0} % {1};", param[0].Name, param[1].Name));
  316. break;
  317. case "Implicit":
  318. case "Explicit":
  319. {
  320. string clsName, realClsName;
  321. bool isByRef;
  322. i.ReturnType.GetClassName(out clsName, out realClsName, out isByRef);
  323. sb.AppendLine(string.Format("({1}){0};", param[0].Name, realClsName));
  324. }
  325. break;
  326. case "Increment":
  327. sb.AppendLine(string.Format("++{0};", param[0].Name));
  328. break;
  329. case "Decrement":
  330. sb.AppendLine(string.Format("--{0};", param[0].Name));
  331. break;
  332. default:
  333. throw new NotImplementedException(i.Name);
  334. }
  335. }
  336. else if(propType == "add")
  337. {
  338. string clsName, realClsName;
  339. bool isByRef;
  340. i.DeclaringType.GetClassName(out clsName, out realClsName, out isByRef);
  341. sb.AppendLine(string.Format("{0}.{1} += {2};", realClsName, i.Name.Substring(4), param[0].Name));
  342. }
  343. else if (propType == "remove")
  344. {
  345. string clsName, realClsName;
  346. bool isByRef;
  347. i.DeclaringType.GetClassName(out clsName, out realClsName, out isByRef);
  348. sb.AppendLine(string.Format("{0}.{1} -= {2};", realClsName, i.Name.Substring(7), param[0].Name));
  349. }
  350. else
  351. throw new NotImplementedException();
  352. }
  353. else
  354. {
  355. sb.Append(string.Format("{0}.{1}{2}(", typeClsName, i.Name, genericArguments));
  356. param.AppendParameters(sb);
  357. sb.AppendLine(");");
  358. }
  359. }
  360. else
  361. {
  362. if (isProperty)
  363. {
  364. string[] t = new string[2];
  365. int firstUnderlineIndex = i.Name.IndexOf("_");
  366. t[0] = i.Name.Substring(0, firstUnderlineIndex);
  367. t[1] = i.Name.Substring(firstUnderlineIndex + 1);
  368. string propType = t[0];
  369. if(noUnbox)
  370. {
  371. if (propType == "get")
  372. {
  373. bool isIndexer = param.Length > 0;
  374. if (isIndexer)
  375. {
  376. sb.AppendLine(string.Format("(({1})instance_of_this_method)[{0}];", param[0].Name, typeClsName));
  377. }
  378. else
  379. sb.AppendLine(string.Format("(({1})instance_of_this_method).{0};", t[1], typeClsName));
  380. }
  381. else if (propType == "set")
  382. {
  383. bool isIndexer = param.Length > 1;
  384. if (isIndexer)
  385. {
  386. sb.AppendLine(string.Format("(({2})instance_of_this_method)[{0}] = {1};", param[0].Name, param[1].Name, typeClsName));
  387. }
  388. else
  389. sb.AppendLine(string.Format("(({2})instance_of_this_method).{0} = {1};", t[1], param[0].Name, typeClsName, typeClsName));
  390. }
  391. else if (propType == "add")
  392. {
  393. sb.AppendLine(string.Format("(({2})instance_of_this_method).{0} += {1};", i.Name.Substring(4), param[0].Name, typeClsName));
  394. }
  395. else if (propType == "remove")
  396. {
  397. sb.AppendLine(string.Format("(({2})instance_of_this_method).{0} -= {1};", i.Name.Substring(7), param[0].Name, typeClsName));
  398. }
  399. else
  400. throw new NotImplementedException();
  401. }
  402. else
  403. {
  404. if (propType == "get")
  405. {
  406. bool isIndexer = param.Length > 0;
  407. if (isIndexer)
  408. {
  409. sb.AppendLine(string.Format("instance_of_this_method[{0}];", param[0].Name));
  410. }
  411. else
  412. sb.AppendLine(string.Format("instance_of_this_method.{0};", t[1]));
  413. }
  414. else if (propType == "set")
  415. {
  416. bool isIndexer = param.Length > 1;
  417. if (isIndexer)
  418. {
  419. sb.AppendLine(string.Format("instance_of_this_method[{0}] = {1};", param[0].Name, param[1].Name));
  420. }
  421. else
  422. sb.AppendLine(string.Format("instance_of_this_method.{0} = {1};", t[1], param[0].Name));
  423. }
  424. else if (propType == "add")
  425. {
  426. sb.AppendLine(string.Format("instance_of_this_method.{0} += {1};", i.Name.Substring(4), param[0].Name));
  427. }
  428. else if (propType == "remove")
  429. {
  430. sb.AppendLine(string.Format("instance_of_this_method.{0} -= {1};", i.Name.Substring(7), param[0].Name));
  431. }
  432. else
  433. throw new NotImplementedException();
  434. }
  435. }
  436. else if (isMultiArr)
  437. {
  438. if (i.Name == "Get")
  439. {
  440. sb.Append("instance_of_this_method[");
  441. param.AppendParameters(sb, true);
  442. sb.AppendLine("];");
  443. }
  444. else
  445. {
  446. sb.Append("instance_of_this_method[");
  447. param.AppendParameters(sb, true, 1);
  448. sb.Append("]");
  449. sb.Append(" = a");
  450. sb.Append(param.Length);
  451. sb.AppendLine(";");
  452. }
  453. }
  454. else
  455. {
  456. if(noUnbox)
  457. sb.Append(string.Format("(({2})instance_of_this_method).{0}{1}(", i.Name, genericArguments, typeClsName));
  458. else
  459. sb.Append(string.Format("instance_of_this_method.{0}{1}(", i.Name, genericArguments));
  460. param.AppendParameters(sb);
  461. sb.AppendLine(");");
  462. }
  463. }
  464. sb.AppendLine();
  465. //Ref/Out
  466. for (int j = param.Length; j > 0; j--)
  467. {
  468. var p = param[j - 1];
  469. if (!p.ParameterType.IsByRef && !hasByRef)
  470. {
  471. continue;
  472. }
  473. string clsName, realClsName;
  474. bool isByRef;
  475. var pt = p.ParameterType.IsByRef ? p.ParameterType.GetElementType() : p.ParameterType;
  476. pt.GetClassName(out clsName, out realClsName, out isByRef);
  477. sb.AppendLine(string.Format(" ptr_of_this_method = ILIntepreter.Minus(__esp, {0});", param.Length - j + 1));
  478. if (p.ParameterType.IsByRef)
  479. {
  480. sb.AppendLine(@" switch(ptr_of_this_method->ObjectType)
  481. {
  482. case ObjectTypes.StackObjectReference:
  483. {
  484. var ___dst = ILIntepreter.ResolveReference(ptr_of_this_method);");
  485. if (pt.IsValueType && !pt.IsPrimitive && valueTypeBinders != null && valueTypeBinders.Contains(pt))
  486. {
  487. sb.AppendLine(string.Format(" if (ILRuntime.Runtime.Generated.CLRBindings.s_{0}_Binder != null) {{", clsName));
  488. sb.AppendLine(string.Format(" ILRuntime.Runtime.Generated.CLRBindings.s_{0}_Binder.WriteBackValue(__domain, ptr_of_this_method, __mStack, ref {1});", clsName, p.Name));
  489. sb.AppendLine(" } else {");
  490. pt.GetRefWriteBackValueCode(sb, p.Name);
  491. sb.AppendLine(" }");
  492. }
  493. else
  494. {
  495. pt.GetRefWriteBackValueCode(sb, p.Name);
  496. }
  497. sb.Append(@" }
  498. break;
  499. case ObjectTypes.FieldReference:
  500. {
  501. var ___obj = __mStack[ptr_of_this_method->Value];
  502. if(___obj is ILTypeInstance)
  503. {
  504. ((ILTypeInstance)___obj)[ptr_of_this_method->ValueLow] = @");
  505. sb.Append(p.Name);
  506. sb.Append(@";
  507. }
  508. else
  509. {
  510. var ___type = __domain.GetType(___obj.GetType()) as CLRType;
  511. ___type.SetFieldValue(ptr_of_this_method->ValueLow, ref ___obj, @");
  512. sb.Append(p.Name);
  513. sb.Append(@");
  514. }
  515. }
  516. break;
  517. case ObjectTypes.StaticFieldReference:
  518. {
  519. var ___type = __domain.GetType(ptr_of_this_method->Value);
  520. if(___type is ILType)
  521. {
  522. ((ILType)___type).StaticInstance[ptr_of_this_method->ValueLow] = @");
  523. sb.Append(p.Name);
  524. sb.Append(@";
  525. }
  526. else
  527. {
  528. ((CLRType)___type).SetStaticFieldValue(ptr_of_this_method->ValueLow, @");
  529. sb.Append(p.Name);
  530. sb.Append(@");
  531. }
  532. }
  533. break;
  534. case ObjectTypes.ArrayReference:
  535. {
  536. var instance_of_arrayReference = __mStack[ptr_of_this_method->Value] as ");
  537. sb.Append(realClsName);
  538. sb.Append(@"[];
  539. instance_of_arrayReference[ptr_of_this_method->ValueLow] = @");
  540. sb.Append(p.Name);
  541. sb.AppendLine(@";
  542. }
  543. break;
  544. }");
  545. sb.AppendLine();
  546. }
  547. else if(pt.IsValueType && !pt.IsPrimitive)
  548. {
  549. sb.AppendLine(" __intp.FreeStackValueType(ptr_of_this_method);");
  550. }
  551. sb.AppendLine(" __intp.Free(ptr_of_this_method);");
  552. }
  553. if (!i.IsStatic && ((type.IsValueType && !type.IsPrimitive) || hasByRef))//need to write back value type instance
  554. {
  555. sb.AppendLine(string.Format(" ptr_of_this_method = ILIntepreter.Minus(__esp, {0});", paramCnt));
  556. bool noWriteback = noUnbox;
  557. if (type.IsValueType && !type.IsPrimitive && !noWriteback)
  558. {
  559. if (valueTypeBinders != null && valueTypeBinders.Contains(type))
  560. {
  561. string clsName, realClsName;
  562. bool isByRef;
  563. type.GetClassName(out clsName, out realClsName, out isByRef);
  564. sb.AppendLine(string.Format(" if (ILRuntime.Runtime.Generated.CLRBindings.s_{0}_Binder != null) {{", clsName));
  565. sb.AppendLine(string.Format(" ILRuntime.Runtime.Generated.CLRBindings.s_{0}_Binder.WriteBackValue(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);", clsName));
  566. sb.AppendLine(" } else {");
  567. sb.AppendLine(" WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);");
  568. sb.AppendLine(" }");
  569. }
  570. else
  571. {
  572. sb.AppendLine(" WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);");
  573. }
  574. sb.AppendLine();
  575. }
  576. sb.AppendLine(" __intp.Free(ptr_of_this_method);");
  577. }
  578. if (i.ReturnType != typeof(void))
  579. {
  580. if (i.ReturnType.IsValueType && !i.ReturnType.IsPrimitive && valueTypeBinders != null && valueTypeBinders.Contains(i.ReturnType))
  581. {
  582. string clsName, realClsName;
  583. bool isByRef;
  584. i.ReturnType.GetClassName(out clsName, out realClsName, out isByRef);
  585. sb.AppendLine(string.Format(" if (ILRuntime.Runtime.Generated.CLRBindings.s_{0}_Binder != null) {{", clsName));
  586. sb.AppendLine(string.Format(" ILRuntime.Runtime.Generated.CLRBindings.s_{0}_Binder.PushValue(ref result_of_this_method, __intp, __ret, __mStack);", clsName));
  587. sb.AppendLine(" return __ret + 1;");
  588. sb.AppendLine(" } else {");
  589. i.ReturnType.GetReturnValueCode(sb, domain);
  590. sb.AppendLine(" }");
  591. }
  592. else
  593. {
  594. i.ReturnType.GetReturnValueCode(sb, domain);
  595. }
  596. }
  597. else
  598. sb.AppendLine(" return __ret;");
  599. sb.AppendLine(" }");
  600. sb.AppendLine();
  601. idx++;
  602. }
  603. return sb.ToString();
  604. }
  605. }
  606. }