コード例 #1
0
 public override void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     ilg.EmitBoolean(_val);
     ilg.Emit(OpCodes.Box,typeof(bool));
     if (rhc == RHC.Statement)
         ilg.Emit(OpCodes.Pop);
 }
コード例 #2
0
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     EmitUnboxed(rhc, objx, ilg);
     HostExpr.EmitBoxReturn(objx, ilg, typeof(bool));
     if (rhc == RHC.Statement)
         ilg.Emit(OpCodes.Pop);
 }
コード例 #3
0
ファイル: DefExpr.cs プロジェクト: robertlj/clojure-clr
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     objx.EmitVar(ilg, _var);
     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);
 }
コード例 #4
0
ファイル: VarExpr.cs プロジェクト: telefunkenvf14/clojure-clr
 public void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val)
 {
     objx.EmitVar(ilg, _var);
     val.Emit(RHC.Expression, objx, ilg);
     ilg.Emit(OpCodes.Call, Compiler.Method_Var_set);
     if (rhc == RHC.Statement)
         ilg.Emit(OpCodes.Pop);
 }
コード例 #5
0
ファイル: ImportExpr.cs プロジェクト: JvJ/clojure-clr
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     ilg.Emit(OpCodes.Call,Compiler.Method_Compiler_CurrentNamespace.GetGetMethod());
     ilg.Emit(OpCodes.Ldstr, _c);
     ilg.Emit(OpCodes.Call, Compiler.Method_RT_classForName);
     ilg.Emit(OpCodes.Call, Compiler.Method_Namespace_importClass1);
     if (rhc == RHC.Statement)
         ilg.Emit(OpCodes.Pop);
 }
コード例 #6
0
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     for (int i = 0; i < _exprs.count() - 1; i++)
     {
         Expr e = (Expr)_exprs.nth(i);
         e.Emit(RHC.Statement, objx, ilg);
     }
     LastExpr.Emit(rhc, objx, ilg);
 }
コード例 #7
0
 public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     for (int i = 0; i < _exprs.count() - 1; i++)
     {
         Expr e = (Expr)_exprs.nth(i);
         e.Emit(RHC.Statement, objx, ilg);
     }
     MaybePrimitiveExpr mbe = (MaybePrimitiveExpr)LastExpr;
     mbe.EmitUnboxed(rhc, objx, ilg);
 }
コード例 #8
0
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     _expr.Emit(RHC.Expression, objx, ilg);
     ilg.Emit(OpCodes.Castclass, typeof(IObj));
     _meta.Emit(RHC.Expression, objx, ilg);
     ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap));
     ilg.EmitCall(Compiler.Method_IObj_withMeta);
     if (rhc == RHC.Statement)
         ilg.Emit(OpCodes.Pop);
 }
コード例 #9
0
ファイル: ThrowExpr.cs プロジェクト: mjmcaulay/clojure-clr
 public override void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     if (_excExpr == null)
     {
         ilg.Emit(OpCodes.Rethrow);
     }
     else
     {
         _excExpr.Emit(RHC.Expression, objx, ilg);
         ilg.Emit(OpCodes.Castclass, typeof(Exception));
         ilg.Emit(OpCodes.Throw);
     }
 }
コード例 #10
0
        public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Type t = _n.GetType();

            if (t == typeof(int))
                ilg.EmitLong((long)(int)_n);
            else if (t == typeof(double))
                ilg.EmitDouble((double)_n);
            else if (t == typeof(long))
                ilg.EmitLong((long)_n);
            else
                throw new ArgumentException("Unsupported Number type: " + _n.GetType().Name);
        }
コード例 #11
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);
        }
コード例 #12
0
ファイル: LetExpr.cs プロジェクト: corvusalba/clojure-clr
        void DoEmit(RHC rhc, ObjExpr objx, CljILGen ilg, bool emitUnboxed)
        {
            List<LocalBuilder> locals = new List<LocalBuilder>();

            for (int i = 0; i < _bindingInits.count(); i++)
            {
                BindingInit bi = (BindingInit)_bindingInits.nth(i);
                Type primType = Compiler.MaybePrimitiveType(bi.Init);
                if (primType != null)
                {
                    LocalBuilder local = ilg.DeclareLocal(primType);
                    locals.Add(local);
                    GenContext.SetLocalName(local, bi.Binding.Name);
                    bi.Binding.LocalVar = local;

                    ((MaybePrimitiveExpr)bi.Init).EmitUnboxed(RHC.Expression, objx, ilg);
                    ilg.Emit(OpCodes.Stloc, local);
                }
                else
                {
                    LocalBuilder local = ilg.DeclareLocal(typeof(Object));
                    locals.Add(local);
                    GenContext.SetLocalName(local, bi.Binding.Name);
                    bi.Binding.LocalVar = local;

                    bi.Init.Emit(RHC.Expression, objx, ilg);
                    ilg.Emit(OpCodes.Stloc, local);
                }
             }

            Label loopLabel = ilg.DefineLabel();
            ilg.MarkLabel(loopLabel);

            try
            {
                if (_isLoop)
                    Var.pushThreadBindings(PersistentHashMap.create(Compiler.LoopLabelVar, loopLabel));

                if (emitUnboxed)
                    ((MaybePrimitiveExpr)_body).EmitUnboxed(rhc, objx, ilg);
                else
                    _body.Emit(rhc, objx, ilg);
            }
            finally
            {
                if (_isLoop)
                    Var.popThreadBindings();
            }
        }
コード例 #13
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);
 }
コード例 #14
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);
 }
コード例 #15
0
ファイル: InstanceOfExpr.cs プロジェクト: JvJ/clojure-clr
        public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            _expr.Emit(RHC.Expression, objx, ilg);

            // This corresponds to the most general case code in System.Linq.Expressions.Compiler.LambdaCompiler

            Type opType = _expr.HasClrType && _expr.ClrType != null ? _expr.ClrType : typeof(object);
            if (opType.IsValueType)
            {
                ilg.Emit(OpCodes.Box, opType);
            }
            ilg.Emit(OpCodes.Isinst, _t);
            ilg.Emit(OpCodes.Ldnull);
            ilg.Emit(OpCodes.Cgt_Un);
        }
コード例 #16
0
ファイル: NewExpr.cs プロジェクト: telefunkenvf14/clojure-clr
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            GenContext.EmitDebugInfo(ilg, _spanMap);

            if (_ctor != null)
                EmitForMethod(rhc, objx, ilg);
            else if (_isNoArgValueTypeCtor)
                EmitForNoArgValueTypeCtor(rhc, objx, ilg);
            else
            {
                EmitComplexCall(rhc, objx, ilg);
                if (_type.IsValueType)
                    HostExpr.EmitBoxReturn(objx, ilg, _type);
            }

            if (rhc == RHC.Statement)
                ilg.Emit(OpCodes.Pop);
        }
コード例 #17
0
ファイル: MethodExpr.cs プロジェクト: TerabyteX/clojure-clr
        public override void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            GenContext.EmitDebugInfo(ilg, _spanMap);

            Type retType;

            if (_method != null)
            {
                EmitForMethod(objx, ilg);
                retType = _method.ReturnType;
            }
            else
            {
                EmitComplexCall(objx, ilg);
                retType = typeof(object);
            }
            HostExpr.EmitBoxReturn(objx, ilg, retType);

            if (rhc == RHC.Statement)
                ilg.Emit(OpCodes.Pop);
        }
コード例 #18
0
ファイル: LetFnExpr.cs プロジェクト: clojure/clojure-clr
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            int n = _bindingInits.count();

            // Define our locals
            for (int i = 0; i < n; i++)
            {
                BindingInit bi = (BindingInit)_bindingInits.nth(i);
                LocalBuilder local = ilg.DeclareLocal(typeof(IFn));
                bi.Binding.LocalVar = local;
                ilg.Emit(OpCodes.Ldnull);
                ilg.Emit(OpCodes.Stloc, local);
            }

            // Then initialize

            IPersistentSet lbset = PersistentHashSet.EMPTY;

            for (int i = 0; i < n; i++)
            {
                BindingInit bi = (BindingInit)_bindingInits.nth(i);
                lbset = (IPersistentSet)lbset.cons(bi.Binding);

                bi.Init.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Stloc,bi.Binding.LocalVar);
            }

            for (int i = 0; i < n; i++)
            {
                BindingInit bi = (BindingInit)_bindingInits.nth(i);
                ObjExpr fe = (ObjExpr)bi.Init;

                ilg.Emit(OpCodes.Ldloc, bi.Binding.LocalVar);
                fe.EmitLetFnInits(ilg, bi.Binding.LocalVar, objx, lbset);
            }

            _body.Emit(rhc, objx, ilg);
        }
コード例 #19
0
ファイル: TryExpr.cs プロジェクト: clojure/clojure-clr
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            if (_catchExprs.count() == 0 && _finallyExpr == null)
            {
                // degenerate case
                _tryExpr.Emit(rhc, objx, ilg);
                return;
            }

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

            ilg.BeginExceptionBlock();
            _tryExpr.Emit(rhc, objx, ilg);
            if (rhc != RHC.Statement)
                ilg.Emit(OpCodes.Stloc, retLocal);

            for (int i = 0; i < _catchExprs.count(); i++)
            {
                CatchClause clause = (CatchClause)_catchExprs.nth(i);
                ilg.BeginCatchBlock(clause.Type);
                // Exception should be on the stack.  Put in clause local
                clause.Lb.LocalVar = ilg.DeclareLocal(clause.Type);
                ilg.Emit(OpCodes.Stloc, clause.Lb.LocalVar);
                clause.Handler.Emit(rhc, objx, ilg);
                if (clause.Handler.HasNormalExit() && rhc != RHC.Statement)
                    ilg.Emit(OpCodes.Stloc, retLocal);
            }

            if (_finallyExpr != null)
            {
                ilg.BeginFinallyBlock();
                _finallyExpr.Emit(RHC.Statement, objx, ilg);
            }
            ilg.EndExceptionBlock();
            if (rhc != RHC.Statement)
                ilg.Emit(OpCodes.Ldloc, retLocal);
        }
コード例 #20
0
        /***
         * Current host interop uses reflection, which requires pre-existing classes
         * Work around this by:
         * Generate a stub class that has the same interfaces and fields as the class we are generating.
         * Use it as a type hint for this, and bind the simple name of the class to this stub (in resolve etc)
         * Unmunge the name (using a magic prefix) on any code gen for classes
         */

        // TODO: Preparse method heads to pick up signatures, implement those methods as abstract or as NotImpelmented so that Reflection can pick up calls during compilation and avoide a callsite.
        static Type CompileStub(GenContext context, Type super, NewInstanceExpr ret, Type[] interfaces, Object frm)
        {
            //GenContext context = Compiler.CompilerContextVar.get() as GenContext ?? GenContext.CreateWithExternalAssembly("stub" + RT.nextID().ToString(), ".dll", false);
            //GenContext context = Compiler.IsCompiling ? Compiler.CompilerContextVar.get() as GenContext : GenContext.CreateWithExternalAssembly("stub" + RT.nextID().ToString(), ".dll", false);
            //context = GenContext.CreateWithExternalAssembly("stub" + RT.nextID().ToString(), ".dll", false);
            TypeBuilder tb = context.ModuleBuilder.DefineType(Compiler.CompileStubPrefix + "." + ret.InternalName + RT.nextID(), TypeAttributes.Public | TypeAttributes.Abstract, super, interfaces);

            tb.DefineDefaultConstructor(MethodAttributes.Public);

            // instance fields for closed-overs
            for (ISeq s = RT.keys(ret.Closes); s != null; s = s.next())
            {
                LocalBinding    lb     = (LocalBinding)s.first();
                FieldAttributes access = FieldAttributes.Public;

                // TODO: FIgure out Volatile
                if (!ret.IsVolatile(lb))
                {
                    access |= FieldAttributes.InitOnly;
                }

                if (lb.PrimitiveType != null)
                {
                    tb.DefineField(lb.Name, lb.PrimitiveType, access);
                }
                else
                {
                    tb.DefineField(lb.Name, typeof(Object), access);
                }
            }

            // ctor that takes closed-overs and does nothing
            if (ret.CtorTypes().Length > 0)
            {
                ConstructorBuilder cb  = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, ret.CtorTypes());
                CljILGen           ilg = new CljILGen(cb.GetILGenerator());
                ilg.EmitLoadArg(0);
                ilg.Emit(OpCodes.Call, super.GetConstructor(Type.EmptyTypes));
                ilg.Emit(OpCodes.Ret);


                if (ret._altCtorDrops > 0)
                {
                    Type[] ctorTypes = ret.CtorTypes();
                    int    newLen    = ctorTypes.Length - ret._altCtorDrops;
                    if (newLen > 0)
                    {
                        Type[] altCtorTypes = new Type[newLen];
                        for (int i = 0; i < altCtorTypes.Length; i++)
                        {
                            altCtorTypes[i] = ctorTypes[i];
                        }
                        ConstructorBuilder cb2  = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, altCtorTypes);
                        CljILGen           ilg2 = new CljILGen(cb2.GetILGenerator());
                        ilg2.EmitLoadArg(0);
                        for (int i = 0; i < newLen; i++)
                        {
                            ilg2.EmitLoadArg(i + 1);
                        }
                        for (int i = 0; i < ret._altCtorDrops; i++)
                        {
                            ilg2.EmitNull();
                        }
                        ilg2.Emit(OpCodes.Call, cb);
                        ilg2.Emit(OpCodes.Ret);
                    }
                }
            }

            Type t = tb.CreateType();

            //Compiler.RegisterDuplicateType(t);
            return(t);
        }
コード例 #21
0
        private void DoEmitPrimOrStatic(ObjExpr fn, TypeBuilder tb, bool isStatic)
        {
            MethodAttributes attribs = isStatic
                ? MethodAttributes.Static | MethodAttributes.Public
                : MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual;

            string methodName = isStatic ? "invokeStatic" : "invokePrim";

            Type returnType;

            if (_retType == typeof(double) || _retType == typeof(long))
            {
                returnType = GetReturnType();
            }
            else
            {
                returnType = typeof(object);
            }

            MethodBuilder baseMB = tb.DefineMethod(methodName, attribs, returnType, _argTypes);

            if (!isStatic)
            {
                SetCustomAttributes(baseMB);
            }

            CljILGen baseIlg = new CljILGen(baseMB.GetILGenerator());

            try
            {
                Label loopLabel = baseIlg.DefineLabel();
                Var.pushThreadBindings(RT.map(Compiler.LoopLabelVar, loopLabel, Compiler.MethodVar, this));

                GenContext.EmitDebugInfo(baseIlg, SpanMap);

                baseIlg.MarkLabel(loopLabel);
                EmitBody(Objx, baseIlg, _retType, _body);
                if (_body.HasNormalExit())
                {
                    baseIlg.Emit(OpCodes.Ret);
                }
            }
            finally
            {
                Var.popThreadBindings();
            }
            // Generate the regular invoke, calling the static or prim method

            MethodBuilder regularMB = tb.DefineMethod(GetMethodName(), MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual, typeof(Object), GetArgTypes());

            SetCustomAttributes(regularMB);

            CljILGen regIlg = new CljILGen(regularMB.GetILGenerator());

            if (!isStatic)
            {
                regIlg.Emit(OpCodes.Ldarg_0);
            }
            for (int i = 0; i < _argTypes.Length; i++)
            {
                regIlg.EmitLoadArg(i + 1);
                HostExpr.EmitUnboxArg(fn, regIlg, _argTypes[i]);
            }
            regIlg.Emit(OpCodes.Call, baseMB);
            if (GetReturnType().IsValueType)
            {
                regIlg.Emit(OpCodes.Box, GetReturnType());
            }
            regIlg.Emit(OpCodes.Ret);
        }
コード例 #22
0
ファイル: FnExpr.cs プロジェクト: silky/clojure-clr
 internal void EmitForDefn(ObjExpr objx, CljILGen ilg)
 {
     Emit(RHC.Expression, objx, ilg);
 }
コード例 #23
0
ファイル: IfExpr.cs プロジェクト: terkhorn/clojure-clr
        void DoEmit(RHC rhc, ObjExpr objx, CljILGen ilg, bool emitUnboxed)
        {
            Label nullLabel  = ilg.DefineLabel();
            Label falseLabel = ilg.DefineLabel();
            Label endLabel   = ilg.DefineLabel();
            Label trueLabel  = ilg.DefineLabel();

            GenContext.EmitDebugInfo(ilg, _sourceSpan);

            StaticMethodExpr sme = _testExpr as StaticMethodExpr;

            if (sme != null && sme.CanEmitIntrinsicPredicate())
            {
                sme.EmitIntrinsicPredicate(RHC.Expression, objx, ilg, falseLabel);
            }
            else if (Compiler.MaybePrimitiveType(_testExpr) == typeof(bool))
            {
                ((MaybePrimitiveExpr)_testExpr).EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Brfalse, falseLabel);
            }
            else
            {
                LocalBuilder tempLoc = ilg.DeclareLocal(typeof(Object));
                GenContext.SetLocalName(tempLoc, "test");

                _testExpr.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Dup);
                ilg.Emit(OpCodes.Stloc, tempLoc);

                ilg.Emit(OpCodes.Brfalse, nullLabel);

                ilg.Emit(OpCodes.Ldloc, tempLoc);
                ilg.Emit(OpCodes.Isinst, typeof(bool));
                ilg.Emit(OpCodes.Ldnull);
                ilg.Emit(OpCodes.Cgt_Un);
                ilg.Emit(OpCodes.Brfalse, trueLabel);

                ilg.Emit(OpCodes.Ldloc, tempLoc);
                ilg.Emit(OpCodes.Unbox_Any, typeof(bool));
                ilg.Emit(OpCodes.Ldc_I4_0);
                ilg.Emit(OpCodes.Ceq);
                ilg.Emit(OpCodes.Brtrue, falseLabel);
            }

            ilg.MarkLabel(trueLabel);

            if (emitUnboxed)
            {
                ((MaybePrimitiveExpr)_thenExpr).EmitUnboxed(rhc, objx, ilg);
            }
            else
            {
                _thenExpr.Emit(rhc, objx, ilg);
            }


            if (_thenExpr.HasNormalExit())
            {
                ilg.Emit(OpCodes.Br, endLabel);
            }

            ilg.MarkLabel(nullLabel);
            ilg.MarkLabel(falseLabel);

            if (emitUnboxed)
            {
                ((MaybePrimitiveExpr)_elseExpr).EmitUnboxed(rhc, objx, ilg);
            }
            else
            {
                _elseExpr.Emit(rhc, objx, ilg);
            }
            ilg.MarkLabel(endLabel);
        }
コード例 #24
0
 protected abstract void EmitSet(CljILGen ilg);
コード例 #25
0
 protected override void EmitTargetExpression(ObjExpr objx, CljILGen ilg)
 {
     ilg.Emit(OpCodes.Ldtoken, _type);
     ilg.Emit(OpCodes.Call, Compiler.Method_Type_GetTypeFromHandle);
 }
コード例 #26
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
        protected static void EmitHasArityMethod(TypeBuilder tb, IList<int> arities, bool isVariadic, int reqArity)
        {
            // TODO: Convert to a Switch instruction
            MethodBuilder mb = tb.DefineMethod(
                "HasArity",
                MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual,
                typeof(bool),
                new Type[] { typeof(int) });

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

            Label falseLabel = gen.DefineLabel();
            Label trueLabel = gen.DefineLabel();

            if (isVariadic)
            {
                gen.EmitLoadArg(1);
                gen.EmitInt(reqArity);
                gen.Emit(OpCodes.Bge, trueLabel);
            }

            if (arities != null)
            {
                foreach (int i in arities)
                {
                    gen.EmitLoadArg(1);
                    gen.EmitInt(i);
                    gen.Emit(OpCodes.Beq, trueLabel);
                }
            }

            gen.MarkLabel(falseLabel);
            gen.EmitBoolean(false);
            gen.Emit(OpCodes.Ret);

            gen.MarkLabel(trueLabel);
            gen.EmitBoolean(true);
            gen.Emit(OpCodes.Ret);
        }
コード例 #27
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
 static void EmitPrimitive(CljILGen ilg, object val)
 {
     switch (Type.GetTypeCode(val.GetType()) )
     {
         case TypeCode.Boolean:
             ilg.EmitBoolean((bool)val); break;
         case TypeCode.Byte:
             ilg.EmitByte((byte)val); break;
         case TypeCode.Char:
             ilg.EmitChar((char)val); break;
         case TypeCode.Decimal:
             ilg.EmitDecimal((decimal)val); break;
         case TypeCode.Double:
             ilg.EmitDouble((double)val); break;
         case TypeCode.Int16:
             ilg.EmitShort((short)val); break;
         case TypeCode.Int32:
             ilg.EmitInt((int)val); break;
         case TypeCode.Int64:
             ilg.EmitLong((long)val); break;
         case TypeCode.SByte:
             ilg.EmitSByte((sbyte)val); break;
         case TypeCode.Single:
             ilg.EmitSingle((float)val); break;
         case TypeCode.UInt16:
             ilg.EmitUShort((ushort)val); break;
         case TypeCode.UInt32:
             ilg.EmitUInt((uint)val); break;
         case TypeCode.UInt64:
             ilg.EmitULong((ulong)val); break;
         default:
             throw new InvalidOperationException("Unknown constant type in EmitPrimitive");
     }
 }
コード例 #28
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
        internal void EmitLocal(CljILGen ilg, LocalBinding lb)
        {
            Type primType = lb.PrimitiveType;

            if (Closes.containsKey(lb))
            {
                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
            {
                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);
            }
        }
コード例 #29
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
 internal void EmitVar(CljILGen ilg, Var var)
 {
     int i = (int)Vars.valAt(var);
     EmitConstant(ilg, i, var);
 }
コード例 #30
0
ファイル: MethodExpr.cs プロジェクト: terkhorn/clojure-clr
        static public void EmitDynamicCallPreamble(DynamicExpression dyn, IPersistentMap spanMap, string methodName, Type returnType, List <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;

            if (context != null && context.DynInitHelper != null)
            {
                call = context.DynInitHelper.ReduceDyn(dyn);
            }

            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);
            }
        }
コード例 #31
0
ファイル: MethodExpr.cs プロジェクト: terkhorn/clojure-clr
        private void EmitComplexCall(ObjExpr objx, CljILGen ilg)
        {
            // This is made more complex than I'd like by light-compiling.
            // Without light-compile, we could just:
            //   Emit the target expression
            //   Emit the arguments (and build up the parameter list for the lambda)
            //   Create the lambda, compile to a methodbuilder, and call it.
            // Light-compile forces us to
            //     create a lambda at the beginning because we must
            //     compile it to a delegate, to get the type
            //     write code to grab the delegate from a cache
            //     Then emit the target expression
            //          emit the arguments (but note we need already to have built the parameter list)
            //          Call the delegate
            //  Combined, this becomes
            //      Build the parameter list
            //      Build the dynamic call and lambda  (slightly different for light-compile vs full)
            //      if light-compile
            //          build the delegate
            //          cache it
            //          emit code to retrieve and cast it
            //       emit the target expression
            //       emit the args
            //       emit the call (slightly different for light compile vs full)
            //

            //  Build the parameter list

            List <ParameterExpression> paramExprs = new List <ParameterExpression>(_args.Count + 1);
            List <Type> paramTypes = new List <Type>(_args.Count + 1);

            Type targetType = GetTargetType();

            if (!targetType.IsPrimitive)
            {
                targetType = typeof(object);
            }

            paramExprs.Add(Expression.Parameter(targetType));
            paramTypes.Add(targetType);
            int i = 0;

            foreach (HostArg ha in _args)
            {
                i++;
                Expr e       = ha.ArgExpr;
                Type argType = e.HasClrType && e.ClrType != null && e.ClrType.IsPrimitive ? e.ClrType : typeof(object);

                switch (ha.ParamType)
                {
                case HostArg.ParameterType.ByRef:
                {
                    Type byRefType = argType.MakeByRefType();
                    paramExprs.Add(Expression.Parameter(byRefType, ha.LocalBinding.Name));
                    paramTypes.Add(byRefType);
                    break;
                }

                case HostArg.ParameterType.Standard:
                    if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr)
                    {
                        paramExprs.Add(Expression.Parameter(argType, ha.LocalBinding != null ? ha.LocalBinding.Name : "__temp_" + i));
                        paramTypes.Add(argType);
                    }
                    else
                    {
                        paramExprs.Add(Expression.Parameter(typeof(object), ha.LocalBinding != null ? ha.LocalBinding.Name : "__temp_" + i));
                        paramTypes.Add(typeof(object));
                    }
                    break;

                default:
                    throw Util.UnreachableCode();
                }
            }

            // Build dynamic call and lambda
            Type returnType           = HasClrType ? ClrType : typeof(object);
            InvokeMemberBinder binder = new ClojureInvokeMemberBinder(ClojureContext.Default, _methodName, paramExprs.Count, IsStaticCall);

            // This is what I want to do.
            //DynamicExpression dyn = Expression.Dynamic(binder, typeof(object), paramExprs);
            // Unfortunately, the Expression.Dynamic method does not respect byRef parameters.
            // The workaround appears to be to roll your delegate type and then use Expression.MakeDynamic, as below.

            List <Type> callsiteParamTypes = new List <Type>(paramTypes.Count + 1);

            callsiteParamTypes.Add(typeof(System.Runtime.CompilerServices.CallSite));
            callsiteParamTypes.AddRange(paramTypes);
            Type dynType = Microsoft.Scripting.Generation.Snippets.Shared.DefineDelegate("__interop__", returnType, callsiteParamTypes.ToArray());

#if CLR2
            // Not covariant. Sigh.
            List <Expression> paramsAsExprs = new List <Expression>(paramExprs.Count);
            paramsAsExprs.AddRange(paramExprs.ToArray());
            DynamicExpression dyn = Expression.MakeDynamic(dynType, binder, paramsAsExprs);
#else
            DynamicExpression dyn = Expression.MakeDynamic(dynType, binder, paramExprs);
#endif
            LambdaExpression lambda;
            Type             delType;
            MethodBuilder    mbLambda;

            EmitDynamicCallPreamble(dyn, _spanMap, "__interop_" + _methodName + RT.nextID(), returnType, paramExprs, paramTypes.ToArray(), ilg, out lambda, out delType, out mbLambda);

            //  Emit target + args

            EmitTargetExpression(objx, ilg);

            i = 0;
            foreach (HostArg ha in _args)
            {
                i++;
                Expr e       = ha.ArgExpr;
                Type argType = e.HasClrType && e.ClrType != null && e.ClrType.IsPrimitive ? e.ClrType : typeof(object);

                switch (ha.ParamType)
                {
                case HostArg.ParameterType.ByRef:
                    EmitByRefArg(ha, objx, ilg);
                    break;

                case HostArg.ParameterType.Standard:
                    if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr)
                    {
                        ((MaybePrimitiveExpr)ha.ArgExpr).EmitUnboxed(RHC.Expression, objx, ilg);
                    }
                    else
                    {
                        ha.ArgExpr.Emit(RHC.Expression, objx, ilg);
                    }
                    break;

                default:
                    throw Util.UnreachableCode();
                }
            }

            EmitDynamicCallPostlude(lambda, delType, mbLambda, ilg);
        }
コード例 #32
0
ファイル: MethodExpr.cs プロジェクト: terkhorn/clojure-clr
 protected abstract void EmitTargetExpression(ObjExpr objx, CljILGen ilg);
コード例 #33
0
ファイル: HostExpr.cs プロジェクト: makufiru/clojure-clr
        internal static void EmitUnboxArg(CljILGen ilg, Type paramType)
        {
            if (paramType.IsPrimitive)
            {
                MethodInfo m = null;

                if (paramType == typeof(bool))
                {
                    m = HostExpr.Method_RT_booleanCast;
                }
                else if (paramType == typeof(char))
                {
                    m = HostExpr.Method_RT_charCast;
                }
                else if (paramType == typeof(IntPtr))
                {
                    m = HostExpr.Method_RT_intPtrCast;
                }
                else if (paramType == typeof(UIntPtr))
                {
                    m = HostExpr.Method_RT_uintPtrCast;
                }
                else
                {
                    var typeCode = Type.GetTypeCode(paramType);
                    if (RT.booleanCast(RT.UncheckedMathVar.deref()))
                    {
                        switch (typeCode)
                        {
                        case TypeCode.SByte:
                            m = HostExpr.Method_RT_uncheckedSbyteCast;
                            break;

                        case TypeCode.Byte:
                            m = HostExpr.Method_RT_uncheckedByteCast;
                            break;

                        case TypeCode.Int16:
                            m = HostExpr.Method_RT_uncheckedShortCast;
                            break;

                        case TypeCode.UInt16:
                            m = HostExpr.Method_RT_uncheckedUshortCast;
                            break;

                        case TypeCode.Int32:
                            m = HostExpr.Method_RT_uncheckedIntCast;
                            break;

                        case TypeCode.UInt32:
                            m = HostExpr.Method_RT_uncheckedUintCast;
                            break;

                        case TypeCode.Int64:
                            m = HostExpr.Method_RT_uncheckedLongCast;
                            break;

                        case TypeCode.UInt64:
                            m = HostExpr.Method_RT_uncheckedUlongCast;
                            break;

                        case TypeCode.Single:
                            m = HostExpr.Method_RT_uncheckedFloatCast;
                            break;

                        case TypeCode.Double:
                            m = HostExpr.Method_RT_uncheckedDoubleCast;
                            break;

                        case TypeCode.Char:
                            m = HostExpr.Method_RT_uncheckedCharCast;
                            break;

                        case TypeCode.Decimal:
                            m = HostExpr.Method_RT_uncheckedDecimalCast;
                            break;

                        default:
                            throw new ArgumentOutOfRangeException("paramType", paramType, string.Format("Don't know how to handle typeCode {0} for paramType", typeCode));
                        }
                    }
                    else
                    {
                        switch (typeCode)
                        {
                        case TypeCode.SByte:
                            m = HostExpr.Method_RT_sbyteCast;
                            break;

                        case TypeCode.Byte:
                            m = HostExpr.Method_RT_byteCast;
                            break;

                        case TypeCode.Int16:
                            m = HostExpr.Method_RT_shortCast;
                            break;

                        case TypeCode.UInt16:
                            m = HostExpr.Method_RT_ushortCast;
                            break;

                        case TypeCode.Int32:
                            m = HostExpr.Method_RT_intCast;
                            break;

                        case TypeCode.UInt32:
                            m = HostExpr.Method_RT_uintCast;
                            break;

                        case TypeCode.Int64:
                            m = HostExpr.Method_RT_longCast;
                            break;

                        case TypeCode.UInt64:
                            m = HostExpr.Method_RT_ulongCast;
                            break;

                        case TypeCode.Single:
                            m = HostExpr.Method_RT_floatCast;
                            break;

                        case TypeCode.Double:
                            m = HostExpr.Method_RT_doubleCast;
                            break;

                        case TypeCode.Char:
                            m = HostExpr.Method_RT_charCast;
                            break;

                        case TypeCode.Decimal:
                            m = HostExpr.Method_RT_decimalCast;
                            break;

                        default:
                            throw new ArgumentOutOfRangeException("paramType", paramType, string.Format("Don't know how to handle typeCode {0} for paramType", typeCode));
                        }
                    }
                }

                ilg.Emit(OpCodes.Castclass, typeof(Object));
                ilg.Emit(OpCodes.Call, m);
            }
            else
            {
                // TODO: Properly handle value types here.  Really, we need to know the incoming type.
                if (paramType.IsValueType)
                {
                    ilg.Emit(OpCodes.Unbox_Any, paramType);
                }
                else
                {
                    ilg.Emit(OpCodes.Castclass, paramType);
                }
            }
        }
コード例 #34
0
ファイル: LetExpr.cs プロジェクト: silky/clojure-clr
 public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     DoEmit(rhc, objx, ilg, true);
 }
コード例 #35
0
ファイル: HostExpr.cs プロジェクト: makufiru/clojure-clr
 internal static void EmitUnboxArg(ObjExpr objx, CljILGen ilg, Type paramType)
 {
     EmitUnboxArg(ilg, paramType);
 }
コード例 #36
0
ファイル: LetExpr.cs プロジェクト: silky/clojure-clr
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     DoEmit(rhc, objx, ilg, false);
 }
コード例 #37
0
 protected override void EmitSet(CljILGen ilg)
 {
     ilg.EmitPropertySet(_tinfo);
 }
コード例 #38
0
 protected override void EmitTargetExpression(ObjExpr objx, CljILGen ilg)
 {
     _target.Emit(RHC.Expression, objx, ilg);
 }
コード例 #39
0
 protected override void EmitSet(CljILGen ilg)
 {
     ilg.EmitFieldSet(_tinfo);
 }
コード例 #40
0
ファイル: FnExpr.cs プロジェクト: silky/clojure-clr
 private void EmitGetCompiledConstants(CljILGen ilg)
 {
     ilg.EmitInt(DynMethodMapKey);
     ilg.Emit(OpCodes.Call, Method_FnExpr_GetCompiledConstants);
 }
コード例 #41
0
 protected override void EmitSet(CljILGen ilg)
 {
     ilg.MaybeEmitVolatileOp(_tinfo);
     ilg.EmitFieldSet(_tinfo);
 }
コード例 #42
0
 public override void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     _target.Emit(RHC.Expression, objx, ilg);
     ilg.EmitCall(Compiler.Method_Monitor_Exit);
     Compiler.NilExprInstance.Emit(rhc, objx, ilg);
 }
コード例 #43
0
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Label?loopLabel = (Label)Compiler.LoopLabelVar.deref();

            if (loopLabel == null)
            {
                throw new InvalidOperationException("Recur not in proper context.");
            }

            {
                for (int i = 0; i < _loopLocals.count(); i++)
                {
                    LocalBinding lb  = (LocalBinding)_loopLocals.nth(i);
                    Expr         arg = (Expr)_args.nth(i);

                    Type primt = lb.PrimitiveType;
                    if (primt != null)
                    {
                        MaybePrimitiveExpr mpeArg = arg as MaybePrimitiveExpr;
                        Type pt = Compiler.MaybePrimitiveType(arg);
                        if (pt == primt)
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                        }
                        else if (primt == typeof(long) && pt == typeof(int))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_I8);
                        }
                        else if (primt == typeof(double) && pt == typeof(float))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_R8);
                        }
                        else if (primt == typeof(int) && pt == typeof(long))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            //ilg.EmitCall(Compiler.Method_RT_intCast_long);
                            ilg.Emit(OpCodes.Conv_I4);
                        }
                        else if (primt == typeof(float) && pt == typeof(double))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_R4);
                        }
                        else
                        {
                            throw new ArgumentException(String.Format(
                                                            "{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}",
                                                            _source, _spanMap != null ? (int)_spanMap.valAt(RT.StartLineKey, 0) : 0,
                                                            lb.Name, (arg.HasClrType ? arg.ClrType.Name : "Object"), primt.Name));
                        }
                    }
                    else
                    {
                        arg.Emit(RHC.Expression, objx, ilg);
                    }
                }
            }
            for (int i = _loopLocals.count() - 1; i >= 0; i--)
            {
                LocalBinding lb = (LocalBinding)_loopLocals.nth(i);
                //Type primt = lb.PrimitiveType;
                if (lb.IsArg)
                {
                    //ilg.Emit(OpCodes.Starg, lb.Index - (objx.IsStatic ? 0 : 1));
                    if (lb.DeclaredType != typeof(Object) && !lb.DeclaredType.IsPrimitive)
                    {
                        ilg.Emit(OpCodes.Castclass, lb.DeclaredType);
                    }
                    ilg.EmitStoreArg(lb.Index);
                }
                else
                {
                    ilg.Emit(OpCodes.Stloc, lb.LocalVar);
                }
            }

            ilg.Emit(OpCodes.Br, loopLabel.Value);
        }
コード例 #44
0
        protected override void EmitStatics(TypeBuilder tb)
        {
            if (IsDefType)
            {
                // getBasis()
                {
                    MethodBuilder mbg = tb.DefineMethod("getBasis", MethodAttributes.Public | MethodAttributes.Static, typeof(IPersistentVector), Type.EmptyTypes);
                    CljILGen      ilg = new CljILGen(mbg.GetILGenerator());
                    EmitValue(_hintedFields, ilg);
                    ilg.Emit(OpCodes.Ret);
                }

                if (Fields.count() > _hintedFields.count())
                {
                    // create(IPersistentMap)
                    MethodBuilder mbc = tb.DefineMethod("create", MethodAttributes.Public | MethodAttributes.Static, tb, new Type[] { typeof(IPersistentMap) });
                    CljILGen      gen = new CljILGen(mbc.GetILGenerator());

                    LocalBuilder        kwLocal = gen.DeclareLocal(typeof(Keyword));
                    List <LocalBuilder> locals  = new List <LocalBuilder>();
                    for (ISeq s = RT.seq(_hintedFields); s != null; s = s.next())
                    {
                        string bName = ((Symbol)s.first()).Name;
                        Type   t     = Compiler.TagType(Compiler.TagOf(s.first()));

                        // local_kw = Keyword.intern(bname)
                        // local_i = arg_0.valAt(kw,null)
                        gen.EmitLoadArg(0);
                        gen.EmitString(bName);
                        gen.EmitCall(Compiler.Method_Keyword_intern_string);
                        gen.Emit(OpCodes.Dup);
                        gen.Emit(OpCodes.Stloc, kwLocal.LocalIndex);
                        gen.EmitNull();
                        gen.EmitCall(Compiler.Method_IPersistentMap_valAt2);
                        LocalBuilder lb = gen.DeclareLocal(t);
                        locals.Add(lb);
                        if (t.IsPrimitive)
                        {
                            gen.EmitUnbox(t);
                        }
                        gen.Emit(OpCodes.Stloc, lb.LocalIndex);

                        // arg_0 = arg_0.without(local_kw);
                        gen.EmitLoadArg(0);
                        gen.Emit(OpCodes.Ldloc, kwLocal.LocalIndex);
                        gen.EmitCall(Compiler.Method_IPersistentMap_without);
                        gen.EmitStoreArg(0);
                    }

                    foreach (LocalBuilder lb in locals)
                    {
                        gen.Emit(OpCodes.Ldloc, lb.LocalIndex);
                    }
                    gen.EmitNull();
                    gen.EmitLoadArg(0);
                    gen.EmitCall(Compiler.Method_RT_seqOrElse);
                    gen.EmitNew(_ctorInfo);

                    gen.Emit(OpCodes.Ret);
                }
            }
        }
コード例 #45
0
ファイル: MethodExpr.cs プロジェクト: terkhorn/clojure-clr
        static public void EmitDynamicCallPostlude(LambdaExpression lambda, Type delType, MethodBuilder mbLambda, CljILGen ilg)
        {
            GenContext context = Compiler.CompilerContextVar.deref() as GenContext;

            if (context == null)
            {
                // light compile

                MethodInfo mi = delType.GetMethod("Invoke");
                ilg.Emit(OpCodes.Callvirt, mi);
            }
            else
            {
                ilg.Emit(OpCodes.Call, mbLambda);
            }
        }
コード例 #46
0
 public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     objx.EmitUnboxedLocal(ilg, _b);
 }
コード例 #47
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
 internal void EmitUnboxedLocal(CljILGen ilg, LocalBinding lb)
 {
     if (Closes.containsKey(lb))
     {
         ilg.Emit(OpCodes.Ldarg_0); // this
         FieldBuilder fb = _closedOverFieldsMap[lb];
         ilg.MaybeEmitVolatileOp(IsVolatile(lb));
         ilg.Emit(OpCodes.Ldfld, fb);
     }
     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);
 }
コード例 #48
0
 public override void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     GenContext.EmitDebugInfo(ilg, _spanMap);
     ilg.EmitPropertyGet(_tinfo);
 }
コード例 #49
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
 internal void EmitVarValue(CljILGen ilg, Var v)
 {
     int i = (int)Vars.valAt(v);
     if ( !v.isDynamic() )
     {
         EmitConstant(ilg, i, v);
         ilg.Emit(OpCodes.Call, Compiler.Method_Var_getRawRoot);
     }
     else
     {
         EmitConstant(ilg, i, v);
         ilg.Emit(OpCodes.Call, Compiler.Method_Var_get);  // or just Method_Var_get??
     }
 }
コード例 #50
0
 public abstract void Emit(RHC rhc, ObjExpr objx, CljILGen ilg);
コード例 #51
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);
                }
            }
        }
コード例 #52
0
ファイル: ObjExpr.cs プロジェクト: rpete4130/clojure-clr
        internal void EmitVar(CljILGen ilg, Var var)
        {
            int i = (int)Vars.valAt(var);

            EmitConstant(ilg, i, var);
        }
コード例 #53
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
        private void EmitConstantFieldInits(CljILGen ilg)
        {
            try
            {
                Var.pushThreadBindings(RT.map(RT.PrintDupVar, true));

                for (int i = 0; i < Constants.count(); i++)
                {
                    if (ConstantFields[i] != null)
                    {
                        EmitValue(Constants.nth(i), ilg);
                        if ( Constants.nth(i).GetType() != ConstantType(i) )
                            ilg.Emit(OpCodes.Castclass, ConstantType(i));
                        FieldBuilder fb = ConstantFields[i];
                        ilg.Emit(OpCodes.Stsfld,fb);
                    }
                }
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
コード例 #54
0
ファイル: ObjExpr.cs プロジェクト: rpete4130/clojure-clr
        internal void EmitKeyword(CljILGen ilg, Keyword kw)
        {
            int i = (int)Keywords.valAt(kw);

            EmitConstant(ilg, i, kw);
        }
コード例 #55
0
ファイル: ObjExpr.cs プロジェクト: rpete4130/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);
                }
            }
        }
コード例 #56
0
ファイル: NewExpr.cs プロジェクト: redchew-fork/clojure-clr
 private void EmitParamsForMethod(ObjExpr objx, CljILGen ilg)
 {
     ParameterInfo[] pis = _ctor.GetParameters();
     MethodExpr.EmitTypedArgs(objx, ilg, pis, _args);
 }
コード例 #57
0
ファイル: TheVarExpr.cs プロジェクト: TerabyteX/clojure-clr
 public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
 {
     objx.EmitVar(ilg, _var);
     if (rhc == RHC.Statement)
         ilg.Emit(OpCodes.Pop);
 }
コード例 #58
0
ファイル: NewExpr.cs プロジェクト: redchew-fork/clojure-clr
        private void EmitComplexCall(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            // See the notes on MethodExpr.EmitComplexCall on why this is so complicated

            List <ParameterExpression> paramExprs = new List <ParameterExpression>(_args.Count + 1);
            List <Type> paramTypes = new List <Type>(_args.Count + 1);

            paramExprs.Add(Expression.Parameter(typeof(Type)));
            paramTypes.Add(typeof(Type));

            int i = 0;

            foreach (HostArg ha in _args)
            {
                i++;
                Expr e       = ha.ArgExpr;
                Type argType = e.HasClrType && e.ClrType != null && e.ClrType.IsPrimitive ? e.ClrType : typeof(object);

                switch (ha.ParamType)
                {
                case HostArg.ParameterType.ByRef:
                {
                    Type byRefType = argType.MakeByRefType();
                    paramExprs.Add(Expression.Parameter(byRefType, ha.LocalBinding.Name));
                    paramTypes.Add(byRefType);
                    break;
                }

                case HostArg.ParameterType.Standard:
                    if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr)
                    {
                        paramExprs.Add(Expression.Parameter(argType, ha.LocalBinding != null ? ha.LocalBinding.Name : "__temp_" + i));
                        paramTypes.Add(argType);
                    }
                    else
                    {
                        paramExprs.Add(Expression.Parameter(typeof(object), ha.LocalBinding != null ? ha.LocalBinding.Name : "__temp_" + i));
                        paramTypes.Add(typeof(object));
                    }
                    break;

                default:
                    throw Util.UnreachableCode();
                }
            }

            // Build dynamic call and lambda
            Type returnType             = HasClrType ? ClrType : typeof(object);
            CreateInstanceBinder binder = new ClojureCreateInstanceBinder(ClojureContext.Default, _args.Count);
            DynamicExpression    dyn    = Expression.Dynamic(binder, typeof(object), paramExprs);

            MethodExpr.EmitDynamicCallPreamble(dyn, _spanMap, "__interop_ctor_" + RT.nextID(), returnType, paramExprs, paramTypes.ToArray(), ilg, out LambdaExpression lambda, out Type delType, out MethodBuilder mbLambda);

            //  Emit target + args

            EmitTargetExpression(objx, ilg);

            i = 0;
            foreach (HostArg ha in _args)
            {
                i++;
                Expr e       = ha.ArgExpr;
                Type argType = e.HasClrType && e.ClrType != null && e.ClrType.IsPrimitive ? e.ClrType : typeof(object);

                switch (ha.ParamType)
                {
                case HostArg.ParameterType.ByRef:
                    MethodExpr.EmitByRefArg(ha, objx, ilg);
                    break;

                case HostArg.ParameterType.Standard:
                    if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr expr)
                    {
                        expr.EmitUnboxed(RHC.Expression, objx, ilg);
                    }
                    else
                    {
                        ha.ArgExpr.Emit(RHC.Expression, objx, ilg);
                    }
                    break;

                default:
                    throw Util.UnreachableCode();
                }
            }

            MethodExpr.EmitDynamicCallPostlude(lambda, delType, mbLambda, ilg);
        }
コード例 #59
0
ファイル: RecurExpr.cs プロジェクト: stuman08/clojure-clr
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Label loopLabel = (Label)Compiler.LoopLabelVar.deref();
            if (loopLabel == null)
                throw new InvalidOperationException("Recur not in proper context.");

            {
                for (int i = 0; i < _loopLocals.count(); i++)
                {
                    LocalBinding lb = (LocalBinding)_loopLocals.nth(i);
                    Expr arg = (Expr)_args.nth(i);

                    Type primt = lb.PrimitiveType;
                    if (primt != null)
                    {
                        MaybePrimitiveExpr mpeArg = arg as MaybePrimitiveExpr;
                        Type pt = Compiler.MaybePrimitiveType(arg);
                        if (pt == primt)
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                        }
                        else if (primt == typeof(long) && pt == typeof(int))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_I8);
                        }
                        else if (primt == typeof(double) && pt == typeof(float))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_R8);
                        }
                        else if (primt == typeof(int) && pt == typeof(long))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.EmitCall(Compiler.Method_RT_intCast_long);

                        }
                        else if (primt == typeof(float) && pt == typeof(double))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_R4);
                        }
                        else
                        {
                            throw new ArgumentException(String.Format(
                                    "{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}",
                                    _source, _spanMap != null ? (int)_spanMap.valAt(RT.StartLineKey, 0) : 0,
                                    lb.Name, (arg.HasClrType ? arg.ClrType.Name : "Object"), primt.Name));
                        }

                    }
                    else
                    {
                        arg.Emit(RHC.Expression, objx, ilg);
                    }

                }
            }
            for (int i = _loopLocals.count() - 1; i >= 0; i--)
            {
                LocalBinding lb = (LocalBinding)_loopLocals.nth(i);
                Type primt = lb.PrimitiveType;
                if (lb.IsArg)
                    //ilg.Emit(OpCodes.Starg, lb.Index - (objx.IsStatic ? 0 : 1));
                    ilg.EmitStoreArg(lb.Index);
                else
                {
                    ilg.Emit(OpCodes.Stloc, lb.LocalVar);
                }
            }

            ilg.Emit(OpCodes.Br, loopLabel);
            //if (rhc != RHC.Statement)
            //    ilg.Emit(OpCodes.Ldnull);
        }
コード例 #60
0
ファイル: FnExpr.cs プロジェクト: silky/clojure-clr
 private void EmitGetDynMethod(int arity, CljILGen ilg)
 {
     ilg.EmitInt(DynMethodMapKey);
     ilg.EmitInt(arity);
     ilg.Emit(OpCodes.Call, Method_FnExpr_GetDynMethod);
 }