2016-08-03 10:59:49 +00:00
|
|
|
<h2>Internal: Dynamic Code Generation</h2>
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|