diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index a6ee9e1f3eeaf5..686dd4c14a85e9 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -6515,6 +6515,19 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; ip += 6; MINT_IN_BREAK; } + MINT_IN_CASE(MINT_STELEM_VT_NOREF) { + MonoArray *o = LOCAL_VAR (ip [1], MonoArray*); + NULL_CHECK (o); + guint32 aindex = LOCAL_VAR (ip [2], guint32); + if (aindex >= mono_array_length_internal (o)) + THROW_EX (interp_get_exception_index_out_of_range (frame, ip), ip); + + guint16 size = ip [5]; + char *dst_addr = mono_array_addr_with_size_fast ((MonoArray *) o, size, aindex); + memcpy (dst_addr, locals + ip [3], size); + ip += 6; + MINT_IN_BREAK; + } MINT_IN_CASE(MINT_CONV_OVF_I4_U4) { gint32 val = LOCAL_VAR (ip [2], gint32); if (val < 0) diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index c2b4a581d7fee2..dba7cd29b8325b 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -419,6 +419,7 @@ OPDEF(MINT_STELEM_R4, "stelem.r4", 4, 0, 3, MintOpNoArgs) OPDEF(MINT_STELEM_R8, "stelem.r8", 4, 0, 3, MintOpNoArgs) OPDEF(MINT_STELEM_REF, "stelem.ref", 4, 0, 3, MintOpNoArgs) OPDEF(MINT_STELEM_VT, "stelem.vt", 6, 0, 3, MintOpTwoShorts) +OPDEF(MINT_STELEM_VT_NOREF, "stelem.vt.noref", 6, 0, 3, MintOpTwoShorts) OPDEF(MINT_LDLEN, "ldlen", 3, 1, 1, MintOpNoArgs) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index e3f938a108f808..bfa21c2d8e355e 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -7080,7 +7080,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, int size = mono_class_value_size (klass, NULL); g_assert (size < G_MAXUINT16); - handle_stelem (td, MINT_STELEM_VT); + handle_stelem (td, m_class_has_references (klass) ? MINT_STELEM_VT : MINT_STELEM_VT_NOREF); td->last_ins->data [0] = get_data_item_index (td, klass); td->last_ins->data [1] = GINT_TO_UINT16 (size); break; diff --git a/src/mono/wasm/runtime/jiterpreter-trace-generator.ts b/src/mono/wasm/runtime/jiterpreter-trace-generator.ts index a8ea1466f5bbb4..81c664443c9629 100644 --- a/src/mono/wasm/runtime/jiterpreter-trace-generator.ts +++ b/src/mono/wasm/runtime/jiterpreter-trace-generator.ts @@ -3260,6 +3260,15 @@ function emit_arrayop(builder: WasmBuilder, frame: NativePointer, ip: MintOpcode builder.callImport("value_copy"); return true; } + case MintOpcode.MINT_STELEM_VT_NOREF: { + const elementSize = getArgU16(ip, 5); + // dest + append_getelema1(builder, ip, objectOffset, indexOffset, elementSize); + // src + append_ldloca(builder, valueOffset, 0); + append_memmove_dest_src(builder, elementSize); + return true; + } default: return false; }