static ProxyGenerator() { ClassLoaderWrapper bootClassLoader = ClassLoaderWrapper.GetBootstrapClassLoader(); proxyClass = bootClassLoader.LoadClassByDottedNameFast("java.lang.reflect.Proxy"); errorClass = bootClassLoader.LoadClassByDottedNameFast("java.lang.Error"); runtimeExceptionClass = bootClassLoader.LoadClassByDottedNameFast("java.lang.RuntimeException"); undeclaredThrowableExceptionConstructor = bootClassLoader.LoadClassByDottedNameFast("java.lang.reflect.UndeclaredThrowableException").GetMethodWrapper("<init>", "(Ljava.lang.Throwable;)V", false); undeclaredThrowableExceptionConstructor.Link(); invocationHandlerField = proxyClass.GetFieldWrapper("h", "Ljava.lang.reflect.InvocationHandler;"); invocationHandlerField.Link(); javaLangReflectMethod = bootClassLoader.LoadClassByDottedNameFast("java.lang.reflect.Method"); javaLangNoSuchMethodException = bootClassLoader.LoadClassByDottedNameFast("java.lang.NoSuchMethodException"); javaLangNoClassDefFoundErrorConstructor = bootClassLoader.LoadClassByDottedNameFast("java.lang.NoClassDefFoundError").GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false); javaLangNoClassDefFoundErrorConstructor.Link(); javaLangThrowable_getMessage = bootClassLoader.LoadClassByDottedNameFast("java.lang.Throwable").GetMethodWrapper("getMessage", "()Ljava.lang.String;", false); javaLangThrowable_getMessage.Link(); javaLangClass_getMethod = CoreClasses.java.lang.Class.Wrapper.GetMethodWrapper("getMethod", "(Ljava.lang.String;[Ljava.lang.Class;)Ljava.lang.reflect.Method;", false); javaLangClass_getMethod.Link(); invocationHandlerClass = bootClassLoader.LoadClassByDottedNameFast("java.lang.reflect.InvocationHandler"); invokeMethod = invocationHandlerClass.GetMethodWrapper("invoke", "(Ljava.lang.Object;Ljava.lang.reflect.Method;[Ljava.lang.Object;)Ljava.lang.Object;", false); proxyConstructor = proxyClass.GetMethodWrapper("<init>", "(Ljava.lang.reflect.InvocationHandler;)V", false); proxyConstructor.Link(); hashCodeMethod = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper("hashCode", "()I", false); equalsMethod = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper("equals", "(Ljava.lang.Object;)Z", false); toStringMethod = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper("toString", "()Ljava.lang.String;", false); }
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); context.RegisterPostFinishProc(delegate { arfuTypeWrapper.Finish(); tb.CreateType(); }); } ilgen.LazyEmitPop(); ilgen.LazyEmitPop(); ilgen.LazyEmitPop(); ilgen.Emit(OpCodes.Newobj, cb); }
protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile classFile, FieldWrapper[] fields, MethodWrapper[] methods) { Dictionary<string, IKVM.Internal.MapXml.Class> mapxml = classLoader.GetMapXmlClasses(); if(mapxml != null) { IKVM.Internal.MapXml.Class clazz; if(mapxml.TryGetValue(classFile.Name, out clazz)) { if(clazz.Attributes != null) { PublishAttributes(typeBuilder, clazz); } if(clazz.Properties != null) { PublishProperties(typeBuilder, clazz); } if(clazz.Fields != null) { foreach(IKVM.Internal.MapXml.Field field in clazz.Fields) { if(field.Attributes != null) { foreach(FieldWrapper fw in fields) { if(fw.Name == field.Name && fw.Signature == field.Sig) { FieldBuilder fb = fw.GetField() as FieldBuilder; if(fb != null) { foreach(IKVM.Internal.MapXml.Attribute attr in field.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, fb, attr); } } } } } } } if(clazz.Constructors != null) { // HACK this isn't the right place to do this, but for now it suffices foreach(IKVM.Internal.MapXml.Constructor constructor in clazz.Constructors) { // are we adding a new constructor? if(GetMethodWrapper(StringConstants.INIT, constructor.Sig, false) == null) { if(constructor.body == null) { Console.Error.WriteLine("Error: Constructor {0}.<init>{1} in xml remap file doesn't have a body.", clazz.Name, constructor.Sig); continue; } bool setmodifiers = false; MethodAttributes attribs = 0; MapModifiers(constructor.Modifiers, true, out setmodifiers, ref attribs); Type returnType; Type[] parameterTypes; MapSignature(constructor.Sig, out returnType, out parameterTypes); MethodBuilder cb = ReflectUtil.DefineConstructor(typeBuilder, attribs, parameterTypes); if(setmodifiers) { AttributeHelper.SetModifiers(cb, (Modifiers)constructor.Modifiers, false); } CompilerClassLoader.AddDeclaredExceptions(cb, constructor.throws); CodeEmitter ilgen = CodeEmitter.Create(cb); constructor.Emit(classLoader, ilgen); ilgen.DoEmit(); if(constructor.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute attr in constructor.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, cb, attr); } } } } foreach(IKVM.Internal.MapXml.Constructor constructor in clazz.Constructors) { if(constructor.Attributes != null) { foreach(MethodWrapper mw in methods) { if(mw.Name == "<init>" && mw.Signature == constructor.Sig) { MethodBuilder mb = mw.GetMethod() as MethodBuilder; if(mb != null) { foreach(IKVM.Internal.MapXml.Attribute attr in constructor.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, mb, attr); } } } } } } } if(clazz.Methods != null) { // HACK this isn't the right place to do this, but for now it suffices foreach(IKVM.Internal.MapXml.Method method in clazz.Methods) { // are we adding a new method? if(GetMethodWrapper(method.Name, method.Sig, false) == null) { if(method.body == null) { Console.Error.WriteLine("Error: Method {0}.{1}{2} in xml remap file doesn't have a body.", clazz.Name, method.Name, method.Sig); continue; } bool setmodifiers = false; MethodAttributes attribs = method.MethodAttributes; MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs); Type returnType; Type[] parameterTypes; MapSignature(method.Sig, out returnType, out parameterTypes); MethodBuilder mb = typeBuilder.DefineMethod(method.Name, attribs, returnType, parameterTypes); if(setmodifiers) { AttributeHelper.SetModifiers(mb, (Modifiers)method.Modifiers, false); } if(method.@override != null) { MethodWrapper mw = GetClassLoader().LoadClassByDottedName([email protected]).GetMethodWrapper([email protected], method.Sig, true); mw.Link(); typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); } CompilerClassLoader.AddDeclaredExceptions(mb, method.throws); CodeEmitter ilgen = CodeEmitter.Create(mb); method.Emit(classLoader, ilgen); ilgen.DoEmit(); if(method.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, mb, attr); } } } } foreach(IKVM.Internal.MapXml.Method method in clazz.Methods) { if(method.Attributes != null) { foreach(MethodWrapper mw in methods) { if(mw.Name == method.Name && mw.Signature == method.Sig) { MethodBuilder mb = mw.GetMethod() as MethodBuilder; if(mb != null) { foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, mb, attr); } } } } } } } if(clazz.Interfaces != null) { foreach(IKVM.Internal.MapXml.Interface iface in clazz.Interfaces) { TypeWrapper tw = GetClassLoader().LoadClassByDottedName(iface.Name); // NOTE since this interface won't be part of the list in the ImplementAttribute, // it won't be visible from Java that the type implements this interface. typeBuilder.AddInterfaceImplementation(tw.TypeAsBaseType); if(iface.Methods != null) { foreach(IKVM.Internal.MapXml.Method m in iface.Methods) { MethodWrapper mw = tw.GetMethodWrapper(m.Name, m.Sig, false); if(mw == null) { throw new InvalidOperationException("Method " + m.Name + m.Sig + " not found in interface " + tw.Name); } mw.Link(); MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(this, typeBuilder, tw.Name + "/" + m.Name, MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.CheckAccessOnOverride); AttributeHelper.HideFromJava(mb); typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); CodeEmitter ilgen = CodeEmitter.Create(mb); m.Emit(classLoader, ilgen); ilgen.DoEmit(); } } } } } } }
protected override void AddMapXmlFields(ref FieldWrapper[] fields) { Dictionary<string, IKVM.Internal.MapXml.Class> mapxml = classLoader.GetMapXmlClasses(); if(mapxml != null) { IKVM.Internal.MapXml.Class clazz; if(mapxml.TryGetValue(this.Name, out clazz)) { if(clazz.Fields != null) { foreach(IKVM.Internal.MapXml.Field field in clazz.Fields) { // are we adding a new field? bool found = false; foreach(FieldWrapper fw in fields) { if(fw.Name == field.Name && fw.Signature == field.Sig) { found = true; break; } } if(!found) { FieldWrapper[] newFields = new FieldWrapper[fields.Length + 1]; Array.Copy(fields, newFields, fields.Length); fields = newFields; fields[fields.Length - 1] = FieldWrapper.Create(this, null, null, field.Name, field.Sig, new ExModifiers((Modifiers)field.Modifiers, false)); } } } } } }
internal override object[] GetFieldAnnotations(FieldWrapper fw) { FieldInfo fi = fw.GetField(); if (fi == null) { return null; } return fi.GetCustomAttributes(false); }
internal static bool TryGet(TypeWrapper wrapper, PropertyInfo property, out FieldWrapper accessStub) { NameSigAttribute nameSig = AttributeHelper.GetNameSig(property); bool hideFromReflection = AttributeHelper.IsHideFromReflection(property); if (nameSig != null || hideFromReflection) { TypeWrapper type; string name; string sig; if (nameSig == null) { type = ClassLoaderWrapper.GetWrapperFromType(property.PropertyType); name = property.Name; sig = type.SigName; } else { type = wrapper.GetClassLoader().FieldTypeWrapperFromSigNoThrow(nameSig.Sig); name = nameSig.Name; sig = nameSig.Sig; } Modifiers modifiers; MemberFlags flags = MemberFlags.AccessStub; if (hideFromReflection) { // it's a Type 1 access stub (to make inherited fields visible) flags |= MemberFlags.HideFromReflection; modifiers = GetModifiers(property); } else { // it's a Type 2 access stub (to make fields that have a non-public field type visible) ModifiersAttribute attr = AttributeHelper.GetModifiersAttribute(property); modifiers = attr.Modifiers; if (attr.IsInternal) { flags |= MemberFlags.InternalAccess; } } accessStub = new CompiledAccessStubFieldWrapper(wrapper, property, type, name, sig, modifiers, flags); return true; } else { accessStub = null; return false; } }
internal override void Link(TypeWrapper thisType) { base.Link(thisType); lock(this) { if(fieldTypeWrapper != null) { return; } } FieldWrapper fw = null; TypeWrapper wrapper = GetClassType(); if(!wrapper.IsUnloadable) { fw = wrapper.GetFieldWrapper(Name, Signature); if(fw != null) { fw.Link(); } } ClassLoaderWrapper classLoader = thisType.GetClassLoader(); TypeWrapper fld = classLoader.FieldTypeWrapperFromSigNoThrow(this.Signature); lock(this) { if(fieldTypeWrapper == null) { fieldTypeWrapper = fld; field = fw; } } }
private static bool IsStaticallyInvocable(FieldWrapper fw) { return fw != null && !fw.FieldTypeWrapper.IsUnloadable && !fw.FieldTypeWrapper.IsGhost && !fw.FieldTypeWrapper.IsNonPrimitiveValueType; }