public void EmitArrayAddress(ArrayContainer ac) { if (ac.Rank > 1) { if (IsAnonymousStoreyMutateRequired) { ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator); } ig.Emit(OpCodes.Call, ac.GetAddressMethod()); if (TrackStackTypes) { SetStackType(ReferenceContainer.MakeType(Module, ac.Element)); } } else { var type = IsAnonymousStoreyMutateRequired ? CurrentAnonymousMethod.Storey.Mutator.Mutate(ac.Element) : ac.Element; ig.Emit(OpCodes.Ldelema, type.GetMetaInfo()); if (TrackStackTypes) { SetStackType(ReferenceContainer.MakeType(Module, type)); } } }
public void Emit(OpCode opcode, FieldSpec field) { if (IsAnonymousStoreyMutateRequired) { field = field.Mutate(CurrentAnonymousMethod.Storey.Mutator); } ig.Emit(opcode, field.GetMetaInfo()); if (TrackStackTypes) { switch (opcode.StackBehaviourPush) { case StackBehaviour.Push0: // nothing break; case StackBehaviour.Push1: SetStackType(field.MemberType); break; case StackBehaviour.Pushi: SetStackType(ReferenceContainer.MakeType(Module, field.MemberType)); break; default: throw new NotImplementedException(); } } }
public TypeSpec GetStackType(EmitContext ec) { var instance_type = instance.Type; if (addressRequired) { return(ReferenceContainer.MakeType(ec.Module, instance_type)); } if (instance_type.IsStructOrEnum) { return(ec.Module.Compiler.BuiltinTypes.Object); } return(instance_type); }
public MethodInfo GetAddressMethod() { var mb = module.Builder; var arg_types = new MetaType[rank]; for (int i = 0; i < rank; i++) { arg_types[i] = TypeManager.int32_type.GetMetaInfo(); } var address = mb.GetArrayMethod( GetMetaInfo(), "Address", CallingConventions.HasThis | CallingConventions.Standard, ReferenceContainer.MakeType(Element).GetMetaInfo(), arg_types); return(address); }
static TypeSpec EmitCallInstance(EmitContext ec, Expression instance, TypeSpec declaringType, OpCode callOpcode) { var instance_type = instance.Type; // // Push the instance expression // if ((instance_type.IsStruct && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType.IsStruct))) || instance_type.IsGenericParameter || declaringType.IsNullableType) { // // If the expression implements IMemoryLocation, then // we can optimize and use AddressOf on the // return. // // If not we have to use some temporary storage for // it. var iml = instance as IMemoryLocation; if (iml != null) { iml.AddressOf(ec, AddressOp.Load); } else { LocalTemporary temp = new LocalTemporary(instance_type); instance.Emit(ec); temp.Store(ec); temp.AddressOf(ec, AddressOp.Load); temp.Release(ec); } return(ReferenceContainer.MakeType(ec.Module, instance_type)); } if (instance_type.IsEnum || instance_type.IsStruct) { instance.Emit(ec); ec.Emit(OpCodes.Box, instance_type); return(ec.BuiltinTypes.Object); } instance.Emit(ec); return(instance_type); }
public void Emit(OpCode opcode, TypeSpec type) { if (IsAnonymousStoreyMutateRequired) { type = CurrentAnonymousMethod.Storey.Mutator.Mutate(type); } ig.Emit(opcode, type.GetMetaInfo()); if (TrackStackTypes) { switch (opcode.StackBehaviourPush) { case StackBehaviour.Push0: // Nothing break; case StackBehaviour.Pushi: SetStackType(ReferenceContainer.MakeType(Module, type)); break; case StackBehaviour.Push1: SetStackType(type); break; default: if (opcode == OpCodes.Box) { SetStackType(Module.Compiler.BuiltinTypes.Object); } else if (opcode == OpCodes.Castclass) { SetStackType(type); } else { throw new NotImplementedException(opcode.Name); } break; } } }
public void EmitToVariable(EmitContext ec) { var type = Expr.Type; if (IsByRef) { var ml = (IMemoryLocation)Expr; ml.AddressOf(ec, AddressOp.LoadStore); type = ReferenceContainer.MakeType(ec.Module, type); } else { Expr.Emit(ec); } variable = new LocalTemporary(type); variable.Store(ec); Expr = variable; }
public void Emit(OpCode opcode, LocalBuilder local, TypeSpec type) { ig.Emit(opcode, local); if (TrackStackTypes) { if (opcode.StackBehaviourPush == StackBehaviour.Push0) { // Nothing } else if (opcode.StackBehaviourPush == StackBehaviour.Push1) { SetStackType(type); } else if (opcode.StackBehaviourPush == StackBehaviour.Pushi) { SetStackType(ReferenceContainer.MakeType(Module, type)); } else { throw new NotImplementedException(opcode.Name); } } }