public void LoadCompiledLambda(CompiledLambda compiledLambda)
        {
            if (ParsedLambda.ConstantsParameter == null)
            {
                throw new InvalidOperationException("There is no constants parameter. Cannot load sublambda");
            }
            Type temp;
            var  delegatesAccessor = ParsedLambda.ConstantsBuilder.MakeAccess(ParsedLambda.ConstantsParameter, ParsedLambda.DelegatesFieldId);

            ExpressionEmittersCollection.Emit(delegatesAccessor, this, out temp);
            Il.Ldc_I4(compiledLambda.Index);
            Il.Ldelem(typeof(Delegate));
        }
        public void EmitLoadArgument(Expression argument, bool convertToBool, out Type argumentType)
        {
            var  argumentIsNullLabel = CanReturn ? Il.DefineLabel("argumentIsNull") : null;
            bool labelUsed           = ExpressionEmittersCollection.Emit(argument, this, argumentIsNullLabel, out argumentType);

            if (convertToBool && argument.Type == typeof(bool) && argumentType == typeof(bool?))
            {
                ConvertFromNullableBoolToBool();
                argumentType = typeof(bool);
            }
            if (labelUsed)
            {
                EmitReturnDefaultValue(argument.Type, argumentIsNullLabel, Il.DefineLabel("argumentIsNotNull"));
            }
        }
Beispiel #3
0
        private static void CompileInternal(LambdaExpression lambda, EmittingContext context)
        {
            var  returnType = lambda.ReturnType;
            var  il         = context.Il;
            var  returnDefaultValueLabel = context.CanReturn ? il.DefineLabel("returnDefaultValue") : null;
            Type resultType;
            var  whatReturn = returnType == typeof(void) ? ResultType.Void : ResultType.Value;
            var  labelUsed  = ExpressionEmittersCollection.Emit(lambda.Body, context, returnDefaultValueLabel, whatReturn, false, out resultType);

            if (returnType == typeof(bool) && resultType == typeof(bool?))
            {
                context.ConvertFromNullableBoolToBool();
            }
            if (returnType == typeof(void) && resultType != typeof(void))
            {
                using (var temp = context.DeclareLocal(resultType))
                    il.Stloc(temp);
            }
            il.Ret();
            if (!labelUsed)
            {
                return;
            }
            context.MarkLabelAndSurroundWithSP(returnDefaultValueLabel);
            il.Pop();
            if (returnType != typeof(void))
            {
                if (!returnType.IsValueType)
                {
                    il.Ldnull();
                }
                else
                {
                    using (var defaultValue = context.DeclareLocal(returnType))
                    {
                        il.Ldloca(defaultValue);
                        il.Initobj(returnType);
                        il.Ldloc(defaultValue);
                    }
                }
            }
            il.Ret();
        }
        public bool EmitMemberAccess(MemberExpression node, GroboIL.Label returnDefaultValueLabel, bool checkNullReferences, bool extend, ResultType whatReturn, out Type resultType, out LocalHolder owner)
        {
            bool result = false;

            owner = null;
            Type    type = node.Expression == null ? null : node.Expression.Type;
            Type    ownerType;
            GroboIL il = Il;

            if (node.Expression == null)
            {
                ownerType = null;
            }
            else
            {
                result |= ExpressionEmittersCollection.Emit(node.Expression, this, returnDefaultValueLabel, ResultType.ByRefValueTypesOnly, extend, out type); // stack: [obj]
                if (!type.IsValueType)
                {
                    ownerType = type;
                }
                else
                {
                    ownerType = type.MakeByRefType();
                    using (var temp = DeclareLocal(type))
                    {
                        il.Stloc(temp);
                        il.Ldloca(temp);
                    }
                }
                if (checkNullReferences && node.Expression != ParsedLambda.ClosureParameter && node.Expression != ParsedLambda.ConstantsParameter && !node.Expression.Type.IsStaticClosure())
                {
                    result |= EmitNullChecking(node.Expression.Type, returnDefaultValueLabel);
                }
            }
            extend &= CanAssign(node.Member);
            Type            memberType  = GetMemberType(node.Member);
            ConstructorInfo constructor = memberType.GetConstructor(Type.EmptyTypes);

            extend &= (memberType.IsClass && constructor != null) || memberType.IsArray;
            if (!extend)
            {
                EmitMemberAccess(type, node.Member, whatReturn, out resultType); // stack: [obj.member]
            }
            else
            {
                if (node.Expression == null)
                {
                    EmitMemberAccess(type, node.Member, whatReturn, out resultType); // stack: [obj.member]
                    var memberIsNotNullLabel = il.DefineLabel("memberIsNotNull");
                    il.Dup();
                    il.Brtrue(memberIsNotNullLabel);
                    il.Pop();
                    Create(memberType);
                    using (var newobj = DeclareLocal(memberType))
                    {
                        il.Stloc(newobj);
                        il.Ldloc(newobj);
                        EmitMemberAssign(type, node.Member);
                        il.Ldloc(newobj);
                    }
                    MarkLabelAndSurroundWithSP(memberIsNotNullLabel);
                }
                else
                {
                    owner = DeclareLocal(ownerType);
                    il.Stloc(owner);
                    il.Ldloc(owner);
                    EmitMemberAccess(type, node.Member, whatReturn, out resultType); // stack: [obj.member]
                    var memberIsNotNullLabel = il.DefineLabel("memberIsNotNull");
                    il.Dup();
                    il.Brtrue(memberIsNotNullLabel);
                    il.Pop();
                    il.Ldloc(owner);
                    Create(memberType);
                    using (var newobj = DeclareLocal(memberType))
                    {
                        il.Stloc(newobj);
                        il.Ldloc(newobj);
                        EmitMemberAssign(type, node.Member);
                        il.Ldloc(newobj);
                    }
                    MarkLabelAndSurroundWithSP(memberIsNotNullLabel);
                }
            }
            return(result);
        }