本文整理汇总了C#中AssemblyCompiler.GetDot42InternalType方法的典型用法代码示例。如果您正苦于以下问题:C# AssemblyCompiler.GetDot42InternalType方法的具体用法?C# AssemblyCompiler.GetDot42InternalType怎么用?C# AssemblyCompiler.GetDot42InternalType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AssemblyCompiler
的用法示例。
在下文中一共展示了AssemblyCompiler.GetDot42InternalType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: ConvertCastclass
/// <summary>
/// Convert node with code Cast.
/// </summary>
private static void ConvertCastclass(AssemblyCompiler compiler, AstExpression node, XTypeSystem typeSystem)
{
var type = (XTypeReference) node.Operand;
if (type.IsSystemArray())
{
// Call cast method
var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var castToArray = arrayHelper.Methods.First(x => x.Name == "CastToArray");
var castToArrayExpr = new AstExpression(node.SourceLocation, AstCode.Call, castToArray, node.Arguments).SetType(type);
node.CopyFrom(castToArrayExpr);
return;
}
string castMethod = null;
if (type.IsSystemCollectionsIEnumerable())
{
castMethod = "CastToEnumerable";
}
else if (type.IsSystemCollectionsICollection())
{
castMethod = "CastToCollection";
}
else if (type.IsSystemCollectionsIList())
{
castMethod = "CastToList";
}
else if (type.IsSystemIFormattable())
{
castMethod = "CastToFormattable";
}
if (castMethod != null)
{
// Call cast method
var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var castToArray = arrayHelper.Methods.First(x => x.Name == castMethod);
// Call "(x instanceof T) ? (T)x : asMethod(x)"
// "instanceof x"
var instanceofExpr = new AstExpression(node.SourceLocation, AstCode.SimpleInstanceOf, type, node.Arguments[0]).SetType(typeSystem.Bool);
// CastX(x)
var castXExpr = new AstExpression(node.SourceLocation, AstCode.Call, castToArray, node.Arguments[0]).SetType(typeSystem.Object);
// T(x)
var txExpr = new AstExpression(node.SourceLocation, AstCode.SimpleCastclass, type, node.Arguments[0]).SetType(type);
// Combine
var conditional = new AstExpression(node.SourceLocation, AstCode.Conditional, type, instanceofExpr, txExpr, castXExpr).SetType(type);
node.CopyFrom(conditional);
return;
}
// Normal castclass
node.Code = AstCode.SimpleCastclass;
}
示例2: CreateAssemblyTypes
public static void CreateAssemblyTypes(AssemblyCompiler compiler, DexTargetPackage targetPackage,
IEnumerable<TypeDefinition> reachableTypes)
{
var xAssemblyTypes = compiler.GetDot42InternalType("AssemblyTypes");
var assemblyTypes = (ClassDefinition)xAssemblyTypes.GetClassReference(targetPackage);
var entryAssembly = assemblyTypes.Fields.First(f => f.Name == "EntryAssembly");
var iAssemblyTypes = compiler.GetDot42InternalType("IAssemblyTypes").GetClassReference(targetPackage);
entryAssembly.Value = compiler.Assemblies.First().Name.Name;
List<object> values = new List<object>();
string prevAssemblyName = null;
foreach (var type in reachableTypes.OrderBy(t => t.Module.Assembly.Name.Name)
.ThenBy(t => t.Namespace)
.ThenBy(t => t.Name))
{
var assemblyName = type.module.Assembly.Name.Name;
if (assemblyName == "dot42")
{
// group all android types into virtual "android" assembly,
// so that MvvmCross can find all view-types.
// -- is this a hack?
if (type.Namespace.StartsWith("Android"))
assemblyName = "android";
else // ignore other types, these will get the "default" assembly.
continue;
}
if (prevAssemblyName != assemblyName)
{
values.Add("!" + assemblyName); // we need some identification of assemblies.
prevAssemblyName = assemblyName;
}
// TODO: With compilationmode=all reachable types contains <Module>
// this should be excluded earlier.
if (type.FullName == "<Module>")
continue;
var tRef = type.GetReference(targetPackage, compiler.Module) as ClassReference;
if(tRef != null) values.Add(tRef.Fullname);
}
var anno = new Annotation(iAssemblyTypes, AnnotationVisibility.Runtime,
new AnnotationArgument("AssemblyTypeList", values.ToArray()));
((IAnnotationProvider)assemblyTypes).Annotations.Add(anno);
}
示例3: Create
/// <summary>
/// Create annotations for all included attributes
/// </summary>
public static void Create(AssemblyCompiler compiler, ICustomAttributeProvider attributeProvider,
IAnnotationProvider annotationProvider, DexTargetPackage targetPackage, bool customAttributesOnly = false)
{
if (!attributeProvider.HasCustomAttributes)
return;
var annotations = new List<Annotation>();
foreach (var attr in attributeProvider.CustomAttributes)
{
var attributeType = attr.AttributeType.Resolve();
if (!attributeType.HasIgnoreAttribute())
{
Create(compiler, attr, attributeType, annotations, targetPackage);
}
}
if (annotations.Count > 0)
{
// Create 1 IAttributes annotation
var attrsAnnotation = new Annotation { Visibility = AnnotationVisibility.Runtime };
attrsAnnotation.Type = compiler.GetDot42InternalType("IAttributes").GetClassReference(targetPackage);
attrsAnnotation.Arguments.Add(new AnnotationArgument("Attributes", annotations.ToArray()));
annotationProvider.Annotations.Add(attrsAnnotation);
}
if (!customAttributesOnly)
{
// Add annotations specified using AnnotationAttribute
foreach (var attr in attributeProvider.CustomAttributes.Where(IsAnnotationAttribute))
{
var annotationType = (TypeReference) attr.ConstructorArguments[0].Value;
var annotationClass = annotationType.GetClassReference(targetPackage, compiler.Module);
annotationProvider.Annotations.Add(new Annotation(annotationClass, AnnotationVisibility.Runtime));
}
}
}
示例4: AddGenericParameters
/// <summary>
/// Add generic parameters to the prototype based on the given XMethodDefinition
/// </summary>
public static void AddGenericParameters(AssemblyCompiler compiler, DexTargetPackage targetPackage, XMethodDefinition method, Prototype result)
{
if (method.NeedsGenericInstanceTypeParameter)
{
var annType = compiler.GetDot42InternalType(InternalConstants.GenericTypeParameterAnnotation).GetClassReference(targetPackage);
int numParameters = method.DeclaringType.GenericParameters.Count;
var buildAsArray = numParameters > InternalConstants.GenericTypeParametersAsArrayThreshold;
var parameterArray = result.GenericInstanceTypeParameters;
AddGenericParameterArguments(result, buildAsArray, numParameters, "__$$git", annType, parameterArray);
}
if (method.NeedsGenericInstanceMethodParameter)
{
// Add GenericInstance parameter
var annType = compiler.GetDot42InternalType(InternalConstants.GenericMethodParameterAnnotation).GetClassReference(targetPackage);
int numParameters = method.GenericParameters.Count;
var buildAsArray = numParameters > InternalConstants.GenericMethodParametersAsArrayThreshold;
var parameterArray = result.GenericInstanceMethodParameters;
AddGenericParameterArguments(result, buildAsArray, numParameters, "__$$gim", annType, parameterArray);
}
}
示例5: BuildPrototype
/// <summary>
/// Create a prototype for the given methods signature
/// </summary>
internal static Prototype BuildPrototype(AssemblyCompiler compiler, DexTargetPackage targetPackage, ClassDefinition declaringClass, XMethodDefinition method)
{
var result = new Prototype();
result.ReturnType = method.ReturnType.GetReference(targetPackage);
if (method.IsAndroidExtension && !method.IsStatic)
{
// Add "this" parameter
var dparameter = new Parameter(method.DeclaringType.GetReference(targetPackage), "this");
result.Parameters.Add(dparameter);
}
foreach (var p in method.Parameters)
{
var dparameter = new Parameter(p.ParameterType.GetReference(targetPackage), p.Name);
result.Parameters.Add(dparameter);
}
if (method.NeedsGenericInstanceTypeParameter)
{
// Add GenericInstance parameter (to pass the generic instance array of the declaring type)
var paramType = FrameworkReferences.ClassArray;
var dparameter = new Parameter(paramType, "__$$git");
var annType = compiler.GetDot42InternalType(InternalConstants.GenericTypeParameterAnnotation).GetClassReference(targetPackage);
dparameter.Annotations.Add(new Annotation(annType, AnnotationVisibility.Runtime));
result.Parameters.Add(dparameter);
result.GenericInstanceTypeParameter = dparameter;
}
if (method.NeedsGenericInstanceMethodParameter)
{
// Add GenericInstance parameter
var paramType = FrameworkReferences.ClassArray;
var dparameter = new Parameter(paramType, "__$$gim");
var annType = compiler.GetDot42InternalType(InternalConstants.GenericMethodParameterAnnotation).GetClassReference(targetPackage);
dparameter.Annotations.Add(new Annotation(annType, AnnotationVisibility.Runtime));
result.Parameters.Add(dparameter);
result.GenericInstanceMethodParameter = dparameter;
}
return result;
}
示例6: DelegateInstanceTypeBuilder
/// <summary>
/// Create the current type as class definition.
/// </summary>
internal DelegateInstanceTypeBuilder(
ISourceLocation sequencePoint,
AssemblyCompiler compiler, DexTargetPackage targetPackage,
ClassDefinition delegateClass,
XMethodDefinition invokeMethod, Prototype invokePrototype,
XMethodDefinition calledMethod)
{
this.sequencePoint = sequencePoint;
this.compiler = compiler;
this.targetPackage = targetPackage;
this.delegateClass = delegateClass;
this.invokeMethod = invokeMethod;
this.invokePrototype = invokePrototype;
this.calledMethod = calledMethod;
this.multicastDelegateClass = compiler.GetDot42InternalType("System", "MulticastDelegate").GetClassReference(targetPackage);
}
示例7: CreateAnnotation
public static Annotation CreateAnnotation(XTypeReference xtype, bool forceTypeDefinition,
AssemblyCompiler compiler, DexTargetPackage targetPackage)
{
var genericsDefAnnotationClass = compiler.GetDot42InternalType(InternalConstants.GenericDefinitionAnnotation)
.GetClassReference(targetPackage);
var annotation = new Annotation
{
Type = genericsDefAnnotationClass,
Visibility = AnnotationVisibility.Runtime
};
string s = GetDefinition(xtype, forceTypeDefinition, compiler, targetPackage);
if (string.IsNullOrEmpty(s)) return null;
annotation.Arguments.Add(new AnnotationArgument("Definition", s));
return annotation;
}
示例8: ConvertInstanceOf
/// <summary>
/// Convert node with code InstanceOf.
/// </summary>
private static void ConvertInstanceOf(AssemblyCompiler compiler, AstExpression node, XTypeSystem typeSystem)
{
var type = (XTypeReference)node.Operand;
if (type.IsSystemArray()) // "is System.Array"
{
// Call ArrayHelper.IsArray
var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var isArray = arrayHelper.Methods.First(x => x.Name == "IsArray");
var isArrayExpr = new AstExpression(node.SourceLocation, AstCode.Call, isArray, node.Arguments).SetType(typeSystem.Bool);
node.CopyFrom(isArrayExpr);
return;
}
// make sure we don't evaluate the expression twice.
var tempVar = new AstGeneratedVariable("temp$$", null) { Type = compiler.Module.TypeSystem.Object };
var storeTempVar = new AstExpression(node.SourceLocation, AstCode.Stloc, tempVar, node.Arguments[0]) { ExpectedType = compiler.Module.TypeSystem.Object };
var loadTempVar = new AstExpression(node.SourceLocation, AstCode.Ldloc, tempVar).SetType(compiler.Module.TypeSystem.Object);
if (type.IsSystemCollectionsIEnumerable() ||
type.IsSystemCollectionsICollection() ||
type.IsSystemCollectionsIList())
{
// Call "(is x) || IsArray(x)"
var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var isArray = arrayHelper.Methods.First(x => x.Name == "IsArray" && x.Parameters.Count == 1);
// "is"
var isExpr = new AstExpression(node).SetArguments(storeTempVar).SetCode(AstCode.SimpleInstanceOf);
// Call IsArray
var isArrayExpr = new AstExpression(node.SourceLocation, AstCode.Call, isArray, loadTempVar).SetType(typeSystem.Bool);
// Combined
var combined = new AstExpression(node.SourceLocation, AstCode.Or, null, isExpr, isArrayExpr).SetType(typeSystem.Bool);
node.CopyFrom(combined);
return;
}
if (type.IsSystemCollectionsIEnumerableT() ||
type.IsSystemCollectionsICollectionT() ||
type.IsSystemCollectionsIListT())
{
// TODO: implement InstanceOf with type check for array types.
// (is that even possible here?)
}
if (type.IsSystemIFormattable())
{
// Call "(is x) || IsFormattable(x)"
var formattable = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var isFormattable = formattable.Methods.First(x => x.Name == "IsVirtualFormattable");
// "is"
var isExpr = new AstExpression(node).SetArguments(storeTempVar).SetCode(AstCode.SimpleInstanceOf);
// Call IsFormattable
var isFormattableExpr = new AstExpression(node.SourceLocation, AstCode.Call, isFormattable, loadTempVar).SetType(typeSystem.Bool);
// Combined
var combined = new AstExpression(node.SourceLocation, AstCode.Or, null, isExpr, isFormattableExpr).SetType(typeSystem.Bool);
node.CopyFrom(combined);
return;
}
// Normal instanceof
node.Code = AstCode.SimpleInstanceOf;
}
示例9: GetGenericDefinitionAnnotationForType
public static Annotation GetGenericDefinitionAnnotationForType(XTypeReference xtype, bool forceTypeDefinition, AssemblyCompiler compiler, DexTargetPackage targetPackage)
{
var genericsDefAnnotationClass = compiler.GetDot42InternalType(InternalConstants.GenericDefinitionAnnotation)
.GetClassReference(targetPackage);
var annotation = new Annotation {Type = genericsDefAnnotationClass, Visibility = AnnotationVisibility.Runtime};
if (xtype.IsGenericInstance)
{
bool handled = false;
List<object> genericArguments = new List<object>();
if (xtype.GetElementType().IsNullableT())
{
// privitives and enums are represented by their marker classes.
// no annotation needed.
var argument = ((XGenericInstanceType) xtype).GenericArguments[0];
if (argument.IsEnum() || argument.IsPrimitive && !forceTypeDefinition)
{
return null;
}
// structs have marker classes.
var classRef = xtype.GetReference(targetPackage) as ClassReference;
var @class = classRef == null ? null : targetPackage.DexFile.GetClass(classRef.Fullname);
if (@class != null && @class.NullableMarkerClass != null)
{
annotation.Arguments.Add(new AnnotationArgument("GenericInstanceType", @class.NullableMarkerClass));
handled = true;
}
}
if (!handled)
{
foreach (var arg in ((XGenericInstanceType) xtype).GenericArguments)
{
if (arg.IsGenericParameter)
{
var gparm = (XGenericParameter) arg;
// TODO: if we wanted to annotate methods as well, we should differentiate
// between generic method arguments and generic type arguments.
genericArguments.Add(gparm.Position);
}
else if (arg.IsGenericInstance)
{
var giparm = GetGenericDefinitionAnnotationForType((XGenericInstanceType) arg, true,compiler, targetPackage);
genericArguments.Add(giparm);
}
else
{
genericArguments.Add(arg.GetReference(targetPackage));
}
}
annotation.Arguments.Add(new AnnotationArgument("GenericArguments", genericArguments.ToArray()));
}
}
else // generic parameter
{
var parm = (XGenericParameter) xtype;
annotation.Arguments.Add(new AnnotationArgument("GenericParameter", parm.Position));
}
if(forceTypeDefinition && annotation.Arguments.All(a => a.Name != "GenericInstanceType"))
annotation.Arguments.Add(new AnnotationArgument("GenericTypeDefinition", xtype.ElementType.GetReference(targetPackage)));
return annotation;
}
示例10: ConvertCallvirtIEnumerable
/// <summary>
/// Convert node with code Callvirt.
///
/// For arrays: intercepts call to IEnumerable.IEnumerable_GetEnumerator generated
/// by foreach statements and swaps them out to System.Array.GetEnumerator.
///
/// This call will then at a later compilation stage be replaced with the final destination.
/// </summary>
private static void ConvertCallvirtIEnumerable(AssemblyCompiler compiler, AstExpression node, XTypeSystem typeSystem)
{
var targetMethodRef = ((XMethodReference)node.Operand);
var targetMethodDefOrRef = targetMethodRef;
if (targetMethodDefOrRef.DeclaringType.IsSystemCollectionsIEnumerable()
&& targetMethodDefOrRef.Name == "IEnumerable_GetEnumerator"
&& node.Arguments.Count == 1)
{
var argument = node.Arguments[0];
if (!argument.InferredType.IsArray)
return;
// swap the call to System.Array
var systemArray = compiler.GetDot42InternalType("System", "Array").Resolve();
var getEnumerator = systemArray.Methods.First(x => x.Name == "GetEnumerator" && !x.IsStatic && x.Parameters.Count == 0);
node.Operand = getEnumerator;
}
else if (targetMethodDefOrRef.DeclaringType.IsSystemCollectionsIEnumerableT()
&& targetMethodDefOrRef.Name.EndsWith("_GetEnumerator")
&& node.Arguments.Count == 1)
{
var argument = node.Arguments[0];
if (!argument.InferredType.IsArray)
return;
var elementType = argument.InferredType.ElementType;
// Use As...Enumerable to convert
var asEnumerableName = FrameworkReferences.GetAsEnumerableTMethodName(elementType);
var compilerHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var asEnumerableMethod = compilerHelper.Methods.First(x => x.Name == asEnumerableName);
var call = new AstExpression(node.SourceLocation, AstCode.Call, asEnumerableMethod, argument)
{
InferredType = asEnumerableMethod.ReturnType
};
node.Arguments[0] = call;
argument.ExpectedType = argument.InferredType;
}
}
示例11: ConvertRetOrStfldOrStsfld
/// <summary>
/// Convert ret or store field node.
///
/// converts to IEnumerable, ICollection or IList if required.
/// </summary>
private static void ConvertRetOrStfldOrStsfld(AssemblyCompiler compiler, XTypeReference targetType, AstExpression node, XTypeSystem typeSystem)
{
var argument = node.Arguments.LastOrDefault();
if (argument == null)
return;
if (argument.InferredType == null || !argument.InferredType.IsArray)
return;
var methodName = GetCollectionConvertMethodName(targetType);
if (methodName == null)
return;
// Call "ret asMethod(x)"
var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var asArray = arrayHelper.Methods.First(x => x.Name == "As" + methodName);
// AsX(x)
var asXExpr = new AstExpression(node.SourceLocation, AstCode.Call, asArray, argument).SetType(typeSystem.Object);
// replace argument.
node.Arguments[node.Arguments.Count-1] = asXExpr;
}
示例12: Convert
/// <summary>
/// Optimize expressions
/// </summary>
public static void Convert(AstNode ast, MethodSource currentMethod, AssemblyCompiler compiler)
{
foreach (var node in ast.GetExpressions(x => (x.Code == AstCode.Call) || (x.Code == AstCode.Calli) || (x.Code == AstCode.Callvirt)))
{
var method = (XMethodReference)node.Operand;
bool processed = false;
XMethodDefinition methodDef;
if (method.TryResolve(out methodDef) && methodDef.DeclaringType.IsPrimitive)
{
if (methodDef.IsConstructor && (node.Arguments.Count == 2))
{
// primitive.ctor(addressof_primitive, value) -> primitive.cast(value)
var locVar = node.Arguments[0].Operand;
node.Arguments.RemoveAt(0);
node.SetCode(AstCode.Stloc).SetType(node.Arguments[0].GetResultType()).Operand = locVar;
processed = true;
}
else if (methodDef.Name == "GetHashCode" && node.Arguments.Count == 1 && methodDef.HasThis)
{
// we try to avoid boxing.
var arg = node.Arguments[0];
switch (arg.Code)
{
case AstCode.AddressOf:
arg = arg.Arguments[0];
break;
case AstCode.Ldloca:
arg.SetCode(AstCode.Ldloc);
arg.SetType(arg.InferredType.ElementType);
break;
case AstCode.Ldflda:
arg.SetCode(AstCode.Ldfld);
arg.SetType(arg.InferredType.ElementType);
break;
case AstCode.Ldsflda:
arg.SetCode(AstCode.Ldsfld);
arg.SetType(arg.InferredType.ElementType);
break;
case AstCode.Ldelema:
arg.SetCode(AstCode.Ldelem_Any);
arg.SetType(arg.InferredType.ElementType);
break;
}
var type = arg.GetResultType();
if (type.IsBoolean()
|| type.IsFloat() || type.IsDouble()
|| type.IsInt64() || type.IsUInt64())
{
var ch = compiler.GetDot42InternalType("CompilerHelper").Resolve();
// these need special handling
var replMethod = ch.Methods.FirstOrDefault(m => m.Name == "GetHashCode" && m.IsStatic
&& m.Parameters[0].ParameterType.IsSame(type, true));
if (replMethod != null)
{
node.Operand = replMethod;
node.SetCode(AstCode.Call);
node.Arguments.Clear();
node.Arguments.Add(arg);
}
}
else
{
// for the other primitive types, we just return the value itself.
node.CopyFrom(arg);
node.ExpectedType = compiler.Module.TypeSystem.Int;
}
processed = true;
}
}
if(!processed)
{
for (var i = 0; i < node.Arguments.Count; i++)
{
ProcessArgument(node, method, i, currentMethod, compiler.Module);
}
}
}
}
示例13: ConvertIsInst
/// <summary>
/// Convert node with code IsInst.
/// </summary>
private static void ConvertIsInst(AssemblyCompiler compiler, AstExpression node, XTypeSystem typeSystem)
{
var type = (XTypeReference)node.Operand;
if (type.IsSystemArray())
{
// Call ArrayHelper.AsArray
var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var asArray = arrayHelper.Methods.First(x => x.Name == "AsArray");
var asArrayExpr = new AstExpression(node.SourceLocation, AstCode.Call, asArray, node.Arguments).SetType(typeSystem.Bool);
node.CopyFrom(asArrayExpr);
return;
}
string asMethod = GetCollectionConvertMethodName(type);
if (asMethod != null)
{
asMethod = "As" + asMethod;
}
else if (type.IsSystemIFormattable())
{
asMethod = "AsFormattable";
}
// make sure we don't evaluate the expression twice.
var tempVar = new AstGeneratedVariable("temp$$", null) { Type = compiler.Module.TypeSystem.Object };
var storeTempVar = new AstExpression(node.SourceLocation, AstCode.Stloc, tempVar, node.Arguments[0]) { ExpectedType = compiler.Module.TypeSystem.Object };
var loadTempVar = new AstExpression(node.SourceLocation, AstCode.Ldloc, tempVar).SetType(compiler.Module.TypeSystem.Object);
if (asMethod != null)
{
// Call "(x instanceof T) ? (T)x : asMethod(x)"
var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve();
var asArray = arrayHelper.Methods.First(x => x.Name == asMethod);
// "instanceof x"
var instanceofExpr = new AstExpression(node.SourceLocation, AstCode.SimpleInstanceOf, type, storeTempVar).SetType(typeSystem.Bool);
// AsX(x)
var asXExpr = new AstExpression(node.SourceLocation, AstCode.Call, asArray, loadTempVar).SetType(typeSystem.Object);
// T(x)
var txExpr = new AstExpression(node.SourceLocation, AstCode.SimpleCastclass, type, loadTempVar).SetType(type);
// Combine
var conditional = new AstExpression(node.SourceLocation, AstCode.Conditional, type, instanceofExpr, txExpr, asXExpr).SetType(type);
node.CopyFrom(conditional);
return;
}
// Normal "as": Convert to (x instanceof T) ? (T)x : null
if(!type.IsPrimitive)
{
// "instanceof x"
var instanceofExpr = new AstExpression(node.SourceLocation, AstCode.SimpleInstanceOf, type, storeTempVar).SetType(typeSystem.Bool);
// T(x)
var txExpr = new AstExpression(node.SourceLocation, AstCode.SimpleCastclass, type, loadTempVar).SetType(type);
// null
var nullExpr = new AstExpression(node.SourceLocation, AstCode.Ldnull, null).SetType(typeSystem.Object);
// Combine
var conditional = new AstExpression(node.SourceLocation, AstCode.Conditional, type, instanceofExpr, txExpr, nullExpr).SetType(type);
node.CopyFrom(conditional);
return;
}
else
{
// treat as "x is T"
if(!node.ExpectedType.IsBoolean())
throw new NotImplementedException(); // can this happen?
node.Code = AstCode.SimpleInstanceOf;
}
}
示例14: UnboxGenericArray
/// <summary>
/// Create code to unbox the given source array of boxed type elements into an array of primitive elements.
/// </summary>
public static RLRange UnboxGenericArray(this IRLBuilder builder, ISourceLocation sequencePoint, RegisterSpec source, RegisterSpec boxedArray,
XTypeReference type, DexTargetPackage targetPackage, IRegisterAllocator frame, AssemblyCompiler compiler)
{
var internalBoxingType = compiler.GetDot42InternalType("Boxing").Resolve();
var ilUnboxMethod = internalBoxingType.Methods.First(x => x.EqualsName("UnboxTo") && (x.Parameters.Count == 2) && (x.Parameters[1].ParameterType.IsSame(type, true)));
var unboxMethod = ilUnboxMethod.GetReference(targetPackage);
var call = builder.Add(sequencePoint, RCode.Invoke_static, unboxMethod, boxedArray, source);
return new RLRange(call, null);
}
示例15: Convert
/// <summary>
/// Optimize expressions
/// </summary>
public static void Convert(AstNode ast, MethodSource currentMethod, AssemblyCompiler compiler)
{
var typeSystem = compiler.Module.TypeSystem;
// Expand typeof
foreach (var node in ast.GetSelfAndChildrenRecursive<AstExpression>(x => x.Code == AstCode.TypeOf))
{
var type = (XTypeReference) node.Operand;
var typeHelperType = compiler.GetDot42InternalType(InternalConstants.TypeHelperName).Resolve();
var loadExpr = LoadTypeForGenericInstance(node.SourceLocation, currentMethod, type, compiler, typeHelperType, typeSystem, TypeConversion.EnsureTrueOrMarkerType);
node.CopyFrom(loadExpr);
}
// Expand instanceOf
foreach (var node in ast.GetSelfAndChildrenRecursive<AstExpression>(x => x.Code == AstCode.SimpleInstanceOf))
{
var type = (XTypeReference)node.Operand;
var gp = type as XGenericParameter;
if (gp == null) continue;
var typeHelperType = compiler.GetDot42InternalType(InternalConstants.TypeHelperName).Resolve();
var loadExpr = LoadTypeForGenericInstance(node.SourceLocation, currentMethod, type, compiler, typeHelperType, typeSystem, TypeConversion.EnsureRuntimeType);
//// both types are boxed, no need for conversion.
var typeType = compiler.GetDot42InternalType("System", "Type").Resolve();
var isInstanceOfType = typeType.Methods.Single(n => n.Name == "JavaIsInstance" && n.Parameters.Count == 1);
var call = new AstExpression(node.SourceLocation, AstCode.Call, isInstanceOfType, loadExpr, node.Arguments[0]);
node.CopyFrom(call);
}
// Expand newarr
foreach (var node in ast.GetSelfAndChildrenRecursive<AstExpression>(x => x.Code == AstCode.Newarr))
{
var type = (XTypeReference)node.Operand;
if (!type.IsDefinitionOrReferenceOrPrimitive())
{
// Resolve type to a Class<?>
var typeHelperType = compiler.GetDot42InternalType(InternalConstants.TypeHelperName).Resolve();
// while having primitive arrays for primitive types would be nice, a lot of boxing and unboxing
// would be needed. only for-primitive-specialized generic classes we could optimize this.
var ldType = LoadTypeForGenericInstance(node.SourceLocation, currentMethod, type, compiler, typeHelperType, typeSystem, TypeConversion.EnsureRuntimeType);
var newInstanceExpr = new AstExpression(node.SourceLocation, AstCode.ArrayNewInstance, null, ldType, node.Arguments[0]) { ExpectedType = typeSystem.Object };
var arrayType = new XArrayType(type);
var cast = new AstExpression(node.SourceLocation, AstCode.SimpleCastclass, arrayType, newInstanceExpr) { ExpectedType = arrayType };
node.CopyFrom(cast);
}
}
// Add generic instance call arguments
foreach (var node in ast.GetSelfAndChildrenRecursive<AstExpression>(x => x.Code.IsCall()))
{
var method = (XMethodReference)node.Operand;
if (method.DeclaringType.IsArray)
continue;
XMethodDefinition methodDef;
if (!method.TryResolve(out methodDef))
continue;
if (methodDef.HasDexNativeAttribute())
continue;
if (methodDef.NeedsGenericInstanceTypeParameter)
{
// Add generic instance type parameter value
var arg = CreateGenericInstanceCallArguments(node.SourceLocation, method.DeclaringType, currentMethod, compiler);
node.Arguments.AddRange(arg);
node.GenericInstanceArgCount += arg.Count;
}
if (methodDef.NeedsGenericInstanceMethodParameter)
{
// Add generic instance method parameter
var arg = CreateGenericInstanceCallArguments(node.SourceLocation, method, currentMethod, compiler);
node.Arguments.AddRange(arg);
node.GenericInstanceArgCount += arg.Count;
}
}
// Add generic instance Delegate arguments for static methods.
foreach (var node in ast.GetSelfAndChildrenRecursive<AstExpression>(x => x.Code == AstCode.Delegate))
{
var delegateInfo = (Tuple<XTypeDefinition, XMethodReference>)node.Operand;
var genMethodDef = delegateInfo.Item2 as IXGenericInstance;
var genTypeDef = delegateInfo.Item2.DeclaringType as IXGenericInstance;
// Add generic instance type parameter value, if method is static
if (genTypeDef != null && delegateInfo.Item2.Resolve().IsStatic)
{
var arg = CreateGenericInstanceCallArguments(node.SourceLocation, delegateInfo.Item2.DeclaringType, currentMethod, compiler);
node.Arguments.AddRange(arg);
node.GenericInstanceArgCount += arg.Count;
}
// add generic method type parameter value.
if (genMethodDef != null)
{
var arg = CreateGenericInstanceCallArguments(node.SourceLocation, delegateInfo.Item2, currentMethod, compiler);
node.Arguments.AddRange(arg);
//.........这里部分代码省略.........