/// <summary> /// Simply get all assembly manifest resources from an assembly given it's file name. /// </summary> public static IEnumerable <ManifestResource> GetAssemblyManifestResources(string fileName) { using (var universe = new IKVM.Reflection.Universe()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile(fileName); } catch { yield break; } foreach (var _r in assembly.GetManifestResourceNames()) { var r = _r; yield return(new ManifestResource(r, () => assembly.GetManifestResourceStream(r))); } } }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { Assert(context != null); var stack = context.Stack; Assert(stack != null); if (stack.Count < 3) { throw new StackTooSmallException(OpCode.Select, 3, stack.Count); } var type = stack.Pop(); if (type != ValueType.Int32) { throw new StackTypeInvalidException(OpCode.Select, ValueType.Int32, type); } var typeB = stack.Pop(); var typeA = stack.Peek(); //Assuming validation passes, the remaining type will be this. if (typeA != typeB) { throw new StackParameterMismatchException(OpCode.Select, typeA, typeB); } HelperMethod helper; switch (typeA) { default: //This shouldn't be possible due to previous validations. Fail("Unknown ValueType."); return; case ValueType.Int32: helper = HelperMethod.SelectInt32; break; case ValueType.Int64: helper = HelperMethod.SelectInt64; break; case ValueType.Float32: helper = HelperMethod.SelectFloat32; break; case ValueType.Float64: helper = HelperMethod.SelectFloat64; break; } context.Emit(IKVM.Reflection.Emit.OpCodes.Call, IKVMCreateSelectHelper(helper, context, universe)); }
private bool GenerateStubs() { // we start by creating the stubs for the boot classes string stubpath = GetStubPath(); Directory.CreateDirectory(stubpath); // note that File.GetLastWriteTime() returns Jan 1st, 1601 for non-existing files, so that works out nicely if (File.GetLastWriteTime(Path.Combine(stubpath, "rt.jar")) < File.GetLastWriteTime(Path.Combine(GetAssemblyPath(), "IKVM.OpenJDK.Core.dll"))) { if (!GenerateStub("IKVM.OpenJDK.Core", Path.Combine(stubpath, "rt.jar"))) { return(false); } } // now generate stubs for the referenced assemblies Dictionary <string, string> stubs = new Dictionary <string, string>(); using (IKVM.Reflection.Universe universe = new IKVM.Reflection.Universe(IKVM.Reflection.UniverseOptions.MetadataOnly)) { foreach (string reference in references) { using (IKVM.Reflection.RawModule module = universe.OpenRawModule(reference)) { string fileName = Path.Combine(stubpath, module.GetAssemblyName().Name + "__" + module.ModuleVersionId.ToString("N") + ".jar"); stubs.Add(fileName, null); if (!File.Exists(fileName)) { if (!GenerateStub(reference, fileName)) { return(false); } } } } } // clean up any left-over stubs foreach (string file in Directory.GetFiles(stubpath, "*.jar")) { if (!stubs.ContainsKey(file) && Path.GetFileName(file) != "rt.jar") { File.Delete(file); } } return(true); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count < 1) { throw new StackTooSmallException(OpCode.Int32CountOneBits, 1, stack.Count); } var type = stack.Peek(); //Assuming validation passes, the remaining type will be this. if (type != ValueType.Int32) { throw new StackTypeInvalidException(OpCode.Int32CountOneBits, ValueType.Int32, type); } context.Emit(IKVM.Reflection.Emit.OpCodes.Call, IKVMCreateHelper(HelperMethod.Int32CountOneBits, context, universe)); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count < 1) { throw new StackTooSmallException(this.OpCode, 1, stack.Count); } var type = stack.Peek(); //Assuming validation passes, the remaining type will be this. if (type != this.ValueType) { throw new StackTypeInvalidException(this.OpCode, this.ValueType, type); } context.Emit(this.IKVMEmittedOpCode); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var signature = context.Types[this.Type]; var paramTypes = signature.RawParameterTypes; var returnTypes = signature.RawReturnTypes; var stack = context.Stack; if (stack.Count < paramTypes.Length) { throw new StackTooSmallException(OpCode.CallIndirect, paramTypes.Length, stack.Count); } var type = stack.Pop(); if (type != ValueType.Int32) { throw new StackTypeInvalidException(OpCode.CallIndirect, ValueType.Int32, type); } for (var i = paramTypes.Length - 1; i >= 0; i--) { type = stack.Pop(); if (type != paramTypes[i]) { throw new StackTypeInvalidException(OpCode.CallIndirect, paramTypes[i], type); } } for (var i = 0; i < returnTypes.Length; i++) { stack.Push(returnTypes[i]); } Int32Constant.Emit(context, checked ((int)this.Type)); context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.GetFunctionPointer]); context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc, context.IndirectPointerLocal.LocalIndex); context.EmitLoadThis(); context.Emit(IKVM.Reflection.Emit.OpCodes.Ldloc, context.IndirectPointerLocal.LocalIndex); context.EmitCalli( signature.IKVMReturnTypes.Length == 0 ? universe.Import(typeof(void)) : signature.IKVMReturnTypes[0], signature.IKVMParameterTypes.Concat(new[] { context.ExportsBuilder.AsType() }).ToArray( )); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count < 1) { throw new StackTooSmallException(OpCode.Int64CountTrailingZeroes, 1, stack.Count); } var type = stack.Peek(); //Assuming validation passes, the remaining type will be this. if (type != ValueType.Int64) { throw new StackTypeInvalidException(OpCode.Int64CountTrailingZeroes, ValueType.Int64, type); } context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.Int64CountTrailingZeroes, (helper, c) => { Assert(c != null); var result = context.ExportsBuilder.DefineMethod( "☣ Int64CountTrailingZeroes", IKVMCompilationContext.HelperMethodAttributes, universe.Import(typeof(long)), new[] { universe.Import(typeof(ulong)) }); //All modern CPUs have a fast instruction specifically for this process, but there's no way to use it from .NET. //Based on the algorithm found here: http://aggregate.org/MAGIC/#Trailing%20Zero%20Count var il = result.GetILGenerator(); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Neg); il.Emit(IKVM.Reflection.Emit.OpCodes.And); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_1); il.Emit(IKVM.Reflection.Emit.OpCodes.Conv_I8); il.Emit(IKVM.Reflection.Emit.OpCodes.Sub); il.Emit(IKVM.Reflection.Emit.OpCodes.Call, Int64CountOneBits.IKVMCreateHelper(HelperMethod.Int64CountOneBits, context, universe)); il.Emit(IKVM.Reflection.Emit.OpCodes.Ret); return(result); } ]); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count == 0) { throw new StackTooSmallException(this.OpCode, 1, 0); } var type = stack.Peek(); //Assuming validation passes, the remaining type will be this. if (type != ValueType.Float32) { throw new StackTypeInvalidException(this.OpCode, ValueType.Float32, type); } context.Emit(IKVM.Reflection.Emit.OpCodes.Conv_R8); context.Emit(IKVM.Reflection.Emit.OpCodes.Call, this.IKVMMethodInfo); context.Emit(IKVM.Reflection.Emit.OpCodes.Conv_R4); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count < 1) { throw new StackTooSmallException(this.OpCode, 1, stack.Count); } var type = stack.Pop(); if (type != ValueType.Int32) { throw new StackTypeInvalidException(this.OpCode, ValueType.Int32, type); } context.Emit(IKVM.Reflection.Emit.OpCodes.Conv_U8); stack.Push(ValueType.Int64); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count == 0) { throw new StackTooSmallException(OpCode.Float32DemoteFloat64, 1, 0); } var type = stack.Pop(); if (type != ValueType.Float64) { throw new StackTypeInvalidException(OpCode.Float32DemoteFloat64, ValueType.Float64, type); } context.Emit(IKVM.Reflection.Emit.OpCodes.Conv_R4); stack.Push(ValueType.Float32); }
public static bool ContainsReferenceToSystemRuntime(string fileName) { using (var universe = new IKVM.Reflection.Universe()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile(fileName); } catch { return(false); } foreach (var r in assembly.GetReferencedAssemblies()) { if (r.FullName.Equals("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")) { return(true); } } } return(false); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { if (this.Index >= context.Methods.Length) { throw new CompilerException($"Function for index {this.Index} requseted, the assembly contains only {context.Methods.Length}."); } var signature = context.FunctionSignatures[this.Index]; var paramTypes = signature.RawParameterTypes; var returnTypes = signature.RawReturnTypes; var stack = context.Stack; if (stack.Count < paramTypes.Length) { throw new StackTooSmallException(this.OpCode, paramTypes.Length, stack.Count); } for (var i = paramTypes.Length - 1; i >= 0; i--) { var type = stack.Pop(); if (type != paramTypes[i]) { throw new StackTypeInvalidException(this.OpCode, paramTypes[i], type); } } for (var i = 0; i < returnTypes.Length; i++) { stack.Push(returnTypes[i]); } var target = context.Methods[this.Index]; if (target is IKVM.Reflection.Emit.MethodBuilder) //Indicates a dynamically generated method. { context.EmitLoadThis(); } context.Emit(IKVM.Reflection.Emit.OpCodes.Call, target); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count == 0) { throw new StackTooSmallException(OpCode.If, 1, 0); } var type = stack.Pop(); if (type != ValueType.Int32) { throw new StackTypeInvalidException(OpCode.If, ValueType.Int32, type); } var label = context.DefineLabel(); context.Labels.Add(checked ((uint)context.Depth.Count), label); context.Depth.Push(Type); context.Emit(IKVM.Reflection.Emit.OpCodes.Brfalse, label); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count < 1) { throw new StackTooSmallException(OpCode.Float32ReinterpretInt32, 1, stack.Count); } var type = stack.Pop(); if (type != ValueType.Int32) { throw new StackTypeInvalidException(OpCode.Float32ReinterpretInt32, ValueType.Int32, type); } stack.Push(ValueType.Float32); context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.Float32ReinterpretInt32, (helper, c) => { var builder = c.ExportsBuilder.DefineMethod( "☣ Float32ReinterpretInt32", IKVMCompilationContext.HelperMethodAttributes, universe.Import(typeof(float)), new[] { universe.Import(typeof(int)), } ); var il = builder.GetILGenerator(); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarga_S, 0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldind_R4); il.Emit(IKVM.Reflection.Emit.OpCodes.Ret); return(builder); } ]); }
/// <summary> /// Get the Mono executable best matching the assembly architecture flags. /// </summary> /// <remarks>Returns a fallback Mono executable, if a match cannot be found.</remarks> /// <returns>The Mono executable that should be used to execute the assembly.</returns> /// <param name="assemblyPath">Assembly path.</param> public string GetMonoExecutableForAssembly(string assemblyPath) { IKVM.Reflection.PortableExecutableKinds peKind; IKVM.Reflection.ImageFileMachine machine; using (var universe = new IKVM.Reflection.Universe()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile(assemblyPath); assembly.ManifestModule.GetPEKind(out peKind, out machine); } catch { peKind = IKVM.Reflection.PortableExecutableKinds.ILOnly; machine = IKVM.Reflection.ImageFileMachine.I386; } } string monoPath; if ((peKind & (IKVM.Reflection.PortableExecutableKinds.Required32Bit | IKVM.Reflection.PortableExecutableKinds.Preferred32Bit)) != 0) { monoPath = Path.Combine(MonoRuntimeInfo.Prefix, "bin", "mono32"); if (File.Exists(monoPath)) { return(monoPath); } } else if ((peKind & IKVM.Reflection.PortableExecutableKinds.PE32Plus) != 0) { monoPath = Path.Combine(MonoRuntimeInfo.Prefix, "bin", "mono64"); if (File.Exists(monoPath)) { return(monoPath); } } return(monoPath = Path.Combine(MonoRuntimeInfo.Prefix, "bin", "mono")); }
private static System.Reflection.Assembly LoadPlugin(IKVM.Reflection.Assembly asm) { foreach (var name in asm.GetManifestResourceNames()) { if (name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { using (var strm = asm.GetManifestResourceStream(name)) using (var ms = new MemoryStream()) using (var uni = new IKVM.Reflection.Universe()) { strm.CopyTo(ms); ms.Position = 0; string referenceName = uni.LoadAssembly(uni.OpenRawModule(ms, name)).GetName().Name; var result = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == referenceName); if (result == null) { result = System.Reflection.Assembly.Load(ms.ToArray()); } return(result); } } } return(null); }
private static IList <Tuple <IUnresolvedAssembly, IList <string>, System.Reflection.Assembly> > LoadReferences(IEnumerable <string> references, IErrorReporter er) { using (var universe = new IKVM.Reflection.Universe(IKVM.Reflection.UniverseOptions.DisablePseudoCustomAttributeRetrieval | IKVM.Reflection.UniverseOptions.SupressReferenceTypeIdentityConversion)) { var assemblies = references.Select(universe.LoadFile).ToList(); var indirectReferences = assemblies.SelectMany(GetReferencedAssemblyNames).Distinct(); var directReferences = from a in assemblies select a.GetName().Name; var missingReferences = indirectReferences.Except(directReferences).ToList(); if (missingReferences.Count > 0) { er.Region = DomRegion.Empty; foreach (var r in missingReferences) { er.Message(Messages._7996, r); } return(null); } return(assemblies.Select(asm => Tuple.Create(new IkvmLoader { IncludeInternalMembers = true }.LoadAssembly(asm), (IList <string>)GetReferencedAssemblyNames(asm).ToList(), LoadPlugin(asm))).ToList()); } }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count < 2) { throw new StackTooSmallException(this.OpCode, 2, stack.Count); } var typeB = stack.Pop(); var typeA = stack.Peek(); //Assuming validation passes, the remaining type will be this. if (typeA != this.ValueType) { throw new StackTypeInvalidException(this.OpCode, this.ValueType, typeA); } if (typeA != typeB) { throw new StackParameterMismatchException(this.OpCode, typeA, typeB); } context.Emit(IKVM.Reflection.Emit.OpCodes.Call, this.IKVMMethodInfo); }
public static IKVM.Reflection.Universe CreateClosedUniverse () { const IKVM.Reflection.UniverseOptions ikvmOptions = IKVM.Reflection.UniverseOptions.DisablePseudoCustomAttributeRetrieval | IKVM.Reflection.UniverseOptions.SupressReferenceTypeIdentityConversion | IKVM.Reflection.UniverseOptions.ResolveMissingMembers; var universe = new IKVM.Reflection.Universe (ikvmOptions); universe.AssemblyResolve += delegate (object sender, IKVM.Reflection.ResolveEventArgs args) { return ((IKVM.Reflection.Universe)sender).CreateMissingAssembly (args.Name); }; return universe; }
/// <summary> /// Simply get all assembly manifest resources from an assembly given it's file name. /// </summary> public static IEnumerable<ManifestResource> GetAssemblyManifestResources (string fileName) { using (var universe = new IKVM.Reflection.Universe ()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile (fileName); } catch { yield break; } foreach (var _r in assembly.GetManifestResourceNames ()) { var r = _r; yield return new ManifestResource (r, () => assembly.GetManifestResourceStream (r)); } } /* CECIL version: Mono.Cecil.AssemblyDefinition a = Mono.Cecil.AssemblyDefinition.ReadAssembly (asmInBundle); foreach (Mono.Cecil.ModuleDefinition m in a.Modules) { for (int i = 0; i < m.Resources.Count; i++) { var er = m.Resources[i] as Mono.Cecil.EmbeddedResource; yield return new ManifestResource (er.Name, () => er.GetResourceStream ().ReadToEnd ()); } }*/ }
static string TryInferFramework(string path) { string imageRuntimeVersion = null; try { using (var uni = new IKVM.Reflection.Universe()) { uni.AssemblyResolve += (s, a) => ((IKVM.Reflection.Universe)s).CreateMissingAssembly(a.Name); var asm = uni.LoadFile(path); imageRuntimeVersion = asm.ImageRuntimeVersion; var attr = uni.GetType("System.Attribute, mscorlib"); foreach (var attrib in asm.__GetCustomAttributes(attr, false)) { if (attrib.Constructor.DeclaringType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute" && attrib.ConstructorArguments.Count == 1) { var parts = ((string)attrib.ConstructorArguments[0].Value).Split(','); string runtime = null, version = null, profile = null; for (int i = 0; i < parts.Length; i++) { int idx = parts[i].IndexOf('='); if (idx < 0) { runtime = parts[i]; } else { switch (parts[i].Substring(0, idx)) { case "Version": version = parts[i].Substring(idx + 1); break; case "Profile": profile = parts[i].Substring(idx + 1); break; } } } if (runtime != null) { var sb = new StringBuilder(runtime); if (version != null) { sb.Append(Path.DirectorySeparatorChar).Append(version); } if (profile != null) { sb.Append(Path.DirectorySeparatorChar).Append("Profile").Append(Path.DirectorySeparatorChar).Append(profile); } string targetFramework = sb.ToString(); return(targetFramework); } } } } } catch (Exception ex) { // not really fussed; we could have multiple inputs to try, and the user // can always use -f:blah to specify it explicitly Debug.WriteLine(ex.Message); } if (!string.IsNullOrEmpty(imageRuntimeVersion)) { string frameworkPath = Path.Combine( Environment.ExpandEnvironmentVariables(@"%windir%\Microsoft.NET\Framework"), imageRuntimeVersion); if (Directory.Exists(frameworkPath)) { return(frameworkPath); } } return(null); }
//TODO: make this abstract instead of virtual and implement in every remaining instruction internal virtual void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { throw new Exception("CompileIKVM override function needs to be implemented for instruction"); }
/// <summary> /// Simply get all assembly manifest resources from an assembly given it's file name. /// </summary> public static IEnumerable<ManifestResource> GetAssemblyManifestResources (string fileName) { using (var universe = new IKVM.Reflection.Universe ()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile (fileName); } catch { yield break; } foreach (var _r in assembly.GetManifestResourceNames ()) { var r = _r; yield return new ManifestResource (r, () => assembly.GetManifestResourceStream (r)); } } }
/// <summary> /// Simply get all assembly reference names from an assembly given it's file name. /// </summary> public static IEnumerable<string> GetAssemblyReferences (string fileName) { using (var universe = new IKVM.Reflection.Universe ()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile (fileName); } catch { yield break; } foreach (var r in assembly.GetReferencedAssemblies ()) { yield return r.Name; } } /* CECIL version: Mono.Cecil.AssemblyDefinition adef; try { adef = Mono.Cecil.AssemblyDefinition.ReadAssembly (fileName); } catch { yield break; } foreach (Mono.Cecil.AssemblyNameReference aref in adef.MainModule.AssemblyReferences) { yield return aref.Name; }*/ }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { context.Labels.Add(checked ((uint)context.Depth.Count), context.DefineLabel()); context.Depth.Push(Type); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { context.Emit(IKVM.Reflection.Emit.OpCodes.Nop); }
internal static IKVM.Reflection.MethodInfo IKVMStartGetter(IKVM.Reflection.Universe universe) { IKVM.Reflection.MethodInfo info = new RegeneratingWeakReference <IKVM.Reflection.MethodInfo>(() => universe.Import(typeof(UnmanagedMemory)).GetTypeInfo().DeclaredProperties.Where(prop => prop.Name == nameof(Start)).First().GetMethod); return(info); }
public Parser() { AssemblyResolveDirs = new List <string>(); Universe = new IKVM.Reflection.Universe(IKVM.Reflection.UniverseOptions.MetadataOnly); Universe.AssemblyResolve += AssemblyResolve; }
/// <summary> /// Simply get all assembly reference names from an assembly given it's file name. /// </summary> public static IEnumerable<string> GetAssemblyReferences (string fileName) { using (var universe = new IKVM.Reflection.Universe ()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile (fileName); } catch { yield break; } foreach (var r in assembly.GetReferencedAssemblies ()) { yield return r.Name; } } }
public static bool ContainsReferenceToSystemRuntime (string fileName) { lock (referenceLock) { bool result; if (referenceDict.TryGetValue (fileName, out result)) return result; //const int cacheLimit = 4096; //if (referenceDict.Count > cacheLimit) // referenceDict = ImmutableDictionary<string, bool>.Empty using (var universe = new IKVM.Reflection.Universe ()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile (fileName); } catch { return false; } foreach (var r in assembly.GetReferencedAssemblies ()) { if (r.FullName.Equals ("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")) { referenceDict = referenceDict.SetItem (fileName, true); return true; } } } referenceDict = referenceDict.SetItem (fileName, false); return false; } }
private static System.Reflection.Assembly LoadPlugin(IKVM.Reflection.Assembly asm) { foreach (var name in asm.GetManifestResourceNames()) { if (name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { using (var strm = asm.GetManifestResourceStream(name)) using (var ms = new MemoryStream()) using (var uni = new IKVM.Reflection.Universe()) { strm.CopyTo(ms); ms.Position = 0; string referenceName = uni.LoadAssembly(uni.OpenRawModule(ms, name)).GetName().Name; var result = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == referenceName); if (result == null) result = System.Reflection.Assembly.Load(ms.ToArray()); return result; } } } return null; }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { Assert(context != null); Assert(context.Depth != null); var stack = context.Stack; Assert(stack != null); var blockType = context.Depth.Count == 0 ? BlockType.Empty : context.Depth.Pop(); if (context.Depth.Count == 0) { if (context.Previous == OpCode.Return) { return; //WebAssembly requires functions to end on "end", but an immediately previous return is allowed. } var returns = context.Signature.RawReturnTypes; var returnsLength = returns.Length; if (returnsLength != stack.Count) { throw new StackSizeIncorrectException(OpCode.End, returnsLength, stack.Count); } Assert(returnsLength == 0 || returnsLength == 1); //WebAssembly doesn't currently offer multiple returns, which should be blocked earlier. if (returnsLength == 1) { var type = stack.Pop(); if (type != returns[0]) { throw new StackTypeInvalidException(OpCode.End, returns[0], type); } } context.Emit(IKVM.Reflection.Emit.OpCodes.Ret); } else { if (blockType.TryToValueType(out var expectedType)) { var type = stack.Peek(); if (type != expectedType) { throw new StackTypeInvalidException(OpCode.End, expectedType, type); } } var depth = checked ((uint)context.Depth.Count); var label = context.Labels[depth]; if (!context.LoopLabels.Contains(label)) //Loop labels are marked where defined. { context.MarkLabel(label); } else { context.LoopLabels.Remove(label); } context.Labels.Remove(depth); } }
private static IList<Tuple<IUnresolvedAssembly, IList<string>, System.Reflection.Assembly>> LoadReferences(IEnumerable<string> references, IErrorReporter er) { using (var universe = new IKVM.Reflection.Universe(IKVM.Reflection.UniverseOptions.DisablePseudoCustomAttributeRetrieval | IKVM.Reflection.UniverseOptions.SupressReferenceTypeIdentityConversion)) { var assemblies = references.Select(universe.LoadFile).ToList(); var indirectReferences = assemblies.SelectMany(GetReferencedAssemblyNames).Distinct(); var directReferences = from a in assemblies select a.GetName().Name; var missingReferences = indirectReferences.Except(directReferences).ToList(); if (missingReferences.Count > 0) { er.Region = DomRegion.Empty; foreach (var r in missingReferences) er.Message(Messages._7996, r); return null; } return assemblies.Select(asm => Tuple.Create(new IkvmLoader { IncludeInternalMembers = true }.LoadAssembly(asm), (IList<string>)GetReferencedAssemblyNames(asm).ToList(), LoadPlugin(asm))).ToList(); } }
//FIXME: this is totally broken. assemblies can't just belong to one framework public TargetFrameworkMoniker GetTargetFrameworkForAssembly (TargetRuntime tr, string file) { var universe = new IKVM.Reflection.Universe (); universe.EnableMissingMemberResolution (); try { IKVM.Reflection.Assembly assembly = universe.LoadFile (file); var att = assembly.CustomAttributes.FirstOrDefault (a => a.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute" ); if (att != null) { if (att.ConstructorArguments.Count == 1) { var v = att.ConstructorArguments[0].Value as string; TargetFrameworkMoniker m; if (v != null && TargetFrameworkMoniker.TryParse (v, out m)) { return m; } } LoggingService.LogError ("Invalid TargetFrameworkAttribute in assembly {0}", file); } foreach (var r in assembly.GetReferencedAssemblies ()) { if (r.Name == "mscorlib") { TargetFramework compatibleFramework = null; // If there are several frameworks that can run the file, pick one that is installed foreach (TargetFramework tf in GetKnownFrameworks ()) { if (tf.GetCorlibVersion () == r.Version.ToString ()) { compatibleFramework = tf; if (tr.IsInstalled (tf)) return tf.Id; } } if (compatibleFramework != null) return compatibleFramework.Id; break; } } } catch (Exception ex) { LoggingService.LogError ("Error to determine target framework for assembly {0}: {1}", file, ex); return TargetFrameworkMoniker.UNKNOWN; } finally { universe.Dispose (); } LoggingService.LogError ("Failed to determine target framework for assembly {0}", file); return TargetFrameworkMoniker.UNKNOWN; }
internal static IKVM.Reflection.Emit.MethodBuilder IKVMCreateHelper(HelperMethod helper, IKVMCompilationContext context, IKVM.Reflection.Universe universe) { Assert(context != null); var result = context.ExportsBuilder.DefineMethod( "☣ Int32CountOneBits", IKVMCompilationContext.HelperMethodAttributes, universe.Import(typeof(uint)), new[] { universe.Import(typeof(uint)) }); //All modern CPUs have a fast instruction specifically for this process, but there's no way to use it from .NET. //This algorithm is from https://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer var il = result.GetILGenerator(); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_1); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x55555555); il.Emit(IKVM.Reflection.Emit.OpCodes.And); il.Emit(IKVM.Reflection.Emit.OpCodes.Sub); il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x33333333); il.Emit(IKVM.Reflection.Emit.OpCodes.And); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_2); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x33333333); il.Emit(IKVM.Reflection.Emit.OpCodes.And); il.Emit(IKVM.Reflection.Emit.OpCodes.Add); il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_4); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Add); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x0f0f0f0f); il.Emit(IKVM.Reflection.Emit.OpCodes.And); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x01010101); il.Emit(IKVM.Reflection.Emit.OpCodes.Mul); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 24); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Ret); return(result); }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count < 1) { throw new StackTooSmallException(OpCode.TeeLocal, 1, stack.Count); } var setType = stack.Peek(); //Assuming validation passes, the remaining type will be this. if (setType != context.Locals[this.Index]) { throw new StackTypeInvalidException(OpCode.TeeLocal, context.Locals[this.Index], setType); } context.Emit(IKVM.Reflection.Emit.OpCodes.Dup); var localIndex = this.Index - context.Signature.ParameterTypes.Length; if (localIndex < 0) { //Referring to a parameter. if (this.Index <= byte.MaxValue) { context.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, checked ((byte)this.Index)); } else { context.Emit(IKVM.Reflection.Emit.OpCodes.Starg, checked ((ushort)this.Index)); } } else { //Referring to a local. switch (localIndex) { default: if (localIndex > 65534) // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stloc { throw new CompilerException($"Implementation limit exceeded: maximum accessible local index is 65534, tried to access {localIndex}."); } if (localIndex <= byte.MaxValue) { context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc_S, (byte)localIndex); } else { context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc, checked ((ushort)localIndex)); } break; case 0: context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc_0); break; case 1: context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc_1); break; case 2: context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc_2); break; case 3: context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc_3); break; } } }
private bool GenerateStubs() { // we start by creating the stubs for the boot classes string stubpath = GetStubPath(); Directory.CreateDirectory(stubpath); // note that File.GetLastWriteTime() returns Jan 1st, 1601 for non-existing files, so that works out nicely if (File.GetLastWriteTime(Path.Combine(stubpath, "rt.jar")) < File.GetLastWriteTime(Path.Combine(GetAssemblyPath(), "IKVM.OpenJDK.Core.dll"))) { if (!GenerateStub("IKVM.OpenJDK.Core", Path.Combine(stubpath, "rt.jar"))) { return false; } } // now generate stubs for the referenced assemblies Dictionary<string, string> stubs = new Dictionary<string, string>(); using (IKVM.Reflection.Universe universe = new IKVM.Reflection.Universe(IKVM.Reflection.UniverseOptions.MetadataOnly)) { foreach (string reference in references) { using (IKVM.Reflection.RawModule module = universe.OpenRawModule(reference)) { string fileName = Path.Combine(stubpath, module.GetAssemblyName().Name + "__" + module.ModuleVersionId.ToString("N") + ".jar"); stubs.Add(fileName, null); if (!File.Exists(fileName)) { if (!GenerateStub(reference, fileName)) { return false; } } } } } // clean up any left-over stubs foreach (string file in Directory.GetFiles(stubpath, "*.jar")) { if (!stubs.ContainsKey(file) && Path.GetFileName(file) != "rt.jar") { File.Delete(file); } } return true; }
private IKVM.Reflection.Type FindSurrogateSourceType(IKVM.Reflection.Type type, IKVM.Reflection.Universe universe) { var attributeType = universe.GetType("System.Attribute, mscorlib"); const IKVM.Reflection.BindingFlags flags = IKVM.Reflection.BindingFlags.Static | IKVM.Reflection.BindingFlags.Public | IKVM.Reflection.BindingFlags.NonPublic; foreach (var m in type.GetMethods(flags)) { var parameters = m.GetParameters(); if (parameters.Length == 1 && m.ReturnType.Name != "Void" && m.ReturnType != type) { foreach (var attrib in m.__GetCustomAttributes(attributeType, true)) { if (attrib.Constructor.DeclaringType.FullName == "ProtoBuf.ProtoConverterAttribute") { return(m.ReturnType); } } if (m.Name == "op_Implicit" || m.Name == "op_Explicit") { return(m.ReturnType); } } } return(null); }
public static bool ContainsReferenceToSystemRuntime (string fileName) { using (var universe = new IKVM.Reflection.Universe ()) { IKVM.Reflection.Assembly assembly; try { assembly = universe.LoadFile (fileName); } catch { return false; } foreach (var r in assembly.GetReferencedAssemblies ()) { if (r.FullName.Equals ("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")) return true; } } return false; }
internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe) { var stack = context.Stack; if (stack.Count < 1) { throw new StackTooSmallException(OpCode.Int32CountLeadingZeroes, 1, stack.Count); } var type = stack.Peek(); //Assuming validation passes, the remaining type will be this. if (type != ValueType.Int32) { throw new StackTypeInvalidException(OpCode.Int32CountLeadingZeroes, ValueType.Int32, type); } context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.Int32CountLeadingZeroes, (helper, c) => { Assert(c != null); var result = context.ExportsBuilder.DefineMethod( "☣ Int32CountLeadingZeroes", IKVMCompilationContext.HelperMethodAttributes, universe.Import(typeof(uint)), new[] { universe.Import(typeof(uint)) }); //All modern CPUs have a fast instruction specifically for this process, but there's no way to use it from .NET. //This algorithm is from https://stackoverflow.com/questions/10439242/count-leading-zeroes-in-an-int32 var il = result.GetILGenerator(); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_1); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Or); il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_2); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Or); il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_4); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Or); il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_8); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Or); il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 16); il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un); il.Emit(IKVM.Reflection.Emit.OpCodes.Or); il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 32); il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(IKVM.Reflection.Emit.OpCodes.Call, Int32CountOneBits.IKVMCreateHelper(HelperMethod.Int32CountOneBits, context, universe)); il.Emit(IKVM.Reflection.Emit.OpCodes.Sub); il.Emit(IKVM.Reflection.Emit.OpCodes.Ret); return(result); } ]); }
public Parser() { Universe = new IKVM.Reflection.Universe(IKVM.Reflection.UniverseOptions.MetadataOnly); }