void doByReferenceType(ByReferenceType byReferenceType) { if (byReferenceTypes.ContainsKey(byReferenceType)) { return; } byReferenceTypes[byReferenceType] = true; addByReferenceType(byReferenceType); }
public JSNewExpression NewMemberReference(JSExpression target, JSLiteral member) { var resultType = new ByReferenceType(member.GetActualType(TypeSystem)); return(new JSNewExpression( Dot("MemberReference", resultType), null, null, target, member )); }
public IType MakeByRefType() { if (byRefType == null) { var def = new ByReferenceType(typeRef); byRefType = new ILType(def, appdomain); } return(byRefType); }
public JSNewExpression NewReference(JSExpression initialValue) { var resultType = new ByReferenceType(initialValue.GetActualType(TypeSystem)); return(new JSNewExpression( Dot("Variable", resultType), null, null, initialValue )); }
/// <summary> /// Get method signature of method definition that complies with how /// CCI generates a method signature. /// </summary> /// <param name="method">Method to get signature.</param> /// <returns> /// Method signature that complies with CCI method signature of the /// definition of the specified method, e.g., List<T>.Add(T); /// (generic parameters are as what they defined). /// </returns> public static string GetMethodSignature(this MethodDefinition method) { string methodSignature; if (method.Name.StartsWith(GetPrefix)) { methodSignature = $"{method.Name.Substring(GetPrefix.Length)}.get"; } else if (method.Name.StartsWith(SetPrefix)) { methodSignature = $"{method.Name.Substring(SetPrefix.Length)}.set"; } else { methodSignature = method.Name; } if (method.HasGenericParameters) { var genericParameters = method.GenericParameters.Select(genericParameter => genericParameter.GetTypeSignature()); methodSignature = $"{methodSignature}<{string.Join(",", genericParameters)}>"; } var parameters = method.Parameters.Select(parameter => { TypeReference resolvedParameterType = parameter.GetTypeWithGenericResolved(); if (resolvedParameterType.IsByReference) { ByReferenceType byReferenceType = (ByReferenceType)resolvedParameterType; string prefix; if (parameter.IsOut) { prefix = "out"; } else if (parameter.IsIn) { prefix = "in"; } else { prefix = "ref"; } return($"{prefix}{byReferenceType.ElementType.GetResolvedTypeSignature()}"); } if (parameter.IsParams()) { return($"params{resolvedParameterType.GetResolvedTypeSignature()}"); } return(resolvedParameterType.GetResolvedTypeSignature()); }); return($"{method.DeclaringType.GetTypeSignature()}.{methodSignature}({string.Join(",", parameters)})"); }
public TypeReference Visit(ByReferenceType current, IGenericContext gcontext) { var result = new ByReferenceType(Get(current.ElementType, gcontext)); if (current.HasGenericParameters) { CopyAndUpdate(result, current, gcontext); } return(result); }
public BlittableByReferenceMarshalInfoWriter(ByReferenceType type, MarshalType marshalType, MarshalInfo marshalInfo) : base(type) { this._elementType = type.ElementType; this._elementTypeMarshalInfoWriter = MarshalDataCollector.MarshalInfoWriterFor(this._elementType, marshalType, marshalInfo, false, true, false, null); if (this._elementTypeMarshalInfoWriter.MarshaledTypes.Length > 1) { throw new InvalidOperationException($"BlittableByReferenceMarshalInfoWriter cannot marshal {type.ElementType.FullName}&."); } this._marshaledTypes = new MarshaledType[] { new MarshaledType(this._elementTypeMarshalInfoWriter.MarshaledTypes[0].Name + "*", this._elementTypeMarshalInfoWriter.MarshaledTypes[0].DecoratedName + "*") }; }
/// <summary> /// Infers the C# type for an IL instruction. /// /// Returns SpecialType.UnknownType for unsupported instructions. /// </summary> public static IType InferType(this ILInstruction inst) { switch (inst) { case NewObj newObj: return(newObj.Method.DeclaringType); case Call call: return(call.Method.ReturnType); case CallVirt callVirt: return(callVirt.Method.ReturnType); case CallIndirect calli: return(calli.ReturnType); case UserDefinedLogicOperator logicOp: return(logicOp.Method.ReturnType); case LdObj ldobj: return(ldobj.Type); case StObj stobj: return(stobj.Type); case LdLoc ldloc: return(ldloc.Variable.Type); case StLoc stloc: return(stloc.Variable.Type); case LdLoca ldloca: return(new ByReferenceType(ldloca.Variable.Type)); case LdFlda ldflda: return(new ByReferenceType(ldflda.Field.Type)); case LdsFlda ldsflda: return(new ByReferenceType(ldsflda.Field.Type)); case LdElema ldelema: if (ldelema.Array.InferType() is ArrayType arrayType) { var refType = new ByReferenceType(arrayType.ElementType); if (TypeUtils.IsCompatibleTypeForMemoryAccess(refType, ldelema.Type)) { return(refType); } } return(new ByReferenceType(ldelema.Type)); default: return(SpecialType.UnknownType); } }
public IType MakeByRefType() { if (byRefType == null) { var def = new ByReferenceType(typeRef); byRefType = new ILType(def, appdomain); ((ILType)byRefType).elementType = this; ((ILType)byRefType).byRefCLRType = this.TypeForCLR.MakeByRefType(); } return(byRefType); }
void IntroducePropertyAccessInstructions(ILExpression expr, ILExpression parentExpr, int posInParent) { if (expr.Code == ILCode.Call || expr.Code == ILCode.Callvirt) { MethodReference cecilMethod = (MethodReference)expr.Operand; if (cecilMethod.DeclaringType is ArrayType) { switch (cecilMethod.Name) { case "Get": expr.Code = ILCode.CallGetter; break; case "Set": expr.Code = ILCode.CallSetter; break; case "Address": ByReferenceType brt = cecilMethod.ReturnType as ByReferenceType; if (brt != null) { MethodReference getMethod = new MethodReference("Get", brt.ElementType, cecilMethod.DeclaringType); foreach (var p in cecilMethod.Parameters) { getMethod.Parameters.Add(p); } getMethod.HasThis = cecilMethod.HasThis; expr.Operand = getMethod; } expr.Code = ILCode.CallGetter; if (parentExpr != null) { parentExpr.Arguments[posInParent] = new ILExpression(ILCode.AddressOf, null, expr); } break; } } else { MethodDefinition cecilMethodDef = cecilMethod.Resolve(); if (cecilMethodDef != null) { if (cecilMethodDef.IsGetter) { expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallGetter : ILCode.CallvirtGetter; } else if (cecilMethodDef.IsSetter) { expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallSetter : ILCode.CallvirtSetter; } } } } }
public void AddIncludesForTypeReference(TypeReference typeReference, bool requiresCompleteType = false) { TypeReference elementType = typeReference; if (!elementType.ContainsGenericParameters()) { ArrayType type = elementType as ArrayType; if (type != null) { this.AddForwardDeclaration(type); } GenericInstanceType type2 = elementType as GenericInstanceType; if (type2 != null) { if (type2.ElementType.IsValueType()) { this.AddIncludeForType(type2); } else { this.AddForwardDeclaration(type2); } } ByReferenceType type3 = elementType as ByReferenceType; if (type3 != null) { elementType = type3.ElementType; } PointerType type4 = elementType as PointerType; if (type4 != null) { elementType = type4.ElementType; } if (elementType.IsPrimitive) { if ((elementType.MetadataType == MetadataType.IntPtr) || (elementType.MetadataType == MetadataType.UIntPtr)) { this.AddIncludeForType(elementType); } } else { bool flag = elementType.IsValueType(); if (flag || (requiresCompleteType && !(elementType is TypeSpecification))) { this.AddIncludeForType(elementType); } if (!flag) { this.AddForwardDeclaration(elementType); } } } }
public NamedInstructionBlockChain CreateThisVariable() { var type = _method.DeclaringType; TypeReference typeRef = type; if (typeRef.IsValueType) { typeRef = new ByReferenceType(type); // Unused? why? } return(CreateThisVariable(type)); }
public JSNewExpression NewElementReference(JSExpression target, JSExpression index) { var resultType = new ByReferenceType( target.GetActualType(TypeSystem).GetElementType() ); return(new JSNewExpression( Dot("MemberReference", resultType), null, null, target, index )); }
public void AddIncludeForTypeDefinition(TypeReference typeReference) { TypeReference reference = typeReference; if (reference.ContainsGenericParameters()) { if (reference.IsGenericParameter) { return; } TypeDefinition definition = reference.Resolve(); if ((definition == null) || definition.IsEnum()) { return; } } reference = Naming.RemoveModifiers(reference); ByReferenceType type = reference as ByReferenceType; if (type != null) { this.AddIncludeForTypeDefinition(type.ElementType); } else { PointerType type2 = reference as PointerType; if (type2 != null) { this.AddIncludeForTypeDefinition(type2.ElementType); } else { ArrayType type3 = reference as ArrayType; if (type3 != null) { this.AddIncludeForType(type3); this.AddIncludeForType(type3.ElementType); } else { GenericInstanceType type4 = reference as GenericInstanceType; if (type4 != null) { this.AddIncludeForType(type4); } else { this.AddIncludeForType(reference); } } } } }
/// <summary> /// Make exact inference from U to V. /// C# 4.0 spec: §7.5.2.8 Exact inferences /// </summary> void MakeExactInference(IType U, IType V) { Log.WriteLine("MakeExactInference from " + U + " to " + V); if (U.Nullability == V.Nullability) { U = U.WithoutNullability(); V = V.WithoutNullability(); } // If V is one of the unfixed Xi then U is added to the set of bounds for Xi. TP tp = GetTPForType(V); if (tp != null && tp.IsFixed == false) { Log.WriteLine(" Add exact bound '" + U + "' to " + tp); tp.AddExactBound(U); return; } // Handle by reference types: ByReferenceType brU = U as ByReferenceType; ByReferenceType brV = V as ByReferenceType; if (brU != null && brV != null) { MakeExactInference(brU.ElementType, brV.ElementType); return; } // Handle array types: ArrayType arrU = U as ArrayType; ArrayType arrV = V as ArrayType; if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions) { MakeExactInference(arrU.ElementType, arrV.ElementType); return; } // Handle parameterized type: ParameterizedType pU = U.TupleUnderlyingTypeOrSelf() as ParameterizedType; ParameterizedType pV = V.TupleUnderlyingTypeOrSelf() as ParameterizedType; if (pU != null && pV != null && object.Equals(pU.GenericType, pV.GenericType) && pU.TypeParameterCount == pV.TypeParameterCount) { Log.Indent(); for (int i = 0; i < pU.TypeParameterCount; i++) { MakeExactInference(pU.GetTypeArgument(i), pV.GetTypeArgument(i)); } Log.Unindent(); } }
public void RefTypeEquality () { var rt1 = new ByReferenceType(T1); var rt1_2 = new ByReferenceType(T1_2); var rt2 = new ByReferenceType(T2); var rt3 = new ByReferenceType(T3); Assert.IsFalse(TypeUtil.TypesAreEqual(rt1, T1)); Assert.IsTrue(TypeUtil.TypesAreEqual(rt1, rt1)); Assert.IsTrue(TypeUtil.TypesAreEqual(rt1, rt1_2)); Assert.IsFalse(TypeUtil.TypesAreEqual(rt1, rt2)); Assert.IsFalse(TypeUtil.TypesAreEqual(rt1, rt3)); }
public static ByReferenceType ChangeByReferenceType(this ByReferenceType type, TypeReference elementType) { if (elementType != type.ElementType) { var result = new ByReferenceType(elementType); if (type.HasGenericParameters) { SetGenericParameters(result, type.GenericParameters); } return(result); } return(type); }
/// <summary> /// Is this a pointer type /// </summary> /// <param name="type">type to test</param> /// <returns>true if pointer type</returns> internal bool IsPointerType(IType type) { if (type.Kind == TypeKind.ByReference) { // Structs are by reference and not pointer ByReferenceType br = (ByReferenceType)type; if (br.ElementType.Kind != TypeKind.Struct) { return(true); } } return(type.Kind == TypeKind.Class || type.Kind == TypeKind.Array); }
public string GetCliFullName(TypeReference typeReference) { if (typeReference.IsByReference) { ByReferenceType byReferenceType = (ByReferenceType)typeReference; return(GetCliFullName(byReferenceType.ElementType) + "&"); } if (typeReference.IsPointer) { PointerType pointerType = (PointerType)typeReference; return(GetCliFullName(pointerType.ElementType) + "*"); } if (typeReference.IsArray) { ArrayType arrayType = (ArrayType)typeReference; string fullNameArray = typeReference.FullName; var suffixStartIndex = fullNameArray.IndexOf("[", StringComparison.Ordinal); string suffix = typeReference.FullName.Substring(suffixStartIndex, fullNameArray.Length - suffixStartIndex); fullNameArray = GetCliFullName(arrayType.ElementType) + suffix; return(fullNameArray); } if (typeReference.IsGenericParameter) { GenericParameter gp = (GenericParameter)typeReference; if (gp.Type == GenericParameterType.Type) { return(GetCliFullName(gp.DeclaringType) + "!!" + gp.Position); } else { string methodFullName = Methods.GetResolutionName(gp.DeclaringMethod); return(methodFullName + "!!" + gp.Position); } } var fullName = typeReference.FullName; return(fullName?.Replace("/", "+") ?? string.Empty); }
public NamedInstructionBlockChain CreateThisVariable(TypeReference typeReference) { typeReference = FixTypeReference(typeReference); if (typeReference.IsValueType) { typeReference = new ByReferenceType(typeReference); } var instanceVariable = _creator.CreateVariable(typeReference); var block = _creator.CreateThisVariable(instanceVariable); var result = new NamedInstructionBlockChain(instanceVariable, typeReference); result.InstructionBlocks.Add(block); return(result); }
/// <summary> /// Make exact inference from U to V. /// C# 4.0 spec: §7.5.2.8 Exact inferences /// </summary> void MakeExactInference(IType U, IType V) { Log("MakeExactInference from " + U + " to " + V); // If V is one of the unfixed Xi then U is added to the set of bounds for Xi. TP tp = GetTPForType(V); if (tp != null && tp.IsFixed == false) { Log(" Add exact bound '" + U + "' to " + tp); tp.LowerBounds.Add(U); tp.UpperBounds.Add(U); return; } // Handle by reference types: ByReferenceType brU = U as ByReferenceType; ByReferenceType brV = V as ByReferenceType; if (brU != null && brV != null) { MakeExactInference(brU.ElementType, brV.ElementType); return; } // Handle array types: ArrayType arrU = U as ArrayType; ArrayType arrV = V as ArrayType; if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions) { MakeExactInference(arrU.ElementType, arrV.ElementType); return; } // Handle parameterized type: ParameterizedType pU = U as ParameterizedType; ParameterizedType pV = V as ParameterizedType; if (pU != null && pV != null && object.Equals(pU.GetDefinition(), pV.GetDefinition()) && pU.TypeParameterCount == pV.TypeParameterCount) { Debug.Indent(); for (int i = 0; i < pU.TypeParameterCount; i++) { MakeExactInference(pU.TypeArguments[i], pV.TypeArguments[i]); } Debug.Unindent(); } }
protected void TypeReferenceInternal(ByReferenceType byref, TypeReferenceContext context) { WriteRaw("$jsilcore"); Dot(); WriteRaw("TypeRef"); LPar(); Value("JSIL.Reference"); Comma(); OpenBracket(false); TypeReference(byref.ElementType, context); CloseBracket(false); RPar(); }
private static TypeReference ResolveTypeReference(TypeReference typeReference, Func <TypeReference, Stack <GenericParameter>, TypeReference> resolver, Stack <GenericParameter> resolutionStack) { if (resolutionStack == null) { resolutionStack = new Stack <GenericParameter>(); } bool stackPushed = false; if (typeReference is GenericParameter) { resolutionStack.Push((GenericParameter)typeReference); stackPushed = true; } typeReference = resolver(typeReference, resolutionStack); if (typeReference is GenericInstanceType) { var git = (GenericInstanceType)typeReference; var newType = new GenericInstanceType(ResolveTypeReference(git.ElementType, resolver, resolutionStack)); foreach (var ga in git.GenericArguments) { newType.GenericArguments.Add(ResolveTypeReference(ga, resolver, resolutionStack)); } return(newType); } if (typeReference is ArrayType) { var at = (ArrayType)typeReference; var newType = new ArrayType(ResolveTypeReference(at.ElementType, resolver, resolutionStack), at.Rank); return(newType); } if (typeReference is ByReferenceType) { var brt = (ByReferenceType)typeReference; var newType = new ByReferenceType(ResolveTypeReference(brt.ElementType, resolver, resolutionStack)); return(newType); } if (stackPushed) { resolutionStack.Pop(); } return(typeReference); }
private static TypeReference GetForwardDeclarationType(TypeReference typeReference) { typeReference = Naming.RemoveModifiers(typeReference); PointerType type = typeReference as PointerType; if (type != null) { return(GetForwardDeclarationType(type.ElementType)); } ByReferenceType type2 = typeReference as ByReferenceType; if (type2 != null) { return(GetForwardDeclarationType(type2.ElementType)); } return(typeReference); }
protected void TypeIdentifier(ByReferenceType type, TypeReferenceContext context, bool includeParens) { if (includeParens) { LPar(); } WriteRaw("JSIL.Reference.Of"); LPar(); TypeIdentifier(type.ElementType as dynamic, context, false); RPar(); if (includeParens) { RPar(); Space(); } }
private static ParameterDefinition CreateThisParameter(MethodDefinition method) { TypeReference typeReference = method.DeclaringType; if (typeReference.HasGenericParameters) { GenericInstanceType genericInstanceType = new GenericInstanceType(typeReference); for (int i = 0; i < typeReference.GenericParameters.Count; i++) { genericInstanceType.GenericArguments.Add(typeReference.GenericParameters[i]); } typeReference = genericInstanceType; } if (typeReference.IsValueType || typeReference.IsPrimitive) { typeReference = new ByReferenceType(typeReference); } return(new ParameterDefinition(typeReference, method)); }
/// <summary> /// Make exact inference from U to V. /// V# 4.0 spec: §7.5.2.8 Exact inferences /// </summary> void MakeExactInference(IType U, IType V) { // If V is one of the unfixed Xi then U is added to the set of bounds for Xi. TP tp = GetTPForType(V); if (tp != null && tp.IsFixed == false) { tp.AddExactBound(U); return; } // Handle by reference types: ByReferenceType brU = U as ByReferenceType; ByReferenceType brV = V as ByReferenceType; if (brU != null && brV != null) { MakeExactInference(brU.ElementType, brV.ElementType); return; } // Handle array types: ArrayType arrU = U as ArrayType; ArrayType arrV = V as ArrayType; if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions) { MakeExactInference(arrU.ElementType, arrV.ElementType); return; } // Handle parameterized type: ParameterizedTypeSpec pU = U as ParameterizedTypeSpec; ParameterizedTypeSpec pV = V as ParameterizedTypeSpec; if (pU != null && pV != null && object.Equals(pU.GetDefinition(), pV.GetDefinition()) && pU.TypeParameterCount == pV.TypeParameterCount) { for (int i = 0; i < pU.TypeParameterCount; i++) { MakeExactInference(pU.GetTypeArgument(i), pV.GetTypeArgument(i)); } } }
private TypeReference FixupType(TypeReference type, TypeReference context = null) { if (type is GenericInstanceType) { return(FixupGenericType((GenericInstanceType)type, context)); } if (type is GenericParameter) { GenericParameter newParameter = null; if (context != null) { if (context is GenericInstanceType) { context = ((GenericInstanceType)context).ElementType; } Dictionary <string, GenericParameter> replacementsForThisType; if (genericParameterReplacements.TryGetValue(context.FullName, out replacementsForThisType)) { replacementsForThisType.TryGetValue(type.FullName, out newParameter); } } return(newParameter ?? type); } if (type is ByReferenceType) { ByReferenceType byRefType = (ByReferenceType)type; return(new ByReferenceType(FixupType(byRefType.ElementType))); } if (type is ArrayType) { return(FixupArrayType((ArrayType)type)); } if (!(type is TypeDefinition)) { type = target.ImportReference(type); } TypeReference replaced; typeReplacements.TryGetValue(type.FullName, out replaced); type = replaced ?? type; return(type); }
public void AddIncludeOrExternForTypeDefinition(TypeReference type) { type = Naming.RemoveModifiers(type); ByReferenceType type2 = type as ByReferenceType; if (type2 != null) { type = type2.ElementType; } PointerType type3 = type as PointerType; if (type3 != null) { type = type3.ElementType; } if (!type.IsValueType()) { this.AddForwardDeclaration(type); } this.AddIncludeForType(type); }
static ParameterDefinition CreateThisParameter(MethodDefinition method) { var parameter_type = method.DeclaringType as TypeReference; if (parameter_type.HasGenericParameters) { var instance = new GenericInstanceType(parameter_type, parameter_type.GenericParameters.Count); for (int i = 0; i < parameter_type.GenericParameters.Count; i++) { instance.GenericArguments.Add(parameter_type.GenericParameters [i]); } parameter_type = instance; } if (parameter_type.IsValueType || parameter_type.IsPrimitive) { parameter_type = new ByReferenceType(parameter_type); } return(new ParameterDefinition(parameter_type, method)); }