Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

WIP: Light Compile edits, still debugging

  • Loading branch information...
commit cfa8d5115b01e78781d040c839728189a586d02a 1 parent 0d11987
@dmiller dmiller authored
View
30 Clojure/Clojure/CljCompiler/Ast/FnExpr.cs
@@ -40,7 +40,7 @@ protected override bool SupportsMeta
private int _dynMethodMapKey = RT.nextID();
public int DynMethodMapKey { get { return _dynMethodMapKey; } }
- private Dictionary<int,WeakReference> _dynMethodMap;
+ private Dictionary<int,DynamicMethod> _dynMethodMap;
private object[] _compiledConstants;
#endregion
@@ -217,7 +217,7 @@ public static Expr Parse(ParserContext pcon, ISeq form, string name)
fn._hasMeta = RT.count(fmeta) > 0;
- if (Compiler.IsCompiling || prims.Count > 0)
+ if (Compiler.IsCompiling || prims.Count > 0|| fn.IsStatic)
{
IPersistentVector primTypes = PersistentVector.EMPTY;
@@ -234,7 +234,7 @@ public static Expr Parse(ParserContext pcon, ISeq form, string name)
else
{
fn.FnMode = FnMode.Light;
- fn.LightCompile(fn.GetPrecompiledType(), newContext);
+ fn.LightCompile(fn.GetPrecompiledType(), Compiler.EvalContext);
}
if (fn.SupportsMeta)
@@ -278,7 +278,7 @@ void LightCompile(Type compiledType, GenContext context)
void LightCompileMethods()
{
- Dictionary<int, WeakReference> dict = new Dictionary<int, WeakReference>();
+ Dictionary<int, DynamicMethod> dict = new Dictionary<int, DynamicMethod>();
// Create a dynamic method that takes an array of closed-over values
// and returns an instance of AFnImpl.
@@ -290,7 +290,8 @@ void LightCompileMethods()
int key = GetMethodKey(method);
Console.WriteLine("Store arity {0}", key);
- dict[key] = new WeakReference(method.DynMethod);
+ //dict[key] = new WeakReference(method.DynMethod);
+ dict[key] = method.DynMethod;
}
DynMethodMap[DynMethodMapKey] = dict;
@@ -315,14 +316,18 @@ void LightCompileConstants()
static readonly MethodInfo Method_FnExpr_GetDynMethod = typeof(FnExpr).GetMethod("GetDynMethod");
static readonly MethodInfo Method_FnExpr_GetCompiledConstants = typeof(FnExpr).GetMethod("GetCompiledConstants");
- static readonly Dictionary<int, Dictionary<int, WeakReference > > DynMethodMap = new Dictionary<int,Dictionary<int,WeakReference>>();
+ static readonly Dictionary<int, Dictionary<int, DynamicMethod > > DynMethodMap = new Dictionary<int,Dictionary<int,DynamicMethod>>();
static readonly Dictionary<int, WeakReference> ConstantsMap = new Dictionary<int, WeakReference>();
public static DynamicMethod GetDynMethod(int key, int arity)
{
- Dictionary<int, WeakReference > dict = DynMethodMap[key];
- WeakReference wr = dict[arity];
- return (DynamicMethod)wr.Target;
+ DynamicMethod dm = DynMethodMap[key][arity];
+ if (dm == null)
+ Console.WriteLine("Bad dynmeth retrieval");
+ return dm;
+ // Dictionary<int, WeakReference > dict = DynMethodMap[key];
+ // WeakReference wr = dict[arity];
+ // return (DynamicMethod)wr.Target;
}
public static object[] GetCompiledConstants(int key)
@@ -338,7 +343,7 @@ void LightEmit(RHC rhc, ObjExpr objx, CljILGen ilg)
//emitting a Fn means constructing an instance, feeding closed-overs from enclosing scope, if any
//objx arg is enclosing objx, not this
-
+
// Create the function instance
LocalBuilder fnLocal = ilg.DeclareLocal(CompiledType);
@@ -354,6 +359,9 @@ void LightEmit(RHC rhc, ObjExpr objx, CljILGen ilg)
ilg.Emit(OpCodes.Stloc, fnLocal);
+ ilg.EmitString(String.Format("Creating fn {0}", Name));
+ ilg.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
+
// Set up the methods
for (ISeq s = RT.seq(_methods); s != null; s = s.next())
@@ -366,7 +374,7 @@ void LightEmit(RHC rhc, ObjExpr objx, CljILGen ilg)
? "_fnDo" + (key - 1) // because key is arity+1 for variadic
: "_fn" + key;
- Console.WriteLine("Look up arity {0}, fieldName {1}", key,fieldName);
+ Console.WriteLine("Look up arity {0}, fieldName {1}", key,fieldName);
FieldInfo fi = CompiledType.GetField(fieldName);
View
46 Clojure/Clojure/CljCompiler/Ast/MethodExpr.cs
@@ -141,6 +141,22 @@ private void EmitForMethod(ObjExpr objx, CljILGen ilg)
ilg.Emit(OpCodes.Callvirt, _method);
}
+ public static readonly MethodInfo Method_MethodExpr_GetDelegate = typeof(MethodExpr).GetMethod("GetDelegate");
+
+ public static readonly Dictionary<int, Delegate> DelegatesMap = new Dictionary<int, Delegate>();
+
+ public static Delegate GetDelegate(int key)
+ {
+ Delegate d = DelegatesMap[key];
+ if (d == null)
+ Console.WriteLine("Bad delegate retrieval");
+ return d;
+ }
+
+ public static void CacheDelegate(int key, Delegate d)
+ {
+ DelegatesMap[key] = d;
+ }
protected abstract void EmitTargetExpression(ObjExpr objx, CljILGen ilg);
protected abstract Type GetTargetType();
@@ -197,7 +213,7 @@ private void EmitComplexCall(ObjExpr objx, CljILGen ilg)
Expression call = dyn;
GenContext context = Compiler.CompilerContextVar.deref() as GenContext;
- if (context.DynInitHelper != null)
+ if (context != null && context.DynInitHelper != null)
call = context.DynInitHelper.ReduceDyn(dyn);
if (returnType == typeof(void))
@@ -208,11 +224,31 @@ private void EmitComplexCall(ObjExpr objx, CljILGen ilg)
call = GenContext.AddDebugInfo(call, _spanMap);
Type[] paramTypes = paramExprs.Map((x) => x.Type);
- MethodBuilder mbLambda = context.TB.DefineMethod("__interop_" + _methodName + RT.nextID(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
- LambdaExpression lambda = Expression.Lambda(call, paramExprs);
- lambda.CompileToMethod(mbLambda);
+ //Type delType = Expression.GetDelegateType(paramTypes.);
+ //LambdaExpression lambda = Expression.Lambda(delType,call, paramExprs);
+
+ LambdaExpression lambda = Expression.Lambda(call, paramExprs);
+ Type delType = lambda.Type;
- ilg.Emit(OpCodes.Call, mbLambda);
+ if (context == null)
+ {
+ // light compile
+
+ Delegate d = lambda.Compile();
+ int key = RT.nextID();
+ CacheDelegate(key,d);
+
+ ilg.EmitInt(key);
+ ilg.Emit(OpCodes.Call, Method_MethodExpr_GetDelegate);
+ ilg.Emit(OpCodes.Call, delType.GetMethod("Invoke"));
+
+ }
+ else
+ {
+ MethodBuilder mbLambda = context.TB.DefineMethod("__interop_" + _methodName + RT.nextID(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
+ lambda.CompileToMethod(mbLambda);
+ ilg.Emit(OpCodes.Call, mbLambda);
+ }
}
internal static void EmitArgsAsArray(IPersistentVector args, ObjExpr objx, CljILGen ilg)
View
23 Clojure/Clojure/CljCompiler/Ast/NewExpr.cs
@@ -255,7 +255,7 @@ private void EmitComplexCall(RHC rhc, ObjExpr objx, CljILGen ilg)
Expression call = dyn;
GenContext context = Compiler.CompilerContextVar.deref() as GenContext;
- if (context.DynInitHelper != null)
+ if ( context != null && context.DynInitHelper != null)
call = context.DynInitHelper.ReduceDyn(dyn);
if (returnType == typeof(void))
@@ -266,12 +266,27 @@ private void EmitComplexCall(RHC rhc, ObjExpr objx, CljILGen ilg)
call = GenContext.AddDebugInfo(call, _spanMap);
Type[] paramTypes = paramExprs.Map((x) => x.Type);
- MethodBuilder mbLambda = context.TB.DefineMethod("__interop_ctor_" + RT.nextID(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
LambdaExpression lambda = Expression.Lambda(call, paramExprs);
- lambda.CompileToMethod(mbLambda);
+ Type delType = lambda.Type;
- ilg.Emit(OpCodes.Call, mbLambda);
+ if (context == null)
+ {
+ // light compile
+
+ Delegate d = lambda.Compile();
+ int key = RT.nextID();
+ MethodExpr.CacheDelegate(key, d);
+ ilg.EmitInt(key);
+ ilg.Emit(OpCodes.Call, MethodExpr.Method_MethodExpr_GetDelegate);
+ ilg.Emit(OpCodes.Call, delType.GetMethod("Invoke"));
+ }
+ else
+ {
+ MethodBuilder mbLambda = context.TB.DefineMethod("__interop_ctor_" + RT.nextID(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
+ lambda.CompileToMethod(mbLambda);
+ ilg.Emit(OpCodes.Call, mbLambda);
+ }
}
static readonly MethodInfo Method_Type_GetTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");
View
13 Clojure/Clojure/CljCompiler/Compiler.cs
@@ -1117,14 +1117,23 @@ public static bool GetLocations(IPersistentMap spanMap, out int startLine, out i
&& GetLocation(spanMap, RT.EndColumnKey, out finishCol);
}
- static GenContext _evalContext = GenContext.CreateWithInternalAssembly("eval", false);
+
+ static GenContext CreateEvalContext(string name, bool createDynInitHelper)
+ {
+ GenContext c = GenContext.CreateWithInternalAssembly("eval", createDynInitHelper);
+ //TypeBuilder tb = c.AssemblyGen.DefinePublicType("__Scratch__", typeof(object), false);
+ //return c.WithTypeBuilder(tb);
+ return c;
+ }
+
+ static GenContext _evalContext = CreateEvalContext("eval", false);
static public GenContext EvalContext { get { return _evalContext; } }
static int _saveId = 0;
public static void SaveEvalContext()
{
_evalContext.SaveAssembly();
- _evalContext = GenContext.CreateWithInternalAssembly("eval" + (_saveId++).ToString(), false);
+ _evalContext = CreateEvalContext("eval" + (_saveId++).ToString(), false);
}
public static bool IsCompiling
Please sign in to comment.
Something went wrong with that request. Please try again.