<?xml version="1.0" encoding="us-ascii"?> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>mono-api-dynamic-codegen.html</title> <style type="text/css"> .mapi-docs { line-height: 1.5; padding-left: 2em; padding-right: 2em; } .mapi-docs p { max-width: 60em; } .mapi-docs .mapi-body { max-width: 60em; } .mapi-docs code { border: 1px solid rgba(214,214,214,1); background-color: rgba(249,249,249,1); padding: 0.1em 0.5em; } .mapi-description code { font-family: "Consolas", "Courier", monospace; border: 1px solid rgba(214,214,214,1); background-color: rgba(249,249,249,1); padding: 0.1em 0.2em; } .mapi-header { padding: 0 0 5pt 5pt; margin: 10pt; white-space: pre; font-family: monospace; border: 1px solid rgba(233,233,233,1); background-color: rgba(249,249,249,1); } .mapi-code { padding: 5pt 5pt; margin: 10pt; white-space: pre; font-family: monospace; border: 1px solid rgba(233,233,233,1); background-color: rgba(249,249,249,1); } .mapi-code:first-line { line-height: 0px; } .mapi-codeblock { display: block; padding: 5pt 5pt; margin: 10pt; white-space: pre; font-family: monospace; border: 1px solid rgba(233,233,233,1); background-color: rgba(249,249,249,1); } .mapi-entry code { border: none; background-color: transparent; } .mapi-parameters { border-collapse: collapse; border-spacing: 0; empty-cells: hide; border: 0; margin: 5px 0 26px; } .mapi-parameters td { border: 1px solid rgba(214,214,214,1); border-left-style: none; padding: 5px 25px 5px 10px; } .mapi-parameters tr>td:last-child { border-right: 0; } .mapi-parameters td:first-of-type { text-align: right; padding: 7px; vertical-align: top; word-break: normal; width: 40px; } .mapi-parameters tr:last-child>td { border-bottom: 0; } .mapi-parameters tr:first-child>td { border-top: 0; } .mapi-parameters tr td:first-of-type { text-align: right; padding: 7px; vertical-align: top; word-break: normal; width: 40px; } .mapi { left: -25px; margin: 0; padding: 13px 25px 0; position: relative; width: 100%; } .mapi-description { background: rgba(249,249,249,1); border-bottom: 1px solid rgba(233,233,233,1); left: -25px; margin: 0; padding: 13px 25px 0; position: relative; width: 100%; } .mapi-entry { background: transparent; } .mapi-docs { } .mapi-prototype { border-left: 5px solid rgba(205,233,244,1); padding: .5em; margin-top: 5pt; margin-bottom: 5pt; font-family: "Consolas", "Courier", monospace; display: block; overflow: auto; background-color: #f9f9f9; } .mapi-declaration { margin-top: 21px; } .mapi-section { font-size: smaller; font-weight: bold; margin-top: 21px; line-height: 1.5; } .mapi-strike { text-decoration: line-through; } .mapi-deprecated { color: red; } .mapi-ptr-container { background: white; border-bottom: 1px solid rgba(233,233,233,1); left: -25px; padding-left: 25px; padding-right: 25px; padding-bottom: 13px; position: relative; width: 100%; } .mapi-ptr { background: rgba(249,249,249,1); border-left: 1px solid rgba(233,233,233,1); border-top: 1px solid rgba(233,233,233,1); height: 12px; left: 37px; top: -7px; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); position: absolute; width: 12px; } .mapi-height-container { left: -25px; padding: 0 25px; position: relative; width: 100%; } </style> </head> <body> <div class="mapi-docs"> <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. </li></li></li></li></li></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> <a name="api:mono_mb_new"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_new</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">MonoMethodBuilder* mono_mb_new (MonoClass *klass, const char *name, MonoWrapperType type) </div> <p /> </div><!--mapi-description --> </div><!--height container --> <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. </div> <!-- class=mapi --> <a name="api:mono_mb_emit_add_to_local"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_add_to_local</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_add_to_local (MonoMethodBuilder *mb, guint16 local, gint32 incr) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_branch"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_branch</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">guint32 mono_mb_emit_branch (MonoMethodBuilder *mb, guint8 op) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_byte"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_byte</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_byte (MonoMethodBuilder *mb, guint8 op) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_exception"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_exception</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_exception (MonoMethodBuilder *mb, const char *exc_name, const char *msg) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_i2"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_i2</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_i2 (MonoMethodBuilder *mb, gint16 data) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_i4"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_i4</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_i4 (MonoMethodBuilder *mb, gint32 data) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_icon"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_icon</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_icon (MonoMethodBuilder *mb, gint32 value) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_ldarg_addr"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_ldarg_addr</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_ldarg_addr (MonoMethodBuilder *mb, guint argnum) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_ldarg"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_ldarg</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_ldarg (MonoMethodBuilder *mb, guint argnum) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_ldflda"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_ldflda</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_ldflda (MonoMethodBuilder *mb, gint32 offset) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_ldloc_addr"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_ldloc_addr</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_ldloc_addr (MonoMethodBuilder *mb, guint locnum) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_ldloc"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_ldloc</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_ldloc (MonoMethodBuilder *mb, guint num) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_ldstr"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_ldstr</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_ldstr (MonoMethodBuilder *mb, char *str) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_managed_call"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_managed_call</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_managed_call (MonoMethodBuilder *mb, MonoMethod *method, MonoMethodSignature *opt_sig) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_native_call"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_native_call</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_native_call (MonoMethodBuilder *mb, MonoMethodSignature *sig, gpointer func) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_emit_stloc"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_emit_stloc</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_emit_stloc (MonoMethodBuilder *mb, guint num) </div> <p /> </div><!--mapi-description --> </div><!--height container --> <h3>Local variables and Methods</h3> </div> <!-- class=mapi --> <a name="api:mono_mb_create_method"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_create_method</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">MonoMethod* mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack) </div> <p /> <div class="mapi-section">Return value</div> <div> the newly created method. </div> <div class="mapi-section">Description</div> <div> Create a <code>MonoMethod</code> from this method builder.</div> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_add_data"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_add_data</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">guint32 mono_mb_add_data (MonoMethodBuilder *mb, gpointer data) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_add_local"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_add_local</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">int mono_mb_add_local (MonoMethodBuilder *mb, MonoType *type) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_free"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_free</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_free (MonoMethodBuilder *mb) </div> <p /> </div><!--mapi-description --> </div><!--height container --> <h3>Patching Addresses</h3> </div> <!-- class=mapi --> <a name="api:mono_mb_patch_addr"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_patch_addr</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_patch_addr (MonoMethodBuilder *mb, int pos, int value) </div> <p /> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_mb_patch_addr_s"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_mb_patch_addr_s</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">void mono_mb_patch_addr_s (MonoMethodBuilder *mb, int pos, gint8 value) </div> <p /> </div><!--mapi-description --> </div><!--height container --> <h3>Method Signatures</h3> </div> <!-- class=mapi --> <a name="api:mono_metadata_signature_alloc"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_metadata_signature_alloc</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">MonoMethodSignature* mono_metadata_signature_alloc (MonoImage *m, guint32 nparams) </div> <p /> <div class="mapi-section">Parameters</div> <table class="mapi-parameters"><tbody><tr><td><i>image</i></td><td> metadata context</td></tr><tr><td><i>nparams</i></td><td> number of parameters in the signature</td></tr></tbody></table> <div class="mapi-section">Return value</div> <div> the new <code>MonoMethodSignature</code> structure. </div> <div class="mapi-section">Description</div> <div> <p /> Allocate a <code>MonoMethodSignature</code> 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. <p /> LOCKING: Assumes the loader lock is held. <p /></div> </div><!--mapi-description --> </div><!--height container --> </div> <!-- class=mapi --> <a name="api:mono_metadata_signature_dup"></a> <div class="mapi"> <div class="mapi-entry "><code>mono_metadata_signature_dup</code></div> <div class="mapi-height-container"> <div class="mapi-ptr-container"></div> <div class="mapi-description"> <div class="mapi-ptr"></div> <div class="mapi-declaration mapi-section">Syntax</div> <div class="mapi-prototype">MonoMethodSignature* mono_metadata_signature_dup (MonoMethodSignature *sig) </div> <p /> <div class="mapi-section">Parameters</div> <table class="mapi-parameters"><tbody><tr><td><i>sig</i></td><td> method signature</td></tr></tbody></table> <div class="mapi-section">Return value</div> <div> the new <code>MonoMethodSignature</code> structure. </div> <div class="mapi-section">Description</div> <div> <p /> Duplicate an existing <code>MonoMethodSignature</code> so it can be modified. This is a Mono runtime internal function. <p /></div> </div><!--mapi-description --> </div><!--height container -->