Skip to content

Commit

Permalink
deploy: 356ba87
Browse files Browse the repository at this point in the history
  • Loading branch information
bitwalker committed Apr 29, 2024
1 parent 8954e54 commit cd502fa
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 16 deletions.
15 changes: 8 additions & 7 deletions print.html
Original file line number Diff line number Diff line change
Expand Up @@ -789,26 +789,27 @@ <h2 id="execution-contexts"><a class="header" href="#execution-contexts">Executi
<p>While executing in a user context, we can request to execute some procedures in the root context. This can be done via the <code>syscall</code> instruction. The set of procedures which can be invoked via the <code>syscall</code> instruction is limited by the <a href="user_docs/assembly/execution_contexts.html#kernels">kernel</a> against which a program is compiled. Once the procedure called via <code>syscall</code> returns, the execution moves back to the user context from which it was invoked. The diagram below illustrates this graphically:</p>
<p><img src="user_docs/assembly/../../assets/user_docs/assembly/execution_contexts/context_transitions.png" alt="context transitions" /></p>
<h3 id="procedure-invocation-semantics"><a class="header" href="#procedure-invocation-semantics">Procedure invocation semantics</a></h3>
<p>As mentioned in the <a href="user_docs/assembly/./code_organization.html">previous section</a>, procedures in Miden assembly can be invoked via five different instructions: <code>exec</code>, <code>call</code>, <code>syscall</code>, <code>dynexec</code>, and <code>dyncall</code>. Invocation semantics of <code>call</code>, <code>dyncall</code>, and <code>syscall</code> instructions are basically the same, the only difference being that the <code>syscall</code> instruction can be used only to call kernel's procedures. The <code>exec</code> and <code>dynexec</code> instructions are different, and we explain these differences below.</p>
<p>As mentioned in the <a href="user_docs/assembly/./code_organization.html">previous section</a>, procedures in Miden assembly can be invoked via five different instructions: <code>exec</code>, <code>call</code>, <code>syscall</code>, <code>dynexec</code>, and <code>dyncall</code>. Invocation semantics of <code>call</code>, <code>dyncall</code>, and <code>syscall</code> instructions are basically the same, the only difference being that the <code>syscall</code> instruction can be used only with procedures which are defined in the program's kernel. The <code>exec</code> and <code>dynexec</code> instructions are different, and we explain these differences below.</p>
<h4 id="invoking-via-call-dyncall-and-syscall-instructions"><a class="header" href="#invoking-via-call-dyncall-and-syscall-instructions">Invoking via <code>call</code>, <code>dyncall</code>, and <code>syscall</code> instructions</a></h4>
<p>When a procedure is invoked via a <code>call</code>, <code>dyncall</code> or a <code>syscall</code> instruction, the following happens:</p>
<p>When a procedure is invoked via a <code>call</code>, <code>dyncall</code>, or a <code>syscall</code> instruction, the following happens:</p>
<ul>
<li>Execution moves into a different context. In case of the <code>call</code> and <code>dyncall</code> instructions, a new user context is created. In case of a <code>syscall</code> instruction, the execution moves back into the root context.</li>
<li>All stack items beyond the 16th item get "hidden" from the invoked procedure. That is, from the standpoint of the invoked procedure, the initial stack depth is set to 16.</li>
</ul>
<p>When the called procedure returns, the following happens:</p>
<p>When the callee returns, the following happens:</p>
<ul>
<li>Execution moves back to the context from which the procedure was invoked.</li>
<li>Stack depth is set to its original depth. Before the stack depth is reset, the VM checks if the current stack depth is exactly 16, and fails otherwise.</li>
<li>The execution context of the caller is restored</li>
<li>If the original stack depth was greater than 16, those elements that were "hidden" during the call as described above, are restored. However, the stack depth must be <em>exactly</em> 16 elements when the procedure returns, or this will fail and the VM will trap.</li>
</ul>
<p>The manipulations of the stack depth described above have the following implications:</p>
<ul>
<li>The top 16 elements of the stack can be used to pass parameters and return values between the caller and the callee.</li>
<li>The top 16 elements of the stack can be used to pass parameters and return values between the caller and the callee. NOTE: Except for <code>dyncall</code>, as that instruction requires the first 4 elements to be the hash of the callee procedure, so only 12 elements are available in that case.</li>
<li>Caller's stack beyond the top 16 elements is inaccessible to the callee, and thus, is guaranteed not to change as the result of the call.</li>
<li>At the end of its execution, the callee must ensure that stack depth is exactly 16. If this is difficult to ensure manually, the <a href="user_docs/assembly/../stdlib/sys.html"><code>truncate_stack</code></a> procedure can be used to drop all elements from the stack except for the top 16.</li>
</ul>
<h4 id="invoking-via-exec-instruction"><a class="header" href="#invoking-via-exec-instruction">Invoking via <code>exec</code> instruction</a></h4>
<p>Procedures invoked via the <code>exec</code> instruction, are inlined at their call sites during compilation. Thus, from the standpoint of the final program, executing procedures this way is indistinguishable from manually including procedure code in place of the <code>exec</code> instruction. This also means that procedures invoked via the <code>exec</code> instruction are executed in the same context as the caller.</p>
<p>The <code>exec</code> instruction can be thought of as the "normal" way of invoking procedures, i.e. it has semantics that would be familiar to anyone coming from a standard programming language, or that is familiar with procedure call instructions in a typical assembly language.</p>
<p>In Miden Assembly, it is used to execute procedures without switching execution contexts, i.e. the callee executes in the same context as the caller. Conceptually, invoking a procedure via <code>exec</code> behaves as if the body of that procedure was inlined at the call site. In practice, the procedure may or may not be actually inlined, based on compiler optimizations around code size, but there is no actual performance tradeoff in the usual sense. Thus, when executing a program, there is no meaningful difference between executing a procedure via <code>exec</code>, or replacing the <code>exec</code> with the body of the procedure.</p>
<h3 id="kernels"><a class="header" href="#kernels">Kernels</a></h3>
<p>A <em>kernel</em> defines a set of procedures which can be invoked from user contexts to be executed in the root context. Miden assembly programs are always compiled against some kernel. The default kernel is empty - i.e., it does not contain any procedures. To compile a program against a non-empty kernel, the kernel needs to be specified when instantiating the <a href="https://crates.io/crates/miden-assembly">Miden Assembler</a>.</p>
<p>A kernel can be defined similarly to a regular <a href="user_docs/assembly/./code_organization.html#library-modules">library module</a> - i.e., it can have internal and exported procedures. However, there are some small differences between what procedures can do in a kernel module vs. what they can do in a regular library module. Specifically:</p>
Expand Down
2 changes: 1 addition & 1 deletion searchindex.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion searchindex.json

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions user_docs/assembly/execution_contexts.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,26 +183,27 @@ <h2 id="execution-contexts"><a class="header" href="#execution-contexts">Executi
<p>While executing in a user context, we can request to execute some procedures in the root context. This can be done via the <code>syscall</code> instruction. The set of procedures which can be invoked via the <code>syscall</code> instruction is limited by the <a href="#kernels">kernel</a> against which a program is compiled. Once the procedure called via <code>syscall</code> returns, the execution moves back to the user context from which it was invoked. The diagram below illustrates this graphically:</p>
<p><img src="../../assets/user_docs/assembly/execution_contexts/context_transitions.png" alt="context transitions" /></p>
<h3 id="procedure-invocation-semantics"><a class="header" href="#procedure-invocation-semantics">Procedure invocation semantics</a></h3>
<p>As mentioned in the <a href="./code_organization.html">previous section</a>, procedures in Miden assembly can be invoked via five different instructions: <code>exec</code>, <code>call</code>, <code>syscall</code>, <code>dynexec</code>, and <code>dyncall</code>. Invocation semantics of <code>call</code>, <code>dyncall</code>, and <code>syscall</code> instructions are basically the same, the only difference being that the <code>syscall</code> instruction can be used only to call kernel's procedures. The <code>exec</code> and <code>dynexec</code> instructions are different, and we explain these differences below.</p>
<p>As mentioned in the <a href="./code_organization.html">previous section</a>, procedures in Miden assembly can be invoked via five different instructions: <code>exec</code>, <code>call</code>, <code>syscall</code>, <code>dynexec</code>, and <code>dyncall</code>. Invocation semantics of <code>call</code>, <code>dyncall</code>, and <code>syscall</code> instructions are basically the same, the only difference being that the <code>syscall</code> instruction can be used only with procedures which are defined in the program's kernel. The <code>exec</code> and <code>dynexec</code> instructions are different, and we explain these differences below.</p>
<h4 id="invoking-via-call-dyncall-and-syscall-instructions"><a class="header" href="#invoking-via-call-dyncall-and-syscall-instructions">Invoking via <code>call</code>, <code>dyncall</code>, and <code>syscall</code> instructions</a></h4>
<p>When a procedure is invoked via a <code>call</code>, <code>dyncall</code> or a <code>syscall</code> instruction, the following happens:</p>
<p>When a procedure is invoked via a <code>call</code>, <code>dyncall</code>, or a <code>syscall</code> instruction, the following happens:</p>
<ul>
<li>Execution moves into a different context. In case of the <code>call</code> and <code>dyncall</code> instructions, a new user context is created. In case of a <code>syscall</code> instruction, the execution moves back into the root context.</li>
<li>All stack items beyond the 16th item get "hidden" from the invoked procedure. That is, from the standpoint of the invoked procedure, the initial stack depth is set to 16.</li>
</ul>
<p>When the called procedure returns, the following happens:</p>
<p>When the callee returns, the following happens:</p>
<ul>
<li>Execution moves back to the context from which the procedure was invoked.</li>
<li>Stack depth is set to its original depth. Before the stack depth is reset, the VM checks if the current stack depth is exactly 16, and fails otherwise.</li>
<li>The execution context of the caller is restored</li>
<li>If the original stack depth was greater than 16, those elements that were "hidden" during the call as described above, are restored. However, the stack depth must be <em>exactly</em> 16 elements when the procedure returns, or this will fail and the VM will trap.</li>
</ul>
<p>The manipulations of the stack depth described above have the following implications:</p>
<ul>
<li>The top 16 elements of the stack can be used to pass parameters and return values between the caller and the callee.</li>
<li>The top 16 elements of the stack can be used to pass parameters and return values between the caller and the callee. NOTE: Except for <code>dyncall</code>, as that instruction requires the first 4 elements to be the hash of the callee procedure, so only 12 elements are available in that case.</li>
<li>Caller's stack beyond the top 16 elements is inaccessible to the callee, and thus, is guaranteed not to change as the result of the call.</li>
<li>At the end of its execution, the callee must ensure that stack depth is exactly 16. If this is difficult to ensure manually, the <a href="../stdlib/sys.html"><code>truncate_stack</code></a> procedure can be used to drop all elements from the stack except for the top 16.</li>
</ul>
<h4 id="invoking-via-exec-instruction"><a class="header" href="#invoking-via-exec-instruction">Invoking via <code>exec</code> instruction</a></h4>
<p>Procedures invoked via the <code>exec</code> instruction, are inlined at their call sites during compilation. Thus, from the standpoint of the final program, executing procedures this way is indistinguishable from manually including procedure code in place of the <code>exec</code> instruction. This also means that procedures invoked via the <code>exec</code> instruction are executed in the same context as the caller.</p>
<p>The <code>exec</code> instruction can be thought of as the "normal" way of invoking procedures, i.e. it has semantics that would be familiar to anyone coming from a standard programming language, or that is familiar with procedure call instructions in a typical assembly language.</p>
<p>In Miden Assembly, it is used to execute procedures without switching execution contexts, i.e. the callee executes in the same context as the caller. Conceptually, invoking a procedure via <code>exec</code> behaves as if the body of that procedure was inlined at the call site. In practice, the procedure may or may not be actually inlined, based on compiler optimizations around code size, but there is no actual performance tradeoff in the usual sense. Thus, when executing a program, there is no meaningful difference between executing a procedure via <code>exec</code>, or replacing the <code>exec</code> with the body of the procedure.</p>
<h3 id="kernels"><a class="header" href="#kernels">Kernels</a></h3>
<p>A <em>kernel</em> defines a set of procedures which can be invoked from user contexts to be executed in the root context. Miden assembly programs are always compiled against some kernel. The default kernel is empty - i.e., it does not contain any procedures. To compile a program against a non-empty kernel, the kernel needs to be specified when instantiating the <a href="https://crates.io/crates/miden-assembly">Miden Assembler</a>.</p>
<p>A kernel can be defined similarly to a regular <a href="./code_organization.html#library-modules">library module</a> - i.e., it can have internal and exported procedures. However, there are some small differences between what procedures can do in a kernel module vs. what they can do in a regular library module. Specifically:</p>
Expand Down

0 comments on commit cd502fa

Please sign in to comment.