Skip to content

Commit cfa8d51

Browse files
committed
WIP: Light Compile edits, still debugging
1 parent 0d11987 commit cfa8d51

File tree

4 files changed

+90
-22
lines changed

4 files changed

+90
-22
lines changed

Clojure/Clojure/CljCompiler/Ast/FnExpr.cs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ protected override bool SupportsMeta
4040
private int _dynMethodMapKey = RT.nextID();
4141
public int DynMethodMapKey { get { return _dynMethodMapKey; } }
4242

43-
private Dictionary<int,WeakReference> _dynMethodMap;
43+
private Dictionary<int,DynamicMethod> _dynMethodMap;
4444
private object[] _compiledConstants;
4545

4646
#endregion
@@ -217,7 +217,7 @@ public static Expr Parse(ParserContext pcon, ISeq form, string name)
217217
fn._hasMeta = RT.count(fmeta) > 0;
218218

219219

220-
if (Compiler.IsCompiling || prims.Count > 0)
220+
if (Compiler.IsCompiling || prims.Count > 0|| fn.IsStatic)
221221
{
222222

223223
IPersistentVector primTypes = PersistentVector.EMPTY;
@@ -234,7 +234,7 @@ public static Expr Parse(ParserContext pcon, ISeq form, string name)
234234
else
235235
{
236236
fn.FnMode = FnMode.Light;
237-
fn.LightCompile(fn.GetPrecompiledType(), newContext);
237+
fn.LightCompile(fn.GetPrecompiledType(), Compiler.EvalContext);
238238
}
239239

240240
if (fn.SupportsMeta)
@@ -278,7 +278,7 @@ void LightCompile(Type compiledType, GenContext context)
278278

279279
void LightCompileMethods()
280280
{
281-
Dictionary<int, WeakReference> dict = new Dictionary<int, WeakReference>();
281+
Dictionary<int, DynamicMethod> dict = new Dictionary<int, DynamicMethod>();
282282

283283
// Create a dynamic method that takes an array of closed-over values
284284
// and returns an instance of AFnImpl.
@@ -290,7 +290,8 @@ void LightCompileMethods()
290290
int key = GetMethodKey(method);
291291
Console.WriteLine("Store arity {0}", key);
292292

293-
dict[key] = new WeakReference(method.DynMethod);
293+
//dict[key] = new WeakReference(method.DynMethod);
294+
dict[key] = method.DynMethod;
294295
}
295296

296297
DynMethodMap[DynMethodMapKey] = dict;
@@ -315,14 +316,18 @@ void LightCompileConstants()
315316
static readonly MethodInfo Method_FnExpr_GetDynMethod = typeof(FnExpr).GetMethod("GetDynMethod");
316317
static readonly MethodInfo Method_FnExpr_GetCompiledConstants = typeof(FnExpr).GetMethod("GetCompiledConstants");
317318

318-
static readonly Dictionary<int, Dictionary<int, WeakReference > > DynMethodMap = new Dictionary<int,Dictionary<int,WeakReference>>();
319+
static readonly Dictionary<int, Dictionary<int, DynamicMethod > > DynMethodMap = new Dictionary<int,Dictionary<int,DynamicMethod>>();
319320
static readonly Dictionary<int, WeakReference> ConstantsMap = new Dictionary<int, WeakReference>();
320321

321322
public static DynamicMethod GetDynMethod(int key, int arity)
322323
{
323-
Dictionary<int, WeakReference > dict = DynMethodMap[key];
324-
WeakReference wr = dict[arity];
325-
return (DynamicMethod)wr.Target;
324+
DynamicMethod dm = DynMethodMap[key][arity];
325+
if (dm == null)
326+
Console.WriteLine("Bad dynmeth retrieval");
327+
return dm;
328+
// Dictionary<int, WeakReference > dict = DynMethodMap[key];
329+
// WeakReference wr = dict[arity];
330+
// return (DynamicMethod)wr.Target;
326331
}
327332

328333
public static object[] GetCompiledConstants(int key)
@@ -338,7 +343,7 @@ void LightEmit(RHC rhc, ObjExpr objx, CljILGen ilg)
338343
//emitting a Fn means constructing an instance, feeding closed-overs from enclosing scope, if any
339344
//objx arg is enclosing objx, not this
340345

341-
346+
342347
// Create the function instance
343348
LocalBuilder fnLocal = ilg.DeclareLocal(CompiledType);
344349

@@ -354,6 +359,9 @@ void LightEmit(RHC rhc, ObjExpr objx, CljILGen ilg)
354359

355360
ilg.Emit(OpCodes.Stloc, fnLocal);
356361

362+
ilg.EmitString(String.Format("Creating fn {0}", Name));
363+
ilg.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
364+
357365
// Set up the methods
358366

359367
for (ISeq s = RT.seq(_methods); s != null; s = s.next())
@@ -366,7 +374,7 @@ void LightEmit(RHC rhc, ObjExpr objx, CljILGen ilg)
366374
? "_fnDo" + (key - 1) // because key is arity+1 for variadic
367375
: "_fn" + key;
368376

369-
Console.WriteLine("Look up arity {0}, fieldName {1}", key,fieldName);
377+
Console.WriteLine("Look up arity {0}, fieldName {1}", key,fieldName);
370378

371379
FieldInfo fi = CompiledType.GetField(fieldName);
372380

Clojure/Clojure/CljCompiler/Ast/MethodExpr.cs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,22 @@ private void EmitForMethod(ObjExpr objx, CljILGen ilg)
141141
ilg.Emit(OpCodes.Callvirt, _method);
142142
}
143143

144+
public static readonly MethodInfo Method_MethodExpr_GetDelegate = typeof(MethodExpr).GetMethod("GetDelegate");
145+
146+
public static readonly Dictionary<int, Delegate> DelegatesMap = new Dictionary<int, Delegate>();
147+
148+
public static Delegate GetDelegate(int key)
149+
{
150+
Delegate d = DelegatesMap[key];
151+
if (d == null)
152+
Console.WriteLine("Bad delegate retrieval");
153+
return d;
154+
}
155+
156+
public static void CacheDelegate(int key, Delegate d)
157+
{
158+
DelegatesMap[key] = d;
159+
}
144160

145161
protected abstract void EmitTargetExpression(ObjExpr objx, CljILGen ilg);
146162
protected abstract Type GetTargetType();
@@ -197,7 +213,7 @@ private void EmitComplexCall(ObjExpr objx, CljILGen ilg)
197213
Expression call = dyn;
198214

199215
GenContext context = Compiler.CompilerContextVar.deref() as GenContext;
200-
if (context.DynInitHelper != null)
216+
if (context != null && context.DynInitHelper != null)
201217
call = context.DynInitHelper.ReduceDyn(dyn);
202218

203219
if (returnType == typeof(void))
@@ -208,11 +224,31 @@ private void EmitComplexCall(ObjExpr objx, CljILGen ilg)
208224
call = GenContext.AddDebugInfo(call, _spanMap);
209225

210226
Type[] paramTypes = paramExprs.Map((x) => x.Type);
211-
MethodBuilder mbLambda = context.TB.DefineMethod("__interop_" + _methodName + RT.nextID(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
212-
LambdaExpression lambda = Expression.Lambda(call, paramExprs);
213-
lambda.CompileToMethod(mbLambda);
227+
//Type delType = Expression.GetDelegateType(paramTypes.);
228+
//LambdaExpression lambda = Expression.Lambda(delType,call, paramExprs);
229+
230+
LambdaExpression lambda = Expression.Lambda(call, paramExprs);
231+
Type delType = lambda.Type;
214232

215-
ilg.Emit(OpCodes.Call, mbLambda);
233+
if (context == null)
234+
{
235+
// light compile
236+
237+
Delegate d = lambda.Compile();
238+
int key = RT.nextID();
239+
CacheDelegate(key,d);
240+
241+
ilg.EmitInt(key);
242+
ilg.Emit(OpCodes.Call, Method_MethodExpr_GetDelegate);
243+
ilg.Emit(OpCodes.Call, delType.GetMethod("Invoke"));
244+
245+
}
246+
else
247+
{
248+
MethodBuilder mbLambda = context.TB.DefineMethod("__interop_" + _methodName + RT.nextID(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
249+
lambda.CompileToMethod(mbLambda);
250+
ilg.Emit(OpCodes.Call, mbLambda);
251+
}
216252
}
217253

218254
internal static void EmitArgsAsArray(IPersistentVector args, ObjExpr objx, CljILGen ilg)

Clojure/Clojure/CljCompiler/Ast/NewExpr.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ private void EmitComplexCall(RHC rhc, ObjExpr objx, CljILGen ilg)
255255
Expression call = dyn;
256256

257257
GenContext context = Compiler.CompilerContextVar.deref() as GenContext;
258-
if (context.DynInitHelper != null)
258+
if ( context != null && context.DynInitHelper != null)
259259
call = context.DynInitHelper.ReduceDyn(dyn);
260260

261261
if (returnType == typeof(void))
@@ -266,12 +266,27 @@ private void EmitComplexCall(RHC rhc, ObjExpr objx, CljILGen ilg)
266266
call = GenContext.AddDebugInfo(call, _spanMap);
267267

268268
Type[] paramTypes = paramExprs.Map((x) => x.Type);
269-
MethodBuilder mbLambda = context.TB.DefineMethod("__interop_ctor_" + RT.nextID(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
270269
LambdaExpression lambda = Expression.Lambda(call, paramExprs);
271-
lambda.CompileToMethod(mbLambda);
270+
Type delType = lambda.Type;
272271

273-
ilg.Emit(OpCodes.Call, mbLambda);
272+
if (context == null)
273+
{
274+
// light compile
275+
276+
Delegate d = lambda.Compile();
277+
int key = RT.nextID();
278+
MethodExpr.CacheDelegate(key, d);
274279

280+
ilg.EmitInt(key);
281+
ilg.Emit(OpCodes.Call, MethodExpr.Method_MethodExpr_GetDelegate);
282+
ilg.Emit(OpCodes.Call, delType.GetMethod("Invoke"));
283+
}
284+
else
285+
{
286+
MethodBuilder mbLambda = context.TB.DefineMethod("__interop_ctor_" + RT.nextID(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
287+
lambda.CompileToMethod(mbLambda);
288+
ilg.Emit(OpCodes.Call, mbLambda);
289+
}
275290
}
276291

277292
static readonly MethodInfo Method_Type_GetTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");

Clojure/Clojure/CljCompiler/Compiler.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,14 +1117,23 @@ public static bool GetLocations(IPersistentMap spanMap, out int startLine, out i
11171117
&& GetLocation(spanMap, RT.EndColumnKey, out finishCol);
11181118
}
11191119

1120-
static GenContext _evalContext = GenContext.CreateWithInternalAssembly("eval", false);
1120+
1121+
static GenContext CreateEvalContext(string name, bool createDynInitHelper)
1122+
{
1123+
GenContext c = GenContext.CreateWithInternalAssembly("eval", createDynInitHelper);
1124+
//TypeBuilder tb = c.AssemblyGen.DefinePublicType("__Scratch__", typeof(object), false);
1125+
//return c.WithTypeBuilder(tb);
1126+
return c;
1127+
}
1128+
1129+
static GenContext _evalContext = CreateEvalContext("eval", false);
11211130
static public GenContext EvalContext { get { return _evalContext; } }
11221131

11231132
static int _saveId = 0;
11241133
public static void SaveEvalContext()
11251134
{
11261135
_evalContext.SaveAssembly();
1127-
_evalContext = GenContext.CreateWithInternalAssembly("eval" + (_saveId++).ToString(), false);
1136+
_evalContext = CreateEvalContext("eval" + (_saveId++).ToString(), false);
11281137
}
11291138

11301139
public static bool IsCompiling

0 commit comments

Comments
 (0)