TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Write Your Own Virtual Machine

546 点作者 vedosity超过 6 年前

9 条评论

chrisaycock超过 6 年前
One of my favorite techniques for implementing VMs is the &quot;computed goto&quot;:<p><a href="https:&#x2F;&#x2F;eli.thegreenplace.net&#x2F;2012&#x2F;07&#x2F;12&#x2F;computed-goto-for-efficient-dispatch-tables" rel="nofollow">https:&#x2F;&#x2F;eli.thegreenplace.net&#x2F;2012&#x2F;07&#x2F;12&#x2F;computed-goto-for-e...</a><p>Consider this example for dispatching instructions from the article:<p><pre><code> while (running) { uint16_t op = mem_read(reg[R_PC]++) &gt;&gt; 12; switch (op) { case OP_ADD: {ADD, 6} break; case OP_AND: {AND, 7} break; case OP_NOT: {NOT, 7} break; case OP_BR: {BR, 7} break; ... } } </code></pre> That code has a lot of branching. The <i>switch</i> statement has to jump to the corresponding <i>case</i>, the <i>break</i> statement branches to the bottom, and then there is third branch to get back to the top of the <i>while</i> loop. Three branches just to hit one instruction.<p>Now imagine we had written the above as:<p><pre><code> static void* dispatch_table[] = { &amp;&amp;OP_ADD, &amp;&amp;OP_AND, &amp;&amp;OP_NOT, &amp;&amp;OP_BR, ... }; #define DISPATCH() goto *dispatch_table[memory[reg[R_PC]++] &gt;&gt; 12] DISPATCH(); OP_ADD: {ADD, 6} DISPATCH(); OP_AND: {AND, 7} DISPATCH(); OP_NOT: {NOT, 7} DISPATCH(); OP_BR: {BR, 7} DISPATCH(); ... </code></pre> Now there is only one branch per instruction. The handler for each instruction directly jumps to the next location via the <i>goto</i>. There is no need to be in an explicit loop because the interpreter runs until it hits a halting instruction.<p>Many VMs now use this technique, including the canonical Ruby and Python interpreters.
评论 #18679643 未加载
评论 #18679386 未加载
评论 #18679970 未加载
评论 #18679477 未加载
评论 #18686800 未加载
评论 #18678969 未加载
评论 #18684075 未加载
评论 #18681208 未加载
评论 #18684027 未加载
评论 #18679440 未加载
评论 #18680665 未加载
jonathanstrange超过 6 年前
I once implemented a VM in Ada and just used a large switch. I extensively benchmarked it and it was blazingly fast at -O3.<p>However, it was only fast when I used packages very sparingly. In contrast to the usual advice given in the Ada community, splitting up the implementation into several packages slowed down the main loop tremendously. I suspect this wouldn&#x27;t happen with whole-program optimization in C, but believe that the version of gcc I was using didn&#x27;t support that for Ada. Also, my Green Threads were slower than a single thread, no matter which tricks I tried.<p>It&#x27;s an abandoned project now, since the accompanying assembler was hacked together in Racket and at some point I simply lost track of what was going on where :O
评论 #18679834 未加载
评论 #18681523 未加载
tombert超过 6 年前
I love these kinds of tutorials, and really any tutorial that makes me think of stuff that was previously &quot;magic&quot; and makes me feel stupid for not previously understanding it after I read it (I honestly mean that in a positive way).<p>This will be a fun weekend project for me...I have had an idea of a lambda-calculus-based VM that I&#x27;ve wanted to build for a few months ago, and I think this will be a good start for me to understand it.
techno_modus超过 6 年前
I like this tutorial but it should be mentioned that before implementing a virtual machine one should understand that there are many computing models and many alternative mechanisms within each of them. Implementing VM for sequential program execution is relatively easy. What is more (conceptually) difficult is concurrency, asynchronous processes etc.
评论 #18679782 未加载
评论 #18681201 未加载
评论 #18679876 未加载
gattr超过 6 年前
I agree it&#x27;s a great exercise. Years ago I added a very simple stack-based VM to my raytracer to allow procedural textures &amp; normal maps. The scene script would e.g. contain a material description like this:<p><pre><code> material { diffuse rgb = [0, 0, 1] * (1-(0.5+0.5*noise(x*0.000002, y*0.000002, z*0.000002, 0.66, 2))) + [1, 1, 1] * (0.5+0.5*noise(x*0.000002, y*0.000002, z*0.000002, 0.66, 2)); } </code></pre> i.e. an expression with 3-vectors and scalars and a few basic functions (noise, sin&#x2F;cos, etc.). This can be easily &quot;compiled&quot; (during script parsing) for execution on the VM. Then the overhead during actual raytracing was quite small.
评论 #18682658 未加载
评论 #18699816 未加载
morazow超过 6 年前
Off-topic.<p>Does anyone know how I can convert AST into stream of bytecodes? Are there any good example language implementations to learn?
评论 #18685264 未加载
评论 #18684572 未加载
评论 #18683719 未加载
评论 #18681246 未加载
评论 #18684284 未加载
wener超过 6 年前
Ok,here is mine <a href="https:&#x2F;&#x2F;github.com&#x2F;wenerme&#x2F;bbvm" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;wenerme&#x2F;bbvm</a><p>Writing a VM is very fun and addictive. Especially writing in different language can learn a lot!
elgfare超过 6 年前
This was a great piece, but I found it funny that there&#x27;s a bug in the very first line of code mentioned:<p><pre><code> &#x2F;* 65536 locations *&#x2F; uint16_t memory[UINT16_MAX]; </code></pre> Spot the leak.
ngcc_hk超过 6 年前
Great site