public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig) { TypeWrapper tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj)); MethodWrapper mw = tw.GetMethodWrapper(name, sig, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { MethodInfo invoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); Type[] parameterTypes = new Type[parameters.Length + 1]; parameterTypes[0] = typeof(object); for (int i = 0; i < parameters.Length; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes); CodeEmitter ilgen = CodeEmitter.Create(dm); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig); ClassLoaderWrapper.GetBootstrapClassLoader() .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError") .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false) .EmitNewobj(ilgen); ilgen.Emit(System.Reflection.Emit.OpCodes.Throw); ilgen.DoEmit(); return(dm.CreateDelegate(delegateType, obj)); } else { mw.ResolveMethod(); return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod())); } }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { if (!Validate()) { return; } MemberInfo member = Resolve(context); Type type = member as Type; MethodInfo method = member as MethodInfo; ConstructorInfo constructor = member as ConstructorInfo; FieldInfo field = member as FieldInfo; if (type != null) { ilgen.Emit(OpCodes.Ldtoken, type); } else if (method != null) { ilgen.Emit(OpCodes.Ldtoken, method); } else if (constructor != null) { ilgen.Emit(OpCodes.Ldtoken, constructor); } else if (field != null) { ilgen.Emit(OpCodes.Ldtoken, field); } else { StaticCompiler.IssueMessage(Message.MapXmlUnableToResolveOpCode, ToString()); } }
internal static bool Emit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, ClassFile classFile, int i, ClassFile.Method.Instruction[] code, InstructionFlags[] flags) { if (i >= 3 && (flags[i - 0] & InstructionFlags.BranchTarget) == 0 && (flags[i - 1] & InstructionFlags.BranchTarget) == 0 && (flags[i - 2] & InstructionFlags.BranchTarget) == 0 && (flags[i - 3] & InstructionFlags.BranchTarget) == 0 && code[i - 1].NormalizedOpCode == NormalizedByteCode.__ldc_nothrow && code[i - 2].NormalizedOpCode == NormalizedByteCode.__ldc && code[i - 3].NormalizedOpCode == NormalizedByteCode.__ldc) { // we now have a structural match, now we need to make sure that the argument values are what we expect TypeWrapper tclass = classFile.GetConstantPoolClassType(code[i - 3].Arg1); TypeWrapper vclass = classFile.GetConstantPoolClassType(code[i - 2].Arg1); string fieldName = classFile.GetConstantPoolConstantString(code[i - 1].Arg1); if (tclass == wrapper && !vclass.IsUnloadable && !vclass.IsPrimitive && !vclass.IsNonPrimitiveValueType) { FieldWrapper field = wrapper.GetFieldWrapper(fieldName, vclass.SigName); if (field != null && !field.IsStatic && field.IsVolatile && field.DeclaringType == wrapper && field.FieldTypeWrapper == vclass) { // everything matches up, now call the actual emitter ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Newobj, context.GetAtomicReferenceFieldUpdater(field)); return(true); } } } return(false); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { base.Generate(context, ilgen); if (typeType != null) { ilgen.Emit(OpCodes.Isinst, typeType); } else { if (typeWrapper.IsGhost || typeWrapper.IsGhostArray) { ilgen.Emit(OpCodes.Dup); typeWrapper.EmitInstanceOf(ilgen); CodeEmitterLabel endLabel = ilgen.DefineLabel(); ilgen.EmitBrtrue(endLabel); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Ldnull); ilgen.MarkLabel(endLabel); } else { ilgen.Emit(OpCodes.Isinst, typeWrapper.TypeAsTBD); } } }
/// <summary> /// Creates and populates any additional contract requirements of the attribute. /// </summary> /// <param name="il">The code emitter.</param> /// <param name="attribute">The attribute.</param> /// <param name="member">The member the attribute is associated with.</param> /// <param name="variable">The variable containing the attribute.</param> /// <param name="isStatic">Whether the attribute container is static.</param> public void CreateAttributeRequirements(CodeEmitter il, CustomAttribute attribute, MemberReference member, Variable variable, bool isStatic) { if (attribute.HasInterface(Context.Finder.IMemberAware) && member != null) { il.Emit(Codes.ThisIf(variable)); il.Emit(Codes.Load(variable)); if (member is MethodReference method) { var minfo = CreateMethodInfo(new MethodEmitter(il.Parent.Parent, method)); il.Emit(Codes.ThisIf(minfo)); il.Emit(Codes.Load(minfo)); } else if (member is PropertyReference property) { var pinfo = CreatePropertyInfo(new PropertyEmitter(il.Parent.Parent, property, isStatic)); il.Emit(Codes.ThisIf(pinfo)); il.Emit(Codes.Load(pinfo)); } il.Emit(Codes.Invoke(Context.Finder.MemberAwareMemberSet)); } if (attribute.HasInterface(Context.Finder.IRequireInitialization)) { il.Emit(Codes.ThisIf(variable)); il.Emit(Codes.Load(variable)); il.Emit(Codes.Invoke(Context.Finder.RequireInitializationInitialize)); } }
private static void EmitCode(Package package, Package stdLibPackage, string path) { var codeEmitter = new CodeEmitter(); codeEmitter.Emit(package); codeEmitter.Emit(stdLibPackage); File.WriteAllText(path, codeEmitter.GetEmittedCode(), Encoding.UTF8); }
public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig) { #if !WINRT #if FIRST_PASS return(null); #else TypeWrapper tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj)); MethodWrapper mw = tw.GetMethodWrapper(name, sig, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { #if NO_REF_EMIT java.lang.invoke.MethodType methodType = MethodHandleUtil.GetDelegateMethodType(delegateType); if (methodType.parameterCount() > MethodHandleUtil.MaxArity) { throw new NotImplementedException(); } java.lang.invoke.MethodHandle exception = java.lang.invoke.MethodHandles.publicLookup() .findConstructor(mw == null || mw.IsStatic ? typeof(java.lang.AbstractMethodError) : typeof(java.lang.IllegalAccessError), java.lang.invoke.MethodType.methodType(typeof(void), typeof(string))) .bindTo(tw.Name + ".Invoke" + sig); return(Delegate.CreateDelegate(delegateType, java.lang.invoke.MethodHandles.dropArguments( java.lang.invoke.MethodHandles.foldArguments(java.lang.invoke.MethodHandles.throwException(methodType.returnType(), exception.type().returnType()), exception), 0, methodType.parameterArray()).vmtarget, "Invoke")); #else MethodInfo invoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); Type[] parameterTypes = new Type[parameters.Length + 1]; parameterTypes[0] = typeof(object); for (int i = 0; i < parameters.Length; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes); CodeEmitter ilgen = CodeEmitter.Create(dm); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig); ClassLoaderWrapper.GetBootstrapClassLoader() .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError") .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false) .EmitNewobj(ilgen); ilgen.Emit(System.Reflection.Emit.OpCodes.Throw); ilgen.DoEmit(); return(dm.CreateDelegate(delegateType, obj)); #endif } else { mw.ResolveMethod(); return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod())); } #endif #else throw new NotImplementedException(); #endif }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { if (Type != null) { ilgen.Emit(OpCodes.Ldsfld, StaticCompiler.GetTypeForMapXml(context.ClassLoader, Type).GetField(Name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); } else { // we don't use fw.EmitGet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Ldsfld, StaticCompiler.GetFieldForMapXml(context.ClassLoader, Class, Name, Sig).GetField()); } }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { if (Type != null) { ilgen.Emit(OpCodes.Ldsfld, StaticCompiler.GetType(context.ClassLoader, Type).GetField(Name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); } else { FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig); fw.Link(); // we don't use fw.EmitGet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Ldsfld, fw.GetField()); } }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig); fw.Link(); ilgen.Emit(OpCodes.Ldflda, fw.GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { FieldWrapper fw = StaticCompiler.GetClassForMapXml(context.ClassLoader, Class).GetFieldWrapper(Name, Sig); fw.Link(); ilgen.Emit(OpCodes.Ldflda, fw.GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { FieldWrapper fw = StaticCompiler.GetClassForMapXml(context.ClassLoader, Class).GetFieldWrapper(Name, Sig); fw.Link(); // we don't use fw.EmitSet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Stsfld, fw.GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig); fw.Link(); // we don't use fw.EmitSet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Stsfld, fw.GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { if (typeType == null) { Debug.Assert(type != null); typeType = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type); } ilgen.Emit(opcode, typeType); }
public void Rewrite(CodeEmitter emitter) { foreach (var de in this.zappedInstructions) { instrs[de.Key].code = de.Value; } foreach (Instruction instr in rewritten) { emitter.Emit(instr); } }
private static void DoEmit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, FieldWrapper field) { ConstructorBuilder cb; bool exists; lock (map) { exists = map.TryGetValue(field, out cb); } if (!exists) { // note that we don't need to lock here, because we're running as part of FinishCore, which is already protected by a lock TypeWrapper arfuTypeWrapper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater"); TypeBuilder tb = wrapper.TypeAsBuilder.DefineNestedType("__<ARFU>_" + field.Name + field.Signature.Replace('.', '/'), TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType); EmitCompareAndSet("compareAndSet", tb, field.GetField()); EmitGet(tb, field.GetField()); EmitSet("set", tb, field.GetField()); cb = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes); lock (map) { map.Add(field, cb); } CodeEmitter ctorilgen = CodeEmitter.Create(cb); ctorilgen.Emit(OpCodes.Ldarg_0); MethodWrapper basector = arfuTypeWrapper.GetMethodWrapper("<init>", "()V", false); basector.Link(); basector.EmitCall(ctorilgen); ctorilgen.Emit(OpCodes.Ret); ctorilgen.DoEmit(); context.RegisterPostFinishProc(delegate { arfuTypeWrapper.Finish(); tb.CreateType(); }); } ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Newobj, cb); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { base.Generate(context, ilgen); if (typeType != null) { ilgen.Emit(OpCodes.Castclass, typeType); } else { typeWrapper.EmitCheckcast(ilgen); } }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { base.Generate(context, ilgen); if (typeType != null) { ilgen.Emit(OpCodes.Isinst, typeType); } else { if (typeWrapper.IsGhost || typeWrapper.IsGhostArray) { ilgen.Emit(OpCodes.Dup); // NOTE we pass a null context, but that shouldn't be a problem, because // typeWrapper should never be an UnloadableTypeWrapper typeWrapper.EmitInstanceOf(null, ilgen); CodeEmitterLabel endLabel = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Brtrue_S, endLabel); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Ldnull); ilgen.MarkLabel(endLabel); } else { ilgen.Emit(OpCodes.Isinst, typeWrapper.TypeAsTBD); } } }
internal static void LoadPackedArg(CodeEmitter ilgen, int index, int firstArg, int packedArgPos, Type packedArgType) { index += firstArg; if (index >= packedArgPos) { ilgen.EmitLdarga(packedArgPos); int fieldPos = index - packedArgPos; Type type = packedArgType; while (fieldPos >= MaxArity || (fieldPos == MaxArity - 1 && IsPackedArgsContainer(type.GetField("t8").FieldType))) { FieldInfo field = type.GetField("t8"); type = field.FieldType; ilgen.Emit(OpCodes.Ldflda, field); fieldPos -= MaxArity - 1; } ilgen.Emit(OpCodes.Ldfld, type.GetField("t" + (1 + fieldPos))); } else { ilgen.EmitLdarg(index); } }
internal void Emit(ClassLoaderWrapper loader, CodeEmitter ilgen) { if (Type != "static" || Class == null || Name == null || Sig == null) { throw new NotImplementedException(); } Type[] redirParamTypes = loader.ArgTypeListFromSig(Sig); for (int i = 0; i < redirParamTypes.Length; i++) { ilgen.EmitLdarg(i); } // HACK if the class name contains a comma, we assume it is a .NET type if (Class.IndexOf(',') >= 0) { #if NETSTANDARD Class = Class.Replace("mscorlib", Universe.CoreLibName); #endif Type type = StaticCompiler.Universe.GetType(Class, true); MethodInfo mi = type.GetMethod(Name, redirParamTypes); if (mi == null) { throw new InvalidOperationException(); } ilgen.Emit(OpCodes.Call, mi); } else { TypeWrapper tw = loader.LoadClassByDottedName(Class); MethodWrapper mw = tw.GetMethodWrapper(Name, Sig, false); if (mw == null) { throw new InvalidOperationException(); } mw.Link(); mw.EmitCall(ilgen); } // TODO we may need a cast here (or a stack to return type conversion) ilgen.Emit(OpCodes.Ret); }
internal static void Box(CodeEmitter ilgen, jlClass srcClass, jlClass dstClass, int level) { for (int i = 0; i < boxers.Length; i++) { if (boxers[i].type == srcClass) { ilgen.Emit(OpCodes.Call, boxers[i].box); EmitConvert(ilgen, boxers[i].clazz, dstClass, level); return; } } throw new InvalidOperationException(); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { base.Generate(context, ilgen); if (typeType != null) { ilgen.Emit(OpCodes.Castclass, typeType); } else { // NOTE we pass a null context, but that shouldn't be a problem, because // typeWrapper should never be an UnloadableTypeWrapper typeWrapper.EmitCheckcast(null, ilgen); } }
internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen) { CodeEmitterLabel l; if (context[Name] == null) { l = ilgen.DefineLabel(); context[Name] = l; } else { l = (CodeEmitterLabel)context[Name]; } ilgen.Emit(opcode, l); }
internal static void Unbox(CodeEmitter ilgen, jlClass srcClass, jlClass dstClass, int level) { for (int i = 0; i < boxers.Length; i++) { if (boxers[i].clazz == srcClass) { // typed unboxing ilgen.Emit(OpCodes.Call, boxers[i].unbox); EmitConvert(ilgen, boxers[i].type, dstClass, level); return; } } for (int i = 0; i < boxers.Length; i++) { if (boxers[i].type == dstClass) { // untyped unboxing ilgen.EmitLdc_I4(level > 1 ? 1 : 0); ilgen.Emit(OpCodes.Call, boxers[i].unboxObject); return; } } throw new InvalidOperationException(); }
private static void EmitSet(string name, TypeBuilder tb, FieldInfo field) { MethodBuilder set = tb.DefineMethod(name, MethodAttributes.Public | MethodAttributes.Virtual, Types.Void, new Type[] { Types.Object, Types.Object }); CodeEmitter ilgen = CodeEmitter.Create(set); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Castclass, field.DeclaringType); ilgen.Emit(OpCodes.Ldarg_2); ilgen.Emit(OpCodes.Castclass, field.FieldType); ilgen.Emit(OpCodes.Volatile); ilgen.Emit(OpCodes.Stfld, field); ilgen.EmitMemoryBarrier(); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); }
private static string EmitCode(Project project, PackageIL package, string cacheDir) { var emittedPackages = new HashSet <PackageIL>(); var packagesToEmit = new Queue <PackageIL>(); packagesToEmit.Enqueue(package); var codeEmitter = new CodeEmitter(); while (packagesToEmit.TryDequeue(out var currentPackage)) { if (!emittedPackages.Contains(currentPackage)) { codeEmitter.Emit(currentPackage); emittedPackages.Add(currentPackage); packagesToEmit.EnqueueRange(currentPackage.References); } } string outputPath; switch (project.Template) { case ProjectTemplate.App: { outputPath = Path.Combine(cacheDir, "program.c"); } break; case ProjectTemplate.Lib: { outputPath = Path.Combine(cacheDir, "lib.c"); } break; default: throw ExhaustiveMatch.Failed(project.Template); } File.WriteAllText(outputPath, codeEmitter.GetEmittedCode(), Encoding.UTF8); return(outputPath); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { CodeEmitterLocal lb = (CodeEmitterLocal)context[Name]; if (lb == null) { if (typeWrapper == null && typeType == null) { Debug.Assert(Class == null ^ type == null); if (type != null) { typeType = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type); } else { typeWrapper = context.ClassLoader.LoadClassByDottedName(Class); } } lb = ilgen.DeclareLocal(typeType != null ? typeType : typeWrapper.TypeAsTBD); context[Name] = lb; } ilgen.Emit(OpCodes.Stloc, lb); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { // we don't use fw.EmitSet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Stsfld, StaticCompiler.GetFieldForMapXml(context.ClassLoader, Class, Name, Sig).GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(OpCodes.Ldflda, StaticCompiler.GetFieldForMapXml(context.ClassLoader, Class, Name, Sig).GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(OpCodes.Ldloc, (CodeEmitterLocal)context[Name]); }