Internal: Dynamic Code Generation

The dynamic code generation interface inside the Mono runtime is similar to the API exposed by System.Reflection.Emit.

This interface is used by Mono internally to generate code on the flight in a cross-platform fashion. For example, P/Invoke marshalling in Mono is implemented in terms of this interface, but it is also used in various other parts of the runtime.

Unlike Reflection.Emit, the dynamic code generation interface does not start with an assembly builder. The code generation interface starts directly at the method level, which is represented by a pointer to the MonoMethodBuilder structure.

To JIT this method, the process is this:

The result of this process is a MonoMethod which can be called using mono_create_jit_trampoline routine or can be passed to any other functions that require the MonoMethod.

Example:

MonoMethod *adder ()
{
    MonoMethodBuilder *mb;
    MonoMethodSignature *sig;
    MonoMethod *method;
    
    mb = mono_mb_new (mono_defaults.object_class, "adder", MONO_WRAPPER_NONE);

    /* Setup method signature */
    sig = mono_metadata_signature_alloc (2);
    sig->ret = &mono_get_int32_class ()->byval_arg;
    sig->params [0] = &mono_get_int32_class ()->byval_arg;
    sig->params [1] = &mono_defaults.int32_class->byval_arg;

    /* Emit CIL code */
    mono_mb_emit_ldarg (mb, 0);
    mono_mb_emit_ldarg (mb, 1);
    mono_mb_emit_byte (mb, CEE_ADD);
    mono_mb_emit_byte (mb, CEE_RET);

    /* Get the method */
    method = mono_mb_create_method (mb, sig, max_stack);
    
    /* Cleanup */
    mono_mb-free (mb);
    return method;
}
	

mono_mb_new

The possible values for the type argument are:

        MONO_WRAPPER_NONE
        MONO_WRAPPER_DELEGATE_INVOKE
        MONO_WRAPPER_DELEGATE_BEGIN_INVOKE
        MONO_WRAPPER_DELEGATE_END_INVOKE
        MONO_WRAPPER_RUNTIME_INVOKE
        MONO_WRAPPER_NATIVE_TO_MANAGED
        MONO_WRAPPER_MANAGED_TO_NATIVE
        MONO_WRAPPER_REMOTING_INVOKE
        MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK
        MONO_WRAPPER_XDOMAIN_INVOKE
        MONO_WRAPPER_XDOMAIN_DISPATCH
        MONO_WRAPPER_LDFLD
        MONO_WRAPPER_STFLD
        MONO_WRAPPER_LDFLD_REMOTE
        MONO_WRAPPER_STFLD_REMOTE
        MONO_WRAPPER_SYNCHRONIZED
        MONO_WRAPPER_DYNAMIC_METHOD
        MONO_WRAPPER_ISINST
        MONO_WRAPPER_CASTCLASS
        MONO_WRAPPER_PROXY_ISINST
        MONO_WRAPPER_STELEMREF
        MONO_WRAPPER_UNBOX
        MONO_WRAPPER_LDFLDA
        MONO_WRAPPER_UNKNOWN

Emitting IL

Functions that can be used to generate IL on the flight, similar in spirit to System.Reflection.Emit.ILGenerator.

mono_mb_emit_add_to_local

mono_mb_emit_branch

mono_mb_emit_byte

mono_mb_emit_exception

mono_mb_emit_i2

mono_mb_emit_i4

mono_mb_emit_icon

mono_mb_emit_ldarg_addr

mono_mb_emit_ldarg

mono_mb_emit_ldflda

mono_mb_emit_ldloc_addr

mono_mb_emit_ldloc

mono_mb_emit_ldstr

mono_mb_emit_managed_call

mono_mb_emit_native_call

mono_mb_emit_stloc

Local variables and Methods

mono_mb_create_method

mono_mb_add_data

mono_mb_add_local

mono_mb_free

Patching Addresses

mono_mb_patch_addr

mono_mb_patch_addr_s

Method Signatures

mono_metadata_signature_alloc

mono_metadata_signature_dup

mono_metadata_signature_equal