@@ -756,6 +756,70 @@ get_virtual_method_fast (InterpMethod *imethod, MonoVTable *vtable, int offset)
756
756
}
757
757
}
758
758
759
+ // Returns the size it uses on the interpreter stack
760
+ static int
761
+ stackval_size (MonoType * type , gboolean pinvoke )
762
+ {
763
+ type = mini_native_type_replace_type (type );
764
+ if (m_type_is_byref (type ))
765
+ return MINT_STACK_SLOT_SIZE ;
766
+ switch (type -> type ) {
767
+ case MONO_TYPE_VOID :
768
+ return 0 ;
769
+ case MONO_TYPE_I1 :
770
+ case MONO_TYPE_U1 :
771
+ case MONO_TYPE_BOOLEAN :
772
+ case MONO_TYPE_I2 :
773
+ case MONO_TYPE_U2 :
774
+ case MONO_TYPE_CHAR :
775
+ case MONO_TYPE_I4 :
776
+ case MONO_TYPE_U :
777
+ case MONO_TYPE_I :
778
+ case MONO_TYPE_PTR :
779
+ case MONO_TYPE_FNPTR :
780
+ case MONO_TYPE_U4 :
781
+ return MINT_STACK_SLOT_SIZE ;
782
+ case MONO_TYPE_R4 :
783
+ return MINT_STACK_SLOT_SIZE ;
784
+ case MONO_TYPE_I8 :
785
+ case MONO_TYPE_U8 :
786
+ return MINT_STACK_SLOT_SIZE ;
787
+ case MONO_TYPE_R8 :
788
+ return MINT_STACK_SLOT_SIZE ;
789
+ case MONO_TYPE_STRING :
790
+ case MONO_TYPE_SZARRAY :
791
+ case MONO_TYPE_CLASS :
792
+ case MONO_TYPE_OBJECT :
793
+ case MONO_TYPE_ARRAY :
794
+ return MINT_STACK_SLOT_SIZE ;
795
+ case MONO_TYPE_VALUETYPE :
796
+ if (m_class_is_enumtype (type -> data .klass )) {
797
+ return stackval_size (mono_class_enum_basetype_internal (type -> data .klass ), pinvoke );
798
+ } else {
799
+ int size ;
800
+ if (pinvoke )
801
+ size = mono_class_native_size (type -> data .klass , NULL );
802
+ else
803
+ size = mono_class_value_size (type -> data .klass , NULL );
804
+ return ALIGN_TO (size , MINT_STACK_SLOT_SIZE );
805
+ }
806
+ case MONO_TYPE_GENERICINST : {
807
+ if (mono_type_generic_inst_is_valuetype (type )) {
808
+ MonoClass * klass = mono_class_from_mono_type_internal (type );
809
+ int size ;
810
+ if (pinvoke )
811
+ size = mono_class_native_size (klass , NULL );
812
+ else
813
+ size = mono_class_value_size (klass , NULL );
814
+ return ALIGN_TO (size , MINT_STACK_SLOT_SIZE );
815
+ }
816
+ return stackval_size (m_class_get_byval_arg (type -> data .generic_class -> container_class ), pinvoke );
817
+ }
818
+ default :
819
+ g_error ("got type 0x%02x" , type -> type );
820
+ }
821
+ }
822
+
759
823
// Returns the size it uses on the interpreter stack
760
824
static int
761
825
stackval_from_data (MonoType * type , stackval * result , const void * data , gboolean pinvoke )
@@ -2859,6 +2923,18 @@ interp_get_interp_method (MonoMethod *method, MonoError *error)
2859
2923
return mono_interp_get_imethod (method , error );
2860
2924
}
2861
2925
2926
+ static MonoJitInfo *
2927
+ interp_compile_interp_method (MonoMethod * method , MonoError * error )
2928
+ {
2929
+ InterpMethod * imethod = mono_interp_get_imethod (method , error );
2930
+ return_val_if_nok (error , NULL );
2931
+
2932
+ mono_interp_transform_method (imethod , get_context (), error );
2933
+ return_val_if_nok (error , NULL );
2934
+
2935
+ return imethod -> jinfo ;
2936
+ }
2937
+
2862
2938
static InterpMethod *
2863
2939
lookup_method_pointer (gpointer addr )
2864
2940
{
@@ -7187,6 +7263,112 @@ interp_run_filter (StackFrameInfo *frame, MonoException *ex, int clause_index, g
7187
7263
return retval .data .i ? TRUE : FALSE;
7188
7264
}
7189
7265
7266
+ static gboolean
7267
+ interp_run_finally_with_il_state (gpointer il_state_ptr , int clause_index , gpointer handler_ip , gpointer handler_ip_end )
7268
+ {
7269
+ MonoMethodILState * il_state = (MonoMethodILState * )il_state_ptr ;
7270
+ MonoMethodSignature * sig ;
7271
+ ThreadContext * context = get_context ();
7272
+ stackval * sp , * sp_args ;
7273
+ InterpMethod * imethod ;
7274
+ FrameClauseArgs clause_args ;
7275
+ ERROR_DECL (error );
7276
+
7277
+ // FIXME: Optimize this ? Its only used during EH
7278
+
7279
+ sig = mono_method_signature_internal (il_state -> method );
7280
+ g_assert (sig );
7281
+
7282
+ imethod = mono_interp_get_imethod (il_state -> method , error );
7283
+ mono_error_assert_ok (error );
7284
+
7285
+ sp_args = sp = (stackval * )context - > stack_pointer ;
7286
+
7287
+ int findex = 0 ;
7288
+ if (sig - > hasthis ) {
7289
+ if (il_state - > data [findex ])
7290
+ sp_args -> data .p = * (gpointer * )il_state - > data [findex ];
7291
+ sp_args + + ;
7292
+ findex + + ;
7293
+ }
7294
+
7295
+ for (int i = 0 ; i < sig - > param_count ; ++ i ) {
7296
+ if (il_state - > data [findex ]) {
7297
+ int size = stackval_from_data (sig - > params [i ], sp_args , il_state - > data [findex ], FALSE );
7298
+ sp_args = STACK_ADD_BYTES (sp_args , size );
7299
+ } else {
7300
+ int size = stackval_size (sig - > params [i ], FALSE );
7301
+ sp_args = STACK_ADD_BYTES (sp_args , size );
7302
+ }
7303
+ findex + + ;
7304
+ }
7305
+
7306
+ /* Allocate frame */
7307
+ InterpFrame frame = {0 };
7308
+ frame .imethod = imethod ;
7309
+ frame .stack = sp ;
7310
+ frame .retval = sp ;
7311
+
7312
+ context - > stack_pointer = (guchar * )sp_args ;
7313
+ context - > stack_pointer + = imethod - > alloca_size ;
7314
+
7315
+ MonoMethodHeader * header = mono_method_get_header_internal (il_state - > method , error );
7316
+ mono_error_assert_ok (error );
7317
+
7318
+ /* Init locals */
7319
+ if (header - > num_locals )
7320
+ memset (frame_locals (& frame ) + imethod - > local_offsets [0 ], 0 , imethod -> locals_size );
7321
+ /* Copy locals from il_state */
7322
+ int locals_start = sig -> hasthis + sig - > param_count ;
7323
+ for (int i = 0 ; i < header - > num_locals ; ++ i ) {
7324
+ if (il_state - > data [locals_start + i ])
7325
+ stackval_from_data (header - > locals [i ], (stackval * )(frame_locals (& frame ) + imethod - > local_offsets [i ]), il_state - > data [locals_start + i ], FALSE );
7326
+ }
7327
+
7328
+ memset (& clause_args , 0 , sizeof (FrameClauseArgs ));
7329
+ clause_args .start_with_ip = (const guint16 * )handler_ip ;
7330
+ clause_args .end_at_ip = (const guint16 * )handler_ip_end ;
7331
+ clause_args .exit_clause = clause_index ;
7332
+ clause_args .exec_frame = & frame ;
7333
+
7334
+ // this informs MINT_ENDFINALLY to return to EH
7335
+ * (guint16 * * )(frame_locals (& frame ) + imethod - > clause_data_offsets [clause_index ]) = NULL;
7336
+
7337
+ interp_exec_method (& frame , context , & clause_args );
7338
+
7339
+ /* Write back args */
7340
+ sp_args = sp ;
7341
+ findex = 0 ;
7342
+ if (sig -> hasthis ) {
7343
+ // FIXME: This
7344
+ sp_args ++ ;
7345
+ findex ++ ;
7346
+ }
7347
+ findex = sig -> hasthis ? 1 : 0 ;
7348
+ for (int i = 0 ; i < sig - > param_count ; ++ i ) {
7349
+ if (il_state -> data [findex ]) {
7350
+ int size = stackval_to_data (sig -> params [i ], sp_args , il_state - > data [findex ], FALSE );
7351
+ sp_args = STACK_ADD_BYTES (sp_args , size );
7352
+ } else {
7353
+ int size = stackval_size (sig -> params [i ], FALSE );
7354
+ sp_args = STACK_ADD_BYTES (sp_args , size );
7355
+ }
7356
+ findex ++ ;
7357
+ }
7358
+ /* Write back locals */
7359
+ for (int i = 0 ; i < header - > num_locals ; ++ i ) {
7360
+ if (il_state -> data [locals_start + i ])
7361
+ stackval_to_data (header -> locals [i ], (stackval * )(frame_locals (& frame ) + imethod - > local_offsets [i ]), il_state - > data [locals_start + i ], FALSE );
7362
+ }
7363
+ mono_metadata_free_mh (header );
7364
+
7365
+ // FIXME: Restore stack ?
7366
+ if (context -> has_resume_state )
7367
+ return TRUE;
7368
+ else
7369
+ return FALSE;
7370
+ }
7371
+
7190
7372
typedef struct {
7191
7373
InterpFrame * current ;
7192
7374
} StackIter ;
0 commit comments