/DLR_Main/Languages/IronPython/IronPython/Compiler/CompilationMode.cs
C# | 176 lines | 110 code | 33 blank | 33 comment | 19 complexity | 6f77c35700fe52c39aa6a275e491f1c0 MD5 | raw file
1/* ****************************************************************************
2 *
3 * Copyright (c) Microsoft Corporation.
4 *
5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. 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 Apache License, Version 2.0, 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 Apache License, Version 2.0.
10 *
11 * You must not remove this notice, or any other, from this software.
12 *
13 *
14 * ***************************************************************************/
15
16#if !CLR2
17using MSAst = System.Linq.Expressions;
18#else
19using MSAst = Microsoft.Scripting.Ast;
20#endif
21
22
23using System;
24using System.Collections.Generic;
25using System.Dynamic;
26using System.Runtime.CompilerServices;
27
28using Microsoft.Scripting;
29using Microsoft.Scripting.Ast;
30using Microsoft.Scripting.Utils;
31
32using IronPython.Compiler.Ast;
33using IronPython.Runtime;
34using System.Collections;
35
36namespace IronPython.Compiler {
37 public delegate object LookupCompilationDelegate(CodeContext context, FunctionCode code);
38
39 /// <summary>
40 /// Specifies the compilation mode which will be used during the AST transformation
41 /// </summary>
42 [Serializable]
43 internal abstract class CompilationMode {
44 /// <summary>
45 /// Compilation will proceed in a manner in which the resulting AST can be serialized to disk.
46 /// </summary>
47 public static readonly CompilationMode ToDisk = new ToDiskCompilationMode();
48 /// <summary>
49 /// Compilation will use a type and declare static fields for globals. The resulting type
50 /// is uncollectible and therefore extended use of this will cause memory leaks.
51 /// </summary>
52 public static readonly CompilationMode Uncollectable = new UncollectableCompilationMode();
53 /// <summary>
54 /// Compilation will use an array for globals. The resulting code will be fully collectible
55 /// and once all references are released will be collected.
56 /// </summary>
57 public static readonly CompilationMode Collectable = new CollectableCompilationMode();
58 /// <summary>
59 /// Compilation will force all global accesses to do a full lookup. This will also happen for
60 /// any unbound local references. This is the slowest form of code generation and is only
61 /// used for exec/eval code where we can run against an arbitrary dictionary.
62 /// </summary>
63 public static readonly CompilationMode Lookup = new LookupCompilationMode();
64
65 public virtual ScriptCode MakeScriptCode(PythonAst ast) {
66 return new RuntimeScriptCode(ast, ast.ModuleContext.GlobalContext);
67 }
68
69 public virtual MSAst.Expression GetConstant(object value) {
70 return MSAst.Expression.Constant(value);
71 }
72
73 public virtual Type GetConstantType(object value) {
74 if (value == null) {
75 return typeof(object);
76 }
77
78 return value.GetType();
79 }
80
81 public virtual void PrepareScope(PythonAst ast, ReadOnlyCollectionBuilder<MSAst.ParameterExpression> locals, List<MSAst.Expression> init) {
82 }
83
84 public virtual Type DelegateType {
85 get {
86 return typeof(MSAst.Expression<LookupCompilationDelegate>);
87 }
88 }
89
90 public virtual UncollectableCompilationMode.ConstantInfo GetContext() {
91 return null;
92 }
93
94 public virtual void PublishContext(CodeContext codeContext, UncollectableCompilationMode.ConstantInfo _contextInfo) {
95 }
96
97 public MSAst.Expression/*!*/ Dynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/ arg0) {
98 if (retType == typeof(object)) {
99 return new PythonDynamicExpression1(binder, this, arg0);
100 } else if (retType == typeof(bool)) {
101 return new PythonDynamicExpression1<bool>(binder, this, arg0);
102 }
103
104 return ReduceDynamic(binder, retType, arg0);
105 }
106
107 public MSAst.Expression/*!*/ Dynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/ arg0, MSAst.Expression/*!*/ arg1) {
108 if (retType == typeof(object)) {
109 return new PythonDynamicExpression2(binder, this, arg0, arg1);
110 } else if (retType == typeof(bool)) {
111 return new PythonDynamicExpression2<bool>(binder, this, arg0, arg1);
112 }
113
114 return ReduceDynamic(binder, retType, arg0, arg1);
115 }
116
117 public MSAst.Expression/*!*/ Dynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/ arg0, MSAst.Expression/*!*/ arg1, MSAst.Expression/*!*/ arg2) {
118 if (retType == typeof(object)) {
119 return new PythonDynamicExpression3(binder, this, arg0, arg1, arg2);
120 }
121 return ReduceDynamic(binder, retType, arg0, arg1, arg2);
122 }
123
124 public MSAst.Expression/*!*/ Dynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/ arg0, MSAst.Expression/*!*/ arg1, MSAst.Expression/*!*/ arg2, MSAst.Expression/*!*/ arg3) {
125 if (retType == typeof(object)) {
126 return new PythonDynamicExpression4(binder, this, arg0, arg1, arg2, arg3);
127 }
128 return ReduceDynamic(binder, retType, arg0, arg1, arg2, arg3);
129 }
130
131 public MSAst.Expression/*!*/ Dynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/[]/*!*/ args) {
132 Assert.NotNull(binder, retType, args);
133 Assert.NotNullItems(args);
134
135 switch (args.Length) {
136 case 1: return Dynamic(binder, retType, args[0]);
137 case 2: return Dynamic(binder, retType, args[0], args[1]);
138 case 3: return Dynamic(binder, retType, args[0], args[1], args[2]);
139 case 4: return Dynamic(binder, retType, args[0], args[1], args[2], args[3]);
140 }
141
142 if (retType == typeof(object)) {
143 return new PythonDynamicExpressionN(binder, this, args);
144 }
145
146 return ReduceDynamic(binder, retType, args);
147 }
148
149 public virtual MSAst.Expression/*!*/ ReduceDynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/ arg0) {
150 return MSAst.Expression.Dynamic(binder, retType, arg0);
151 }
152
153 public virtual MSAst.Expression/*!*/ ReduceDynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/ arg0, MSAst.Expression/*!*/ arg1) {
154 return MSAst.Expression.Dynamic(binder, retType, arg0, arg1);
155 }
156
157 public virtual MSAst.Expression/*!*/ ReduceDynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/ arg0, MSAst.Expression/*!*/ arg1, MSAst.Expression/*!*/ arg2) {
158 return MSAst.Expression.Dynamic(binder, retType, arg0, arg1, arg2);
159 }
160
161 public virtual MSAst.Expression/*!*/ ReduceDynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/ arg0, MSAst.Expression/*!*/ arg1, MSAst.Expression/*!*/ arg2, MSAst.Expression/*!*/ arg3) {
162 return MSAst.Expression.Dynamic(binder, retType, arg0, arg1, arg2, arg3);
163 }
164
165 public virtual MSAst.Expression/*!*/ ReduceDynamic(DynamicMetaObjectBinder/*!*/ binder, Type/*!*/ retType, MSAst.Expression/*!*/[]/*!*/ args) {
166 Assert.NotNull(binder, retType, args);
167 Assert.NotNullItems(args);
168
169 return MSAst.Expression.Dynamic(binder, retType, args);
170 }
171
172 public abstract MSAst.Expression GetGlobal(MSAst.Expression globalContext, int arrayIndex, PythonVariable variable, PythonGlobal global);
173
174 public abstract LightLambdaExpression ReduceAst(PythonAst instance, string name);
175 }
176}