@@ -470,10 +470,54 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
470
470
return start ;
471
471
}
472
472
473
+ /**
474
+ *
475
+ * @brief Architecture-specific delegation virtual trampoline processing
476
+ *
477
+ * @param[in] @sig - Method signature
478
+ * @param[in] @method - Method
479
+ * @param[in] @offset - Offset into vtable
480
+ * @param[in] @load_imt_reg - Whether to load the LMT register
481
+ * @returns Trampoline
482
+ *
483
+ * Return a pointer to a delegation virtual trampoline
484
+ */
485
+
473
486
gpointer
474
487
mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature * sig , MonoMethod * method , int offset , gboolean load_imt_reg )
475
488
{
476
- return NULL ;
489
+ guint8 * code , * start ;
490
+ int size = 32 ;
491
+
492
+ start = code = (guint8 * ) mono_global_codeman_reserve (size );
493
+
494
+ /*
495
+ * Replace the "this" argument with the target
496
+ */
497
+ ppc_mr (code , ppc_r12 , ppc_r3 );
498
+ ppc_ldptr (code , ppc_r3 , MONO_STRUCT_OFFSET (MonoDelegate , target ), ppc_r12 );
499
+
500
+ /*
501
+ * Load the IMT register, if needed
502
+ */
503
+ if (load_imt_reg ) {
504
+ ppc_ldptr (code , MONO_ARCH_IMT_REG , MONO_STRUCT_OFFSET (MonoDelegate , method ), ppc_r12 );
505
+ }
506
+
507
+ /*
508
+ * Load the vTable
509
+ */
510
+ ppc_ldptr (code , ppc_r12 , MONO_STRUCT_OFFSET (MonoObject , vtable ), ppc_r3 );
511
+ if (!ppc_is_imm16 (offset ))
512
+ ppc_addis (code , ppc_r12 , ppc_r12 , ppc_ha (offset ));
513
+ ppc_ldptr (code , ppc_r12 , offset , ppc_r12 );
514
+ ppc_mtctr (code , ppc_r12 );
515
+ ppc_bcctr (code , PPC_BR_ALWAYS , 0 );
516
+
517
+ mono_arch_flush_icache (start , code - start );
518
+ MONO_PROFILER_RAISE (jit_code_buffer , (start , code - start , MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE , NULL ));
519
+
520
+ return (start );
477
521
}
478
522
479
523
gpointer
0 commit comments