コード例 #1
0
        public override void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Type targetType = _targetType;

            GenContext.EmitDebugInfo(ilg, _spanMap);

            if (targetType != null && _tinfo != null)
            {
                _target.Emit(RHC.Expression, objx, ilg);
                MethodExpr.EmitPrepForCall(ilg, typeof(object), FieldDeclaringType);
                EmitGet(ilg);
                HostExpr.EmitBoxReturn(objx, ilg, FieldType);
            }
            else
            {
                // We could convert this to a dynamic call-site
                _target.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Ldstr, _memberName);
                ilg.Emit(OpCodes.Call, Compiler.Method_Reflector_GetInstanceFieldOrProperty);
            }
            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #2
0
        public override void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Type targetType = _targetType;

            //Type stubType = Compiler.CompileStubOrigClassVar.isBound ? (Type)Compiler.CompileStubOrigClassVar.deref() : null;

            //if (_targetType == stubType)
            //    targetType = objx.BaseType;

            GenContext.EmitDebugInfo(ilg, _spanMap);

            if (targetType != null && _tinfo != null)
            {
                _target.Emit(RHC.Expression, objx, ilg);
                MethodExpr.EmitPrepForCall(ilg, typeof(object), FieldDeclaringType);
                EmitGet(ilg);
                HostExpr.EmitBoxReturn(objx, ilg, FieldType);
            }
            else
            {
                // TODO: convert to dynamic?
                _target.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Ldstr, _fieldName);
                ilg.Emit(OpCodes.Call, Compiler.Method_Reflector_GetInstanceFieldOrProperty);
            }
            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #3
0
        public override void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            // See MethodExpr.EmitComplexCall to see why this is so complicated

            //  Build the parameter list

            List <ParameterExpression> paramExprs = new List <ParameterExpression>();
            List <Type> paramTypes = new List <Type>();

            Type paramType            = _target.HasClrType && _target.ClrType != null && _target.ClrType.IsPrimitive ? _target.ClrType : typeof(object);
            ParameterExpression param = Expression.Parameter(paramType);

            paramExprs.Add(param);
            paramTypes.Add(paramType);


            // Build dynamic call and lambda
            Type returnType = HasClrType ? ClrType : typeof(object);

            GetMemberBinder   binder = new ClojureGetZeroArityMemberBinder(ClojureContext.Default, _memberName, false);
            DynamicExpression dyn    = Expression.Dynamic(binder, returnType, paramExprs);

            LambdaExpression lambda;
            Type             delType;
            MethodBuilder    mbLambda;

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

            //  Emit target + args (no args, actually)

            _target.Emit(RHC.Expression, objx, ilg);

            MethodExpr.EmitDynamicCallPostlude(lambda, delType, mbLambda, ilg);
        }
コード例 #4
0
ファイル: ObjExpr.cs プロジェクト: makufiru/clojure-clr
        internal void EmitAssignLocal(CljILGen ilg, LocalBinding lb, Expr val)
        {
            if (!IsMutable(lb))
                throw new ArgumentException("Cannot assign to non-mutable: ", lb.Name);

            FieldBuilder fb = null;
            bool hasField = ClosedOverFieldsMap.TryGetValue(lb, out fb);

            ilg.Emit(OpCodes.Ldarg_0);  // this

            Type primt = lb.PrimitiveType;
            if (primt != null)
            {
                MaybePrimitiveExpr mbe = val as MaybePrimitiveExpr;
                if (!(mbe != null && mbe.CanEmitPrimitive))
                    throw new ArgumentException("Must assign primitive to primitive mutable", lb.Name);
                mbe.EmitUnboxed(RHC.Expression, this, ilg);

            }
            else
            {
                val.Emit(RHC.Expression, this, ilg);
            }

            if (hasField)
            {
                ilg.MaybeEmitVolatileOp(IsVolatile(lb));
                ilg.Emit(OpCodes.Stfld, fb);
            }
            else
                ilg.Emit(OpCodes.Stloc, lb.LocalVar);
        }
コード例 #5
0
ファイル: DefExpr.cs プロジェクト: rpete4130/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);
     }
 }
コード例 #6
0
        public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            if (_variadic)
            {
                ParameterInfo[] pinfos = _method.GetParameters();
                for (int i = 0; i < pinfos.Length - 1; i++)
                {
                    Expr e = (Expr)_args.nth(i);
                    if (Compiler.MaybePrimitiveType(e) == pinfos[i].ParameterType)
                    {
                        ((MaybePrimitiveExpr)e).EmitUnboxed(RHC.Expression, objx, ilg);
                    }
                    else
                    {
                        e.Emit(RHC.Expression, objx, ilg);
                        HostExpr.EmitUnboxArg(objx, ilg, pinfos[i].ParameterType);
                    }
                }
                IPersistentVector restArgs = RT.subvec(_args, pinfos.Length - 1, _args.count());
                MethodExpr.EmitArgsAsArray(restArgs, objx, ilg);
                ilg.EmitCall(Compiler.Method_ArraySeq_create);
            }
            else
            {
                MethodExpr.EmitTypedArgs(objx, ilg, _method.GetParameters(), _args);
            }

            ilg.EmitCall(_method);
        }
コード例 #7
0
        void EmitArgsAndCall(int firstArgToEmit, RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            for (int i = firstArgToEmit; i < Math.Min(Compiler.MaxPositionalArity, _args.count()); i++)
            {
                Expr e = (Expr)_args.nth(i);
                e.Emit(RHC.Expression, objx, ilg);
            }
            if (_args.count() > Compiler.MaxPositionalArity)
            {
                IPersistentVector restArgs = PersistentVector.EMPTY;
                for (int i = Compiler.MaxPositionalArity; i < _args.count(); i++)
                {
                    restArgs = restArgs.cons(_args.nth(i));
                }
                MethodExpr.EmitArgsAsArray(restArgs, objx, ilg);
            }

            //if ( rhc == RHC.Return )
            //{
            //    ObjMethod2 method = (ObjMethod2)Compiler.MethodVar.deref();
            //    method.EmitClearLocals(context);
            //}

            MethodInfo mi = Compiler.Methods_IFn_invoke[Math.Min(Compiler.MaxPositionalArity + 1, _args.count())];

            ilg.Emit(OpCodes.Callvirt, mi);
        }
コード例 #8
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);
 }
コード例 #9
0
        public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            _expr.Emit(RHC.Expression, objx, ilg);

            ilg.Emit(OpCodes.Isinst, _t);
            ilg.Emit(OpCodes.Ldnull);
            ilg.Emit(OpCodes.Cgt_Un);
        }
コード例 #10
0
ファイル: LetExpr.cs プロジェクト: redchew-fork/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();
                }
            }
        }
コード例 #11
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);
 }
コード例 #12
0
ファイル: DefExpr.cs プロジェクト: redchew-fork/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 expr)
                {
                    expr.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);
            }
        }
コード例 #13
0
        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 (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);
            }
        }
コード例 #14
0
ファイル: VarExpr.cs プロジェクト: willemdijkgraaf/ClojureClr
 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);
     }
 }
コード例 #15
0
ファイル: CaseExpr.cs プロジェクト: redchew-fork/clojure-clr
 private static void EmitExpr(ObjExpr objx, CljILGen ilg, Expr expr, bool emitUnboxed)
 {
     if (emitUnboxed && expr is MaybePrimitiveExpr mbe)
     {
         mbe.EmitUnboxed(RHC.Expression, objx, ilg);
     }
     else
     {
         expr.Emit(RHC.Expression, objx, ilg);
     }
 }
コード例 #16
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);
        }
コード例 #17
0
ファイル: MetaExpr.cs プロジェクト: terkhorn/clojure-clr
 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);
     }
 }
コード例 #18
0
ファイル: ObjMethod.cs プロジェクト: makufiru/clojure-clr
        protected static void EmitBody(ObjExpr objx, CljILGen ilg, Type retType, Expr body)
        {
            MaybePrimitiveExpr be = (MaybePrimitiveExpr)body;

            if (Util.IsPrimitive(retType) && be.CanEmitPrimitive)
            {
                Type bt = Compiler.MaybePrimitiveType(be);
                if (bt == retType)
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                }
                else if (retType == typeof(long) && bt == typeof(int))
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                    ilg.Emit(OpCodes.Conv_I8);
                }
                else if (retType == typeof(double) && bt == typeof(float))
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                    ilg.Emit(OpCodes.Conv_R8);
                }
                else if (retType == typeof(int) && bt == typeof(long))
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                    ilg.Emit(OpCodes.Call, Compiler.Method_RT_intCast_long);
                }
                else if (retType == typeof(float) && bt == typeof(double))
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                    ilg.Emit(OpCodes.Conv_R4);
                }
                else
                {
                    throw new ArgumentException(String.Format("Mismatched primitive return, expected: {0}, had: {1}", retType, be.ClrType));
                }
            }
            else
            {
                body.Emit(RHC.Return, objx, ilg);
                if (body.HasNormalExit())
                {
                    if (retType == typeof(void))
                    {
                        ilg.Emit(OpCodes.Pop);
                    }
                    else
                    {
                        EmitUnboxArg(ilg, typeof(object), retType);
                    }
                }
            }
        }
コード例 #19
0
        public override void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val)
        {
            GenContext.EmitDebugInfo(ilg, _spanMap);

            val.Emit(RHC.Expression, objx, ilg);
            ilg.Emit(OpCodes.Dup);
            HostExpr.EmitUnboxArg(objx, ilg, FieldType);
            ilg.EmitPropertySet(_tinfo);
            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #20
0
ファイル: ThrowExpr.cs プロジェクト: nasser/Clojure.Runtime
 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);
     }
 }
コード例 #21
0
        public override void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val)
        {
            GenContext.EmitDebugInfo(ilg, _spanMap);

            if (_targetType != null && _tinfo != null)
            {
                _target.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Castclass, _targetType);
                val.Emit(RHC.Expression, objx, ilg);
                LocalBuilder tmp = ilg.DeclareLocal(typeof(object));
                GenContext.SetLocalName(tmp, "valTemp");
                ilg.Emit(OpCodes.Dup);
                ilg.Emit(OpCodes.Stloc, tmp);
                if (FieldType.IsValueType)
                {
                    HostExpr.EmitUnboxArg(objx, ilg, FieldType);
                }
                else
                {
                    ilg.Emit(OpCodes.Castclass, FieldType);
                }
                EmitSet(ilg);
                ilg.Emit(OpCodes.Ldloc, tmp);
            }
            else
            {
                _target.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Ldstr, _memberName);
                val.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Call, Compiler.Method_Reflector_SetInstanceFieldOrProperty);
            }
            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #22
0
 void EmitThenForHashes(ObjExpr objx, CljILGen ilg, Expr test, Expr then, Label defaultLabel, bool emitUnboxed)
 {
     _expr.Emit(RHC.Expression, objx, ilg);
     test.Emit(RHC.Expression, objx, ilg);
     if (_testType == _hashIdentityKey)
     {
         ilg.Emit(OpCodes.Ceq);
         ilg.Emit(OpCodes.Brfalse, defaultLabel);
     }
     else
     {
         ilg.Emit(OpCodes.Call, Compiler.Method_Util_equiv);
         ilg.Emit(OpCodes.Brfalse, defaultLabel);
     }
     EmitExpr(objx, ilg, then, emitUnboxed);
 }
コード例 #23
0
        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);
        }
コード例 #24
0
 private void EmitThenForInts(ObjExpr objx, CljILGen ilg, Type exprType, Expr test, Expr then, Label defaultLabel, bool emitUnboxed)
 {
     if (exprType == null)
     {
         _expr.Emit(RHC.Expression, objx, ilg);
         test.Emit(RHC.Expression, objx, ilg);
         ilg.Emit(OpCodes.Call, Compiler.Method_Util_equiv);
         ilg.Emit(OpCodes.Brfalse, defaultLabel);
         EmitExpr(objx, ilg, then, emitUnboxed);
     }
     else if (exprType == typeof(long))
     {
         ((NumberExpr)test).EmitUnboxed(RHC.Expression, objx, ilg);
         _expr.EmitUnboxed(RHC.Expression, objx, ilg);
         ilg.Emit(OpCodes.Ceq);
         ilg.Emit(OpCodes.Brfalse, defaultLabel);
         EmitExpr(objx, ilg, then, emitUnboxed);
     }
     else if (exprType == typeof(int) ||
              exprType == typeof(short) ||
              exprType == typeof(byte) ||
              exprType == typeof(ulong) ||
              exprType == typeof(uint) ||
              exprType == typeof(ushort) ||
              exprType == typeof(sbyte))
     {
         if (IsShiftMasked)
         {
             ((NumberExpr)test).EmitUnboxed(RHC.Expression, objx, ilg);
             _expr.EmitUnboxed(RHC.Expression, objx, ilg);
             ilg.Emit(OpCodes.Conv_I8);
             ilg.Emit(OpCodes.Ceq);
             ilg.Emit(OpCodes.Brfalse, defaultLabel);
             EmitExpr(objx, ilg, then, emitUnboxed);
         }
         // else direct match
         EmitExpr(objx, ilg, then, emitUnboxed);
     }
     else
     {
         ilg.Emit(OpCodes.Br, defaultLabel);
     }
 }
コード例 #25
0
        public override void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val)
        {
            if (_tinfo.IsInitOnly)
            {
                throw new InvalidOperationException(String.Format("Attempt to set readonly static field {0} in class {1}", _tinfo.Name, _tinfo.DeclaringType));
            }

            GenContext.EmitDebugInfo(ilg, _spanMap);

            val.Emit(RHC.Expression, objx, ilg);
            ilg.Emit(OpCodes.Dup);
            HostExpr.EmitUnboxArg(objx, ilg, FieldType);
            ilg.MaybeEmitVolatileOp(_tinfo);
            ilg.EmitFieldSet(_tinfo);
            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #26
0
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            GenContext.EmitDebugInfo(ilg, _spanMap);

            if (_isProtocol)
            {
                EmitProto(rhc, objx, ilg);
            }
            else
            {
                _fexpr.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Castclass, typeof(IFn));
                EmitArgsAndCall(0, rhc, objx, ilg);
            }
            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
コード例 #27
0
        public static void EmitTypedArg(ObjExpr objx, CljILGen ilg, Type paramType, Expr arg)
        {
            Type primt             = Compiler.MaybePrimitiveType(arg);
            MaybePrimitiveExpr mpe = arg as MaybePrimitiveExpr;

            if (primt == paramType)
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
            }
            else if (primt == typeof(int) && paramType == typeof(long))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_I8);
            }
            else if (primt == typeof(long) && paramType == typeof(int))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                if (RT.booleanCast(RT.UncheckedMathVar.deref()))
                {
                    ilg.Emit(OpCodes.Call, Compiler.Method_RT_uncheckedIntCast_long);
                }
                else
                {
                    ilg.Emit(OpCodes.Call, Compiler.Method_RT_intCast_long);
                }
            }
            else if (primt == typeof(float) && paramType == typeof(double))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_R8);
            }
            else if (primt == typeof(double) && paramType == typeof(float))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_R4);
            }
            else
            {
                arg.Emit(RHC.Expression, objx, ilg);
                HostExpr.EmitUnboxArg(objx, ilg, paramType);
            }
        }
コード例 #28
0
ファイル: ObjMethod.cs プロジェクト: terkhorn/clojure-clr
        public virtual void Emit(ObjExpr fn, TypeBuilder tb)
        {
            MethodBuilder mb = tb.DefineMethod(GetMethodName(), MethodAttributes.Public, GetReturnType(), GetArgTypes());

            CljILGen ilg       = new CljILGen(mb.GetILGenerator());
            Label    loopLabel = ilg.DefineLabel();

            GenContext.EmitDebugInfo(ilg, SpanMap);

            try
            {
                Var.pushThreadBindings(RT.map(Compiler.LoopLabelVar, loopLabel, Compiler.MethodVar, this));
                ilg.MarkLabel(loopLabel);
                _body.Emit(RHC.Return, fn, ilg);
                ilg.Emit(OpCodes.Ret);
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
コード例 #29
0
        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);
        }
コード例 #30
0
ファイル: MethodExpr.cs プロジェクト: chrisortman/clojure-clr
        public static void EmitTypedArg(ObjExpr objx, CljILGen ilg, Type paramType, Expr arg)
        {
            Type primt = Compiler.MaybePrimitiveType(arg);
            MaybePrimitiveExpr mpe = arg as MaybePrimitiveExpr;

            if (primt == paramType)
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
            }
            else if (primt == typeof(int) && paramType == typeof(long))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_I8);
             }
            else if (primt == typeof(long) && paramType == typeof(int))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                if (RT.booleanCast(RT.UncheckedMathVar.deref()))
                    ilg.Emit(OpCodes.Call,Compiler.Method_RT_uncheckedIntCast_long);
                else
                    ilg.Emit(OpCodes.Call,Compiler.Method_RT_intCast_long);
            }
            else if (primt == typeof(float) && paramType == typeof(double))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_R8);
            }
            else if (primt == typeof(double) && paramType == typeof(float))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_R4);
            }
            else
            {
                arg.Emit(RHC.Expression, objx, ilg);
                HostExpr.EmitUnboxArg(objx, ilg, paramType);
            }
        }
コード例 #31
0
ファイル: RecurExpr.cs プロジェクト: makufiru/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.Value);
        }
コード例 #32
0
ファイル: CaseExpr.cs プロジェクト: stuman08/clojure-clr
        private void EmitThenForInts(ObjExpr objx, CljILGen ilg, Type exprType, Expr test, Expr then, Label defaultLabel, bool emitUnboxed)
        {
            if (exprType == null)
            {
                _expr.Emit(RHC.Expression, objx, ilg);
                test.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Call, Compiler.Method_Util_equiv);
                ilg.Emit(OpCodes.Brfalse, defaultLabel);
                EmitExpr(objx, ilg, then, emitUnboxed);
            }
            else if (exprType == typeof(long))
            {
                ((NumberExpr)test).EmitUnboxed(RHC.Expression, objx, ilg);
                _expr.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Ceq);
                ilg.Emit(OpCodes.Brfalse, defaultLabel);
                EmitExpr(objx, ilg, then, emitUnboxed);

            }
            else if (exprType == typeof(int)
                || exprType == typeof(short)
                || exprType == typeof(byte)
                || exprType == typeof(ulong)
                || exprType == typeof(uint)
                || exprType == typeof(ushort)
                || exprType == typeof(sbyte))
            {
                if (IsShiftMasked)
                {
                    ((NumberExpr)test).EmitUnboxed(RHC.Expression, objx, ilg);
                    _expr.EmitUnboxed(RHC.Expression, objx, ilg);
                    ilg.Emit(OpCodes.Conv_I8);
                    ilg.Emit(OpCodes.Ceq);
                    ilg.Emit(OpCodes.Brfalse, defaultLabel);
                    EmitExpr(objx, ilg, then, emitUnboxed);
                }
                // else direct match
                EmitExpr(objx, ilg, then, emitUnboxed);
            }
            else
            {
                ilg.Emit(OpCodes.Br, defaultLabel);
            }
        }
コード例 #33
0
 protected override void EmitTargetExpression(ObjExpr objx, CljILGen ilg)
 {
     _target.Emit(RHC.Expression, objx, ilg);
 }
コード例 #34
0
ファイル: ObjExpr.cs プロジェクト: EricThorsen/clojure-clr
        internal void EmitAssignLocal(CljILGen ilg, LocalBinding lb, Expr val)
        {
            if (!IsMutable(lb))
                throw new ArgumentException("Cannot assign to non-mutable: ", lb.Name);

            FieldBuilder fb = null;
            bool hasField = _closedOverFieldsMap.TryGetValue(lb, out fb);

            ilg.Emit(OpCodes.Ldarg_0);  // this

            Type primt = lb.PrimitiveType;
            if (primt != null)
            {
                MaybePrimitiveExpr mbe = val as MaybePrimitiveExpr;
                if (!(mbe != null && mbe.CanEmitPrimitive))
                    throw new ArgumentException("Must assign primitive to primitive mutable", lb.Name);
                mbe.EmitUnboxed(RHC.Expression, this, ilg);

            }
            else
            {
                val.Emit(RHC.Expression, this, ilg);
            }

            if (hasField)
            {
                ilg.MaybeEmitVolatileOp(IsVolatile(lb));
                ilg.Emit(OpCodes.Stfld, fb);
            }
            else
                ilg.Emit(OpCodes.Stloc, lb.LocalVar);
        }
コード例 #35
0
ファイル: CaseExpr.cs プロジェクト: stuman08/clojure-clr
 void EmitThenForHashes(ObjExpr objx, CljILGen ilg, Expr test, Expr then, Label defaultLabel, bool emitUnboxed)
 {
     _expr.Emit(RHC.Expression, objx, ilg);
     test.Emit(RHC.Expression, objx, ilg);
     if (_testType == _hashIdentityKey)
     {
         ilg.Emit(OpCodes.Ceq);
         ilg.Emit(OpCodes.Brfalse, defaultLabel);
     }
     else
     {
         ilg.Emit(OpCodes.Call, Compiler.Method_Util_equiv);
         ilg.Emit(OpCodes.Brfalse, defaultLabel);
     }
     EmitExpr(objx, ilg, then, emitUnboxed);
 }
コード例 #36
0
ファイル: CaseExpr.cs プロジェクト: stuman08/clojure-clr
 private static void EmitExpr(ObjExpr objx, CljILGen ilg, Expr expr, bool emitUnboxed)
 {
     MaybePrimitiveExpr mbe = expr as MaybePrimitiveExpr;
     if (emitUnboxed && mbe != null)
         mbe.EmitUnboxed(RHC.Expression, objx, ilg);
     else
         expr.Emit(RHC.Expression, objx, ilg);
 }
コード例 #37
0
ファイル: ObjMethod.cs プロジェクト: clojure/clojure-clr
 protected static void EmitBody(ObjExpr objx, CljILGen ilg, Type retType, Expr body)
 {
     MaybePrimitiveExpr be = (MaybePrimitiveExpr)body;
     if (Util.IsPrimitive(retType) && be.CanEmitPrimitive)
     {
         Type bt = Compiler.MaybePrimitiveType(be);
         if (bt == retType)
             be.EmitUnboxed(RHC.Return, objx, ilg);
         else if (retType == typeof(long) && bt == typeof(int))
         {
             be.EmitUnboxed(RHC.Return, objx, ilg);
             ilg.Emit(OpCodes.Conv_I8);
         }
         else if (retType == typeof(double) && bt == typeof(float))
         {
             be.EmitUnboxed(RHC.Return, objx, ilg);
             ilg.Emit(OpCodes.Conv_R8);
         }
         else if (retType == typeof(int) && bt == typeof(long))
         {
             be.EmitUnboxed(RHC.Return, objx, ilg);
             ilg.Emit(OpCodes.Call,Compiler.Method_RT_intCast_long);
         }
         else if (retType == typeof(float) && bt == typeof(double))
         {
             be.EmitUnboxed(RHC.Return, objx, ilg);
             ilg.Emit(OpCodes.Conv_R4);
         }
         else
         {
             throw new ArgumentException(String.Format("Mismatched primitive return, expected: {0}, had: {1}", retType, be.ClrType));
         }
     }
     else
     {
         body.Emit(RHC.Return, objx, ilg);
         if (body.HasNormalExit())
         {
             if (retType == typeof(void))
                 ilg.Emit(OpCodes.Pop);
             else
                 EmitUnboxArg(ilg, typeof(object), retType);
         }
     }
 }