- /* bytes = vtable->klass->instance_size */
- mono_mb_emit_ldarg (mb, 0);
- mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoVTable, klass));
- mono_mb_emit_byte (mb, MONO_CEE_ADD);
- mono_mb_emit_byte (mb, MONO_CEE_LDIND_I);
- mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoClass, instance_size));
- mono_mb_emit_byte (mb, MONO_CEE_ADD);
- /* FIXME: assert instance_size stays a 4 byte integer */
- mono_mb_emit_byte (mb, MONO_CEE_LDIND_U4);
- mono_mb_emit_stloc (mb, bytes_var);
+ if (atype == ATYPE_STRING) {
+ /* a string alloator method takes the args: (vtable, len) */
+ /* bytes = (sizeof (MonoString) + ((len + 1) * 2)); */
+ mono_mb_emit_ldarg (mb, 1);
+ mono_mb_emit_icon (mb, 1);
+ mono_mb_emit_byte (mb, MONO_CEE_ADD);
+ mono_mb_emit_icon (mb, 1);
+ mono_mb_emit_byte (mb, MONO_CEE_SHL);
+ // sizeof (MonoString) might include padding
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoString, chars));
+ mono_mb_emit_byte (mb, MONO_CEE_ADD);
+ mono_mb_emit_stloc (mb, bytes_var);
+ } else {
+ /* bytes = vtable->klass->instance_size */
+ mono_mb_emit_ldarg (mb, 0);
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoVTable, klass));
+ mono_mb_emit_byte (mb, MONO_CEE_ADD);
+ mono_mb_emit_byte (mb, MONO_CEE_LDIND_I);
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoClass, instance_size));
+ mono_mb_emit_byte (mb, MONO_CEE_ADD);
+ /* FIXME: assert instance_size stays a 4 byte integer */
+ mono_mb_emit_byte (mb, MONO_CEE_LDIND_U4);
+ mono_mb_emit_stloc (mb, bytes_var);
+ }