@@ -19,13 +19,12 @@ public ExportMethodDispatchEmitter (PEAssemblyBuilder pe, ExportMethodDispatchEm
1919
2020 public MethodDefinitionHandle EmitUcoMethod ( UcoMethodData uco )
2121 {
22+ var exportMethodDispatch = GetRequiredExportMethodDispatch ( uco ) ;
2223 var jniParams = JniSignatureHelper . ParseParameterTypes ( uco . JniSignature ) ;
2324 var returnKind = JniSignatureHelper . ParseReturnType ( uco . JniSignature ) ;
2425 int paramCount = 2 + jniParams . Count ;
2526 bool isVoid = returnKind == JniParamKind . Void ;
26- var exportMethodDispatchLocals = uco . UsesExportMethodDispatch
27- ? CreateExportMethodDispatchLocals ( GetRequiredExportMethodDispatch ( uco ) , isVoid )
28- : ExportMethodDispatchLocals . Empty ;
27+ var exportMethodDispatchLocals = CreateExportMethodDispatchLocals ( exportMethodDispatch , isVoid ) ;
2928
3029 Action < BlobEncoder > encodeSig = sig => sig . MethodSignature ( ) . Parameters ( paramCount ,
3130 rt => { if ( isVoid ) rt . Void ( ) ; else JniSignatureHelper . EncodeClrType ( rt . Type ( ) , returnKind ) ; } ,
@@ -37,23 +36,13 @@ public MethodDefinitionHandle EmitUcoMethod (UcoMethodData uco)
3736 }
3837 } ) ;
3938 var callbackTypeHandle = _pe . ResolveTypeRef ( uco . CallbackType ) ;
40- var callbackRef = uco . UsesExportMethodDispatch
41- ? AddExportMethodDispatchRef ( uco , callbackTypeHandle )
42- : _pe . AddMemberRef ( callbackTypeHandle , uco . CallbackMethodName , encodeSig ) ;
39+ var callbackRef = AddExportMethodDispatchRef ( uco , callbackTypeHandle ) ;
4340
4441 var handle = _pe . EmitBody ( uco . WrapperName ,
4542 MethodAttributes . Public | MethodAttributes . Static | MethodAttributes . HideBySig ,
4643 encodeSig ,
4744 encoder => {
48- if ( ! uco . UsesExportMethodDispatch ) {
49- for ( int p = 0 ; p < paramCount ; p ++ ) {
50- encoder . LoadArgument ( p ) ;
51- }
52-
53- encoder . Call ( callbackRef ) ;
54- } else {
55- EmitExportMethodDispatch ( encoder , uco , callbackTypeHandle , callbackRef , jniParams , returnKind , exportMethodDispatchLocals ) ;
56- }
45+ EmitExportMethodDispatch ( encoder , uco , callbackTypeHandle , callbackRef , jniParams , returnKind , exportMethodDispatchLocals ) ;
5746 encoder . OpCode ( ILOpCode . Ret ) ;
5847 } ,
5948 exportMethodDispatchLocals . EncodeLocals ,
@@ -63,131 +52,6 @@ public MethodDefinitionHandle EmitUcoMethod (UcoMethodData uco)
6352 return handle ;
6453 }
6554
66- public MethodDefinitionHandle EmitUcoConstructor ( UcoConstructorData uco )
67- {
68- var userTypeRef = _pe . ResolveTypeRef ( uco . TargetType ) ;
69-
70- // UCO constructor wrappers must match the JNI native method signature exactly.
71- var jniParams = JniSignatureHelper . ParseParameterTypes ( uco . JniSignature ) ;
72- int paramCount = 2 + jniParams . Count ;
73-
74- var handle = _pe . EmitBody ( uco . WrapperName ,
75- MethodAttributes . Public | MethodAttributes . Static | MethodAttributes . HideBySig ,
76- sig => sig . MethodSignature ( ) . Parameters ( paramCount ,
77- rt => rt . Void ( ) ,
78- p => {
79- p . AddParameter ( ) . Type ( ) . IntPtr ( ) ;
80- p . AddParameter ( ) . Type ( ) . IntPtr ( ) ;
81- for ( int j = 0 ; j < jniParams . Count ; j ++ ) {
82- JniSignatureHelper . EncodeClrType ( p . AddParameter ( ) . Type ( ) , jniParams [ j ] ) ;
83- }
84- } ) ,
85- encoder => {
86- encoder . LoadArgument ( 1 ) ;
87- encoder . OpCode ( ILOpCode . Ldtoken ) ;
88- encoder . Token ( userTypeRef ) ;
89- encoder . Call ( _context . GetTypeFromHandleRef ) ;
90- encoder . Call ( _context . ActivateInstanceRef ) ;
91- encoder . OpCode ( ILOpCode . Ret ) ;
92- } ) ;
93-
94- AddUnmanagedCallersOnlyAttribute ( handle ) ;
95- return handle ;
96- }
97-
98- public void EmitRegisterNatives ( List < NativeRegistrationData > registrations , Dictionary < string , MethodDefinitionHandle > wrapperHandles )
99- {
100- var validRegs = new List < ( NativeRegistrationData Reg , MethodDefinitionHandle Wrapper ) > ( registrations . Count ) ;
101- foreach ( var reg in registrations ) {
102- if ( wrapperHandles . TryGetValue ( reg . WrapperMethodName , out var wrapperHandle ) ) {
103- validRegs . Add ( ( reg , wrapperHandle ) ) ;
104- }
105- }
106-
107- if ( validRegs . Count == 0 ) {
108- _pe . EmitBody ( "RegisterNatives" ,
109- MethodAttributes . Public | MethodAttributes . Virtual | MethodAttributes . HideBySig |
110- MethodAttributes . NewSlot | MethodAttributes . Final ,
111- sig => sig . MethodSignature ( isInstanceMethod : true ) . Parameters ( 1 ,
112- rt => rt . Void ( ) ,
113- p => p . AddParameter ( ) . Type ( ) . Type ( _context . JniTypeRef , false ) ) ,
114- encoder => encoder . OpCode ( ILOpCode . Ret ) ) ;
115- return ;
116- }
117-
118- var nameFields = new FieldDefinitionHandle [ validRegs . Count ] ;
119- var sigFields = new FieldDefinitionHandle [ validRegs . Count ] ;
120- for ( int i = 0 ; i < validRegs . Count ; i ++ ) {
121- nameFields [ i ] = _pe . GetOrAddUtf8Field ( validRegs [ i ] . Reg . JniMethodName ) ;
122- sigFields [ i ] = _pe . GetOrAddUtf8Field ( validRegs [ i ] . Reg . JniSignature ) ;
123- }
124-
125- int methodCount = validRegs . Count ;
126-
127- _pe . EmitBody ( "RegisterNatives" ,
128- MethodAttributes . Public | MethodAttributes . Virtual | MethodAttributes . HideBySig |
129- MethodAttributes . NewSlot | MethodAttributes . Final ,
130- sig => sig . MethodSignature ( isInstanceMethod : true ) . Parameters ( 1 ,
131- rt => rt . Void ( ) ,
132- p => p . AddParameter ( ) . Type ( ) . Type ( _context . JniTypeRef , false ) ) ,
133- encoder => {
134- encoder . LoadConstantI4 ( methodCount ) ;
135- encoder . OpCode ( ILOpCode . Sizeof ) ;
136- encoder . Token ( _context . JniNativeMethodRef ) ;
137- encoder . OpCode ( ILOpCode . Mul ) ;
138- encoder . OpCode ( ILOpCode . Localloc ) ;
139- encoder . StoreLocal ( 0 ) ;
140-
141- for ( int i = 0 ; i < methodCount ; i ++ ) {
142- encoder . LoadLocal ( 0 ) ;
143- if ( i > 0 ) {
144- encoder . LoadConstantI4 ( i ) ;
145- encoder . OpCode ( ILOpCode . Sizeof ) ;
146- encoder . Token ( _context . JniNativeMethodRef ) ;
147- encoder . OpCode ( ILOpCode . Mul ) ;
148- encoder . OpCode ( ILOpCode . Add ) ;
149- }
150-
151- encoder . OpCode ( ILOpCode . Ldsflda ) ;
152- encoder . Token ( nameFields [ i ] ) ;
153-
154- encoder . OpCode ( ILOpCode . Ldsflda ) ;
155- encoder . Token ( sigFields [ i ] ) ;
156-
157- encoder . OpCode ( ILOpCode . Ldftn ) ;
158- encoder . Token ( validRegs [ i ] . Wrapper ) ;
159-
160- encoder . OpCode ( ILOpCode . Newobj ) ;
161- encoder . Token ( _context . JniNativeMethodCtorRef ) ;
162- encoder . OpCode ( ILOpCode . Stobj ) ;
163- encoder . Token ( _context . JniNativeMethodRef ) ;
164- }
165-
166- encoder . LoadArgument ( 1 ) ;
167- encoder . OpCode ( ILOpCode . Callvirt ) ;
168- encoder . Token ( _context . JniTypePeerReferenceRef ) ;
169- encoder . StoreLocal ( 1 ) ;
170-
171- encoder . LoadLocalAddress ( 2 ) ;
172- encoder . LoadLocal ( 0 ) ;
173- encoder . LoadConstantI4 ( methodCount ) ;
174- encoder . Call ( _context . ReadOnlySpanOfJniNativeMethodCtorRef ) ;
175-
176- encoder . LoadLocal ( 1 ) ;
177- encoder . LoadLocal ( 2 ) ;
178- encoder . Call ( _context . JniEnvTypesRegisterNativesRef ) ;
179- encoder . OpCode ( ILOpCode . Ret ) ;
180- } ,
181- encodeLocals : localSig => {
182- localSig . WriteByte ( 0x07 ) ;
183- localSig . WriteCompressedInteger ( 3 ) ;
184- localSig . WriteByte ( 0x18 ) ;
185- localSig . WriteByte ( 0x11 ) ;
186- localSig . WriteCompressedInteger ( CodedIndex . TypeDefOrRefOrSpec ( _context . JniObjectReferenceRef ) ) ;
187- EncodeGenericValueTypeInst ( localSig , _context . ReadOnlySpanOpenRef , _context . JniNativeMethodRef ) ;
188- } ) ;
189- }
190-
19155 sealed class ExportMethodDispatchLocals
19256 {
19357 public static readonly ExportMethodDispatchLocals Empty = new ( new Dictionary < int , int > ( ) , - 1 , null ) ;
@@ -208,7 +72,7 @@ public ExportMethodDispatchLocals (Dictionary<int, int> arrayParameterLocals, in
20872
20973 static ExportMethodDispatchData GetRequiredExportMethodDispatch ( UcoMethodData uco )
21074 {
211- return uco . ExportMethodDispatch ?? throw new InvalidOperationException ( $ "UCO method ' { uco . WrapperName } ' is missing ExportMethodDispatch metadata.") ;
75+ return uco . ExportMethodDispatch ?? throw new InvalidOperationException ( $ "ExportMethodDispatchEmitter only supports UCO methods with ExportMethodDispatch metadata.") ;
21276 }
21377
21478 ExportMethodDispatchLocals CreateExportMethodDispatchLocals ( ExportMethodDispatchData exportMethodDispatch , bool isVoid )
@@ -592,15 +456,6 @@ void AddUnmanagedCallersOnlyAttribute (MethodDefinitionHandle handle)
592456 _pe . Metadata . AddCustomAttribute ( handle , _context . UcoAttrCtorRef , _context . UcoAttrBlobHandle ) ;
593457 }
594458
595- static void EncodeGenericValueTypeInst ( BlobBuilder builder , EntityHandle openType , EntityHandle valueTypeArg )
596- {
597- builder . WriteByte ( 0x15 ) ;
598- builder . WriteByte ( 0x11 ) ;
599- builder . WriteCompressedInteger ( CodedIndex . TypeDefOrRefOrSpec ( openType ) ) ;
600- builder . WriteCompressedInteger ( 1 ) ;
601- builder . WriteByte ( 0x11 ) ;
602- builder . WriteCompressedInteger ( CodedIndex . TypeDefOrRefOrSpec ( valueTypeArg ) ) ;
603- }
604459}
605460
606461sealed class ExportMethodDispatchEmitterContext
0 commit comments