@@ -1187,8 +1187,30 @@ get_wrapper_shared_vtype (MonoType *t)
11871187 if (mono_class_has_failure (klass ))
11881188 return NULL ;
11891189
1190- if (m_class_get_type_token (klass ) && mono_metadata_packing_from_typedef (m_class_get_image (klass ), m_class_get_type_token (klass ), NULL , NULL ))
1191- return NULL ;
1190+ guint32 packing , packing_size ;
1191+ gboolean has_explicit_size = FALSE;
1192+ if (m_class_get_type_token (klass ) && mono_metadata_packing_from_typedef (m_class_get_image (klass ), m_class_get_type_token (klass ), & packing , & packing_size )) {
1193+ // FIXME: Support other sizes
1194+ if (packing == 0 && (packing_size == 8 || packing_size == 16 )) {
1195+ has_explicit_size = TRUE;
1196+ switch (packing_size ) {
1197+ case 8 :
1198+ findex = 1 ;
1199+ args [0 ] = m_class_get_byval_arg (mono_get_int64_class ());
1200+ break ;
1201+ case 16 :
1202+ findex = 2 ;
1203+ args [0 ] = m_class_get_byval_arg (mono_get_int64_class ());
1204+ args [1 ] = m_class_get_byval_arg (mono_get_int64_class ());
1205+ break ;
1206+ default :
1207+ g_assert_not_reached ();
1208+ break ;
1209+ }
1210+ } else {
1211+ return NULL ;
1212+ }
1213+ }
11921214
11931215 gpointer iter = NULL ;
11941216 MonoClassField * field ;
@@ -1199,20 +1221,21 @@ get_wrapper_shared_vtype (MonoType *t)
11991221 if (m_class_is_byreflike (mono_class_from_mono_type_internal (ftype )))
12001222 /* Cannot inflate generic params with byreflike types */
12011223 return NULL ;
1202- args [findex ++ ] = ftype ;
1203- if (findex >= 16 )
1204- break ;
1224+ if (!has_explicit_size ) {
1225+ args [findex ++ ] = ftype ;
1226+ if (findex >= 16 )
1227+ break ;
1228+ }
12051229#ifdef TARGET_WASM
12061230 if (ftype -> type == MONO_TYPE_R4 || ftype -> type == MONO_TYPE_R8 || MONO_TYPE_ISSTRUCT (ftype ))
12071231 has_fp = TRUE;
12081232#endif
12091233 }
12101234
12111235#ifdef TARGET_WASM
1212- if (!has_fp ) {
1236+ if (!has_explicit_size && ! has_fp ) {
12131237 guint32 align ;
12141238 int size = mono_class_value_size (klass , & align );
1215-
12161239 /* Other platforms might pass small valuetypes or valuetypes with non-int fields differently */
12171240 if (align == 4 && size <= 4 * 5 ) {
12181241 findex = size / align ;
0 commit comments