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")); } }
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); }