зеркало из https://github.com/mono/ikvm-fork.git
Implemented type 2 access stubs for methods (not constructors) and rewrote how type 1 access stubs are handled.
This commit is contained in:
Родитель
46828f2616
Коммит
44c6177691
|
@ -404,7 +404,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.XML.Transform.dll
|
||||
-baseaddress:0x57EC0000
|
||||
-baseaddress:0x57EF0000
|
||||
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/java_cup/internal/runtime/*.class
|
||||
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/*.class
|
||||
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/classfile/*.class
|
||||
|
@ -428,7 +428,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.XML.Bind.dll
|
||||
-baseaddress:0x58310000
|
||||
-baseaddress:0x58340000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/xml/bind/*
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/bind/*
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/fastinfoset/*
|
||||
|
@ -487,7 +487,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.XML.WebServices.dll
|
||||
-baseaddress:0x586A0000
|
||||
-baseaddress:0x586D0000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/messaging/*
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/ws/*
|
||||
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/amx/*.class
|
||||
|
@ -607,7 +607,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.XML.Crypto.dll
|
||||
-baseaddress:0x58C10000
|
||||
-baseaddress:0x58C40000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/security/*
|
||||
@OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/*.class
|
||||
@OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/*.class
|
||||
|
@ -643,7 +643,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.SwingAWT.dll
|
||||
-baseaddress:0x58D60000
|
||||
-baseaddress:0x58D90000
|
||||
-remap:swingawt.xml
|
||||
-resource:META-INF/services/sun.java2d.pipe.RenderingEngine=resources/META-INF/services/sun.java2d.pipe.RenderingEngine
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/sun.java2d.cmm.PCMM
|
||||
|
@ -743,7 +743,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Charsets.dll
|
||||
-baseaddress:0x59F60000
|
||||
-baseaddress:0x59F90000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/sun/nio/cs/ext/sjis0213.dat
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/META-INF/services/java.nio.charset.spi.CharsetProvider
|
||||
@OPENJDK7@/build/linux-amd64/gensrc/sun/nio/cs/ext/*.class
|
||||
|
@ -752,7 +752,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Util.dll
|
||||
-baseaddress:0x5A5F0000
|
||||
-baseaddress:0x5A620000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/java/util/jar/pack/intrinsic.properties
|
||||
-resource:META-INF/services/java.nio.file.spi.FileSystemProvider=@OPENJDK7@/jdk/src/share/demo/nio/zipfs/src/META-INF/services/java.nio.file.spi.FileSystemProvider
|
||||
java/util/zip/*.class
|
||||
|
@ -773,7 +773,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Text.dll
|
||||
-baseaddress:0x5AB90000
|
||||
-baseaddress:0x5ABC0000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/text/*
|
||||
@OPENJDK7@/build/linux-amd64/j2re-image/lib/ext/localedata.jar
|
||||
@OPENJDK7@/jdk/src/share/classes/java/text/*.class
|
||||
|
@ -785,7 +785,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Security.dll
|
||||
-baseaddress:0x5AE00000
|
||||
-baseaddress:0x5AE30000
|
||||
-remap:security.xml
|
||||
sun/security/jgss/wrapper/*.class
|
||||
@OPENJDK7@/jdk/src/share/classes/com/sun/crypto/provider/*.class
|
||||
|
@ -856,7 +856,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Management.dll
|
||||
-baseaddress:0x5B5E0000
|
||||
-baseaddress:0x5B610000
|
||||
com/sun/management/*.class
|
||||
java/lang/management/*.class
|
||||
sun/management/*.class
|
||||
|
@ -890,7 +890,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Misc.dll
|
||||
-baseaddress:0x5B940000
|
||||
-baseaddress:0x5B970000
|
||||
-resource:com/sun/servicetag/resources/javase_5_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties
|
||||
-resource:com/sun/servicetag/resources/javase_6_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties
|
||||
-resource:com/sun/servicetag/resources/javase_7_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties
|
||||
|
@ -991,7 +991,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Naming.dll
|
||||
-baseaddress:0x5BA30000
|
||||
-baseaddress:0x5BA60000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/ldap/jndiprovider.properties
|
||||
-resource:META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor=@OPENJDK7@/jdk/src/share/classes/sun/net/spi/nameservice/dns/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
|
||||
sun/net/dns/*.class
|
||||
|
@ -1017,7 +1017,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Jdbc.dll
|
||||
-baseaddress:0x5BB80000
|
||||
-baseaddress:0x5BBB0000
|
||||
-resource:META-INF/services/java.sql.Driver=resources/META-INF/services/java.sql.Driver
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/rowset/*
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/sql/*
|
||||
|
@ -1035,7 +1035,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Remoting.dll
|
||||
-baseaddress:0x5BCD0000
|
||||
-baseaddress:0x5BD00000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/rmi/*
|
||||
@OPENJDK7@/build/linux-amd64/classes/sun/rmi/registry/*.class
|
||||
@OPENJDK7@/build/linux-amd64/classes/sun/rmi/server/*.class
|
||||
|
@ -1061,7 +1061,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Beans.dll
|
||||
-baseaddress:0x5BDF0000
|
||||
-baseaddress:0x5BE20000
|
||||
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/activation/registries/*.class
|
||||
@OPENJDK7@/build/linux-amd64/impsrc/javax/activation/*.class
|
||||
@OPENJDK7@/jdk/src/share/classes/com/sun/beans/*.class
|
||||
|
@ -1074,7 +1074,7 @@ assembly.class
|
|||
}
|
||||
{
|
||||
-out:IKVM.OpenJDK.Media.dll
|
||||
-baseaddress:0x5BEB0000
|
||||
-baseaddress:0x5BEE0000
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.print.*
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.sound.*
|
||||
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/imageio/plugins/common/iio-plugin.properties
|
||||
|
|
|
@ -2431,7 +2431,11 @@ namespace IKVM.Internal
|
|||
{
|
||||
break;
|
||||
}
|
||||
if (baseMethod2.DeclaringType.IsPackageAccessibleFrom(wrapper) && !baseMethod2.IsPrivate)
|
||||
if (baseMethod2.IsAccessStub)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
else if (baseMethod2.DeclaringType.IsPackageAccessibleFrom(wrapper) && !baseMethod2.IsPrivate)
|
||||
{
|
||||
if (baseMethod2.IsFinal)
|
||||
{
|
||||
|
@ -2540,7 +2544,11 @@ namespace IKVM.Internal
|
|||
{
|
||||
break;
|
||||
}
|
||||
if (baseMethod2.DeclaringType.IsPackageAccessibleFrom(wrapper) && !baseMethod2.IsPrivate)
|
||||
if (baseMethod2.IsAccessStub)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
else if (baseMethod2.DeclaringType.IsPackageAccessibleFrom(wrapper) && !baseMethod2.IsPrivate)
|
||||
{
|
||||
if (baseMethod2.IsFinal)
|
||||
{
|
||||
|
@ -4149,12 +4157,10 @@ namespace IKVM.Internal
|
|||
// See if there is any additional metadata
|
||||
wrapper.EmitMapXmlMetadata(typeBuilder, classFile, fields, methods);
|
||||
|
||||
// if we have public fields that have non-public field types, we need access stubs
|
||||
// if we inherit public members from non-public base classes or have public members with non-public types in their signature, we need access stubs
|
||||
if (wrapper.IsPublic)
|
||||
{
|
||||
AddType1FieldAccessStubs(wrapper);
|
||||
AddType2FieldAccessStubs();
|
||||
AddType1MethodAccessStubs();
|
||||
AddAccessStubs();
|
||||
}
|
||||
#endif // STATIC_COMPILER
|
||||
|
||||
|
@ -4336,7 +4342,44 @@ namespace IKVM.Internal
|
|||
}
|
||||
|
||||
#if STATIC_COMPILER
|
||||
private void AddType1FieldAccessStubs(TypeWrapper tw)
|
||||
private void AddAccessStubs()
|
||||
{
|
||||
/*
|
||||
* There are two types of access stubs:
|
||||
*
|
||||
* Type 1 These are required when a public class extends a non-public class.
|
||||
* In that case we need access stubs for all public and protected members
|
||||
* of the non-public base classes.
|
||||
*
|
||||
* Type 2 When a public class exposes a member that contains a non-public type in
|
||||
* its signature, we need an access stub for that member (where we convert
|
||||
* the non-public type in the signature to the first public base type).
|
||||
*
|
||||
* Note that type 1 access stubs may also need the type 2 signature type widening
|
||||
* if the signature contains non-public types.
|
||||
*
|
||||
* Type 1 access stubs are always required, because the JVM allow access to these
|
||||
* members via the derived class while the CLR doesn't. Historically, we've exposed
|
||||
* these access stubs in such a way that they are also consumable from other .NET
|
||||
* languages (when feasible), so we'll continue to do that for back compat.
|
||||
*
|
||||
* Type 2 access stubs are only required by the CLR when running on CLR v4 and the
|
||||
* caller assembly is security transparent code (level 2). We also want the access
|
||||
* stubs to allow other .NET languages (e.g. C#) to consume broken APIs that
|
||||
* (accidentally) expose these members.
|
||||
*/
|
||||
List<string> propertyNames = null;
|
||||
AddType2FieldAccessStubs(ref propertyNames);
|
||||
AddType1FieldAccessStubs(wrapper, ref propertyNames);
|
||||
if (!wrapper.IsInterface)
|
||||
{
|
||||
int id = 0;
|
||||
AddType2MethodAccessStubs(ref id);
|
||||
AddType1MethodAccessStubs(ref id);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddType1FieldAccessStubs(TypeWrapper tw, ref List<string> propertyNames)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
@ -4347,36 +4390,64 @@ namespace IKVM.Internal
|
|||
if ((fw.IsPublic || fw.IsProtected)
|
||||
&& wrapper.GetFieldWrapper(fw.Name, fw.Signature) == fw)
|
||||
{
|
||||
GenerateAccessStub(fw, true);
|
||||
GenerateAccessStub(fw, ref propertyNames, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (TypeWrapper iface in tw.Interfaces)
|
||||
{
|
||||
AddType1FieldAccessStubs(iface);
|
||||
AddType1FieldAccessStubs(iface, ref propertyNames);
|
||||
}
|
||||
tw = tw.BaseTypeWrapper;
|
||||
} while (tw != null && !tw.IsPublic);
|
||||
}
|
||||
|
||||
private void AddType2FieldAccessStubs()
|
||||
private void AddType2FieldAccessStubs(ref List<string> propertyNames)
|
||||
{
|
||||
foreach (FieldWrapper fw in wrapper.GetFields())
|
||||
{
|
||||
if (fw.HasNonPublicTypeInSignature)
|
||||
if (fw.HasNonPublicTypeInSignature && fw.FieldTypeWrapper.IsAccessibleFrom(wrapper))
|
||||
{
|
||||
GenerateAccessStub(fw, false);
|
||||
GenerateAccessStub(fw, ref propertyNames, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateAccessStub(FieldWrapper fw, bool type1)
|
||||
private void GenerateAccessStub(FieldWrapper fw, ref List<string> propertyNames, bool type1)
|
||||
{
|
||||
string name = fw.Name;
|
||||
if (propertyNames == null)
|
||||
{
|
||||
propertyNames = new List<string>();
|
||||
// add all the fields, to avoid clashing with real fields (which can happen for type 2 or type 1 if field type is non-public or unloadable)
|
||||
foreach (FieldWrapper fw1 in wrapper.GetFields())
|
||||
{
|
||||
if (!fw1.HasNonPublicTypeInSignature)
|
||||
{
|
||||
propertyNames.Add(fw1.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
int uniq = 0;
|
||||
while (propertyNames.Contains(name))
|
||||
{
|
||||
// when we clash, we don't want the access stub property to be visible from (e.g.) C# so we mangle the name
|
||||
name = "<>" + fw.Name + "_" + uniq++;
|
||||
}
|
||||
propertyNames.Add(name);
|
||||
|
||||
if (fw is ConstantFieldWrapper)
|
||||
{
|
||||
// constants cannot have a type 2 access stub, because constant types are always public
|
||||
Debug.Assert(type1);
|
||||
|
||||
if (uniq != 0)
|
||||
{
|
||||
// we only add access stubs for constant fields for consumption by other languages,
|
||||
// so when the field is hidden by another field, we don't need to bother
|
||||
return;
|
||||
}
|
||||
|
||||
FieldAttributes attribs = fw.IsPublic ? FieldAttributes.Public : FieldAttributes.FamORAssem;
|
||||
attribs |= FieldAttributes.Static | FieldAttributes.Literal;
|
||||
FieldBuilder fb = typeBuilder.DefineField(fw.Name, fw.FieldTypeWrapper.TypeAsSignatureType, attribs);
|
||||
|
@ -4385,25 +4456,12 @@ namespace IKVM.Internal
|
|||
}
|
||||
else
|
||||
{
|
||||
string name = fw.Name;
|
||||
// If there is a potential for property name clashes (e.g. we have multiple fields with the same name in this class,
|
||||
// or the current class hides a field in the base class) we will mangle the name as a precaution. We could use a more
|
||||
// complicated scheme which would result in less mangling, but it is exceedingly unlikely to encounter a class with
|
||||
// these field name clashes, because Java cannot handle them either.
|
||||
foreach (FieldWrapper field in wrapper.GetFields())
|
||||
{
|
||||
if (field != fw && !field.IsPrivate && field.Name == name)
|
||||
{
|
||||
name = "<>" + fw.Name + fw.Signature;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Type propType = fw.FieldTypeWrapper.GetPublicBaseTypeWrapper().TypeAsSignatureType;
|
||||
Type propType = ToPublicSignatureType(fw.FieldTypeWrapper);
|
||||
PropertyBuilder pb = typeBuilder.DefineProperty(name, PropertyAttributes.None, propType, Type.EmptyTypes);
|
||||
if (type1)
|
||||
{
|
||||
AttributeHelper.HideFromReflection(pb);
|
||||
if (fw.HasNonPublicTypeInSignature)
|
||||
if (fw.HasNonPublicTypeInSignature || fw.FieldTypeWrapper.IsUnloadable)
|
||||
{
|
||||
AttributeHelper.SetNameSig(pb, fw.Name, fw.Signature);
|
||||
}
|
||||
|
@ -4447,6 +4505,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
ilgen.Emit(OpCodes.Ldarg_1);
|
||||
}
|
||||
// we don't do a DynamicCast if fw.FieldTypeWrapper is unloadable, because for normal unloadable fields we don't enfore the type either
|
||||
if (propType != fw.FieldTypeWrapper.TypeAsSignatureType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Castclass, fw.FieldTypeWrapper.TypeAsSignatureType);
|
||||
|
@ -4458,9 +4517,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
private void AddType1MethodAccessStubs()
|
||||
{
|
||||
for (int pass = 0; pass < 2; pass++)
|
||||
private void AddType1MethodAccessStubs(ref int id)
|
||||
{
|
||||
for (TypeWrapper tw = wrapper.BaseTypeWrapper; tw != null && !tw.IsPublic; tw = tw.BaseTypeWrapper)
|
||||
{
|
||||
|
@ -4469,85 +4526,39 @@ namespace IKVM.Internal
|
|||
if ((mw.IsPublic || mw.IsProtected)
|
||||
&& (!mw.IsAbstract || wrapper.IsAbstract)
|
||||
&& mw.Name != StringConstants.INIT
|
||||
&& wrapper.GetMethodWrapper(mw.Name, mw.Signature, true) == mw)
|
||||
&& wrapper.GetMethodWrapper(mw.Name, mw.Signature, true) == mw
|
||||
&& ParametersAreAccessible(mw))
|
||||
{
|
||||
// we generate type 1a in the first pass, because it can't deal with name collisions
|
||||
if (pass == 0)
|
||||
GenerateAccessStub(id, mw, true, true);
|
||||
if (!mw.IsStatic && !mw.IsFinal && !mw.IsAbstract)
|
||||
{
|
||||
if (!mw.HasNonPublicTypeInSignature)
|
||||
{
|
||||
GenerateType1aAccessStub(mw);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mw.HasNonPublicTypeInSignature)
|
||||
{
|
||||
GenerateType1bAccessStub(mw, true);
|
||||
if (!wrapper.IsFinal && !mw.IsStatic)
|
||||
{
|
||||
GenerateType1bAccessStub(mw, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
GenerateAccessStub(id, mw, false, true);
|
||||
}
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateType1aAccessStub(MethodWrapper mw)
|
||||
private void AddType2MethodAccessStubs(ref int id)
|
||||
{
|
||||
Debug.Assert(!mw.HasCallerID);
|
||||
MethodAttributes stubattribs = mw.IsPublic ? MethodAttributes.Public : MethodAttributes.FamORAssem;
|
||||
stubattribs |= MethodAttributes.HideBySig;
|
||||
if (mw.IsStatic)
|
||||
foreach (MethodWrapper mw in wrapper.GetMethods())
|
||||
{
|
||||
stubattribs |= MethodAttributes.Static;
|
||||
if (mw.HasNonPublicTypeInSignature
|
||||
&& mw.Name != StringConstants.INIT // TODO we don't currently support constructors
|
||||
&& ParametersAreAccessible(mw))
|
||||
{
|
||||
GenerateAccessStub(id, mw, true, false);
|
||||
if (!mw.IsStatic && !mw.IsFinal && !mw.IsAbstract)
|
||||
{
|
||||
GenerateAccessStub(id, mw, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
stubattribs |= MethodAttributes.CheckAccessOnOverride | MethodAttributes.Virtual;
|
||||
if (mw.IsAbstract)
|
||||
{
|
||||
stubattribs |= MethodAttributes.Abstract;
|
||||
id++;
|
||||
}
|
||||
if (mw.IsFinal)
|
||||
{
|
||||
// NOTE final methods still need to be virtual, because a subclass may need this method to
|
||||
// implement an interface method
|
||||
stubattribs |= MethodAttributes.Final | MethodAttributes.NewSlot;
|
||||
}
|
||||
}
|
||||
Type[] parameterTypes = mw.GetParametersForDefineMethod();
|
||||
Type returnType = mw.ReturnTypeForDefineMethod;
|
||||
// register the name where about to use up (it can't exist already)
|
||||
if (mw.Name != wrapper.GenerateUniqueMethodName(mw.Name, returnType, parameterTypes))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
MethodBuilder mb = typeBuilder.DefineMethod(mw.Name, stubattribs, returnType, parameterTypes);
|
||||
AttributeHelper.HideFromReflection(mb, HideFromReflectionAttribute.Type1aAccessStub);
|
||||
if (!mw.IsAbstract)
|
||||
{
|
||||
CodeEmitter ilgen = CodeEmitter.Create(mb);
|
||||
Type[] realParamTypes = mw.GetParametersForDefineMethod();
|
||||
int argpos = 0;
|
||||
if (!mw.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldarg_S, (byte)argpos++);
|
||||
}
|
||||
for (int i = 0; i < realParamTypes.Length; i++)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldarg_S, (byte)argpos++);
|
||||
}
|
||||
mw.EmitCall(ilgen);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
ilgen.DoEmit();
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateType1bAccessStub(MethodWrapper mw, bool virt)
|
||||
private void GenerateAccessStub(int id, MethodWrapper mw, bool virt, bool type1)
|
||||
{
|
||||
Debug.Assert(!mw.HasCallerID);
|
||||
MethodAttributes stubattribs = mw.IsPublic && virt ? MethodAttributes.Public : MethodAttributes.FamORAssem;
|
||||
|
@ -4556,30 +4567,43 @@ namespace IKVM.Internal
|
|||
{
|
||||
stubattribs |= MethodAttributes.Static;
|
||||
}
|
||||
TypeWrapper[] realParameterTypes = mw.GetParameters();
|
||||
Type[] parameterTypes = new Type[realParameterTypes.Length];
|
||||
for (int i = 0; i < realParameterTypes.Length; i++)
|
||||
TypeWrapper[] parameters = mw.GetParameters();
|
||||
Type[] realParameterTypes = new Type[parameters.Length];
|
||||
Type[] parameterTypes = new Type[parameters.Length];
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
parameterTypes[i] = realParameterTypes[i].GetPublicBaseTypeWrapper().TypeAsSignatureType;
|
||||
realParameterTypes[i] = parameters[i].TypeAsSignatureType;
|
||||
parameterTypes[i] = ToPublicSignatureType(parameters[i]);
|
||||
}
|
||||
Type returnType = mw.ReturnType.GetPublicBaseTypeWrapper().TypeAsSignatureType;
|
||||
string realName = wrapper.GenerateUniqueMethodName(virt ? mw.Name : NamePrefix.Type1bNonVirtualAccessStub + mw.Name, returnType, parameterTypes);
|
||||
MethodBuilder mb = typeBuilder.DefineMethod(realName, stubattribs, returnType, parameterTypes);
|
||||
AttributeHelper.HideFromReflection(mb, mw.IsStatic ? HideFromReflectionAttribute.Type1bAccessStubStatic : virt ? HideFromReflectionAttribute.Type1bAccessStubVirtual : HideFromReflectionAttribute.Type1bAccessStubNonVirtual);
|
||||
Type returnType = ToPublicSignatureType(mw.ReturnType);
|
||||
string name = virt ? wrapper.GenerateUniqueMethodName(mw.Name, returnType, parameterTypes) : NamePrefix.NonVirtual + id;
|
||||
MethodBuilder mb = typeBuilder.DefineMethod(name, stubattribs, returnType, parameterTypes);
|
||||
if (virt && type1)
|
||||
{
|
||||
AttributeHelper.HideFromReflection(mb);
|
||||
AttributeHelper.SetNameSig(mb, NamePrefix.AccessStub + id + "|" + mw.Name, mw.Signature);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttributeHelper.HideFromJava(mb);
|
||||
if (!type1)
|
||||
{
|
||||
AttributeHelper.SetNameSig(mb, mw.Name, mw.Signature);
|
||||
}
|
||||
}
|
||||
CodeEmitter ilgen = CodeEmitter.Create(mb);
|
||||
Type[] realParamTypes = mw.GetParametersForDefineMethod();
|
||||
int argpos = 0;
|
||||
if (!mw.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldarg_S, (byte)argpos++);
|
||||
}
|
||||
for (int i = 0; i < realParamTypes.Length; i++)
|
||||
for (int i = 0; i < parameterTypes.Length; i++)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldarg_S, (byte)argpos++);
|
||||
if (realParamTypes[i] != parameterTypes[i])
|
||||
// we don't need to do a DynamicCast if for unloadables, because the method itself will already do that
|
||||
if (parameterTypes[i] != realParameterTypes[i])
|
||||
{
|
||||
ilgen.Emit(OpCodes.Castclass, realParamTypes[i]);
|
||||
ilgen.Emit(OpCodes.Castclass, realParameterTypes[i]);
|
||||
}
|
||||
}
|
||||
if (mw.IsStatic || !virt)
|
||||
|
@ -4593,6 +4617,23 @@ namespace IKVM.Internal
|
|||
ilgen.Emit(OpCodes.Ret);
|
||||
ilgen.DoEmit();
|
||||
}
|
||||
|
||||
private static Type ToPublicSignatureType(TypeWrapper tw)
|
||||
{
|
||||
return (tw.IsPublic ? tw : tw.GetPublicBaseTypeWrapper()).TypeAsSignatureType;
|
||||
}
|
||||
|
||||
private bool ParametersAreAccessible(MethodWrapper mw)
|
||||
{
|
||||
foreach (TypeWrapper tw in mw.GetParameters())
|
||||
{
|
||||
if (!tw.IsAccessibleFrom(wrapper))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // STATIC_COMPILER
|
||||
|
||||
private void ImplementInterfaceMethodStubs(Dictionary<TypeWrapper, TypeWrapper> doneSet, TypeWrapper interfaceTypeWrapper, bool baseClassInterface)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002-2009 Jeroen Frijters
|
||||
Copyright (C) 2002-2011 Jeroen Frijters
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -467,7 +467,7 @@ namespace IKVM.Internal
|
|||
|
||||
private void UpdateNonPublicTypeInSignatureFlag()
|
||||
{
|
||||
if ((IsPublic || IsProtected) && (returnTypeWrapper != null && parameterTypeWrappers != null))
|
||||
if ((IsPublic || IsProtected) && (returnTypeWrapper != null && parameterTypeWrappers != null) && !(this is AccessStubMethodWrapper))
|
||||
{
|
||||
if (!returnTypeWrapper.IsPublic && !returnTypeWrapper.IsUnloadable)
|
||||
{
|
||||
|
@ -1205,11 +1205,13 @@ namespace IKVM.Internal
|
|||
|
||||
sealed class AccessStubMethodWrapper : SmartMethodWrapper
|
||||
{
|
||||
private readonly MethodInfo stubVirtual;
|
||||
private readonly MethodInfo stubNonVirtual;
|
||||
|
||||
internal AccessStubMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo stubVirtual, MethodInfo stubNonVirtual, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, name, sig, stubVirtual, returnType, parameterTypes, modifiers, flags)
|
||||
internal AccessStubMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo core, MethodInfo stubVirtual, MethodInfo stubNonVirtual, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, name, sig, core, returnType, parameterTypes, modifiers, flags)
|
||||
{
|
||||
this.stubVirtual = stubVirtual;
|
||||
this.stubNonVirtual = stubNonVirtual;
|
||||
}
|
||||
|
||||
|
@ -1221,7 +1223,7 @@ namespace IKVM.Internal
|
|||
|
||||
protected override void CallvirtImpl(CodeEmitter ilgen)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Callvirt, (MethodInfo)GetMethod());
|
||||
ilgen.Emit(OpCodes.Callvirt, stubVirtual);
|
||||
}
|
||||
#endif // !STUB_GENERATOR
|
||||
}
|
||||
|
|
|
@ -496,37 +496,6 @@ namespace IKVM.Internal
|
|||
return mi.IsDefined(typeofHideFromReflectionAttribute, false);
|
||||
}
|
||||
|
||||
internal static bool IsHideFromReflection(MemberInfo mi, out int reason)
|
||||
{
|
||||
#if !STATIC_COMPILER && !STUB_GENERATOR
|
||||
object[] attr = mi.GetCustomAttributes(typeof(HideFromReflectionAttribute), false);
|
||||
if (attr.Length == 1)
|
||||
{
|
||||
reason = ((HideFromReflectionAttribute)attr[0]).Reason;
|
||||
return true;
|
||||
}
|
||||
reason = HideFromReflectionAttribute.Unknown;
|
||||
return false;
|
||||
#else
|
||||
IList<CustomAttributeData> attr = CustomAttributeData.__GetCustomAttributes(mi, typeofHideFromReflectionAttribute, false);
|
||||
if (attr.Count == 1)
|
||||
{
|
||||
IList<CustomAttributeTypedArgument> args = attr[0].ConstructorArguments;
|
||||
if (args.Count == 1)
|
||||
{
|
||||
reason = (int)args[0].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reason = HideFromReflectionAttribute.Unknown;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
reason = HideFromReflectionAttribute.Unknown;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static void HideFromJava(TypeBuilder typeBuilder)
|
||||
{
|
||||
if(hideFromJavaAttribute == null)
|
||||
|
@ -1686,7 +1655,8 @@ namespace IKVM.Internal
|
|||
static class NamePrefix
|
||||
{
|
||||
internal const string Type2AccessStubBackingField = "__<>";
|
||||
internal const string Type1bNonVirtualAccessStub = "<nonvirtual>";
|
||||
internal const string AccessStub = "<accessstub>";
|
||||
internal const string NonVirtual = "<nonvirtual>";
|
||||
}
|
||||
|
||||
internal abstract class TypeWrapper
|
||||
|
@ -3105,6 +3075,7 @@ namespace IKVM.Internal
|
|||
|
||||
internal TypeWrapper GetPublicBaseTypeWrapper()
|
||||
{
|
||||
Debug.Assert(!this.IsPublic);
|
||||
if (this.IsUnloadable || this.IsInterface)
|
||||
{
|
||||
return CoreClasses.java.lang.Object.Wrapper;
|
||||
|
@ -3983,7 +3954,6 @@ namespace IKVM.Internal
|
|||
{
|
||||
bool isDelegate = type.BaseType == Types.MulticastDelegate;
|
||||
List<MethodWrapper> methods = new List<MethodWrapper>();
|
||||
List<MethodInfo> type1bAccessStubs = null;
|
||||
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
|
||||
foreach(ConstructorInfo ctor in type.GetConstructors(flags))
|
||||
{
|
||||
|
@ -3993,21 +3963,17 @@ namespace IKVM.Internal
|
|||
}
|
||||
else
|
||||
{
|
||||
AddMethodOrConstructor(ctor, methods, ref type1bAccessStubs);
|
||||
AddMethodOrConstructor(ctor, methods);
|
||||
}
|
||||
}
|
||||
foreach(MethodInfo method in type.GetMethods(flags))
|
||||
{
|
||||
AddMethodOrConstructor(method, methods, ref type1bAccessStubs);
|
||||
}
|
||||
if(type1bAccessStubs != null)
|
||||
{
|
||||
AddType1bAccessStubs(methods, type1bAccessStubs);
|
||||
AddMethodOrConstructor(method, methods);
|
||||
}
|
||||
SetMethods(methods.ToArray());
|
||||
}
|
||||
|
||||
private void AddMethodOrConstructor(MethodBase method, List<MethodWrapper> methods, ref List<MethodInfo> type1bAccessStubs)
|
||||
private void AddMethodOrConstructor(MethodBase method, List<MethodWrapper> methods)
|
||||
{
|
||||
if(!AttributeHelper.IsHideFromJava(method))
|
||||
{
|
||||
|
@ -4022,86 +3988,63 @@ namespace IKVM.Internal
|
|||
TypeWrapper retType;
|
||||
TypeWrapper[] paramTypes;
|
||||
MethodInfo mi = method as MethodInfo;
|
||||
int reason = HideFromReflectionAttribute.Unknown;
|
||||
bool hideFromReflection = mi != null ? AttributeHelper.IsHideFromReflection(mi, out reason) : false;
|
||||
bool hideFromReflection = mi != null ? AttributeHelper.IsHideFromReflection(mi) : false;
|
||||
MemberFlags flags = hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None;
|
||||
switch (reason)
|
||||
{
|
||||
case HideFromReflectionAttribute.Type1aAccessStub:
|
||||
case HideFromReflectionAttribute.Type1bAccessStubStatic:
|
||||
flags |= MemberFlags.AccessStub;
|
||||
break;
|
||||
case HideFromReflectionAttribute.Type1bAccessStubVirtual:
|
||||
case HideFromReflectionAttribute.Type1bAccessStubNonVirtual:
|
||||
if (type1bAccessStubs == null)
|
||||
{
|
||||
type1bAccessStubs = new List<MethodInfo>();
|
||||
}
|
||||
type1bAccessStubs.Add(mi);
|
||||
return;
|
||||
}
|
||||
GetNameSigFromMethodBase(method, out name, out sig, out retType, out paramTypes, ref flags);
|
||||
ExModifiers mods = AttributeHelper.GetModifiers(method, false);
|
||||
if(mods.IsInternal)
|
||||
{
|
||||
flags |= MemberFlags.InternalAccess;
|
||||
}
|
||||
methods.Add(MethodWrapper.Create(this, name, sig, method, retType, paramTypes, mods.Modifiers, flags));
|
||||
if(hideFromReflection && name.StartsWith(NamePrefix.AccessStub, StringComparison.Ordinal))
|
||||
{
|
||||
int id = Int32.Parse(name.Substring(NamePrefix.AccessStub.Length, name.IndexOf('|', NamePrefix.AccessStub.Length) - NamePrefix.AccessStub.Length));
|
||||
name = name.Substring(name.IndexOf('|', NamePrefix.AccessStub.Length) + 1);
|
||||
flags |= MemberFlags.AccessStub;
|
||||
MethodInfo nonvirt = type.GetMethod(NamePrefix.NonVirtual + id, BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance);
|
||||
methods.Add(new AccessStubMethodWrapper(this, name, sig, mi, mi, nonvirt ?? mi, retType, paramTypes, mods.Modifiers & ~Modifiers.Final, flags));
|
||||
return;
|
||||
}
|
||||
MethodWrapper mw = MethodWrapper.Create(this, name, sig, method, retType, paramTypes, mods.Modifiers, flags);
|
||||
if (mw.HasNonPublicTypeInSignature)
|
||||
{
|
||||
MethodInfo stubVirt;
|
||||
MethodInfo stubNonVirt;
|
||||
if (GetType2AccessStubs(name, sig, out stubVirt, out stubNonVirt))
|
||||
{
|
||||
mw = new AccessStubMethodWrapper(this, name, sig, mi, stubVirt, stubNonVirt ?? stubVirt, retType, paramTypes, mw.Modifiers, flags);
|
||||
}
|
||||
}
|
||||
methods.Add(mw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddType1bAccessStubs(List<MethodWrapper> methods, List<MethodInfo> type1bAccessStubs)
|
||||
private bool GetType2AccessStubs(string name, string sig, out MethodInfo stubVirt, out MethodInfo stubNonVirt)
|
||||
{
|
||||
for (int i = 0; i < type1bAccessStubs.Count; i++)
|
||||
stubVirt = null;
|
||||
stubNonVirt = null;
|
||||
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
|
||||
foreach (MethodInfo method in type.GetMethods(flags))
|
||||
{
|
||||
if (type1bAccessStubs[i] != null)
|
||||
if (AttributeHelper.IsHideFromJava(method))
|
||||
{
|
||||
string name1;
|
||||
string sig1;
|
||||
TypeWrapper retType1;
|
||||
TypeWrapper[] paramTypes1;
|
||||
MemberFlags flags1 = MemberFlags.HideFromReflection;
|
||||
GetNameSigFromMethodBase(type1bAccessStubs[i], out name1, out sig1, out retType1, out paramTypes1, ref flags1);
|
||||
MethodInfo found = null;
|
||||
for (int j = i + 1; j < type1bAccessStubs.Count; j++)
|
||||
NameSigAttribute attr = AttributeHelper.GetNameSig(method);
|
||||
if (attr != null && attr.Name == name && attr.Sig == sig)
|
||||
{
|
||||
if (type1bAccessStubs[j] != null)
|
||||
if (method.Name.StartsWith(NamePrefix.NonVirtual, StringComparison.Ordinal))
|
||||
{
|
||||
string name2;
|
||||
string sig2;
|
||||
TypeWrapper retType2;
|
||||
TypeWrapper[] paramTypes2;
|
||||
MemberFlags flags2 = MemberFlags.HideFromReflection | MemberFlags.AccessStub;
|
||||
GetNameSigFromMethodBase(type1bAccessStubs[j], out name2, out sig2, out retType2, out paramTypes2, ref flags2);
|
||||
if (name1 == name2 && sig1 == sig2)
|
||||
{
|
||||
found = type1bAccessStubs[j];
|
||||
type1bAccessStubs[j] = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodInfo stubVirtual;
|
||||
MethodInfo stubNonVirtual;
|
||||
if (found == null)
|
||||
{
|
||||
stubVirtual = stubNonVirtual = type1bAccessStubs[i];
|
||||
}
|
||||
else if (found.Name.StartsWith(NamePrefix.Type1bNonVirtualAccessStub, StringComparison.Ordinal))
|
||||
{
|
||||
stubVirtual = type1bAccessStubs[i];
|
||||
stubNonVirtual = found;
|
||||
stubNonVirt = method;
|
||||
}
|
||||
else
|
||||
{
|
||||
stubVirtual = found;
|
||||
stubNonVirtual = type1bAccessStubs[i];
|
||||
}
|
||||
methods.Add(new AccessStubMethodWrapper(this, name1, sig1, stubVirtual, stubNonVirtual, retType1, paramTypes1, stubVirtual.IsPublic ? Modifiers.Public : Modifiers.Protected, MemberFlags.HideFromReflection | MemberFlags.AccessStub));
|
||||
stubVirt = method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stubVirt != null;
|
||||
}
|
||||
|
||||
private static int SortFieldByToken(FieldInfo field1, FieldInfo field2)
|
||||
{
|
||||
|
|
|
@ -423,28 +423,6 @@ namespace IKVM.Attributes
|
|||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public sealed class HideFromReflectionAttribute : Attribute
|
||||
{
|
||||
private readonly int reason;
|
||||
// reasons
|
||||
public const int Unknown = 0;
|
||||
public const int Type1aAccessStub = 1;
|
||||
public const int Type1bAccessStubVirtual = 2;
|
||||
public const int Type1bAccessStubNonVirtual = 3;
|
||||
public const int Type1bAccessStubStatic = 4;
|
||||
|
||||
public HideFromReflectionAttribute()
|
||||
: this(Unknown)
|
||||
{
|
||||
}
|
||||
|
||||
public HideFromReflectionAttribute(int reason)
|
||||
{
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public int Reason
|
||||
{
|
||||
get { return reason; }
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
|
Загрузка…
Ссылка в новой задаче