問題タブ [vm-implementation]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - VM の作成 - 整形式のバイトコード?
楽しみのために C で仮想マシンを作成しています。ラメ、私は知っていますが、幸いなことに私はSOにいるので、誰もからかわないことを願っています:)
私は、(自分の) ASM の行を読み取り、何かを実行する、非常に迅速で汚れた VM を作成しました。現在、3 つの命令しかありません: add
、jmp
、end
。すべてが順調で、実際に行をフィードできるのはかなりクールです(次のようwrite_line(&prog[1], "jmp", regA, regB, 0);
にしてプログラムを実行します:
私は C でオペコード ルックアップ テーブル (効率的ではないかもしれませんが、エレガントです) を使用していますが、すべて正常に動作しているようです。
私の質問は「ベストプラクティス」の質問ですが、正しい答えがあると思います。VM がバイナリ ファイルを読み取って (バイトを に格納unsigned char[]
)、バイトコードを実行できるようにしています。私の質問は次のとおりです。バイトコードが整形式であることを確認するのは VM の仕事ですか、それとも、吐き出すバイナリ ファイルが整形式であることを確認するのはコンパイラの仕事ですか?
誰かがバイナリファイルを編集して何かを台無しにするとどうなるか(その任意の部分を削除するなど)、私がこれを尋ねるだけです。明らかに、プログラムにはバグがあり、おそらく機能しません。これは VM の問題でもありますか? 私よりずっと頭のいい人たちが、これらの問題の解決策を見つけているに違いありません。
lua - C++ は Lua VM の実装を簡素化できますか?
Lua C VM の実装に目を通したことがある人にとって、C++ を使用すると実装が大幅に簡素化されるでしょうか?
c++ - カスタムVMに末尾呼び出しを実装する方法
カスタム仮想マシンに末尾呼び出しを実装するにはどうすればよいですか?
元の関数のローカルスタックをポップオフし、次に引数を取得してから、新しい引数をプッシュする必要があることはわかっています。しかし、関数のローカルスタックをポップオフした場合、新しい引数をどのようにプッシュする必要がありますか?それらはスタックからポップされたばかりです。
c++ - 管理のヒントを登録する
カスタムVMを実装すると、レジスターを使用するようになりました(これらはポインターを格納し、空の場合はNULLになります)。しかし、実際にはレジスタベースのメモリを管理する方法がわからないことに気づきました。たとえば、すべてのレジスタが使い果たされ、一部のコードが別のレジスタを必要としている場合はどうすればよいですか?できれば、新しいものを作成するだけではいけません。
これはC++です。
parsing - 1レジスタVMでインタプリタ-すべての数学を評価することが可能です。表現?
通訳を書いています。私は以前にそれを行ったことがありますが、のような式で機能するものを試したことはありません3 + 4 * 2 / ( 1 − 5 ) ^ 2 ^ 3
。
解析プロセスに問題はありません。実際には、VMがコードを実行します。
私の目標は高速インタプリタだったので、たとえば(push、push、mul)のように、乗算に複数の命令が必要なスタックベースのVMを使用しないことにしました。
パーサーによって生成されたVMの「アセンブリ」コードは次のようになります。
3 + 4 * 2 / ( 1 − 5 ) ^ 2 ^ 3
になります
(結果は正しいです)
- ご覧のとおり、すべての命令は1つまたは2つの引数を取りません。最後の命令の結果を保持する結果レジスタがあります。以上です。
この構造の言語と1つのレジスタのみを備えたVMは、PythonやPHPなどのすべての数式を計算できますか?
スタックなしでは不可能な場合は、今すぐやり直します。
c++ - カスタムVMにはいくつのレジスタがありますか?
カスタムVMを設計していますが、使用するレジスタの数に興味があります。最初は255でしたが、関数を呼び出すたびに、ほとんどが使用されない場合に、255のポインター(KB全体)をスタックまたはヒープに戻すことについて少し心配しています。いくつのレジスタを使用する必要がありますか?
c++ - JITコンパイラでは+8ではなくebp+6
私は楽しみのために書いているVMに単純なJITコンパイラーを実装しています(主に言語設計についてもっと学ぶために)、そして私はいくつかの奇妙な振る舞いをしています、多分誰かが私に理由を教えてくれます。
まず、CとC++の両方のJIT「プロトタイプ」を定義します。
compile()
ASMにコンパイルしてメモリ内のどこかに貼り付ける関数があります。
そして最後に、私はプログラムのメインチャンクを持っています:
ご覧のとおり、このcompile()
関数には、期待どおりの結果が得られることを確認するために実行したいくつかのテストがあり、ほとんどすべてが機能しますが、質問があります...
ほとんどのチュートリアルまたはドキュメントリソースでは、渡される関数の最初の値(intの場合)を取得するために、2番目の値を取得し[ebp+8]
ます[ebp+12]
。どういうわけか、私はその時などをしなければなりませ[ebp+6]
ん[ebp+10]
。誰か教えてもらえますか?
vm-implementation - エンドユーザーにとっての Parrot VM の利点は何ですか?
エンドユーザー (ソフトウェア開発者) にとってのParrot Virtual Machineの利点は何ですか?
たとえば、Perl や Python に対して直接プログラミングできるのに、どうしてわざわざ Parrot でプログラミングする必要があるのでしょうか。
compiler-construction - 中間コードが仮想マシンで実行されると言うのは誤解を招きますか?
私が読んだことの理解が正しければ、仮想マシンは本質的に中間コードのコンパイラです。しかし、(アンマネージ コードの例として)Delphi がそのコンパイラで実行されるとは決して言われません。仮想マシンを単にコンパイラとして説明したほうが混乱しにくいでしょうか?
.net - .NET VMはコンパイラですか、それともインタプリタですか?
.NETの仮想マシンはCILバイトコードをコンパイルしますか(そしてコードを最下位レベルで実行します-CPUアセンブラー)、それともインタープリターです(次の命令を読み取って実行します)?