1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
<h2>Internal: Dynamic Code Generation</h2>
<p>The dynamic code generation interface inside the Mono
runtime is similar to the API exposed by
System.Reflection.Emit.
<p>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.
<p>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.
<p>To JIT this method, the process is this:
<ul>
<li>Create a <tt>MonoMethodBuilder</tt> object using
the <tt>mono_mb_new</tt> method. The method's class
is specified as the first argument.
<li>Create the method signature, using
<tt>mono_metadata_signature_alloc</tt>. The call
takes the number of arguments that the method takes.
Then you must initialize the types for each one of the
parameters.
<li>Emit the CIL code, using one of the
<tt>mono_mb_emit_*</tt> functions. There are some
helper routines that you can use.
<li>Create the <tt>MonoMethod</tt> from the
<tt>MethodBuilder</tt> using
<tt>mono_mb_create_method</tt>.
<li>Release the <tt>MonoMethodBuilder</tt> resources
using mono_mb_free.
</ul>
<p>The result of this process is a <tt>MonoMethod</tt> which
can be called using <tt><a
href="api:mono_create_jit_trampoline">mono_create_jit_trampoline</a></tt>
routine or can be passed to any other functions that require
the MonoMethod.
<p>Example:
<pre>
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;
}
</pre>
<h4><a name="api:mono_mb_new">mono_mb_new</a></h4>
<p>The possible values for the <i>type</i> argument are:
<pre>
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
</pre>
<h3>Emitting IL</h3>
<p>Functions that can be used to generate IL on the flight,
similar in spirit to System.Reflection.Emit.ILGenerator.
<h4><a name="api:mono_mb_emit_add_to_local">mono_mb_emit_add_to_local</a></h4>
<h4><a name="api:mono_mb_emit_branch">mono_mb_emit_branch</a></h4>
<h4><a name="api:mono_mb_emit_byte">mono_mb_emit_byte</a></h4>
<h4><a name="api:mono_mb_emit_exception">mono_mb_emit_exception</a></h4>
<h4><a name="api:mono_mb_emit_i2">mono_mb_emit_i2</a></h4>
<h4><a name="api:mono_mb_emit_i4">mono_mb_emit_i4</a></h4>
<h4><a name="api:mono_mb_emit_icon">mono_mb_emit_icon</a></h4>
<h4><a name="api:mono_mb_emit_ldarg_addr">mono_mb_emit_ldarg_addr</a></h4>
<h4><a name="api:mono_mb_emit_ldarg">mono_mb_emit_ldarg</a></h4>
<h4><a name="api:mono_mb_emit_ldflda">mono_mb_emit_ldflda</a></h4>
<h4><a name="api:mono_mb_emit_ldloc_addr">mono_mb_emit_ldloc_addr</a></h4>
<h4><a name="api:mono_mb_emit_ldloc">mono_mb_emit_ldloc</a></h4>
<h4><a name="api:mono_mb_emit_ldstr">mono_mb_emit_ldstr</a></h4>
<h4><a name="api:mono_mb_emit_managed_call">mono_mb_emit_managed_call</a></h4>
<h4><a name="api:mono_mb_emit_native_call">mono_mb_emit_native_call</a></h4>
<h4><a name="api:mono_mb_emit_stloc">mono_mb_emit_stloc</a></h4>
<h3>Local variables and Methods</h3>
<h4><a name="api:mono_mb_create_method">mono_mb_create_method</a></h4>
<h4><a name="api:mono_mb_add_data">mono_mb_add_data</a></h4>
<h4><a name="api:mono_mb_add_local">mono_mb_add_local</a></h4>
<h4><a name="api:mono_mb_free">mono_mb_free</a></h4>
<h3>Patching Addresses</h3>
<h4><a name="api:mono_mb_patch_addr">mono_mb_patch_addr</a></h4>
<h4><a name="api:mono_mb_patch_addr_s">mono_mb_patch_addr_s</a></h4>
<h3>Method Signatures</h3>
<h4><a name="api:mono_metadata_signature_alloc">mono_metadata_signature_alloc</a></h4>
<h4><a name="api:mono_metadata_signature_dup">mono_metadata_signature_dup</a></h4>
<h4><a name="api:mono_metadata_signature_equal">mono_metadata_signature_equal</a></h4>
|