コード例 #1
0
ファイル: EmptyExpr.cs プロジェクト: stuman08/clojure-clr
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     if (_coll is IPersistentList)
         ilg.EmitFieldGet(ListEmptyFI);
     else if (_coll is IPersistentVector)
         ilg.EmitFieldGet(VectorEmptyFI);
     else if (_coll is IPersistentMap)
         ilg.EmitFieldGet(HashMapEmptyFI);
     else if (_coll is IPersistentSet)
         ilg.EmitFieldGet(HashSetEmptyFI);
     else
         throw new InvalidOperationException("Unknown collection type.");
     if (rhc == RHC.Statement)
         ilg.Emit(OpCodes.Pop);
 }
コード例 #2
0
ファイル: EmptyExpr.cs プロジェクト: mjmcaulay/clojure-clr
 //static readonly FieldInfo VectorEmptyFI = typeof(PersistentVector).GetField("EMPTY");
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     if (_coll is IPersistentList || _coll is LazySeq) // JVM does not include LazySeq test.  I'm getting it in some places.  LazySeq of 0 size got us here, we'll treat as an empty list
         ilg.EmitFieldGet(ListEmptyFI);
     else if (_coll is IPersistentVector)
         ilg.EmitFieldGet(TupleEmptyFI);
     else if (_coll is IPersistentMap)
         ilg.EmitFieldGet(HashMapEmptyFI);
     else if (_coll is IPersistentSet)
         ilg.EmitFieldGet(HashSetEmptyFI);
     else
         throw new InvalidOperationException("Unknown collection type.");
     if (rhc == RHC.Statement)
         ilg.Emit(OpCodes.Pop);
 }
コード例 #3
0
ファイル: GenProxy.cs プロジェクト: stuman08/clojure-clr
        private static FieldBuilder AddIProxyMethods(TypeBuilder proxyTB)
        {
            FieldBuilder fb = proxyTB.DefineField(
                _methodMapFieldName,
                typeof(IPersistentMap),
                 FieldAttributes.Private);

            MethodBuilder initMb = proxyTB.DefineMethod(
                "__initClojureFnMappings",
                 MethodAttributes.Public|MethodAttributes.Virtual|MethodAttributes.HideBySig,
                 typeof(void),
                 new Type[] { typeof(IPersistentMap) });
            CljILGen gen = new CljILGen(initMb.GetILGenerator());
            gen.EmitLoadArg(0);                     // gen.Emit(OpCodes.Ldarg_0);
            gen.EmitLoadArg(1);                     // gen.Emit(OpCodes.Ldarg_1);
            gen.EmitFieldSet(fb);                   // gen.Emit(OpCodes.Stfld, fb);
            gen.Emit(OpCodes.Ret);

            MethodBuilder updateTB = proxyTB.DefineMethod(
                "__updateClojureFnMappings",
                 MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
                 typeof(void),
                 new Type[] { typeof(IPersistentMap) });
            gen = new CljILGen(updateTB.GetILGenerator());
            gen.EmitLoadArg(0);                     // gen.Emit(OpCodes.Ldarg_0);

            gen.Emit(OpCodes.Dup);
            gen.EmitFieldGet(fb);                   // gen.Emit(OpCodes.Ldfld, fb);
            gen.Emit(OpCodes.Castclass, typeof(IPersistentMap));

            gen.EmitLoadArg(1);                                     // gen.Emit(OpCodes.Ldarg_1);
            gen.EmitCall(Method_IPersistentMap_Cons);        //gen.Emit(OpCodes.Call, Method_IPersistentCollection_Cons);

            gen.EmitFieldSet(fb);                                   // gen.Emit(OpCodes.Stfld, fb);
            gen.Emit(OpCodes.Ret);

            MethodBuilder getMb = proxyTB.DefineMethod(
                "__getClojureFnMappings",
                 MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
                typeof(IPersistentMap),
                Type.EmptyTypes);

            gen = new CljILGen(getMb.GetILGenerator());
            gen.EmitLoadArg(0);                                     // gen.Emit(OpCodes.Ldarg_0);
            gen.EmitFieldGet(fb);                                   // gen.Emit(OpCodes.Ldfld, fb);
            gen.Emit(OpCodes.Ret);

            return fb;
        }
コード例 #4
0
ファイル: GenClass.cs プロジェクト: chrisortman/clojure-clr
        static void EmitGetVar(CljILGen gen, FieldBuilder fb)
        {
            Label falseLabel = gen.DefineLabel();
            Label endLabel = gen.DefineLabel();

            gen.EmitFieldGet(fb);                       // gen.Emit(OpCodes.Ldsfld,fb);
            gen.Emit(OpCodes.Dup);
            gen.EmitCall(Method_Var_isBound);           // gen.Emit(OpCodes.Call, Method_Var_IsBound);
            gen.Emit(OpCodes.Brfalse_S,falseLabel);
            gen.Emit(OpCodes.Call,Method_Var_get);
            gen.Emit(OpCodes.Br_S,endLabel);
            gen.MarkLabel(falseLabel);
            gen.Emit(OpCodes.Pop);
            gen.EmitNull();                             // gen.Emit(OpCodes.Ldnull);
            gen.MarkLabel(endLabel);
        }
コード例 #5
0
ファイル: GenClass.cs プロジェクト: chrisortman/clojure-clr
        private static void EmitExposers(TypeBuilder proxyTB, Type superClass, IPersistentMap exposesFields)
        {
            for ( ISeq s = RT.seq(exposesFields); s != null; s = s.next() )
            {
                IMapEntry me = (IMapEntry)s.first();
                Symbol protectedFieldSym = (Symbol)me.key();
                IPersistentMap accessMap = (IPersistentMap)me.val();

                string fieldName = protectedFieldSym.Name;
                Symbol getterSym = (Symbol)accessMap.valAt(_getKw, null);
                Symbol setterSym = (Symbol)accessMap.valAt(_setKW, null);

                FieldInfo fld = null;

                if ( getterSym != null || setterSym != null )
                    fld = superClass.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance);

                if (getterSym != null)
                {
                    MethodAttributes attribs = MethodAttributes.Public;
                    if (fld.IsStatic)
                        attribs |= MethodAttributes.Static;

                    MethodBuilder mb = proxyTB.DefineMethod(getterSym.Name, attribs, fld.FieldType, Type.EmptyTypes);
                    CljILGen gen = new CljILGen(mb.GetILGenerator());
                    //if (fld.IsStatic)
                    //    gen.Emit(OpCodes.Ldsfld, fld);
                    //else
                    //{
                    //    gen.Emit(OpCodes.Ldarg_0);
                    //    gen.Emit(OpCodes.Ldfld, fld);
                    //}
                    if (!fld.IsStatic)
                        gen.EmitLoadArg(0);
                    gen.MaybeEmitVolatileOp(fld);
                    gen.EmitFieldGet(fld);

                    gen.Emit(OpCodes.Ret);
                }

                if (setterSym != null)
                {
                    MethodAttributes attribs = MethodAttributes.Public;
                    if (fld.IsStatic)
                        attribs |= MethodAttributes.Static;

                    MethodBuilder mb = proxyTB.DefineMethod(setterSym.Name, attribs, typeof(void), new Type[] { fld.FieldType });
                    CljILGen gen = new CljILGen(mb.GetILGenerator());
                    if (fld.IsStatic)
                    {
                        gen.Emit(OpCodes.Ldarg_0);
                        //gen.Emit(OpCodes.Stsfld, fld);
                    }
                    else
                    {
                        gen.Emit(OpCodes.Ldarg_0);
                        gen.Emit(OpCodes.Ldarg_1);
                        //gen.Emit(OpCodes.Stfld, fld);
                    }
                    gen.MaybeEmitVolatileOp(fld);
                    gen.EmitFieldSet(fld);
                    gen.Emit(OpCodes.Ret);
                }
            }
        }
コード例 #6
0
ファイル: InvokeExpr.cs プロジェクト: EricThorsen/clojure-clr
        void EmitProto(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Label onLabel = ilg.DefineLabel();
            Label callLabel = ilg.DefineLabel();
            Label endLabel = ilg.DefineLabel();

            Var v = ((VarExpr)_fexpr).Var;

            Expr e = (Expr)_args.nth(0);
            e.Emit(RHC.Expression, objx, ilg);               // target
            ilg.Emit(OpCodes.Dup);                               // target, target

            LocalBuilder targetTemp = ilg.DeclareLocal(typeof(Object));
            GenContext.SetLocalName(targetTemp, "target");
            ilg.Emit(OpCodes.Stloc,targetTemp);                  // target

            ilg.Emit(OpCodes.Call,Compiler.Method_Util_classOf);          // class
            ilg.EmitLoadArg(0);                                  // class, this
            ilg.EmitFieldGet(objx.CachedTypeField(_siteIndex));  // class, cached-class
            ilg.Emit(OpCodes.Beq, callLabel);                    //
            if (_protocolOn != null)
            {
                ilg.Emit(OpCodes.Ldloc,targetTemp);              // target
                ilg.Emit(OpCodes.Isinst, _protocolOn);           // null or target
                ilg.Emit(OpCodes.Ldnull);                        // (null or target), null
                ilg.Emit(OpCodes.Cgt_Un);                        // (0 or 1)
                ilg.Emit(OpCodes.Brtrue, onLabel);
            }
            ilg.Emit(OpCodes.Ldloc,targetTemp);                  // target
            ilg.Emit(OpCodes.Call,Compiler.Method_Util_classOf);          // class

            LocalBuilder typeTemp = ilg.DeclareLocal(typeof(Type));
            GenContext.SetLocalName(typeTemp, "type");
            ilg.Emit(OpCodes.Stloc,typeTemp);                    //    (typeType <= class)

            ilg.EmitLoadArg(0);                                  // this

            ilg.Emit(OpCodes.Ldloc,typeTemp);                    // this, class
            ilg.EmitFieldSet(objx.CachedTypeField(_siteIndex));  //

            ilg.MarkLabel(callLabel);

            objx.EmitVar(ilg,v);                              // var
            ilg.Emit(OpCodes.Call,Compiler.Method_Var_getRawRoot);         // proto-fn
            ilg.Emit(OpCodes.Castclass, typeof(AFunction));

            ilg.Emit(OpCodes.Ldloc,targetTemp);                  // proto-fn, target

            EmitArgsAndCall(1,rhc,objx,ilg);
            ilg.Emit(OpCodes.Br,endLabel);

            ilg.MarkLabel(onLabel);
            ilg.Emit(OpCodes.Ldloc,targetTemp);                  // target
            if ( _protocolOn != null )
            {
                ilg.Emit(OpCodes.Castclass, _protocolOn);
                MethodExpr.EmitTypedArgs(objx, ilg, _onMethod.GetParameters(), RT.subvec(_args, 1, _args.count()));
                //if (rhc == RHC.Return)
                //{
                //    ObjMethod2 method = (ObjMethod)Compiler.MethodVar.deref();
                //    method.EmitClearLocals(context);
                //}
                ilg.Emit(OpCodes.Callvirt, _onMethod);
                HostExpr.EmitBoxReturn(objx, ilg, _onMethod.ReturnType);
            }
            ilg.MarkLabel(endLabel);
        }
コード例 #7
0
ファイル: MethodExpr.cs プロジェクト: einert/clojure-clr
        static public void EmitDynamicCallPreamble(DynamicExpression dyn, IPersistentMap spanMap, string methodName, Type returnType, IList <ParameterExpression> paramExprs, Type[] paramTypes, CljILGen ilg, out LambdaExpression lambda, out Type delType, out MethodBuilder mbLambda)
        {
            Expression call = dyn;

            GenContext context = Compiler.CompilerContextVar.deref() as GenContext;

            DynInitHelper.SiteInfo siteInfo;
            if (context != null && context.DynInitHelper != null)
            {
                call = context.DynInitHelper.ReduceDyn(dyn, out siteInfo);
            }
            else
            {
                throw new InvalidOperationException("Don't know how to handle callsite in this case");
            }

            if (returnType == typeof(void))
            {
                call       = Expression.Block(call, Expression.Default(typeof(object)));
                returnType = typeof(object);
            }
            else if (returnType != call.Type)
            {
                call = Expression.Convert(call, returnType);
            }

            call = GenContext.AddDebugInfo(call, spanMap);


            delType  = Microsoft.Scripting.Generation.Snippets.Shared.DefineDelegate("__interop__", returnType, paramTypes);
            lambda   = Expression.Lambda(delType, call, paramExprs);
            mbLambda = null;

            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.Castclass, delType);
            }
            else
            {
                mbLambda = context.TB.DefineMethod(methodName, MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
                //lambda.CompileToMethod(mbLambda);
                // Now we get to do all this code create by hand.
                // the primary code is
                // (loc1 = fb).Target.Invoke(loc1,*args);
                // if return type if void, pop the value and push a null
                // if return type does not match the call site, add a conversion
                CljILGen ilg2 = new CljILGen(mbLambda.GetILGenerator());
                ilg2.EmitFieldGet(siteInfo.FieldBuilder);
                ilg2.Emit(OpCodes.Dup);
                LocalBuilder siteVar = ilg2.DeclareLocal(siteInfo.DelegateType);
                ilg2.Emit(OpCodes.Stloc, siteVar);
                ilg2.EmitFieldGet(siteInfo.SiteType.GetField("Target"));
                ilg2.Emit(OpCodes.Ldloc, siteVar);
                for (int i = 0; i < paramExprs.Count; i++)
                {
                    ilg2.EmitLoadArg(i);
                }

                ilg2.EmitCall(siteInfo.DelegateType.GetMethod("Invoke"));
                if (returnType == typeof(void))
                {
                    ilg2.Emit(OpCodes.Pop);
                    ilg2.EmitNull();
                }
                else if (returnType != call.Type)
                {
                    EmitConvertToType(ilg2, call.Type, returnType, false);
                }

                ilg2.Emit(OpCodes.Ret);


                /*
                 *             return Expression.Block(
                 * new[] { site },
                 * Expression.Call(
                 * Expression.Field(
                 *  Expression.Assign(site, access),
                 *  cs.GetType().GetField("Target")
                 * ),
                 * node.DelegateType.GetMethod("Invoke"),
                 * ClrExtensions.ArrayInsert(site, node.Arguments)
                 * )
                 */
            }
        }
コード例 #8
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
        protected void EmitValue(object value, CljILGen ilg)
        {
            bool partial = true;

            if (value == null)
                ilg.Emit(OpCodes.Ldnull);
            else if (value is String)
                ilg.Emit(OpCodes.Ldstr, (String)value);
            else if (value is Boolean)
            {
                ilg.EmitBoolean((Boolean)value);
                ilg.Emit(OpCodes.Box,typeof(bool));
            }
            else if (value is Int32)
            {
                ilg.EmitInt((int)value);
                ilg.Emit(OpCodes.Box, typeof(int));
            }
            else if (value is Int64)
            {
                ilg.EmitLong((long)value);
                ilg.Emit(OpCodes.Box, typeof(long));
            }
            else if (value is Double)
            {
                ilg.EmitDouble((double)value);
                ilg.Emit(OpCodes.Box, typeof(double));
            }
            else if (value is Char)
            {
                ilg.EmitChar((char)value);
                ilg.Emit(OpCodes.Box,typeof(char));
            }
            else if (value is Type)
            {
                Type t = (Type)value;
                if (t.IsValueType)
                    ilg.EmitType(t);
                else
                {
                    //ilg.EmitString(Compiler.DestubClassName(((Type)value).FullName));
                    ilg.EmitString(((Type)value).FullName);
                    ilg.EmitCall(Compiler.Method_RT_classForName);
                }
            }
            else if (value is Symbol)
            {
                Symbol sym = (Symbol)value;
                if (sym.Namespace == null)
                    ilg.EmitNull();
                else
                    ilg.EmitString(sym.Namespace);
                ilg.EmitString(sym.Name);
                ilg.EmitCall(Compiler.Method_Symbol_intern2);
            }
            else if (value is Keyword)
            {
                Keyword keyword = (Keyword)value;
                if (keyword.Namespace == null)
                    ilg.EmitNull();
                else
                    ilg.EmitString(keyword.Namespace);
                ilg.EmitString(keyword.Name);
                ilg.EmitCall(Compiler.Method_RT_keyword);
            }
            else if (value is Var)
            {
                Var var = (Var)value;
                ilg.EmitString(var.Namespace.Name.ToString());
                ilg.EmitString(var.Symbol.Name.ToString());
                ilg.EmitCall(Compiler.Method_RT_var2);
            }
            else if (value is IType)
            {
                IPersistentVector fields = (IPersistentVector)Reflector.InvokeStaticMethod(value.GetType(), "getBasis", Type.EmptyTypes);

                for (ISeq s = RT.seq(fields); s != null; s = s.next())
                {
                    Symbol field = (Symbol)s.first();
                    Type k = Compiler.TagType(Compiler.TagOf(field));
                    object val = Reflector.GetInstanceFieldOrProperty(value, field.Name);
                    EmitValue(val, ilg);
                    if (k.IsPrimitive)
                    {
                        ilg.Emit(OpCodes.Castclass, k);
                    }

                }

                ConstructorInfo cinfo = value.GetType().GetConstructors()[0];
                ilg.EmitNew(cinfo);
            }
            else if (value is IRecord)
            {
                //MethodInfo[] minfos = value.GetType().GetMethods(BindingFlags.Static | BindingFlags.Public);
                EmitValue(PersistentArrayMap.create((IDictionary)value), ilg);

                MethodInfo createMI = value.GetType().GetMethod("create", BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Standard, new Type[] { typeof(IPersistentMap) }, null);
                ilg.EmitCall(createMI);
            }
            else if (value is IPersistentMap)
            {
                IPersistentMap map = (IPersistentMap)value;
                List<object> entries = new List<object>(map.count() * 2);
                foreach (IMapEntry entry in map)
                {
                    entries.Add(entry.key());
                    entries.Add(entry.val());
                }
                EmitListAsObjectArray(entries, ilg);
                ilg.EmitCall(Compiler.Method_RT_map);
            }
            else if (value is IPersistentVector)
            {
                EmitListAsObjectArray(value, ilg);
                ilg.EmitCall(Compiler.Method_RT_vector);
            }
            else if (value is PersistentHashSet)
            {
                ISeq vs = RT.seq(value);
                if (vs == null)
                    ilg.EmitFieldGet(Compiler.Method_PersistentHashSet_EMPTY);
                else
                {
                    EmitListAsObjectArray(vs, ilg);
                    ilg.EmitCall(Compiler.Method_PersistentHashSet_create);
                }
            }
            else if (value is ISeq || value is IPersistentList)
            {
                EmitListAsObjectArray(value, ilg);
                ilg.EmitCall(Compiler.Method_PersistentList_create);
            }
            else if (value is Regex)
            {
                ilg.EmitString(((Regex)value).ToString());
                ilg.EmitNew(Compiler.Ctor_Regex_1);
            }
            else
            {
                string cs = null;
                try
                {
                    cs = RT.printString(value);
                }
                catch (Exception)
                {
                    throw new InvalidOperationException(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", value));
                }
                if (cs.Length == 0)
                    throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + value));
                if (cs.StartsWith("#<"))
                    throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + cs));

                ilg.EmitString(cs);
                ilg.EmitCall(Compiler.Method_RT_readString);
                partial = false;
            }

            if (partial)
            {
                if (value is IObj && RT.count(((IObj)value).meta()) > 0)
                {
                    ilg.Emit(OpCodes.Castclass, typeof(IObj));
                    Object m = ((IObj)value).meta();
                    EmitValue(Compiler.ElideMeta(m), ilg);
                    ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap));
                    ilg.Emit(OpCodes.Callvirt, Compiler.Method_IObj_withMeta);
                }
            }
        }
コード例 #9
0
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            if (objx.FnMode == FnMode.Light)
            {
                // This will emit a plain Keyword reference, rather than a callsite.
                InvokeExpr ie = new InvokeExpr(_source, _spanMap, (Symbol)_tag, _kw, RT.vector(_target));
                ie.Emit(rhc, objx, ilg);
            }
            else
            {
                Label endLabel = ilg.DefineLabel();
                Label faultLabel = ilg.DefineLabel();

                GenContext.EmitDebugInfo(ilg, _spanMap);

                LocalBuilder thunkLoc = ilg.DeclareLocal(typeof(ILookupThunk));
                LocalBuilder targetLoc = ilg.DeclareLocal(typeof(Object));
                LocalBuilder resultLoc = ilg.DeclareLocal(typeof(Object));
                GenContext.SetLocalName(thunkLoc, "thunk");
                GenContext.SetLocalName(targetLoc, "target");
                GenContext.SetLocalName(resultLoc, "result");

                // TODO: Debug info

                // pseudo-code:
                //  ILookupThunk thunk = objclass.ThunkField(i)
                //  object target = ...code...
                //  object val = thunk.get(target)
                //  if ( val != thunk )
                //     return val
                //  else
                //     KeywordLookupSite site = objclass.SiteField(i)
                //     thunk = site.fault(target)
                //     objclass.ThunkField(i) = thunk
                //     val = thunk.get(target)
                //     return val

                ilg.EmitFieldGet(objx.ThunkField(_siteIndex));                     // thunk
                ilg.Emit(OpCodes.Stloc, thunkLoc);                                  //  (thunkLoc <= thunk)

                _target.Emit(RHC.Expression, objx, ilg);                         // target
                ilg.Emit(OpCodes.Stloc, targetLoc);                                  //   (targetLoc <= target)

                ilg.Emit(OpCodes.Ldloc, thunkLoc);
                ilg.Emit(OpCodes.Ldloc, targetLoc);
                ilg.EmitCall(Compiler.Method_ILookupThunk_get);                    // result
                ilg.Emit(OpCodes.Stloc, resultLoc);                                 //    (resultLoc <= result)

                ilg.Emit(OpCodes.Ldloc, thunkLoc);
                ilg.Emit(OpCodes.Ldloc, resultLoc);
                ilg.Emit(OpCodes.Beq, faultLabel);

                ilg.Emit(OpCodes.Ldloc, resultLoc);                                  // result
                ilg.Emit(OpCodes.Br, endLabel);

                ilg.MarkLabel(faultLabel);
                ilg.EmitFieldGet(objx.KeywordLookupSiteField(_siteIndex));           // site
                ilg.Emit(OpCodes.Ldloc, targetLoc);                                  // site, target
                ilg.EmitCall(Compiler.Method_ILookupSite_fault);                    // new-thunk
                ilg.Emit(OpCodes.Dup);                                              // new-thunk, new-thunk
                ilg.EmitFieldSet(objx.ThunkField(_siteIndex));                      // new-thunk

                ilg.Emit(OpCodes.Ldloc, targetLoc);                                 // new-thunk, target
                ilg.EmitCall(Compiler.Method_ILookupThunk_get);                    // result

                ilg.MarkLabel(endLabel);                                           // result
                if (rhc == RHC.Statement)
                    ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #10
0
ファイル: ObjExpr.cs プロジェクト: aaronc/clojure-clr
 internal void EmitUnboxedLocal(CljILGen ilg, LocalBinding lb)
 {
     if (Closes.containsKey(lb))
     {
         if (_fnMode == FnMode.Full)
         {
             ilg.Emit(OpCodes.Ldarg_0); // this
             FieldBuilder fb = _closedOverFieldsMap[lb];
             ilg.MaybeEmitVolatileOp(IsVolatile(lb));
             ilg.Emit(OpCodes.Ldfld, fb);
         }
         else
         {
             ilg.Emit(OpCodes.Ldarg_0); // this
             ilg.Emit(OpCodes.Castclass, typeof(IFnClosure));
             ilg.EmitCall(Compiler.Method_IFnClosure_GetClosure);
             ilg.EmitFieldGet(Compiler.Field_Closure_Locals);
             ilg.EmitInt(lb.Index);
             ilg.EmitLoadElement(typeof(Object));
             if (lb.PrimitiveType != null)
                 ilg.Emit(OpCodes.Unbox, lb.PrimitiveType);
         }
     }
     else if (lb.IsArg)
     {
         //int argOffset = IsStatic ? 0 : 1;
         //ilg.Emit(OpCodes.Ldarg, lb.Index + argOffset);
         ilg.EmitLoadArg(lb.Index);
     }
     else if (lb.IsThis)
     {
         ilg.EmitLoadArg(0);
     }
     else
         ilg.Emit(OpCodes.Ldloc, lb.LocalVar);
 }
コード例 #11
0
ファイル: ObjExpr.cs プロジェクト: aaronc/clojure-clr
        internal void EmitLocal(CljILGen ilg, LocalBinding lb)
        {
            Type primType = lb.PrimitiveType;

            if (Closes.containsKey(lb))
            {
                if (_fnMode == FnMode.Full)
                {
                    ilg.Emit(OpCodes.Ldarg_0); // this
                    FieldBuilder fb = _closedOverFieldsMap[lb];
                    ilg.MaybeEmitVolatileOp(IsVolatile(lb));
                    ilg.Emit(OpCodes.Ldfld, fb);
                    if (primType != null)
                        HostExpr.EmitBoxReturn(this, ilg, primType);
                    // TODO: ONCEONLY?
                }
                else // FnMode.Light
                {
                    ilg.Emit(OpCodes.Ldarg_0); // this
                    ilg.Emit(OpCodes.Castclass, typeof(IFnClosure));
                    ilg.EmitCall(Compiler.Method_IFnClosure_GetClosure);
                    ilg.EmitFieldGet(Compiler.Field_Closure_Locals);
                    ilg.EmitInt(lb.Index);
                    ilg.EmitLoadElement(typeof(Object));
                }
            }
            else
            {
                if (lb.IsArg)
                {
                    //int argOffset = IsStatic ? 1 : 0;
                    //ilg.Emit(OpCodes.Ldarg, lb.Index - argOffset);
                    ilg.EmitLoadArg(lb.Index);
                }
                else if (lb.IsThis)
                {
                    ilg.EmitLoadArg(0);
                }
                else
                {
                    ilg.Emit(OpCodes.Ldloc, lb.LocalVar);
                }
                if (primType != null)
                    HostExpr.EmitBoxReturn(this, ilg, primType);
            }
        }
コード例 #12
0
ファイル: ObjExpr.cs プロジェクト: aaronc/clojure-clr
 internal void EmitConstant(CljILGen ilg, int id, object val)
 {
     if (_fnMode == Ast.FnMode.Light)
     {
         if (val == null)
         {
             ilg.EmitNull();
         }
         if (val.GetType().IsPrimitive)
         {
             EmitPrimitive(ilg, val);
             ilg.Emit(OpCodes.Box,val.GetType());
         }
         else
         {
             ilg.Emit(OpCodes.Ldarg_0); // this
             ilg.Emit(OpCodes.Castclass, typeof(IFnClosure));
             ilg.EmitCall(Compiler.Method_IFnClosure_GetClosure);
             ilg.EmitFieldGet(Compiler.Field_Closure_Constants);
             ilg.EmitInt(id);
             ilg.EmitLoadElement(typeof(Object));
             ilg.Emit(OpCodes.Castclass, ConstantType(id));
         }
     }
     else
     {
         FieldBuilder fb = null;
         if (_fnMode == FnMode.Full && ConstantFields != null && ConstantFields.TryGetValue(id, out fb))
         {
             ilg.MaybeEmitVolatileOp(fb);
             ilg.Emit(OpCodes.Ldsfld, fb);
         }
         else
             EmitValue(val, ilg);
     }
 }
コード例 #13
0
        protected void EmitValue(object value, CljILGen ilg)
        {
            bool partial = true;

            if (value == null)
            {
                ilg.Emit(OpCodes.Ldnull);
            }
            else if (value is String)
            {
                ilg.Emit(OpCodes.Ldstr, (String)value);
            }
            else if (value is Boolean)
            {
                ilg.EmitBoolean((Boolean)value);
                ilg.Emit(OpCodes.Box, typeof(bool));
            }
            else if (value is Int32)
            {
                ilg.EmitInt((int)value);
                ilg.Emit(OpCodes.Box, typeof(int));
            }
            else if (value is Int64)
            {
                ilg.EmitLong((long)value);
                ilg.Emit(OpCodes.Box, typeof(long));
            }
            else if (value is Double)
            {
                ilg.EmitDouble((double)value);
                ilg.Emit(OpCodes.Box, typeof(double));
            }
            else if (value is Char)
            {
                ilg.EmitChar((char)value);
                ilg.Emit(OpCodes.Box, typeof(char));
            }
            else if (value is Type)
            {
                Type t = (Type)value;
                if (t.IsValueType)
                {
                    ilg.EmitType(t);
                }
                else
                {
                    //ilg.EmitString(Compiler.DestubClassName(((Type)value).FullName));
                    ilg.EmitString(((Type)value).FullName);
                    ilg.EmitCall(Compiler.Method_RT_classForName);
                }
            }
            else if (value is Symbol)
            {
                Symbol sym = (Symbol)value;
                if (sym.Namespace == null)
                {
                    ilg.EmitNull();
                }
                else
                {
                    ilg.EmitString(sym.Namespace);
                }
                ilg.EmitString(sym.Name);
                ilg.EmitCall(Compiler.Method_Symbol_intern2);
            }
            else if (value is Keyword)
            {
                Keyword keyword = (Keyword)value;
                if (keyword.Namespace == null)
                {
                    ilg.EmitNull();
                }
                else
                {
                    ilg.EmitString(keyword.Namespace);
                }
                ilg.EmitString(keyword.Name);
                ilg.EmitCall(Compiler.Method_RT_keyword);
            }
            else if (value is Var)
            {
                Var var = (Var)value;
                ilg.EmitString(var.Namespace.Name.ToString());
                ilg.EmitString(var.Symbol.Name.ToString());
                ilg.EmitCall(Compiler.Method_RT_var2);
            }
            else if (value is IType)
            {
                IPersistentVector fields = (IPersistentVector)Reflector.InvokeStaticMethod(value.GetType(), "getBasis", Type.EmptyTypes);

                for (ISeq s = RT.seq(fields); s != null; s = s.next())
                {
                    Symbol field = (Symbol)s.first();
                    Type   k     = Compiler.TagType(Compiler.TagOf(field));
                    object val   = Reflector.GetInstanceFieldOrProperty(value, Compiler.munge(field.Name));
                    EmitValue(val, ilg);
                    if (k.IsPrimitive)
                    {
                        ilg.Emit(OpCodes.Castclass, k);
                    }
                }

                ConstructorInfo cinfo = value.GetType().GetConstructors()[0];
                ilg.EmitNew(cinfo);
            }
            else if (value is IRecord)
            {
                //MethodInfo[] minfos = value.GetType().GetMethods(BindingFlags.Static | BindingFlags.Public);
                EmitValue(PersistentArrayMap.create((IDictionary)value), ilg);

                MethodInfo createMI = value.GetType().GetMethod("create", BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Standard, new Type[] { typeof(IPersistentMap) }, null);
                ilg.EmitCall(createMI);
            }
            else if (value is IPersistentMap)
            {
                IPersistentMap map     = (IPersistentMap)value;
                List <object>  entries = new List <object>(map.count() * 2);
                foreach (IMapEntry entry in map)
                {
                    entries.Add(entry.key());
                    entries.Add(entry.val());
                }
                EmitListAsObjectArray(entries, ilg);
                ilg.EmitCall(Compiler.Method_RT_map);
            }
            else if (value is IPersistentVector)
            {
                IPersistentVector args = (IPersistentVector)value;
                if (args.count() <= Tuple.MAX_SIZE)
                {
                    for (int i = 0; i < args.count(); i++)
                    {
                        EmitValue(args.nth(i), ilg);
                    }
                    ilg.Emit(OpCodes.Call, Compiler.Methods_CreateTuple[args.count()]);
                }
                else
                {
                    EmitListAsObjectArray(value, ilg);
                    ilg.EmitCall(Compiler.Method_RT_vector);
                }
            }
            else if (value is PersistentHashSet)
            {
                ISeq vs = RT.seq(value);
                if (vs == null)
                {
                    ilg.EmitFieldGet(Compiler.Method_PersistentHashSet_EMPTY);
                }
                else
                {
                    EmitListAsObjectArray(vs, ilg);
                    ilg.EmitCall(Compiler.Method_PersistentHashSet_create);
                }
            }
            else if (value is ISeq || value is IPersistentList)
            {
                EmitListAsObjectArray(value, ilg);
                ilg.EmitCall(Compiler.Method_PersistentList_create);
            }
            else if (value is Regex)
            {
                ilg.EmitString(((Regex)value).ToString());
                ilg.EmitNew(Compiler.Ctor_Regex_1);
            }
            else
            {
                string cs = null;
                try
                {
                    cs = RT.printString(value);
                }
                catch (Exception)
                {
                    throw new InvalidOperationException(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", value));
                }
                if (cs.Length == 0)
                {
                    throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + value));
                }
                if (cs.StartsWith("#<"))
                {
                    throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + cs));
                }

                ilg.EmitString(cs);
                ilg.EmitCall(Compiler.Method_RT_readString);
                partial = false;
            }

            if (partial)
            {
                if (value is IObj && RT.count(((IObj)value).meta()) > 0)
                {
                    ilg.Emit(OpCodes.Castclass, typeof(IObj));
                    Object m = ((IObj)value).meta();
                    EmitValue(Compiler.ElideMeta(m), ilg);
                    ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap));
                    ilg.Emit(OpCodes.Callvirt, Compiler.Method_IObj_withMeta);
                }
            }
        }
コード例 #14
0
ファイル: InvokeExpr.cs プロジェクト: nasser/Clojure.Runtime
        void EmitProto(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Label onLabel   = ilg.DefineLabel();
            Label callLabel = ilg.DefineLabel();
            Label endLabel  = ilg.DefineLabel();

            Var v = ((VarExpr)_fexpr).Var;

            Expr e = (Expr)_args.nth(0);

            e.Emit(RHC.Expression, objx, ilg);               // target
            ilg.Emit(OpCodes.Dup);                           // target, target

            LocalBuilder targetTemp = ilg.DeclareLocal(typeof(Object));

            GenContext.SetLocalName(targetTemp, "target");
            ilg.Emit(OpCodes.Stloc, targetTemp);                  // target

            ilg.Emit(OpCodes.Call, Compiler.Method_Util_classOf); // class
            ilg.EmitFieldGet(objx.CachedTypeField(_siteIndex));   // class, cached-class
            ilg.Emit(OpCodes.Beq, callLabel);                     //
            if (_protocolOn != null)
            {
                ilg.Emit(OpCodes.Ldloc, targetTemp);             // target
                ilg.Emit(OpCodes.Isinst, _protocolOn);           // null or target
                ilg.Emit(OpCodes.Ldnull);                        // (null or target), null
                ilg.Emit(OpCodes.Cgt_Un);                        // (0 or 1)
                ilg.Emit(OpCodes.Brtrue, onLabel);
            }
            ilg.Emit(OpCodes.Ldloc, targetTemp);                  // target
            ilg.Emit(OpCodes.Call, Compiler.Method_Util_classOf); // class

            LocalBuilder typeTemp = ilg.DeclareLocal(typeof(Type));

            GenContext.SetLocalName(typeTemp, "type");
            ilg.Emit(OpCodes.Stloc, typeTemp);                    //    (typeType <= class)


            ilg.Emit(OpCodes.Ldloc, typeTemp);                   // this, class
            ilg.EmitFieldSet(objx.CachedTypeField(_siteIndex));  //

            ilg.MarkLabel(callLabel);

            objx.EmitVar(ilg, v);                                   // var
            ilg.Emit(OpCodes.Call, Compiler.Method_Var_getRawRoot); // proto-fn
            ilg.Emit(OpCodes.Castclass, typeof(AFunction));

            ilg.Emit(OpCodes.Ldloc, targetTemp);                  // proto-fn, target

            EmitArgsAndCall(1, rhc, objx, ilg);
            ilg.Emit(OpCodes.Br, endLabel);

            ilg.MarkLabel(onLabel);
            ilg.Emit(OpCodes.Ldloc, targetTemp);                  // target
            if (_protocolOn != null)
            {
                ilg.Emit(OpCodes.Castclass, _protocolOn);
                MethodExpr.EmitTypedArgs(objx, ilg, _onMethod.GetParameters(), RT.subvec(_args, 1, _args.count()));
                // In JVM.  No necessary here.
                //if (_tailPosition)
                //{
                //    ObjMethod method = (ObjMethod)Compiler.MethodVar.deref();
                //    method.EmitClearThis(ilg);
                //}
                ilg.Emit(OpCodes.Callvirt, _onMethod);
                HostExpr.EmitBoxReturn(objx, ilg, _onMethod.ReturnType);
            }
            ilg.MarkLabel(endLabel);
        }
コード例 #15
0
 protected override void EmitGet(CljILGen ilg)
 {
     ilg.MaybeEmitVolatileOp(_tinfo);
     ilg.EmitFieldGet(_tinfo);
 }
コード例 #16
0
ファイル: GenProxy.cs プロジェクト: stuman08/clojure-clr
        private static void GenerateProxyMethod(
            TypeBuilder proxyTB,
            FieldBuilder mapField,
            MethodInfo m,
            HashSet<MethodBuilder> specialMethods)
        {
            MethodAttributes attribs = m.Attributes;

            bool callBaseMethod;

            if ( (attribs & MethodAttributes.Abstract) == MethodAttributes.Abstract )
            {
                attribs &= ~MethodAttributes.Abstract;
                callBaseMethod = false;
            }
            else
            {
                callBaseMethod = true;

            }

            attribs &= ~MethodAttributes.NewSlot;
            attribs |= MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.Public;

            //Console.Write("Generating proxy method {0}(", m.Name);
            //foreach (ParameterInfo p in m.GetParameters())
            //    Console.Write("{0}, ", p.ParameterType.FullName);
            //Console.Write(") ");
            //Console.WriteLine(attribs.ToString());

            MethodBuilder proxym = proxyTB.DefineMethod(
                m.Name,
                attribs,
                m.CallingConvention,
                m.ReturnType,
                m.GetParameters().Select<ParameterInfo, Type>(p => p.ParameterType).ToArray<Type>());

            if (m.IsSpecialName)
                specialMethods.Add(proxym);

            CljILGen gen = new CljILGen(proxym.GetILGenerator());

            Label elseLabel = gen.DefineLabel();
            Label endLabel = gen.DefineLabel();

            //// Print a little message, for debugging purposes
            //gen.Emit(OpCodes.Ldstr, String.Format("Calling {0} / {1}", proxyTB.FullName, m.ToString()));
            //gen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
            //    new Type[] { typeof(string) }));
            //gen.Emit(OpCodes.Call, typeof(Console).GetMethod("get_Out"));
            //gen.Emit(OpCodes.Call, typeof(System.IO.TextWriter).GetMethod("Flush"));

            // Lookup method name in map
            gen.EmitLoadArg(0);                             // gen.Emit(OpCodes.Ldarg_0);
            gen.EmitFieldGet(mapField);                     // gen.Emit(OpCodes.Ldfld, mapField);
            gen.EmitString(m.Name);                         // gen.Emit(OpCodes.Ldstr, m.Name);
            gen.EmitCall(Method_RT_get);                    // gen.Emit(OpCodes.Call, Method_RT_get);
            gen.Emit(OpCodes.Dup);
            gen.EmitNull();                                 // gen.Emit(OpCodes.Ldnull);
            gen.Emit(OpCodes.Beq_S, elseLabel);

            // map entry found
            ParameterInfo[] pinfos = m.GetParameters();
            gen.Emit(OpCodes.Castclass, typeof(IFn));
            gen.EmitLoadArg(0);                             // gen.Emit(OpCodes.Ldarg_0);  // push implicit 'this' arg.
            for (int i = 0; i < pinfos.Length; i++)
            {
                gen.EmitLoadArg(i + 1);                     // gen.Emit(OpCodes.Ldarg, i + 1);
                if (m.GetParameters()[i].ParameterType.IsValueType)
                    gen.Emit(OpCodes.Box,pinfos[i].ParameterType);
            }

            int parmCount = pinfos.Length;
            gen.EmitCall(GetIFnInvokeMethodInfo(parmCount+1));        // gen.Emit(OpCodes.Call, GetIFnInvokeMethodInfo(parmCount + 1));
            if (m.ReturnType == typeof(void))
                gen.Emit(OpCodes.Pop);
            else
                gen.Emit(OpCodes.Unbox_Any, m.ReturnType);

            gen.Emit(OpCodes.Br_S,endLabel);

            // map entry not found
            gen.MarkLabel(elseLabel);
            gen.Emit(OpCodes.Pop); // get rid of null leftover from the 'get'

            if ( callBaseMethod )
            {
                gen.EmitLoadArg(0);                                     // gen.Emit(OpCodes.Ldarg_0);
                for (int i = 0; i < parmCount; i++)
                    gen.EmitLoadArg(i + 1);                             // gen.Emit(OpCodes.Ldarg, i + 1);
                gen.Emit(OpCodes.Call, m);                              // gen.EmitCall(m) improperly emits a callvirt in some cases
            }
            else
            {
                gen.EmitString(m.Name);                                 // gen.Emit(OpCodes.Ldstr, m.Name);
                gen.EmitNew(CtorInfo_NotImplementedException_1);        // gen.Emit(OpCodes.Newobj, CtorInfo_NotImplementedException_1);
                gen.Emit(OpCodes.Throw);
            }

            gen.MarkLabel(endLabel);
            gen.Emit(OpCodes.Ret);
        }
コード例 #17
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
        private void EmitMetaFunctions(TypeBuilder fnTB)
        {
            // IPersistentMap meta()
            MethodBuilder metaMB = fnTB.DefineMethod("meta", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(IPersistentMap), Type.EmptyTypes);
            CljILGen gen = new CljILGen(metaMB.GetILGenerator());
            if (SupportsMeta)
            {
                gen.EmitLoadArg(0);
                gen.EmitFieldGet(_metaField);
            }
            else
                gen.EmitNull();
            gen.Emit(OpCodes.Ret);

            // IObj withMeta(IPersistentMap)
            MethodBuilder withMB = fnTB.DefineMethod("withMeta", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(IObj), new Type[] { typeof(IPersistentMap) });
            gen = new CljILGen(withMB.GetILGenerator());

            if (SupportsMeta)
            {
                gen.EmitLoadArg(1);   // meta arg
                foreach (FieldBuilder fb in _closedOverFields)
                {
                    gen.EmitLoadArg(0);
                    gen.MaybeEmitVolatileOp(fb);
                    gen.EmitFieldGet(fb);
                }

                gen.EmitNew(_ctorInfo);
            }
            else
                gen.EmitLoadArg(0);  //this
            gen.Emit(OpCodes.Ret);
        }
コード例 #18
0
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Label endLabel   = ilg.DefineLabel();
            Label faultLabel = ilg.DefineLabel();

            GenContext.EmitDebugInfo(ilg, _spanMap);

            LocalBuilder thunkLoc  = ilg.DeclareLocal(typeof(ILookupThunk));
            LocalBuilder targetLoc = ilg.DeclareLocal(typeof(Object));
            LocalBuilder resultLoc = ilg.DeclareLocal(typeof(Object));

            GenContext.SetLocalName(thunkLoc, "thunk");
            GenContext.SetLocalName(targetLoc, "target");
            GenContext.SetLocalName(resultLoc, "result");

            // TODO: Debug info

            // pseudo-code:
            //  ILookupThunk thunk = objclass.ThunkField(i)
            //  object target = ...code...
            //  object val = thunk.get(target)
            //  if ( val != thunk )
            //     return val
            //  else
            //     KeywordLookupSite site = objclass.SiteField(i)
            //     thunk = site.fault(target)
            //     objclass.ThunkField(i) = thunk
            //     val = thunk.get(target)
            //     return val

            ilg.EmitFieldGet(objx.ThunkField(_siteIndex));                   // thunk
            ilg.Emit(OpCodes.Stloc, thunkLoc);                               //  (thunkLoc <= thunk)

            _target.Emit(RHC.Expression, objx, ilg);                         // target
            ilg.Emit(OpCodes.Stloc, targetLoc);                              //   (targetLoc <= target)

            ilg.Emit(OpCodes.Ldloc, thunkLoc);
            ilg.Emit(OpCodes.Ldloc, targetLoc);
            ilg.EmitCall(Compiler.Method_ILookupThunk_get);                    // result
            ilg.Emit(OpCodes.Stloc, resultLoc);                                //    (resultLoc <= result)

            ilg.Emit(OpCodes.Ldloc, thunkLoc);
            ilg.Emit(OpCodes.Ldloc, resultLoc);
            ilg.Emit(OpCodes.Beq, faultLabel);

            ilg.Emit(OpCodes.Ldloc, resultLoc);                                  // result
            ilg.Emit(OpCodes.Br, endLabel);

            ilg.MarkLabel(faultLabel);
            ilg.EmitFieldGet(objx.KeywordLookupSiteField(_siteIndex));         // site
            ilg.Emit(OpCodes.Ldloc, targetLoc);                                // site, target
            ilg.EmitCall(Compiler.Method_ILookupSite_fault);                   // new-thunk
            ilg.Emit(OpCodes.Dup);                                             // new-thunk, new-thunk
            ilg.EmitFieldSet(objx.ThunkField(_siteIndex));                     // new-thunk

            ilg.Emit(OpCodes.Ldloc, targetLoc);                                // new-thunk, target
            ilg.EmitCall(Compiler.Method_ILookupThunk_get);                    // result

            ilg.MarkLabel(endLabel);                                           // result
            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #19
0
ファイル: DefExpr.cs プロジェクト: telefunkenvf14/clojure-clr
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            objx.EmitVar(ilg, _var);

            if ( _shadowsCoreMapping )
            {
                LocalBuilder locNs = ilg.DeclareLocal(typeof(Namespace));
                GenContext.SetLocalName(locNs, "ns");

                ilg.Emit(OpCodes.Dup);
                ilg.EmitFieldGet(VarNsFI);
                ilg.Emit(OpCodes.Stloc,locNs);

                LocalBuilder locSym = ilg.DeclareLocal(typeof(Symbol));
                GenContext.SetLocalName(locSym, "sym");

                ilg.Emit(OpCodes.Dup);
                ilg.EmitFieldGet(VarSymFI);
                ilg.Emit(OpCodes.Stloc, locSym);

                ilg.Emit(OpCodes.Ldloc, locNs);
                ilg.Emit(OpCodes.Ldloc, locSym);
                ilg.Emit(OpCodes.Call, NamespaceReferMI);
            }

            if (_isDynamic)
            {
                ilg.Emit(OpCodes.Call, Compiler.Method_Var_setDynamic0);
            }
            if (_meta != null)
            {
                if (_initProvided || true) //IncludesExplicitMetadata((MapExpr)_meta))
                {
                    ilg.Emit(OpCodes.Dup);
                    _meta.Emit(RHC.Expression, objx, ilg);
                    ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap));
                    ilg.Emit(OpCodes.Call, Compiler.Method_Var_setMeta);
                }
            }
            if (_initProvided)
            {
                ilg.Emit(OpCodes.Dup);
                if (_init is FnExpr)
                    ((FnExpr)_init).EmitForDefn(objx, ilg);
                else
                    _init.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Call,Compiler.Method_Var_bindRoot);
            }
            if (rhc == RHC.Statement)
                ilg.Emit(OpCodes.Pop);
        }
コード例 #20
0
 protected override void EmitGet(CljILGen ilg)
 {
     ilg.EmitFieldGet(_tinfo);
 }