public MetadataGenerator(Disk disk, IBuildData data, IEssentials essentials, MetadataBackend backend, CilLinker linker, SourcePackage package, string outputDir) : base(disk) { _data = data; _essentials = essentials; _backend = backend; _package = package; _linker = linker; _outputDir = outputDir; _assembly = _linker.Universe.DefineDynamicAssembly( new AssemblyName(package.Name) { Version = package.ParseVersion(Log) }, AssemblyBuilderAccess.Save, outputDir); var module = _assembly.DefineDynamicModule( package.Name, package.Name + ".dll", true); _types = new CilTypeFactory(backend, essentials, linker, module); }
static CustomAttributeBuilder GetDelegateParameterCustomAttribute( Universe universe, IEssentials essentials, Parameter p, int paramIndex) { var dt = p.Type; if (dt == essentials.Bool) { return(GetBoolCustomAttribute(universe)); } if (dt.IsArray) { var argTypes = new[] { universe.Import(typeof(UnmanagedType)) }; var attrType = universe.Import(typeof(MarshalAsAttribute)); var ci = attrType.GetConstructor(argTypes); var args = new object[] { UnmanagedType.LPArray }; var fields = new[] { attrType.GetField("SizeParamIndex") }; var fieldValues = new object[] { (short)(paramIndex + 1) }; return(new CustomAttributeBuilder(ci, args, fields, fieldValues)); } if (dt == essentials.String) { var argTypes = new[] { universe.Import(typeof(UnmanagedType)) }; var attrType = universe.Import(typeof(MarshalAsAttribute)); var ci = attrType.GetConstructor(argTypes); var args = new object[] { UnmanagedType.LPWStr }; return(new CustomAttributeBuilder(ci, args)); } return(null); }
public CilTypeFactory(Backend backend, IEssentials essentials, CilLinker linker, ModuleBuilder module) { _backend = backend; _essentials = essentials; _linker = linker; _module = module; }
public ForeignHelpers(IEnvironment environment, IEssentials essentials, CppBackend backend, IBuildData data) { Environment = environment; Essentials = essentials; Backend = backend; Data = data; }
public Converter(DataType boxedJavaObject, IEssentials essentials, IILFactory ilFactory, ForeignHelpers helpers) { Essentials = essentials; Type = new TypeConverter(this, boxedJavaObject, essentials, helpers); Name = new NameConverter(this, ilFactory); Param = new ParamConverter(this); Signature = new SignatureConverter(this, essentials); }
public TypeConverter(Converter converter, DataType boxedJavaObject, IEssentials essentials, ForeignHelpers helpers) { _helpers = helpers; _convert = converter; _boxedJavaObject = boxedJavaObject; _essentials = essentials; Void = _essentials.Void; }
protected Pass(ShaderBackend backend) : base(backend.Log) { Disk = backend.Disk; Data = backend.Data; Environment = backend.Environment; Essentials = backend.Essentials; ILFactory = backend.ILFactory; }
protected Pass(Pass parent) : base(parent.Log) { Disk = parent.Disk; Data = parent.Data; Environment = parent.Environment; Essentials = parent.Essentials; ILFactory = parent.ILFactory; }
internal CilType(Backend backend, IEssentials essentials, CilLinker linker, TypeBuilder builder, DataType definition) : base(backend.Log) { _backend = backend; _essentials = essentials; _linker = linker; Builder = builder; Definition = definition; }
public static bool IsPInvokable(this Backend backend, IEssentials essentials, DelegateType dt) { foreach (var attr in dt.Attributes) { if (attr.ReferencedType == essentials.ForeignAttribute && essentials.Language.Literals[(int)attr.Arguments[0].ConstantValue].Name == "CPlusPlus") { return(true); } } return(false); }
protected Pass( Disk disk, IBuildData data, IEnvironment environment, IILFactory ilf) : base(disk) { Disk = disk; Data = data; Environment = environment; Essentials = ilf.Essentials; ILFactory = ilf; }
// ------------------------------------------------------------------------------------------------------------- // CIL implementation public static MethodBuilder CreateCilPInvokeMethod( Universe universe, IEssentials essentials, TypeBuilder builder, Method m, MethodAttributes methodAttributes, Type resolvedReturnType, Type[] resolvedParameterTypes) { var mb = builder.DefinePInvokeMethod( m.Name, m.Source.Package.Name + "-PInvoke.dll", PInvokeBackend.CName(m), methodAttributes | MethodAttributes.PinvokeImpl, CallingConventions.Standard, resolvedReturnType, null, null, resolvedParameterTypes, GetRequiredModifiers(universe, m.Parameters), null, CallingConvention.Cdecl, CharSet.Unicode); mb.SetImplementationFlags(MethodImplAttributes.PreserveSig); var rb = mb.DefineParameter(0, ParameterAttributes.None, null); var customReturnAttribute = GetCustomAttribute(universe, essentials, m.ReturnType); if (customReturnAttribute != null) { rb.SetCustomAttribute(customReturnAttribute); } int i = 1; foreach (var param in m.Parameters) { var pb = mb.DefineParameter(i, GetParameterTypeAttributes(param.Type), param.Name); var customAttribute = GetCustomAttribute(universe, essentials, param.Type); if (customAttribute != null) { pb.SetCustomAttribute(customAttribute); } ++i; } return(mb); }
static CustomAttributeBuilder GetCustomAttribute(Universe universe, IEssentials essentials, DataType dt) { if (dt == essentials.Bool) { return(GetBoolCustomAttribute(universe)); } if (dt.IsDelegate) { var argTypes = new[] { universe.Import(typeof(UnmanagedType)) }; var ci = universe.Import(typeof(MarshalAsAttribute)).GetConstructor(argTypes); object[] args = { UnmanagedType.FunctionPtr }; return(new CustomAttributeBuilder(ci, args)); } return(null); }
public static ParameterBuilder DefineCilDelegateParameter( Universe universe, IEssentials essentials, MethodBuilder mb, Parameter p, int paramIndex) { var pb = mb.DefineParameter(paramIndex + 1, GetParameterTypeAttributes(p.Type), p.Name); var cab = GetDelegateParameterCustomAttribute(universe, essentials, p, paramIndex); if (cab != null) { pb.SetCustomAttribute(cab); } return(pb); }
public static bool IsPInvokable(this Backend backend, IEssentials essentials, Function f) { foreach (var attr in f.Attributes) { if (attr.ReferencedType == essentials.ForeignAttribute && essentials.Language.Literals[(int)attr.Arguments[0].ConstantValue].Name == "CPlusPlus") { if (!f.IsStatic) { backend.Log.Error(f.Source, ErrorCode.E0000, "Foreign CPlusPlus methods must be static."); } return(true); } } return(false); }
public static bool IsPInvokable(this Function f, IEssentials essentials, Log log) { foreach (var attr in f.Attributes) { if (attr.ReferencedType == essentials.ForeignAttribute && essentials.Language.Literals[(int)attr.Arguments[0].ConstantValue].Name == "CPlusPlus") { // FIXME: Move validation code to different module? if (!f.IsStatic) { log.Error(f.Source, ErrorCode.E0000, "Foreign CPlusPlus methods must be static."); } return(true); } } return(false); }
public ForeignMethod(Function f, IEssentials essentials, Converters.Converter convert, ForeignHelpers helpers, List <string> annotations) { _essentials = essentials; Convert = convert; Helpers = helpers; CppHeadersForDeclaringType = new List <string> { "jni.h", "Uno/JNIHelper.h", "@{global::Android.Base.Wrappers.JWrapper:Include}", "@{global::Android.Base.Wrappers.JavaObjectHelper:Include}", "@{" + ForeignJavaPass.UnoToJavaBoxingClass.FullName + ":Include}" }; Annotations = annotations; ValidateMethod(f, essentials); InitialUnoMethod = f; JavaName = convert.Name.JavaMethodName(f); }
public CilGenerator(Disk disk, IBuildData data, IEssentials essentials, CilBackend backend, CilLinker linker, SourcePackage package, string outputDir) : base(disk) { _data = data; _essentials = essentials; _backend = backend; _package = package; _linker = linker; _outputDir = outputDir; _assembly = _linker.Universe.DefineDynamicAssembly( new AssemblyName(package.Name) /*{Version = new Version(package.Version)}*/, AssemblyBuilderAccess.Save, outputDir); _module = _assembly.DefineDynamicModule( package.Name, package.Name + ".dll", true); }
public CilLinker(Log log, IEssentials essentials) : base(log) { _essentials = essentials; System_Object = Universe.Import(typeof(object)); System_String = Universe.Import(typeof(string)); System_ValueType = Universe.Import(typeof(ValueType)); System_MulticastDelegate = Universe.Import(typeof(MulticastDelegate)); System_Enum = Universe.Import(typeof(Enum)); System_IntPtr = Universe.Import(typeof(IntPtr)); System_Int32 = Universe.Import(typeof(int)); System_Void = Universe.Import(typeof(void)); System_ParamAttribute_ctor = Universe.Import(typeof(ParamArrayAttribute)).GetConstructor(Type.EmptyTypes); System_Diagnostics_DebuggableAttribute_ctor = Universe.Import(typeof(DebuggableAttribute)).GetConstructor(new[] { Universe.Import(typeof(DebuggableAttribute.DebuggingModes)) }); System_Runtime_CompilerServices_ExtensionAttribute_ctor = Universe.Import(typeof(ExtensionAttribute)).GetConstructor(Type.EmptyTypes); System_Runtime_CompilerServices_InternalsVisibleToAttribute_ctor = Universe.Import(typeof(InternalsVisibleToAttribute)).GetConstructor(new[] {System_String}); System_NotSupportedException_ctor = Universe.Import(typeof(NotSupportedException)).GetConstructor(new[] {System_String}); System_Activator_CreateInstance = Universe.Import(typeof(Activator)).GetMethod("CreateInstance", Type.EmptyTypes); System_Type_GetTypeFromHandle = Universe.Import(typeof(System.Type)).GetMethod("GetTypeFromHandle"); _types.Add(DataType.Void, System_Void); }
void ValidateMethod(ParametersMember f, IEssentials essentials) { if (f.Parameters.Any(x => x.Type.IsGenericType)) { throw new Exception("Foreign Code Limitation: The compiler cannot currently convert generics arguments to a Java types.\nFound in: " + f.FullName); } if (f.ReturnType.IsGenericType) { throw new Exception("Foreign Code Limitation: The compiler cannot currently handle generics return types.\nFound in: " + f.FullName); } foreach (var p in f.Parameters) { if ((p.Type.IsEnum ? p.Type.Base : p.Type) == _essentials.Byte) { throw new Exception("Foreign Code Limitation: Method '" + f.FullName + "' has an argument '" + p.UnoName + "' of type byte. Java does not support byte. It does however support sbyte."); } } if ((f.ReturnType.IsEnum ? f.ReturnType.Base : f.ReturnType) == _essentials.Byte) { throw new Exception("Foreign Code Limitation: Method '" + f.FullName + "' has a return type of byte. Java does not support byte. It does however support sbyte."); } }
public static Type TryGetDotNetType(this DataType unoType, IEssentials essentials) { var netName = unoType.TryGetAttributeString(essentials.DotNetTypeAttribute); return(netName != null?Type.GetType(netName) : null); }
public static InterfaceType TryFindDotNetInterface(this DataType unoType, Type netInterface, IEssentials essentials) { if (unoType != null) { foreach (var it in unoType.Interfaces) { if (TryGetDotNetType(it, essentials) == netInterface) { return(it); } } } return(null); }
static void FindInheritedDotNetInterfaceMembers(InterfaceType unoInterface, Type netInterface, IEssentials essentials, HashSet <object> visited, HashSet <MemberInfo> result) { if (unoInterface != null) { if (visited.Contains(unoInterface)) { return; } visited.Add(unoInterface); foreach (var it in unoInterface.Interfaces) { FindInheritedDotNetInterfaceMembers(it, TryGetDotNetType(it, essentials), essentials, visited, result); } } if (netInterface != null) { var key = netInterface.ToString(); if (visited.Contains(key)) { return; } visited.Add(key); foreach (var m in netInterface.GetInterfaces()) { FindInheritedDotNetInterfaceMembers(TryFindDotNetInterface(unoInterface, m, essentials), m, essentials, visited, result); } foreach (var m in netInterface.GetMethods()) { if (!m.Name.StartsWith("op_", StringComparison.InvariantCulture) && !m.Name.StartsWith("get_", StringComparison.InvariantCulture) && !m.Name.StartsWith("set_", StringComparison.InvariantCulture) && !m.Name.StartsWith("add_", StringComparison.InvariantCulture) && !m.Name.StartsWith("remove_", StringComparison.InvariantCulture) && !ContainsDotNetMethod(unoInterface, m)) { result.Add(m); } } foreach (var m in netInterface.GetProperties()) { if (!ContainsDotNetProperty(unoInterface, m)) { result.Add(m); } } foreach (var m in netInterface.GetEvents()) { if (!ContainsDotNetEvent(unoInterface, m)) { result.Add(m); } } } }
public static IEnumerable <MemberInfo> EnumerateInheritedDotNetInterfaceMembers(this DataType dt, IEssentials essentials) { var result = new HashSet <MemberInfo>(); var visited = new HashSet <object>(); if (!dt.IsInterface) { foreach (var it in dt.Interfaces) { FindInheritedDotNetInterfaceMembers(it, TryGetDotNetType(it, essentials), essentials, visited, result); } } return(result); }
public JniValueCast(DataType dt, JniFreeingTechnique free, string jniTmpVarName, string unoTmpVarName, Converter convert, IEssentials essentials, ForeignHelpers helpers) { JniVarName = jniTmpVarName; UnoTmpVarName = unoTmpVarName; UnoTmpVarLet = line => "@{" + dt.FullName + "} " + unoTmpVarName + "=" + line + ";"; var typeUsuallyFreed = true; string cast; if (helpers.IsPrimitive(dt) || dt.IsEnum) { cast = "(" + convert.Type.UnoToJniType(dt) + ")" + unoTmpVarName; typeUsuallyFreed = false; } else if (dt == essentials.String) { cast = "JniHelper::UnoToJavaString(" + unoTmpVarName + ")"; } else if (convert.Type.IsJavaObject(dt)) { cast = "(" + unoTmpVarName + "==NULL ? NULL : U_JNIVAR->NewLocalRef(@{global::Android.Base.Wrappers.IJWrapper:Of((@{global::Android.Base.Wrappers.IJWrapper})" + unoTmpVarName + ")._GetJavaObject():Call()}))"; } else if (dt.IsSubclassOfOrEqual(essentials.Delegate)) { var d = (DelegateType)dt; cast = "@{" + ForeignJavaPass.UnoToJavaBoxingClass.FullName + ".BoxDelegate(object,global::Android.Base.Primitives.ConstCharPtr):Call((@{object})" + unoTmpVarName + ", \"" + convert.Name.JavaDelegateName(d, true) + "\")}"; } else if (convert.Type.HasJavaEquivalent(dt)) { cast = "@{" + ForeignJavaPass.UnoToJavaBoxingClass.FullName + ".Box(" + dt.FullName + "):Call(" + unoTmpVarName + ")}"; } else if (dt.IsStruct) { cast = "@{" + ForeignJavaPass.UnoToJavaBoxingClass.FullName + ".Box(object):Call(" + helpers.BoxStruct(dt, unoTmpVarName) + ")}"; } else { cast = "@{" + ForeignJavaPass.UnoToJavaBoxingClass.FullName + ".Box(object):Call(" + unoTmpVarName + ")}"; } if (typeUsuallyFreed) { switch (free) { case JniFreeingTechnique.Default: Free = "if (" + JniVarName + "!=NULL) { U_JNIVAR->DeleteLocalRef(" + JniVarName + "); }"; break; case JniFreeingTechnique.WithScope: if (dt.IsStruct) // no null check needed if is uno struct { cast = "U_JNIVAR->NewLocalRef((" + cast + "))"; } else { cast = "(" + unoTmpVarName + "==NULL ? NULL : U_JNIVAR->NewLocalRef((" + cast + ")))"; } Free = ""; break; case JniFreeingTechnique.None: Free = ""; break; default: throw new ArgumentOutOfRangeException(nameof(free), free, null); } } CastSet = jniTmpVarName + " = " + cast + ";"; CastLet = convert.Type.UnoToJniType(dt, true) + " " + CastSet; }
public SignatureConverter(Converters.Converter convert, IEssentials essentials) { _convert = convert; _essentials = essentials; }