зеркало из https://github.com/mono/ikvm-fork.git
Added ikvm.lang.DllExport annotation to export static methods as unmanaged exports.
This commit is contained in:
Родитель
ad824ad22e
Коммит
0f0a0963c7
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright (C) 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
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jeroen Frijters
|
||||
jeroen@frijters.net
|
||||
|
||||
*/
|
||||
package ikvm.lang;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Can be used to define an unmanaged export for a static method.
|
||||
* Only works with ikvmc compiled code.
|
||||
*/
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ ElementType.METHOD })
|
||||
public @interface DllExport
|
||||
{
|
||||
String name();
|
||||
int ordinal();
|
||||
}
|
|
@ -3276,6 +3276,11 @@ namespace IKVM.Internal
|
|||
{
|
||||
StaticCompiler.IssueMessage(options, msgId, values);
|
||||
}
|
||||
|
||||
internal void ClearILOnlyFlag()
|
||||
{
|
||||
options.pekind &= ~PortableExecutableKinds.ILOnly;
|
||||
}
|
||||
}
|
||||
|
||||
struct ResourceItem
|
||||
|
@ -3403,6 +3408,7 @@ namespace IKVM.Internal
|
|||
LegacySearchRule = 126,
|
||||
AssemblyLocationIgnored = 127,
|
||||
InterfaceMethodCantBeInternal = 128,
|
||||
DllExportMustBeStaticMethod = 129,
|
||||
UnknownWarning = 999,
|
||||
// This is where the errors start
|
||||
StartErrors = 4000,
|
||||
|
@ -3621,6 +3627,10 @@ namespace IKVM.Internal
|
|||
msg = "ignoring @ikvm.lang.Internal annotation on interface method" + Environment.NewLine +
|
||||
" (\"{0}.{1}{2}\")";
|
||||
break;
|
||||
case Message.DllExportMustBeStaticMethod:
|
||||
msg = "ignoring @ikvm.lang.DllExport annotation on non-static method" + Environment.NewLine +
|
||||
" (\"{0}.{1}{2}\")";
|
||||
break;
|
||||
case Message.UnableToCreateProxy:
|
||||
msg = "unable to create proxy \"{0}\"" + Environment.NewLine +
|
||||
" (\"{1}\")";
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
../classpath/ikvm/internal/WeakIdentityMap.java
|
||||
../classpath/ikvm/io/InputStreamWrapper.java
|
||||
../classpath/ikvm/lang/CIL.java
|
||||
../classpath/ikvm/lang/DllExport.java
|
||||
../classpath/ikvm/lang/Internal.java
|
||||
../classpath/ikvm/lang/IterableEnumerator.java
|
||||
../classpath/ikvm/lang/MapEnumerator.java
|
||||
|
|
|
@ -2448,8 +2448,15 @@ namespace IKVM.Internal
|
|||
{
|
||||
private Code code;
|
||||
private string[] exceptions;
|
||||
private object annotationDefault;
|
||||
private object[][] parameterAnnotations;
|
||||
private LowFreqData low;
|
||||
|
||||
sealed class LowFreqData
|
||||
{
|
||||
internal object annotationDefault;
|
||||
internal object[][] parameterAnnotations;
|
||||
internal string DllExportName;
|
||||
internal int DllExportOrdinal;
|
||||
}
|
||||
|
||||
internal Method(ClassFile classFile, ClassFileParseOptions options, BigEndianBinaryReader br) : base(classFile, br)
|
||||
{
|
||||
|
@ -2541,16 +2548,20 @@ namespace IKVM.Internal
|
|||
{
|
||||
goto default;
|
||||
}
|
||||
if(low == null)
|
||||
{
|
||||
low = new LowFreqData();
|
||||
}
|
||||
BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
|
||||
byte num_parameters = rdr.ReadByte();
|
||||
parameterAnnotations = new object[num_parameters][];
|
||||
low.parameterAnnotations = new object[num_parameters][];
|
||||
for(int j = 0; j < num_parameters; j++)
|
||||
{
|
||||
ushort num_annotations = rdr.ReadUInt16();
|
||||
parameterAnnotations[j] = new object[num_annotations];
|
||||
low.parameterAnnotations[j] = new object[num_annotations];
|
||||
for(int k = 0; k < num_annotations; k++)
|
||||
{
|
||||
parameterAnnotations[j][k] = ReadAnnotation(rdr, classFile);
|
||||
low.parameterAnnotations[j][k] = ReadAnnotation(rdr, classFile);
|
||||
}
|
||||
}
|
||||
if(!rdr.IsAtEnd)
|
||||
|
@ -2565,8 +2576,12 @@ namespace IKVM.Internal
|
|||
{
|
||||
goto default;
|
||||
}
|
||||
if(low == null)
|
||||
{
|
||||
low = new LowFreqData();
|
||||
}
|
||||
BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
|
||||
annotationDefault = ReadAnnotationElementValue(rdr, classFile);
|
||||
low.annotationDefault = ReadAnnotationElementValue(rdr, classFile);
|
||||
if(!rdr.IsAtEnd)
|
||||
{
|
||||
throw new ClassFormatError("{0} (AnnotationDefault attribute has wrong length)", classFile.Name);
|
||||
|
@ -2597,6 +2612,38 @@ namespace IKVM.Internal
|
|||
{
|
||||
flags |= FLAG_HAS_CALLERID;
|
||||
}
|
||||
if(annot[1].Equals("Likvm/lang/DllExport;"))
|
||||
{
|
||||
string name = null;
|
||||
int? ordinal = null;
|
||||
for (int j = 2; j < annot.Length; j += 2)
|
||||
{
|
||||
if (annot[j].Equals("name") && annot[j + 1] is string)
|
||||
{
|
||||
name = (string)annot[j + 1];
|
||||
}
|
||||
else if (annot[j].Equals("ordinal") && annot[j + 1] is int)
|
||||
{
|
||||
ordinal = (int)annot[j + 1];
|
||||
}
|
||||
}
|
||||
if (name != null && ordinal != null)
|
||||
{
|
||||
if (!IsStatic)
|
||||
{
|
||||
StaticCompiler.IssueMessage(Message.DllExportMustBeStaticMethod, classFile.Name, this.Name, this.Signature);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (low == null)
|
||||
{
|
||||
low = new LowFreqData();
|
||||
}
|
||||
low.DllExportName = name;
|
||||
low.DllExportOrdinal = ordinal.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -2672,7 +2719,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
get
|
||||
{
|
||||
return parameterAnnotations;
|
||||
return low == null ? null : low.parameterAnnotations;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2680,7 +2727,23 @@ namespace IKVM.Internal
|
|||
{
|
||||
get
|
||||
{
|
||||
return annotationDefault;
|
||||
return low == null ? null : low.annotationDefault;
|
||||
}
|
||||
}
|
||||
|
||||
internal string DllExportName
|
||||
{
|
||||
get
|
||||
{
|
||||
return low == null ? null : low.DllExportName;
|
||||
}
|
||||
}
|
||||
|
||||
internal int DllExportOrdinal
|
||||
{
|
||||
get
|
||||
{
|
||||
return low == null ? -1 : low.DllExportOrdinal;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4342,6 +4342,12 @@ namespace IKVM.Internal
|
|||
AttributeHelper.SetEditorBrowsableNever((MethodBuilder)mb);
|
||||
EmitCallerIDStub(methods[i], parameterNames);
|
||||
}
|
||||
if (m.DllExportName != null)
|
||||
{
|
||||
mBuilder.__AddUnmanagedExport(m.DllExportName, m.DllExportOrdinal);
|
||||
// when you add unmanaged exports, the ILOnly flag MUST NOT be set or the DLL will fail to load
|
||||
((CompilerClassLoader)wrapper.GetClassLoader()).ClearILOnlyFlag();
|
||||
}
|
||||
#endif // STATIC_COMPILER
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче