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:
- Create a MonoMethodBuilder object using
the mono_mb_new method. The method's class
is specified as the first argument.
- Create the method signature, using
mono_metadata_signature_alloc. The call
takes the number of arguments that the method takes.
Then you must initialize the types for each one of the
parameters.
- Emit the CIL code, using one of the
mono_mb_emit_* functions. There are some
helper routines that you can use.
- Create the MonoMethod from the
MethodBuilder using
mono_mb_create_method.
- Release the MonoMethodBuilder resources
using mono_mb_free.
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
Syntax
MonoMethodBuilder*
mono_mb_new (MonoClass *klass, const char *name, MonoWrapperType type)
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
Syntax
void
mono_mb_emit_add_to_local (MonoMethodBuilder *mb, guint16 local, gint32 incr)
mono_mb_emit_branch
Syntax
guint32
mono_mb_emit_branch (MonoMethodBuilder *mb, guint8 op)
mono_mb_emit_byte
Syntax
void
mono_mb_emit_byte (MonoMethodBuilder *mb, guint8 op)
mono_mb_emit_exception
Syntax
void
mono_mb_emit_exception (MonoMethodBuilder *mb, const char *exc_name, const char *msg)
mono_mb_emit_i2
Syntax
void
mono_mb_emit_i2 (MonoMethodBuilder *mb, gint16 data)
mono_mb_emit_i4
Syntax
void
mono_mb_emit_i4 (MonoMethodBuilder *mb, gint32 data)
mono_mb_emit_icon
Syntax
void
mono_mb_emit_icon (MonoMethodBuilder *mb, gint32 value)
mono_mb_emit_ldarg_addr
Syntax
void
mono_mb_emit_ldarg_addr (MonoMethodBuilder *mb, guint argnum)
mono_mb_emit_ldarg
Syntax
void
mono_mb_emit_ldarg (MonoMethodBuilder *mb, guint argnum)
mono_mb_emit_ldflda
Syntax
void
mono_mb_emit_ldflda (MonoMethodBuilder *mb, gint32 offset)
mono_mb_emit_ldloc_addr
Syntax
void
mono_mb_emit_ldloc_addr (MonoMethodBuilder *mb, guint locnum)
mono_mb_emit_ldloc
Syntax
void
mono_mb_emit_ldloc (MonoMethodBuilder *mb, guint num)
mono_mb_emit_ldstr
Syntax
void
mono_mb_emit_ldstr (MonoMethodBuilder *mb, char *str)
mono_mb_emit_managed_call
Syntax
void
mono_mb_emit_managed_call (MonoMethodBuilder *mb, MonoMethod *method, MonoMethodSignature *opt_sig)
mono_mb_emit_native_call
Syntax
void
mono_mb_emit_native_call (MonoMethodBuilder *mb, MonoMethodSignature *sig, gpointer func)
mono_mb_emit_stloc
Syntax
void
mono_mb_emit_stloc (MonoMethodBuilder *mb, guint num)
Local variables and Methods
mono_mb_create_method
Syntax
MonoMethod*
mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack)
Return value
the newly created method.
Description
Create a MonoMethod
from this method builder.
mono_mb_add_data
Syntax
guint32
mono_mb_add_data (MonoMethodBuilder *mb, gpointer data)
mono_mb_add_local
Syntax
int
mono_mb_add_local (MonoMethodBuilder *mb, MonoType *type)
mono_mb_free
Syntax
void
mono_mb_free (MonoMethodBuilder *mb)
Patching Addresses
mono_mb_patch_addr
Syntax
void
mono_mb_patch_addr (MonoMethodBuilder *mb, int pos, int value)
mono_mb_patch_addr_s
Syntax
void
mono_mb_patch_addr_s (MonoMethodBuilder *mb, int pos, gint8 value)
Method Signatures
mono_metadata_signature_alloc
Syntax
MonoMethodSignature*
mono_metadata_signature_alloc (MonoImage *m, guint32 nparams)
Parameters
image | metadata context |
nparams | number of parameters in the signature |
Return value
the new MonoMethodSignature
structure.
Description
Allocate a
MonoMethodSignature
structure with the specified number of params.
The return type and the params types need to be filled later.
This is a Mono runtime internal function.
LOCKING: Assumes the loader lock is held.
mono_metadata_signature_dup
Syntax
MonoMethodSignature*
mono_metadata_signature_dup (MonoMethodSignature *sig)
Parameters
Return value
the new MonoMethodSignature
structure.
Description
Duplicate an existing
MonoMethodSignature
so it can be modified.
This is a Mono runtime internal function.