@@ -162,7 +162,7 @@ where type.CustomAttributes.Any(ca => ca.AttributeType == hotfixDelegateAttribut
162
162
{
163
163
if ( method . Name != ".cctor" )
164
164
{
165
- if ( method . HasGenericParameters ? ! InjectGenericMethod ( assembly , method , hotfixType , stateTable ) :
165
+ if ( ( method . HasGenericParameters || method . ContainsGenericParameter ) ? ! InjectGenericMethod ( assembly , method , hotfixType , stateTable ) :
166
166
! InjectMethod ( assembly , method , hotfixType , stateTable ) )
167
167
{
168
168
return ;
@@ -205,10 +205,7 @@ static bool InjectMethod(AssemblyDefinition assembly, MethodDefinition method, i
205
205
Debug . LogError ( "too many overload!" ) ;
206
206
return false ;
207
207
}
208
- if ( method . HasGenericParameters )
209
- {
210
- return true ;
211
- }
208
+
212
209
TypeReference delegateType = null ;
213
210
MethodReference invoke = null ;
214
211
@@ -227,21 +224,22 @@ static bool InjectMethod(AssemblyDefinition assembly, MethodDefinition method, i
227
224
FieldDefinition fieldDefinition = new FieldDefinition ( luaDelegateName , Mono . Cecil . FieldAttributes . Static | Mono . Cecil . FieldAttributes . Private ,
228
225
delegateType ) ;
229
226
type . Fields . Add ( fieldDefinition ) ;
227
+ FieldReference fieldReference = fieldDefinition . GetGeneric ( ) ;
230
228
231
229
bool statefulConstructor = ( hotfixType == 1 ) && method . IsConstructor && ! method . IsStatic ;
232
230
233
231
234
- var firstIns = method . Body . Instructions [ 0 ] ;
232
+ var firstIns = method . IsConstructor ? method . Body . Instructions [ 2 ] : method . Body . Instructions [ 0 ] ;
235
233
var processor = method . Body . GetILProcessor ( ) ;
236
234
237
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
235
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
238
236
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Brfalse , firstIns ) ) ;
239
237
240
238
if ( statefulConstructor )
241
239
{
242
240
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldarg_0 ) ) ;
243
241
}
244
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
242
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
245
243
for ( int i = 0 ; i < param_count ; i ++ )
246
244
{
247
245
if ( i < ldargs . Length )
@@ -280,18 +278,49 @@ static MethodReference MakeGenericMethod(this MethodReference self, params TypeR
280
278
return instance ;
281
279
}
282
280
281
+ static FieldReference GetGeneric ( this FieldDefinition definition )
282
+ {
283
+ if ( definition . DeclaringType . HasGenericParameters )
284
+ {
285
+ var declaringType = new GenericInstanceType ( definition . DeclaringType ) ;
286
+ foreach ( var parameter in definition . DeclaringType . GenericParameters )
287
+ {
288
+ declaringType . GenericArguments . Add ( parameter ) ;
289
+ }
290
+ return new FieldReference ( definition . Name , definition . FieldType , declaringType ) ;
291
+ }
292
+
293
+ return definition ;
294
+ }
295
+
296
+ public static TypeReference GetGeneric ( this TypeDefinition definition )
297
+ {
298
+ if ( definition . HasGenericParameters )
299
+ {
300
+ var genericInstanceType = new GenericInstanceType ( definition ) ;
301
+ foreach ( var parameter in definition . GenericParameters )
302
+ {
303
+ genericInstanceType . GenericArguments . Add ( parameter ) ;
304
+ }
305
+ return genericInstanceType ;
306
+ }
307
+
308
+ return definition ;
309
+ }
310
+
283
311
static bool InjectGenericMethod ( AssemblyDefinition assembly , MethodDefinition method , int hotfixType , FieldDefinition stateTable )
284
312
{
285
313
string fieldName = method . Name ;
286
314
if ( fieldName . StartsWith ( "." ) )
287
315
{
288
316
fieldName = fieldName . Substring ( 1 ) ;
289
317
}
318
+ string ccFlag = method . IsConstructor ? "_c" : "" ;
290
319
string luaDelegateName = null ;
291
320
var type = method . DeclaringType ;
292
321
for ( int i = 0 ; i < MAX_OVERLOAD ; i ++ )
293
322
{
294
- string tmp = "__Hitfix" + i + "_" + fieldName ;
323
+ string tmp = ccFlag + "__Hitfix" + i + "_" + fieldName ;
295
324
if ( ! type . Fields . Any ( f => f . Name == tmp ) ) // injected
296
325
{
297
326
luaDelegateName = tmp ;
@@ -308,35 +337,41 @@ static bool InjectGenericMethod(AssemblyDefinition assembly, MethodDefinition me
308
337
luaFunctionType ) ;
309
338
type . Fields . Add ( fieldDefinition ) ;
310
339
340
+ FieldReference fieldReference = fieldDefinition . GetGeneric ( ) ;
341
+
311
342
int param_start = method . IsStatic ? 0 : 1 ;
312
343
int param_count = method . Parameters . Count + param_start ;
313
- var firstIns = method . Body . Instructions [ 0 ] ;
344
+ var firstIns = method . IsConstructor ? method . Body . Instructions [ 2 ] : method . Body . Instructions [ 0 ] ;
314
345
var processor = method . Body . GetILProcessor ( ) ;
315
346
316
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
347
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
317
348
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Brfalse , firstIns ) ) ;
318
349
319
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
350
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
320
351
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Callvirt , invokeSessionStart ) ) ;
321
352
322
- bool isVoid = method . ReturnType . FullName == "System.Void" ;
353
+ bool statefulConstructor = ( hotfixType == 1 ) && method . IsConstructor && ! method . IsStatic ;
354
+
355
+ TypeReference returnType = statefulConstructor ? luaTableType : method . ReturnType ;
356
+
357
+ bool isVoid = returnType . FullName == "System.Void" ;
323
358
324
359
int outCout = 0 ;
325
360
326
361
for ( int i = 0 ; i < param_count ; i ++ )
327
362
{
328
363
if ( i == 0 && ! method . IsStatic )
329
364
{
330
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
365
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
331
366
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldarg_0 ) ) ;
332
- if ( hotfixType == 1 )
367
+ if ( hotfixType == 1 && ! method . IsConstructor )
333
368
{
334
369
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldfld , stateTable ) ) ;
335
370
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Callvirt , MakeGenericMethod ( inParam , luaTableType ) ) ) ;
336
371
}
337
372
else
338
373
{
339
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Callvirt , MakeGenericMethod ( inParam , method . DeclaringType ) ) ) ;
374
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Callvirt , MakeGenericMethod ( inParam , method . DeclaringType . GetGeneric ( ) ) ) ) ;
340
375
}
341
376
}
342
377
else
@@ -348,7 +383,7 @@ static bool InjectGenericMethod(AssemblyDefinition assembly, MethodDefinition me
348
383
}
349
384
if ( ! param . IsOut )
350
385
{
351
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
386
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
352
387
353
388
if ( i < ldargs . Length )
354
389
{
@@ -387,7 +422,7 @@ static bool InjectGenericMethod(AssemblyDefinition assembly, MethodDefinition me
387
422
388
423
int outStart = ( isVoid ? 0 : 1 ) ;
389
424
390
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
425
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
391
426
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldc_I4 , outCout + outStart ) ) ;
392
427
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Callvirt , functionInvoke ) ) ;
393
428
@@ -396,7 +431,7 @@ static bool InjectGenericMethod(AssemblyDefinition assembly, MethodDefinition me
396
431
{
397
432
if ( method . Parameters [ i ] . ParameterType . IsByReference )
398
433
{
399
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
434
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
400
435
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldc_I4 , outPos ) ) ;
401
436
int arg_pos = param_start + i ;
402
437
if ( arg_pos < ldargs . Length )
@@ -412,17 +447,23 @@ static bool InjectGenericMethod(AssemblyDefinition assembly, MethodDefinition me
412
447
outPos ++ ;
413
448
}
414
449
}
415
-
416
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldDefinition ) ) ;
450
+ if ( statefulConstructor )
451
+ {
452
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldarg_0 ) ) ;
453
+ }
454
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ldsfld , fieldReference ) ) ;
417
455
if ( isVoid )
418
456
{
419
457
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Callvirt , invokeSessionEnd ) ) ;
420
458
}
421
459
else
422
460
{
423
- processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Callvirt , MakeGenericMethod ( invokeSessionEndWithResult , method . ReturnType ) ) ) ;
461
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Callvirt , MakeGenericMethod ( invokeSessionEndWithResult , returnType ) ) ) ;
462
+ }
463
+ if ( statefulConstructor )
464
+ {
465
+ processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Stfld , stateTable ) ) ;
424
466
}
425
-
426
467
processor . InsertBefore ( firstIns , processor . Create ( OpCodes . Ret ) ) ;
427
468
428
469
return true ;
0 commit comments