public override LocalBuilder DeclareLocal(Type type, bool pinned) { // The handle itself is out of sync with the "backing" VariableDefinition. int index = IL.Body.Variables.Count; LocalBuilder handle = (LocalBuilder)( c_LocalBuilder_params == 4 ? c_LocalBuilder.Invoke(new object[] { index, type, null, pinned }) : c_LocalBuilder_params == 3 ? c_LocalBuilder.Invoke(new object[] { index, type, null }) : c_LocalBuilder_params == 2 ? c_LocalBuilder.Invoke(new object[] { type, null }) : c_LocalBuilder_params == 0 ? c_LocalBuilder.Invoke(new object[] { }) : throw new NotSupportedException() ); f_LocalBuilder_position?.SetValue(handle, (ushort)index); f_LocalBuilder_is_pinned?.SetValue(handle, pinned); TypeReference typeRef = _(type); if (pinned) { typeRef = new PinnedType(typeRef); } VariableDefinition def = new VariableDefinition(typeRef); IL.Body.Variables.Add(def); _Variables[handle] = def; return(handle); }
public override void VisitVariableDefinitionCollection(VariableDefinitionCollection variables) { MethodBody body = variables.Container as MethodBody; if (body == null || body.LocalVarToken == 0) { return; } StandAloneSigTable sasTable = m_reflectReader.TableReader.GetStandAloneSigTable(); StandAloneSigRow sasRow = sasTable [(int)GetRid(body.LocalVarToken) - 1]; LocalVarSig sig = m_reflectReader.SigReader.GetLocalVarSig(sasRow.Signature); for (int i = 0; i < sig.Count; i++) { LocalVarSig.LocalVariable lv = sig.LocalVariables [i]; TypeReference varType = m_reflectReader.GetTypeRefFromSig( lv.Type, new GenericContext(body.Method)); if (lv.ByRef) { varType = new ReferenceType(varType); } if ((lv.Constraint & Constraint.Pinned) != 0) { varType = new PinnedType(varType); } varType = m_reflectReader.GetModifierType(lv.CustomMods, varType); body.Variables.Add(new VariableDefinition( string.Concat("V_", i), i, body.Method, varType)); } }
void addPinnedType(PinnedType pt) { if (pt == null) { return; } addTypeSpecification(pt); }
void doPinnedType(PinnedType pinnedType) { if (pinnedTypes.ContainsKey(pinnedType)) { return; } pinnedTypes[pinnedType] = true; addPinnedType(pinnedType); }
public TypeReference Visit(PinnedType current, IGenericContext gcontext) { var result = new PinnedType(Get(current.ElementType, gcontext)); if (current.HasGenericParameters) { CopyAndUpdate(result, current, gcontext); } return(result); }
public static PinnedType ChangePinnedType(this PinnedType type, TypeReference elementType) { if (elementType != type.ElementType) { var result = new PinnedType(elementType); if (type.HasGenericParameters) { SetGenericParameters(result, type.GenericParameters); } return(result); } return(type); }
internal Type ResolveTypeSpecification(TypeSpecification typeSpecification) { Type elementType = ResolveType(typeSpecification.ElementType); ArrayType arrayType = typeSpecification as ArrayType; if (arrayType != null) { if (arrayType.IsSizedArray) { return(elementType.MakeArrayType()); } return(elementType.MakeArrayType(arrayType.Rank)); } GenericInstanceType genericInstanceType = typeSpecification as GenericInstanceType; if (genericInstanceType != null) { Type[] args = ResolveTypes(genericInstanceType.GenericArguments); return(elementType.MakeGenericType(args)); } ReferenceType referenceType = typeSpecification as ReferenceType; if (referenceType != null) { return(elementType.MakeByRefType()); } PointerType pointerType = typeSpecification as PointerType; if (pointerType != null) { return(elementType.MakePointerType()); } FunctionPointerType functionPointerType = typeSpecification as FunctionPointerType; PinnedType pinnedType = typeSpecification as PinnedType; ModifierOptional modifierOptional = typeSpecification as ModifierOptional; ModifierRequired modifierRequired = typeSpecification as ModifierRequired; SentinelType sentinelType = typeSpecification as SentinelType; throw new NotImplementedException(); }
private void _CopyMethodToDefinition() { MethodBase method = OriginalMethod; Module moduleFrom = method.Module; System.Reflection.MethodBody bodyFrom = method.GetMethodBody(); byte[] data = bodyFrom?.GetILAsByteArray(); if (data == null) { throw new NotSupportedException("Body-less method"); } MethodDefinition def = Definition; ModuleDefinition moduleTo = def.Module; Mono.Cecil.Cil.MethodBody bodyTo = def.Body; ILProcessor processor = bodyTo.GetILProcessor(); Type[] typeArguments = null; if (method.DeclaringType.IsGenericType) { typeArguments = method.DeclaringType.GetGenericArguments(); } Type[] methodArguments = null; if (method.IsGenericMethod) { methodArguments = method.GetGenericArguments(); } foreach (LocalVariableInfo info in bodyFrom.LocalVariables) { TypeReference type = moduleTo.ImportReference(info.LocalType); if (info.IsPinned) { type = new PinnedType(type); } bodyTo.Variables.Add(new VariableDefinition(type)); } using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) { while (reader.BaseStream.Position < reader.BaseStream.Length) { int offset = (int)reader.BaseStream.Position; Instruction instr = Instruction.Create(OpCodes.Nop); byte op = reader.ReadByte(); instr.OpCode = op != 0xfe ? _CecilOpCodes1X[op] : _CecilOpCodes2X[reader.ReadByte()]; instr.Offset = offset; ReadOperand(reader, instr); bodyTo.Instructions.Add(instr); } } foreach (Instruction instr in bodyTo.Instructions) { switch (instr.OpCode.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: instr.Operand = GetInstruction((int)instr.Operand); break; case OperandType.InlineSwitch: int[] offsets = (int[])instr.Operand; Instruction[] targets = new Instruction[offsets.Length]; for (int i = 0; i < offsets.Length; i++) { targets[i] = GetInstruction(offsets[i]); } instr.Operand = targets; break; } } foreach (ExceptionHandlingClause clause in bodyFrom.ExceptionHandlingClauses) { ExceptionHandler handler = new ExceptionHandler((ExceptionHandlerType)clause.Flags); bodyTo.ExceptionHandlers.Add(handler); handler.TryStart = GetInstruction(clause.TryOffset); handler.TryEnd = GetInstruction(clause.TryOffset + clause.TryLength); handler.FilterStart = handler.HandlerType != ExceptionHandlerType.Filter ? null : GetInstruction(clause.FilterOffset); handler.HandlerStart = GetInstruction(clause.HandlerOffset); handler.HandlerEnd = GetInstruction(clause.HandlerOffset + clause.HandlerLength); handler.CatchType = handler.HandlerType != ExceptionHandlerType.Catch ? null : clause.CatchType == null ? null : moduleTo.ImportReference(clause.CatchType); } void ReadOperand(BinaryReader reader, Instruction instr) { int index, offs, length; switch (instr.OpCode.OperandType) { case OperandType.InlineNone: instr.Operand = null; break; case OperandType.InlineSwitch: length = reader.ReadInt32(); offs = (int)reader.BaseStream.Position + (4 * length); int[] targets = new int[length]; for (int i = 0; i < length; i++) { targets[i] = reader.ReadInt32() + offs; } instr.Operand = targets; break; case OperandType.ShortInlineBrTarget: offs = reader.ReadSByte(); instr.Operand = (int)reader.BaseStream.Position + offs; break; case OperandType.InlineBrTarget: offs = reader.ReadInt32(); instr.Operand = (int)reader.BaseStream.Position + offs; break; case OperandType.ShortInlineI: instr.Operand = instr.OpCode == OpCodes.Ldc_I4_S ? reader.ReadSByte() : (object)reader.ReadByte(); break; case OperandType.InlineI: instr.Operand = reader.ReadInt32(); break; case OperandType.ShortInlineR: instr.Operand = reader.ReadSingle(); break; case OperandType.InlineR: instr.Operand = reader.ReadDouble(); break; case OperandType.InlineI8: instr.Operand = reader.ReadInt64(); break; case OperandType.InlineSig: throw new NotSupportedException("Parsing CallSites at runtime currently not supported"); case OperandType.InlineString: instr.Operand = moduleFrom.ResolveString(reader.ReadInt32()); break; case OperandType.InlineTok: switch (moduleFrom.ResolveMember(reader.ReadInt32(), typeArguments, methodArguments)) { case Type i: instr.Operand = moduleTo.ImportReference(i); break; case FieldInfo i: instr.Operand = moduleTo.ImportReference(i); break; case MethodBase i: instr.Operand = moduleTo.ImportReference(i); break; } break; case OperandType.InlineType: instr.Operand = moduleTo.ImportReference(moduleFrom.ResolveType(reader.ReadInt32(), typeArguments, methodArguments)); break; case OperandType.InlineMethod: instr.Operand = moduleTo.ImportReference(moduleFrom.ResolveMethod(reader.ReadInt32(), typeArguments, methodArguments)); break; case OperandType.InlineField: instr.Operand = moduleTo.ImportReference(moduleFrom.ResolveField(reader.ReadInt32(), typeArguments, methodArguments)); break; case OperandType.ShortInlineVar: case OperandType.InlineVar: index = instr.OpCode.OperandType == OperandType.ShortInlineVar ? reader.ReadByte() : reader.ReadInt16(); instr.Operand = bodyTo.Variables[index]; break; case OperandType.InlineArg: case OperandType.ShortInlineArg: index = instr.OpCode.OperandType == OperandType.ShortInlineArg ? reader.ReadByte() : reader.ReadInt16(); instr.Operand = def.Parameters[index]; break; case OperandType.InlinePhi: // No opcode seems to use this default: throw new NotSupportedException($"Unsupported opcode ${instr.OpCode.Name}"); } } Instruction GetInstruction(int offset) { int last = bodyTo.Instructions.Count - 1; if (offset < 0 || offset > bodyTo.Instructions[last].Offset) { return(null); } int min = 0; int max = last; while (min <= max) { int mid = min + ((max - min) / 2); Instruction instr = bodyTo.Instructions[mid]; if (offset == instr.Offset) { return(instr); } if (offset < instr.Offset) { max = mid - 1; } else { min = mid + 1; } } return(null); } }
public NetTypeReference Visit(PinnedType type, ResolveData data) { throw new NotImplementedException("PinnedType to NetTypeReference"); }
public TypeReference Resolve(TypeReference typeReference) { GenericParameter genericParameter = typeReference as GenericParameter; if (genericParameter != null) { return(this.Resolve(this.ResolveGenericParameter(genericParameter))); } ArrayType type = typeReference as ArrayType; if (type != null) { return(new ArrayType(this.Resolve(type.ElementType), type.Rank)); } PointerType type2 = typeReference as PointerType; if (type2 != null) { return(new PointerType(this.Resolve(type2.ElementType))); } ByReferenceType type3 = typeReference as ByReferenceType; if (type3 != null) { return(new ByReferenceType(this.Resolve(type3.ElementType))); } GenericInstanceType type4 = typeReference as GenericInstanceType; if (type4 != null) { GenericInstanceType type5 = new GenericInstanceType(this.Resolve(type4.ElementType)); foreach (TypeReference reference2 in type4.GenericArguments) { type5.GenericArguments.Add(this.Resolve(reference2)); } return(type5); } PinnedType type6 = typeReference as PinnedType; if (type6 != null) { return(new PinnedType(this.Resolve(type6.ElementType))); } RequiredModifierType type7 = typeReference as RequiredModifierType; if (type7 != null) { return(this.Resolve(type7.ElementType)); } OptionalModifierType type8 = typeReference as OptionalModifierType; if (type8 != null) { return(new OptionalModifierType(this.Resolve(type8.ModifierType), this.Resolve(type8.ElementType))); } SentinelType type9 = typeReference as SentinelType; if (type9 != null) { return(new SentinelType(this.Resolve(type9.ElementType))); } if (typeReference is FunctionPointerType) { throw new NotSupportedException("Function pointer types are not supported by the SerializationWeaver"); } if (typeReference is TypeSpecification) { throw new NotSupportedException(); } return(typeReference); }
public TypeReference Resolve(TypeReference typeReference, bool includeTypeDefinitions) { if (!this.IsDummy()) { if ((this._typeDefinitionContext != null) && this._typeDefinitionContext.GenericArguments.Contains(typeReference)) { return(typeReference); } if ((this._methodDefinitionContext != null) && this._methodDefinitionContext.GenericArguments.Contains(typeReference)) { return(typeReference); } GenericParameter item = typeReference as GenericParameter; if (item != null) { if ((this._typeDefinitionContext != null) && this._typeDefinitionContext.GenericArguments.Contains(item)) { return(item); } if ((this._methodDefinitionContext != null) && this._methodDefinitionContext.GenericArguments.Contains(item)) { return(item); } return(this.ResolveGenericParameter(item)); } ArrayType type = typeReference as ArrayType; if (type != null) { return(new ArrayType(this.Resolve(type.ElementType), type.Rank)); } PointerType type2 = typeReference as PointerType; if (type2 != null) { return(new PointerType(this.Resolve(type2.ElementType))); } ByReferenceType type3 = typeReference as ByReferenceType; if (type3 != null) { return(new ByReferenceType(this.Resolve(type3.ElementType))); } PinnedType type4 = typeReference as PinnedType; if (type4 != null) { return(new PinnedType(this.Resolve(type4.ElementType))); } GenericInstanceType type5 = typeReference as GenericInstanceType; if (type5 != null) { GenericInstanceType type6 = new GenericInstanceType(type5.ElementType); foreach (TypeReference reference2 in type5.GenericArguments) { type6.GenericArguments.Add(this.Resolve(reference2)); } return(type6); } RequiredModifierType type7 = typeReference as RequiredModifierType; if (type7 != null) { return(this.Resolve(type7.ElementType, includeTypeDefinitions)); } if (includeTypeDefinitions) { TypeDefinition definition = typeReference as TypeDefinition; if ((definition != null) && definition.HasGenericParameters) { GenericInstanceType type8 = new GenericInstanceType(definition); foreach (GenericParameter parameter2 in definition.GenericParameters) { type8.GenericArguments.Add(this.Resolve(parameter2)); } return(type8); } } if (typeReference is TypeSpecification) { throw new NotSupportedException($"The type {typeReference.FullName} cannot be resolved correctly."); } } return(typeReference); }
/// <summary> /// Gets a TypeRef from a TypeReference. /// </summary> /// <param name="type">The TypeReference.</param> /// <returns>The TypeRef.</returns> public static TypeRef GetTypeRefFromType(TypeReference type) { switch (type.MetadataType) { case MetadataType.UInt64: case MetadataType.Int64: return(Int64); case MetadataType.UInt32: case MetadataType.Int32: return(Int32); case MetadataType.UInt16: case MetadataType.Int16: return(Int16); case MetadataType.Byte: case MetadataType.SByte: return(Int8); case MetadataType.Char: return(Int8); case MetadataType.String: return(String); case MetadataType.Boolean: return(Boolean); case MetadataType.Void: return(Void); case MetadataType.Single: return(Float); case MetadataType.Double: return(Double); case MetadataType.IntPtr: case MetadataType.UIntPtr: return(NativeIntType); case MetadataType.Array: ArrayType array = (ArrayType)type; return(LLVM.PointerType(GetTypeRefFromType(array.ElementType), 0)); case MetadataType.Pointer: PointerType ptr = (PointerType)type; return(LLVM.PointerType(GetTypeRefFromType(ptr.ElementType), 0)); case MetadataType.ByReference: ByReferenceType byRef = (ByReferenceType)type; return(LLVM.PointerType(GetTypeRefFromType(byRef.ElementType), 0)); case MetadataType.Pinned: PinnedType pinned = (PinnedType)type; return(GetTypeRefFromType(pinned.ElementType)); case MetadataType.Class: return(LLVM.PointerType(mLookup.GetTypeRef(type), 0)); case MetadataType.ValueType: return(mLookup.GetTypeRef(type)); case MetadataType.GenericInstance: case MetadataType.Var: case MetadataType.Object: return(VoidPtr); case MetadataType.RequiredModifier: RequiredModifierType requiredModifier = (RequiredModifierType)type; return(GetTypeRefFromType(requiredModifier.ElementType)); case MetadataType.OptionalModifier: OptionalModifierType optionalModifier = (OptionalModifierType)type; return(GetTypeRefFromType(optionalModifier.ElementType)); default: throw new InvalidOperationException("Invalid meta data type to get type from: " + type.MetadataType); } }
private static TypeReference InflateGenericType(GenericInstanceType genericInstanceProvider, TypeReference typeToInflate) { ArrayType type = typeToInflate as ArrayType; if (type != null) { TypeReference reference = InflateGenericType(genericInstanceProvider, type.ElementType); if (reference != type.ElementType) { return(new ArrayType(reference, type.Rank)); } return(type); } GenericInstanceType baseType = typeToInflate as GenericInstanceType; if (baseType != null) { return(MakeGenericType(genericInstanceProvider, baseType)); } GenericParameter genericParameter = typeToInflate as GenericParameter; if (genericParameter != null) { GenericParameter parameter = ResolveType(genericInstanceProvider.ElementType).GenericParameters.Single <GenericParameter>(p => p == genericParameter); return(genericInstanceProvider.GenericArguments[parameter.Position]); } FunctionPointerType type3 = typeToInflate as FunctionPointerType; if (type3 != null) { FunctionPointerType type9 = new FunctionPointerType { ReturnType = InflateGenericType(genericInstanceProvider, type3.ReturnType) }; for (int i = 0; i < type3.Parameters.Count; i++) { TypeReference parameterType = InflateGenericType(genericInstanceProvider, type3.Parameters[i].ParameterType); type9.Parameters.Add(new ParameterDefinition(parameterType)); } return(type9); } IModifierType type4 = typeToInflate as IModifierType; if (type4 != null) { TypeReference modifierType = InflateGenericType(genericInstanceProvider, type4.ModifierType); TypeReference reference4 = InflateGenericType(genericInstanceProvider, type4.ElementType); if (type4 is OptionalModifierType) { return(new OptionalModifierType(modifierType, reference4)); } return(new RequiredModifierType(modifierType, reference4)); } PinnedType type5 = typeToInflate as PinnedType; if (type5 != null) { TypeReference reference5 = InflateGenericType(genericInstanceProvider, type5.ElementType); if (reference5 != type5.ElementType) { return(new PinnedType(reference5)); } return(type5); } PointerType type6 = typeToInflate as PointerType; if (type6 != null) { TypeReference reference6 = InflateGenericType(genericInstanceProvider, type6.ElementType); if (reference6 != type6.ElementType) { return(new PointerType(reference6)); } return(type6); } ByReferenceType type7 = typeToInflate as ByReferenceType; if (type7 != null) { TypeReference reference7 = InflateGenericType(genericInstanceProvider, type7.ElementType); if (reference7 != type7.ElementType) { return(new ByReferenceType(reference7)); } return(type7); } SentinelType type8 = typeToInflate as SentinelType; if (type8 == null) { return(typeToInflate); } TypeReference reference8 = InflateGenericType(genericInstanceProvider, type8.ElementType); if (reference8 != type8.ElementType) { return(new SentinelType(reference8)); } return(type8); }
private static TypeReference ImportType(TypeReference typeRef, ModuleDefinition mod, MethodReference context, Dictionary <MetadataToken, IMemberDefinition> mems) { TypeReference ret = typeRef; if (typeRef is TypeSpecification) { if (typeRef is ArrayType) { ArrayType _spec = typeRef as ArrayType; ret = new ArrayType(ImportType(_spec.ElementType, mod, context, mems)); (ret as ArrayType).Dimensions.Clear(); foreach (var i in _spec.Dimensions) { (ret as ArrayType).Dimensions.Add(i); } } else if (typeRef is GenericInstanceType) { GenericInstanceType _spec = typeRef as GenericInstanceType; ret = new GenericInstanceType(ImportType(_spec.ElementType, mod, context, mems)); foreach (var i in _spec.GenericArguments) { (ret as GenericInstanceType).GenericArguments.Add(ImportType(i, mod, context, mems)); } } else if (typeRef is OptionalModifierType) { ret = new OptionalModifierType( ImportType((typeRef as OptionalModifierType).ModifierType, mod, context, mems), ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); } else if (typeRef is RequiredModifierType) { ret = new RequiredModifierType( ImportType((typeRef as RequiredModifierType).ModifierType, mod, context, mems), ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); } else if (typeRef is ByReferenceType) { ret = new ByReferenceType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); } else if (typeRef is PointerType) { ret = new PointerType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); } else if (typeRef is PinnedType) { ret = new PinnedType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); } else if (typeRef is SentinelType) { ret = new SentinelType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); } else { throw new NotSupportedException(); } } else if (typeRef is GenericParameter) { if (context == null || (typeRef as GenericParameter).Owner is TypeReference || (typeRef as GenericParameter).Position >= context.GenericParameters.Count) { return(typeRef); } return(context.GenericParameters[(typeRef as GenericParameter).Position]); } else { if (mems != null && mems.ContainsKey(typeRef.MetadataToken)) { ret = mems[typeRef.MetadataToken] as TypeReference; } else if (!(ret is TypeDefinition) && typeRef.Scope.Name != "Confuser.Core.Injections.dll") { ret = mod.Import(ret); } } return(ret); }
protected virtual PinnedType updatePinnedType(PinnedType a) { return(new PinnedType(update(a.ElementType))); }
protected void VisitTypeReference(TypeReference typeReference, Context context) { GenericParameter genericParameter = typeReference as GenericParameter; if (genericParameter != null) { this.Visit(genericParameter, context); } else { ArrayType arrayType = typeReference as ArrayType; if (arrayType != null) { this.Visit(arrayType, context); } else { PointerType pointerType = typeReference as PointerType; if (pointerType != null) { this.Visit(pointerType, context); } else { ByReferenceType byReferenceType = typeReference as ByReferenceType; if (byReferenceType != null) { this.Visit(byReferenceType, context); } else { FunctionPointerType functionPointerType = typeReference as FunctionPointerType; if (functionPointerType != null) { this.Visit(functionPointerType, context); } else { PinnedType pinnedType = typeReference as PinnedType; if (pinnedType != null) { this.Visit(pinnedType, context); } else { SentinelType sentinelType = typeReference as SentinelType; if (sentinelType != null) { this.Visit(sentinelType, context); } else { GenericInstanceType genericInstanceType = typeReference as GenericInstanceType; if (genericInstanceType != null) { this.Visit(genericInstanceType, context); } else { RequiredModifierType requiredModifierType = typeReference as RequiredModifierType; if (requiredModifierType != null) { this.Visit(requiredModifierType, context); } else { this.Visit(typeReference, context); } } } } } } } } } }
public static TypeReference StackTypeFor(TypeReference type) { PinnedType type2 = type as PinnedType; if (type2 != null) { type = type2.ElementType; } ByReferenceType type3 = type as ByReferenceType; if (type3 != null) { return(type3); } RequiredModifierType type4 = type as RequiredModifierType; if (type4 != null) { return(StackTypeFor(type4.ElementType)); } if ((type.IsSameType(TypeProvider.NativeIntTypeReference) || type.IsSameType(TypeProvider.NativeUIntTypeReference)) || type.IsPointer) { return(TypeProvider.NativeIntTypeReference); } if (!type.IsValueType()) { return(TypeProvider.ObjectTypeReference); } MetadataType metadataType = type.MetadataType; if (type.IsValueType() && type.IsEnum()) { metadataType = type.GetUnderlyingEnumType().MetadataType; } switch (metadataType) { case MetadataType.Boolean: case MetadataType.Char: case MetadataType.SByte: case MetadataType.Byte: case MetadataType.Int16: case MetadataType.UInt16: case MetadataType.Int32: case MetadataType.UInt32: return(TypeProvider.Int32TypeReference); case MetadataType.Int64: case MetadataType.UInt64: return(TypeProvider.Int64TypeReference); case MetadataType.Single: return(TypeProvider.SingleTypeReference); case MetadataType.Double: return(TypeProvider.DoubleTypeReference); case MetadataType.IntPtr: case MetadataType.UIntPtr: return(TypeProvider.NativeIntTypeReference); } throw new ArgumentException($"Cannot get stack type for {type.Name}"); }
public CodeTypeReference Visit(PinnedType type, object data) { throw new System.NotImplementedException(); }
public TypeReference Resolve(TypeReference typeReference) { GenericParameter genericParameter = typeReference as GenericParameter; if (genericParameter != null) { return(this.Resolve(this.ResolveGenericParameter(genericParameter))); } ArrayType arrayType = typeReference as ArrayType; if (arrayType != null) { return(new ArrayType(this.Resolve(arrayType.ElementType), arrayType.Rank)); } PointerType pointerType = typeReference as PointerType; if (pointerType != null) { return(new PointerType(this.Resolve(pointerType.ElementType))); } ByReferenceType byReferenceType = typeReference as ByReferenceType; if (byReferenceType != null) { return(new ByReferenceType(this.Resolve(byReferenceType.ElementType))); } GenericInstanceType genericInstanceType = typeReference as GenericInstanceType; if (genericInstanceType != null) { GenericInstanceType genericInstanceType2 = new GenericInstanceType(this.Resolve(genericInstanceType.ElementType)); foreach (TypeReference current in genericInstanceType.GenericArguments) { genericInstanceType2.GenericArguments.Add(this.Resolve(current)); } return(genericInstanceType2); } PinnedType pinnedType = typeReference as PinnedType; if (pinnedType != null) { return(new PinnedType(this.Resolve(pinnedType.ElementType))); } RequiredModifierType requiredModifierType = typeReference as RequiredModifierType; if (requiredModifierType != null) { return(this.Resolve(requiredModifierType.ElementType)); } OptionalModifierType optionalModifierType = typeReference as OptionalModifierType; if (optionalModifierType != null) { return(new OptionalModifierType(this.Resolve(optionalModifierType.ModifierType), this.Resolve(optionalModifierType.ElementType))); } SentinelType sentinelType = typeReference as SentinelType; if (sentinelType != null) { return(new SentinelType(this.Resolve(sentinelType.ElementType))); } FunctionPointerType functionPointerType = typeReference as FunctionPointerType; if (functionPointerType != null) { throw new NotSupportedException("Function pointer types are not supported by the SerializationWeaver"); } if (typeReference is TypeSpecification) { throw new NotSupportedException(); } return(typeReference); }
/// <summary> /// Replace generic parameters with actual arguments /// </summary> private MonoTypeContext ResolveGenericParameter() { switch (Type.etype) { case ElementType.Var: case ElementType.MVar: { GenericParameter parameter = (GenericParameter)Type; TypeReference resolvedType = Arguments[parameter]; return(new MonoTypeContext(resolvedType)); } case ElementType.Array: { ArrayType array = (ArrayType)Type; MonoTypeContext arrayContext = new MonoTypeContext(array.ElementType, Arguments); MonoTypeContext resolvedContext = arrayContext.ResolveGenericParameter(); ArrayType newArray = new ArrayType(resolvedContext.Type, array.Rank); if (array.Rank > 1) { for (int i = 0; i < array.Rank; i++) { newArray.Dimensions[i] = array.Dimensions[i]; } } return(new MonoTypeContext(newArray, Arguments)); } case ElementType.GenericInst: { GenericInstanceType genericInstance = (GenericInstanceType)Type; GenericInstanceType newInstance = new GenericInstanceType(genericInstance.ElementType); foreach (TypeReference argument in genericInstance.GenericArguments) { MonoTypeContext argumentContext = new MonoTypeContext(argument, Arguments); MonoTypeContext resolvedArgument = argumentContext.Resolve(); newInstance.GenericArguments.Add(resolvedArgument.Type); } return(new MonoTypeContext(newInstance, Arguments)); } case ElementType.ByRef: { ByReferenceType reference = (ByReferenceType)Type; MonoTypeContext refContext = new MonoTypeContext(reference.ElementType, Arguments); MonoTypeContext resolvedContext = refContext.ResolveGenericParameter(); ByReferenceType newReference = new ByReferenceType(resolvedContext.Type); return(new MonoTypeContext(newReference, Arguments)); } case ElementType.Ptr: { PointerType pointer = (PointerType)Type; MonoTypeContext ptrContext = new MonoTypeContext(pointer.ElementType, Arguments); MonoTypeContext resolvedContext = ptrContext.ResolveGenericParameter(); PointerType newPointer = new PointerType(resolvedContext.Type); return(new MonoTypeContext(newPointer, Arguments)); } case ElementType.Pinned: { PinnedType pinned = (PinnedType)Type; MonoTypeContext pinContext = new MonoTypeContext(pinned.ElementType, Arguments); MonoTypeContext resolvedContext = pinContext.ResolveGenericParameter(); PinnedType newPinned = new PinnedType(resolvedContext.Type); return(new MonoTypeContext(newPinned, Arguments)); } case ElementType.FnPtr: { FunctionPointerType funcPtr = (FunctionPointerType)Type; FunctionPointerType newFuncPtr = new FunctionPointerType(); newFuncPtr.HasThis = funcPtr.HasThis; newFuncPtr.ExplicitThis = funcPtr.ExplicitThis; newFuncPtr.CallingConvention = funcPtr.CallingConvention; MonoTypeContext returnContext = new MonoTypeContext(funcPtr.ReturnType, Arguments); MonoTypeContext resolvedReturn = returnContext.Resolve(); newFuncPtr.ReturnType = resolvedReturn.Type; foreach (ParameterDefinition param in funcPtr.Parameters) { MonoTypeContext paramContext = new MonoTypeContext(param.ParameterType, Arguments); MonoTypeContext resolvedParam = paramContext.Resolve(); ParameterDefinition newParameter = new ParameterDefinition(param.Name, param.Attributes, resolvedParam.Type); newFuncPtr.Parameters.Add(newParameter); } return(new MonoTypeContext(newFuncPtr, Arguments)); } default: throw new Exception($"Unknown generic parameter container {Type}"); } }
static bool comparePinnedTypes(Type a, PinnedType b) { return compareTypes(a, b.ElementType); }
protected virtual void Visit(PinnedType pinnedType, Context context) { this.VisitTypeReference(pinnedType.ElementType, context.ElementType(pinnedType)); }
private void _CopyMethodToDefinition() { MethodBase method = OriginalMethod; Module moduleFrom = method.Module; System.Reflection.MethodBody bodyFrom = method.GetMethodBody(); byte[] data = bodyFrom?.GetILAsByteArray(); if (data == null) { throw new NotSupportedException("Body-less method"); } MethodDefinition def = Definition; ModuleDefinition moduleTo = def.Module; Mono.Cecil.Cil.MethodBody bodyTo = def.Body; ILProcessor processor = bodyTo.GetILProcessor(); Type[] typeArguments = null; if (method.DeclaringType.IsGenericType) { typeArguments = method.DeclaringType.GetGenericArguments(); } Type[] methodArguments = null; if (method.IsGenericMethod) { methodArguments = method.GetGenericArguments(); } foreach (LocalVariableInfo info in bodyFrom.LocalVariables) { TypeReference type = moduleTo.ImportReference(info.LocalType); if (info.IsPinned) { type = new PinnedType(type); } bodyTo.Variables.Add(new VariableDefinition(type)); } using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) { for (Instruction instr = null, prev = null; reader.BaseStream.Position < reader.BaseStream.Length; prev = instr) { int offset = (int)reader.BaseStream.Position; instr = Instruction.Create(OpCodes.Nop); byte op = reader.ReadByte(); instr.OpCode = op != 0xfe ? _CecilOpCodes1X[op] : _CecilOpCodes2X[reader.ReadByte()]; instr.Offset = offset; if (prev != null) { prev.Next = instr; } instr.Previous = prev; ReadOperand(reader, instr); bodyTo.Instructions.Add(instr); } } foreach (Instruction instr in bodyTo.Instructions) { switch (instr.OpCode.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: instr.Operand = GetInstruction((int)instr.Operand); break; case OperandType.InlineSwitch: int[] offsets = (int[])instr.Operand; Instruction[] targets = new Instruction[offsets.Length]; for (int i = 0; i < offsets.Length; i++) { targets[i] = GetInstruction(offsets[i]); } instr.Operand = targets; break; } } foreach (ExceptionHandlingClause clause in bodyFrom.ExceptionHandlingClauses) { ExceptionHandler handler = new ExceptionHandler((ExceptionHandlerType)clause.Flags); bodyTo.ExceptionHandlers.Add(handler); handler.TryStart = GetInstruction(clause.TryOffset); handler.TryEnd = GetInstruction(clause.TryOffset + clause.TryLength); handler.FilterStart = handler.HandlerType != ExceptionHandlerType.Filter ? null : GetInstruction(clause.FilterOffset); handler.HandlerStart = GetInstruction(clause.HandlerOffset); handler.HandlerEnd = GetInstruction(clause.HandlerOffset + clause.HandlerLength); handler.CatchType = handler.HandlerType != ExceptionHandlerType.Catch ? null : clause.CatchType == null ? null : moduleTo.ImportReference(clause.CatchType); } void ReadOperand(BinaryReader reader, Instruction instr) { int index, offs, length; switch (instr.OpCode.OperandType) { case OperandType.InlineNone: instr.Operand = null; break; case OperandType.InlineSwitch: length = reader.ReadInt32(); offs = (int)reader.BaseStream.Position + (4 * length); int[] targets = new int[length]; for (int i = 0; i < length; i++) { targets[i] = reader.ReadInt32() + offs; } instr.Operand = targets; break; case OperandType.ShortInlineBrTarget: offs = reader.ReadSByte(); instr.Operand = (int)reader.BaseStream.Position + offs; break; case OperandType.InlineBrTarget: offs = reader.ReadInt32(); instr.Operand = (int)reader.BaseStream.Position + offs; break; case OperandType.ShortInlineI: instr.Operand = instr.OpCode == OpCodes.Ldc_I4_S ? reader.ReadSByte() : (object)reader.ReadByte(); break; case OperandType.InlineI: instr.Operand = reader.ReadInt32(); break; case OperandType.ShortInlineR: instr.Operand = reader.ReadSingle(); break; case OperandType.InlineR: instr.Operand = reader.ReadDouble(); break; case OperandType.InlineI8: instr.Operand = reader.ReadInt64(); break; case OperandType.InlineSig: instr.Operand = moduleTo.ImportCallSite(moduleFrom, moduleFrom.ResolveSignature(reader.ReadInt32())); break; case OperandType.InlineString: instr.Operand = moduleFrom.ResolveString(reader.ReadInt32()); break; case OperandType.InlineTok: instr.Operand = ResolveTokenAs(reader.ReadInt32(), TokenResolutionMode.Any); break; case OperandType.InlineType: instr.Operand = ResolveTokenAs(reader.ReadInt32(), TokenResolutionMode.Type); break; case OperandType.InlineMethod: instr.Operand = ResolveTokenAs(reader.ReadInt32(), TokenResolutionMode.Method); break; case OperandType.InlineField: instr.Operand = ResolveTokenAs(reader.ReadInt32(), TokenResolutionMode.Field); break; case OperandType.ShortInlineVar: case OperandType.InlineVar: index = instr.OpCode.OperandType == OperandType.ShortInlineVar ? reader.ReadByte() : reader.ReadInt16(); instr.Operand = bodyTo.Variables[index]; break; case OperandType.InlineArg: case OperandType.ShortInlineArg: index = instr.OpCode.OperandType == OperandType.ShortInlineArg ? reader.ReadByte() : reader.ReadInt16(); instr.Operand = def.Parameters[index]; break; case OperandType.InlinePhi: // No opcode seems to use this default: throw new NotSupportedException($"Unsupported opcode ${instr.OpCode.Name}"); } } MemberReference ResolveTokenAs(int token, TokenResolutionMode resolveMode) { try { switch (resolveMode) { case TokenResolutionMode.Type: return(moduleTo.ImportReference(moduleFrom.ResolveType(token, typeArguments, methodArguments))); case TokenResolutionMode.Method: return(moduleTo.ImportReference(moduleFrom.ResolveMethod(token, typeArguments, methodArguments))); case TokenResolutionMode.Field: return(moduleTo.ImportReference(moduleFrom.ResolveField(token, typeArguments, methodArguments))); case TokenResolutionMode.Any: switch (moduleFrom.ResolveMember(token, typeArguments, methodArguments)) { case Type i: return(moduleTo.ImportReference(i)); case MethodBase i: return(moduleTo.ImportReference(i)); case FieldInfo i: return(moduleTo.ImportReference(i)); case var resolved: throw new NotSupportedException($"Invalid resolved member type {resolved.GetType()}"); } default: throw new NotSupportedException($"Invalid TokenResolutionMode {resolveMode}"); } } catch (MissingMemberException) { // we could not resolve the method normally, so lets read the import table // but we can only do that if the module was loaded from disk // this can still throw if the assembly is a dynamic one, but if that's broken, you have bigger issues string filePath = moduleFrom.Assembly.Location; if (!File.Exists(filePath)) { // in this case, the fallback cannot be followed, and so throwing the original error gives the user information throw; } // TODO: make this cached somehow so its not read and re-opened a bunch using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(filePath, new ReaderParameters { ReadingMode = ReadingMode.Deferred })) { ModuleDefinition module = assembly.Modules.First(m => m.Name == moduleFrom.Name); // this should only fail if the token itself is somehow wrong MemberReference reference = (MemberReference)module.LookupToken(token); // the explicit casts here are to throw if they are incorrect // normally the references would need to be imported, but moduleTo isn't written to anywhere switch (resolveMode) { case TokenResolutionMode.Type: return((TypeReference)reference); case TokenResolutionMode.Method: return((MethodReference)reference); case TokenResolutionMode.Field: return((FieldReference)reference); case TokenResolutionMode.Any: return(reference); default: throw new NotSupportedException($"Invalid TokenResolutionMode {resolveMode}"); } } } } Instruction GetInstruction(int offset) { int last = bodyTo.Instructions.Count - 1; if (offset < 0 || offset > bodyTo.Instructions[last].Offset) { return(null); } int min = 0; int max = last; while (min <= max) { int mid = min + ((max - min) / 2); Instruction instr = bodyTo.Instructions[mid]; if (offset == instr.Offset) { return(instr); } if (offset < instr.Offset) { max = mid - 1; } else { min = mid + 1; } } return(null); } }
public virtual TypeReference Visit(PinnedType type) { type = type.ChangePinnedType(VisitDynamic(type.ElementType)); return(type.ChangeGenericParameters(VisitDynamicList(type.GenericParameters))); }
public static int GetHashCodeFor(TypeReference obj) { MetadataType metadataType = obj.MetadataType; switch (metadataType) { case MetadataType.GenericInstance: { GenericInstanceType type2 = (GenericInstanceType)obj; int num = (GetHashCodeFor(type2.ElementType) * 0x1cfaa2db) + 0x1f; for (int i = 0; i < type2.GenericArguments.Count; i++) { num = (num * 0x1cfaa2db) + GetHashCodeFor(type2.GenericArguments[i]); } return(num); } case MetadataType.Array: { ArrayType type3 = (ArrayType)obj; return((GetHashCodeFor(type3.ElementType) * 0x1cfaa2db) + type3.Rank.GetHashCode()); } case MetadataType.Var: case MetadataType.MVar: { GenericParameter parameter = (GenericParameter)obj; int num7 = (int)metadataType; int num5 = (parameter.Position.GetHashCode() * 0x1cfaa2db) + num7.GetHashCode(); TypeReference owner = parameter.Owner as TypeReference; if (owner != null) { return((num5 * 0x1cfaa2db) + GetHashCodeFor(owner)); } MethodReference reference2 = parameter.Owner as MethodReference; if (reference2 == null) { throw new InvalidOperationException("Generic parameter encountered with invalid owner"); } return((num5 * 0x1cfaa2db) + Unity.IL2CPP.Common.MethodReferenceComparer.GetHashCodeFor(reference2)); } case MetadataType.ByReference: { ByReferenceType type4 = (ByReferenceType)obj; return((GetHashCodeFor(type4.ElementType) * 0x1cfaa2db) * 0x25); } case MetadataType.Pointer: { PointerType type5 = (PointerType)obj; return((GetHashCodeFor(type5.ElementType) * 0x1cfaa2db) * 0x29); } case MetadataType.RequiredModifier: { RequiredModifierType type6 = (RequiredModifierType)obj; int num8 = GetHashCodeFor(type6.ElementType) * 0x2b; return((num8 * 0x1cfaa2db) + GetHashCodeFor(type6.ModifierType)); } case MetadataType.OptionalModifier: { OptionalModifierType type7 = (OptionalModifierType)obj; int num9 = GetHashCodeFor(type7.ElementType) * 0x2f; return((num9 * 0x1cfaa2db) + GetHashCodeFor(type7.ModifierType)); } case MetadataType.Pinned: { PinnedType type8 = (PinnedType)obj; return((GetHashCodeFor(type8.ElementType) * 0x1cfaa2db) * 0x35); } case MetadataType.Sentinel: { SentinelType type9 = (SentinelType)obj; return((GetHashCodeFor(type9.ElementType) * 0x1cfaa2db) * 0x3b); } case MetadataType.FunctionPointer: throw new NotImplementedException("We currently don't handle function pointer types."); } return((obj.Namespace.GetHashCode() * 0x1cfaa2db) + obj.FullName.GetHashCode()); }
protected override void Visit(PinnedType pinnedType, Context context) { Touch(pinnedType); base.Visit(pinnedType, context); }
public TypeReference Retarget(TypeReference type, GenericContext context) { TypeReference reference; if (type == null) { return(type); } if ((type.IsFunctionPointer || type.IsOptionalModifier) || type.IsSentinel) { throw new NotImplementedException(); } if (type.IsArray) { ArrayType type2 = (ArrayType)type; ArrayType type3 = new ArrayType(this.Retarget(type2.ElementType, context), type2.Rank); for (int i = 0; i < type2.Dimensions.Count; i++) { ArrayDimension dimension = type2.Dimensions[i]; type3.Dimensions[i] = new ArrayDimension(dimension.LowerBound, dimension.UpperBound); } reference = type3; } else if (type.IsByReference) { ByReferenceType type4 = (ByReferenceType)type; reference = new ByReferenceType(this.Retarget(type4.ElementType, context)); } else if (type.IsDefinition && Utility.SameScope(type.Scope, this.Module)) { reference = type; } else if (type.IsGenericInstance) { GenericInstanceType type5 = (GenericInstanceType)type; GenericInstanceType type6 = new GenericInstanceType(this.Retarget(type5.ElementType, context)); foreach (TypeReference reference2 in type5.GenericArguments) { TypeReference item = this.Retarget(reference2, context); type6.GenericArguments.Add(item); } reference = type6; } else { if (type.IsGenericParameter) { GenericParameter parameter = (GenericParameter)type; return(context.Retarget(parameter)); } if (type.IsPinned) { PinnedType type7 = (PinnedType)type; reference = new PinnedType(this.Retarget(type7.ElementType, context)); } else if (type.IsPointer) { PointerType type8 = (PointerType)type; reference = new PointerType(this.Retarget(type8.ElementType, context)); } else if (type.IsRequiredModifier) { RequiredModifierType type9 = (RequiredModifierType)type; reference = new RequiredModifierType(this.Retarget(type9.ModifierType, context), this.Retarget(type9.ElementType, context)); } else { reference = type.Resolve(); if ((reference == null) && (this.OperationContext.Platform == Platform.UAP)) { string fullName = null; string str2 = type.FullName; if ((!(str2 == "System.Collections.ArrayList") && !(str2 == "System.Collections.CollectionBase")) && (!(str2 == "System.Collections.Hashtable") && !(str2 == "System.Collections.Stack"))) { if (str2 == "System.Reflection.BindingFlags") { fullName = "System.Reflection.TypeExtensions"; } } else { fullName = "System.Collections.NonGeneric"; } if (fullName != null) { IMetadataScope scope = type.Scope; type.Scope = AssemblyNameReference.Parse(fullName); reference = type.Resolve(); type.Scope = scope; } } } } return(this.Module.ImportReference(reference)); }