PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/DICK.B1/IronPython/Compiler/Ast/CallExpression.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 420 lines | 329 code | 68 blank | 23 comment | 53 complexity | c8b886177cc89730cc9425dc33a1853e MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if !CLR2
  16. using MSAst = System.Linq.Expressions;
  17. #else
  18. using MSAst = Microsoft.Scripting.Ast;
  19. #endif
  20. using System;
  21. using System.Collections.Generic;
  22. using System.Diagnostics;
  23. using System.Runtime.CompilerServices;
  24. using Microsoft.Scripting.Actions;
  25. using Microsoft.Scripting.Utils;
  26. using Microsoft.Scripting.Interpreter;
  27. using IronPython.Runtime;
  28. using IronPython.Runtime.Operations;
  29. namespace IronPython.Compiler.Ast {
  30. public class CallExpression : Expression, IInstructionProvider {
  31. private readonly Expression _target;
  32. private readonly Arg[] _args;
  33. public CallExpression(Expression target, Arg[] args) {
  34. _target = target;
  35. _args = args;
  36. }
  37. public Expression Target {
  38. get { return _target; }
  39. }
  40. public IList<Arg> Args {
  41. get { return _args; }
  42. }
  43. public bool NeedsLocalsDictionary() {
  44. NameExpression nameExpr = _target as NameExpression;
  45. if (nameExpr == null) return false;
  46. if (_args.Length == 0) {
  47. if (nameExpr.Name == "locals") return true;
  48. if (nameExpr.Name == "vars") return true;
  49. if (nameExpr.Name == "dir") return true;
  50. return false;
  51. } else if (_args.Length == 1 && (nameExpr.Name == "dir" || nameExpr.Name == "vars")) {
  52. if (_args[0].Name == "*" || _args[0].Name == "**") {
  53. // could be splatting empty list or dict resulting in 0-param call which needs context
  54. return true;
  55. }
  56. } else if (_args.Length == 2 && (nameExpr.Name == "dir" || nameExpr.Name == "vars")) {
  57. if (_args[0].Name == "*" && _args[1].Name == "**") {
  58. // could be splatting empty list and dict resulting in 0-param call which needs context
  59. return true;
  60. }
  61. } else {
  62. if (nameExpr.Name == "eval") return true;
  63. if (nameExpr.Name == "execfile") return true;
  64. }
  65. return false;
  66. }
  67. public override MSAst.Expression Reduce() {
  68. return UnicodeCall() ?? NormalCall(_target);
  69. }
  70. private MSAst.Expression NormalCall(MSAst.Expression target) {
  71. MSAst.Expression[] values = new MSAst.Expression[_args.Length + 2];
  72. Argument[] kinds = new Argument[_args.Length];
  73. values[0] = Parent.LocalContext;
  74. values[1] = target;
  75. for (int i = 0; i < _args.Length; i++) {
  76. kinds[i] = _args[i].GetArgumentInfo();
  77. values[i + 2] = _args[i].Expression;
  78. }
  79. return Parent.Invoke(
  80. new CallSignature(kinds),
  81. values
  82. );
  83. }
  84. private MSAst.Expression UnicodeCall() {
  85. if (_target is NameExpression && ((NameExpression)_target).Name == "unicode") {
  86. // NameExpressions are always typed to object
  87. Debug.Assert(_target.Type == typeof(object));
  88. var tmpVar = Expression.Variable(typeof(object));
  89. return Expression.Block(
  90. new[] { tmpVar },
  91. Expression.Assign(tmpVar, _target),
  92. Expression.Condition(
  93. Expression.Call(
  94. AstMethods.IsUnicode,
  95. tmpVar
  96. ),
  97. NormalCall(Expression.Constant(UnicodeHelper.Function)),
  98. NormalCall(tmpVar)
  99. )
  100. );
  101. }
  102. return null;
  103. }
  104. #region IInstructionProvider Members
  105. void IInstructionProvider.AddInstructions(LightCompiler compiler) {
  106. if (_target is NameExpression && ((NameExpression)_target).Name == "unicode") {
  107. compiler.Compile(Reduce());
  108. return;
  109. }
  110. for (int i = 0; i < _args.Length; i++) {
  111. if (!_args[i].GetArgumentInfo().IsSimple) {
  112. compiler.Compile(Reduce());
  113. return;
  114. }
  115. }
  116. switch (_args.Length) {
  117. #region Generated Python Call Expression Instruction Switch
  118. // *** BEGIN GENERATED CODE ***
  119. // generated by function: gen_call_expression_instruction_switch from: generate_calls.py
  120. case 0:
  121. compiler.Compile(Parent.LocalContext);
  122. compiler.Compile(_target);
  123. compiler.Instructions.Emit(new Invoke0Instruction(Parent.PyContext));
  124. return;
  125. case 1:
  126. compiler.Compile(Parent.LocalContext);
  127. compiler.Compile(_target);
  128. compiler.Compile(_args[0].Expression);
  129. compiler.Instructions.Emit(new Invoke1Instruction(Parent.PyContext));
  130. return;
  131. case 2:
  132. compiler.Compile(Parent.LocalContext);
  133. compiler.Compile(_target);
  134. compiler.Compile(_args[0].Expression);
  135. compiler.Compile(_args[1].Expression);
  136. compiler.Instructions.Emit(new Invoke2Instruction(Parent.PyContext));
  137. return;
  138. case 3:
  139. compiler.Compile(Parent.LocalContext);
  140. compiler.Compile(_target);
  141. compiler.Compile(_args[0].Expression);
  142. compiler.Compile(_args[1].Expression);
  143. compiler.Compile(_args[2].Expression);
  144. compiler.Instructions.Emit(new Invoke3Instruction(Parent.PyContext));
  145. return;
  146. case 4:
  147. compiler.Compile(Parent.LocalContext);
  148. compiler.Compile(_target);
  149. compiler.Compile(_args[0].Expression);
  150. compiler.Compile(_args[1].Expression);
  151. compiler.Compile(_args[2].Expression);
  152. compiler.Compile(_args[3].Expression);
  153. compiler.Instructions.Emit(new Invoke4Instruction(Parent.PyContext));
  154. return;
  155. case 5:
  156. compiler.Compile(Parent.LocalContext);
  157. compiler.Compile(_target);
  158. compiler.Compile(_args[0].Expression);
  159. compiler.Compile(_args[1].Expression);
  160. compiler.Compile(_args[2].Expression);
  161. compiler.Compile(_args[3].Expression);
  162. compiler.Compile(_args[4].Expression);
  163. compiler.Instructions.Emit(new Invoke5Instruction(Parent.PyContext));
  164. return;
  165. case 6:
  166. compiler.Compile(Parent.LocalContext);
  167. compiler.Compile(_target);
  168. compiler.Compile(_args[0].Expression);
  169. compiler.Compile(_args[1].Expression);
  170. compiler.Compile(_args[2].Expression);
  171. compiler.Compile(_args[3].Expression);
  172. compiler.Compile(_args[4].Expression);
  173. compiler.Compile(_args[5].Expression);
  174. compiler.Instructions.Emit(new Invoke6Instruction(Parent.PyContext));
  175. return;
  176. // *** END GENERATED CODE ***
  177. #endregion
  178. }
  179. compiler.Compile(Reduce());
  180. }
  181. #endregion
  182. abstract class InvokeInstruction : Instruction {
  183. public override int ProducedStack {
  184. get {
  185. return 1;
  186. }
  187. }
  188. public override string InstructionName {
  189. get {
  190. return "Python Invoke" + (ConsumedStack - 1);
  191. }
  192. }
  193. }
  194. #region Generated Python Call Expression Instructions
  195. // *** BEGIN GENERATED CODE ***
  196. // generated by function: gen_call_expression_instructions from: generate_calls.py
  197. class Invoke0Instruction : InvokeInstruction {
  198. private readonly CallSite<Func<CallSite, CodeContext, object, object>> _site;
  199. public Invoke0Instruction(PythonContext context) {
  200. _site = context.CallSite0;
  201. }
  202. public override int ConsumedStack {
  203. get {
  204. return 2;
  205. }
  206. }
  207. public override int Run(InterpretedFrame frame) {
  208. var target = frame.Pop();
  209. frame.Push(_site.Target(_site, (CodeContext)frame.Pop(), target));
  210. return +1;
  211. }
  212. }
  213. class Invoke1Instruction : InvokeInstruction {
  214. private readonly CallSite<Func<CallSite, CodeContext, object, object, object>> _site;
  215. public Invoke1Instruction(PythonContext context) {
  216. _site = context.CallSite1;
  217. }
  218. public override int ConsumedStack {
  219. get {
  220. return 3;
  221. }
  222. }
  223. public override int Run(InterpretedFrame frame) {
  224. var arg0 = frame.Pop();
  225. var target = frame.Pop();
  226. frame.Push(_site.Target(_site, (CodeContext)frame.Pop(), target, arg0));
  227. return +1;
  228. }
  229. }
  230. class Invoke2Instruction : InvokeInstruction {
  231. private readonly CallSite<Func<CallSite, CodeContext, object, object, object, object>> _site;
  232. public Invoke2Instruction(PythonContext context) {
  233. _site = context.CallSite2;
  234. }
  235. public override int ConsumedStack {
  236. get {
  237. return 4;
  238. }
  239. }
  240. public override int Run(InterpretedFrame frame) {
  241. var arg1 = frame.Pop();
  242. var arg0 = frame.Pop();
  243. var target = frame.Pop();
  244. frame.Push(_site.Target(_site, (CodeContext)frame.Pop(), target, arg0, arg1));
  245. return +1;
  246. }
  247. }
  248. class Invoke3Instruction : InvokeInstruction {
  249. private readonly CallSite<Func<CallSite, CodeContext, object, object, object, object, object>> _site;
  250. public Invoke3Instruction(PythonContext context) {
  251. _site = context.CallSite3;
  252. }
  253. public override int ConsumedStack {
  254. get {
  255. return 5;
  256. }
  257. }
  258. public override int Run(InterpretedFrame frame) {
  259. var arg2 = frame.Pop();
  260. var arg1 = frame.Pop();
  261. var arg0 = frame.Pop();
  262. var target = frame.Pop();
  263. frame.Push(_site.Target(_site, (CodeContext)frame.Pop(), target, arg0, arg1, arg2));
  264. return +1;
  265. }
  266. }
  267. class Invoke4Instruction : InvokeInstruction {
  268. private readonly CallSite<Func<CallSite, CodeContext, object, object, object, object, object, object>> _site;
  269. public Invoke4Instruction(PythonContext context) {
  270. _site = context.CallSite4;
  271. }
  272. public override int ConsumedStack {
  273. get {
  274. return 6;
  275. }
  276. }
  277. public override int Run(InterpretedFrame frame) {
  278. var arg3 = frame.Pop();
  279. var arg2 = frame.Pop();
  280. var arg1 = frame.Pop();
  281. var arg0 = frame.Pop();
  282. var target = frame.Pop();
  283. frame.Push(_site.Target(_site, (CodeContext)frame.Pop(), target, arg0, arg1, arg2, arg3));
  284. return +1;
  285. }
  286. }
  287. class Invoke5Instruction : InvokeInstruction {
  288. private readonly CallSite<Func<CallSite, CodeContext, object, object, object, object, object, object, object>> _site;
  289. public Invoke5Instruction(PythonContext context) {
  290. _site = context.CallSite5;
  291. }
  292. public override int ConsumedStack {
  293. get {
  294. return 7;
  295. }
  296. }
  297. public override int Run(InterpretedFrame frame) {
  298. var arg4 = frame.Pop();
  299. var arg3 = frame.Pop();
  300. var arg2 = frame.Pop();
  301. var arg1 = frame.Pop();
  302. var arg0 = frame.Pop();
  303. var target = frame.Pop();
  304. frame.Push(_site.Target(_site, (CodeContext)frame.Pop(), target, arg0, arg1, arg2, arg3, arg4));
  305. return +1;
  306. }
  307. }
  308. class Invoke6Instruction : InvokeInstruction {
  309. private readonly CallSite<Func<CallSite, CodeContext, object, object, object, object, object, object, object, object>> _site;
  310. public Invoke6Instruction(PythonContext context) {
  311. _site = context.CallSite6;
  312. }
  313. public override int ConsumedStack {
  314. get {
  315. return 8;
  316. }
  317. }
  318. public override int Run(InterpretedFrame frame) {
  319. var arg5 = frame.Pop();
  320. var arg4 = frame.Pop();
  321. var arg3 = frame.Pop();
  322. var arg2 = frame.Pop();
  323. var arg1 = frame.Pop();
  324. var arg0 = frame.Pop();
  325. var target = frame.Pop();
  326. frame.Push(_site.Target(_site, (CodeContext)frame.Pop(), target, arg0, arg1, arg2, arg3, arg4, arg5));
  327. return +1;
  328. }
  329. }
  330. // *** END GENERATED CODE ***
  331. #endregion
  332. internal override string CheckAssign() {
  333. return "can't assign to function call";
  334. }
  335. internal override string CheckDelete() {
  336. return "can't delete function call";
  337. }
  338. public override void Walk(PythonWalker walker) {
  339. if (walker.Walk(this)) {
  340. if (_target != null) {
  341. _target.Walk(walker);
  342. }
  343. if (_args != null) {
  344. foreach (Arg arg in _args) {
  345. arg.Walk(walker);
  346. }
  347. }
  348. }
  349. walker.PostWalk(this);
  350. }
  351. }
  352. }