19

私はプログラミング言語がどのように機能するかを調べてきましたが、そのうちのいくつかにはいわゆる仮想マシンがあります。これは、別のプログラミング言語内でのプログラミング言語のエミュレーションの一種であり、コンパイルされた言語がスタックを使用して実行されるように機能することを理解しています。私はそれを正しく理解しましたか?

私が行った但し書きで、多くのコンパイルされていない言語が「リベラルな」型システムを持つ変数を許可するということは、私を困惑させます。たとえば、Python では、次のように記述できます。

x = "Hello world!"
x = 2**1000

文字列と大きな整数はまったく無関係であり、メモリ内で異なる量のスペースを占めるため、スタックベースの環境でこのコードを表現するにはどうすればよいでしょうか? ここで正確に何が起こりますか?x はスタック上の新しい場所を指していて、古い文字列データは参照されていませんか? これらの言語はスタックを使用しませんか? そうでない場合、変数は内部的にどのように表現されますか?

4

5 に答える 5

7

おそらく、あなたの質問は「動的言語はどのように機能しますか?」というタイトルにする必要があります。

それは簡単です。変数の型情報を一緒にメモリに保存します。これは、インタープリターまたは JIT コンパイル言語だけでなく、Objective-C などのネイティブ コンパイル言語でも行われます。

于 2009-05-29T21:05:35.193 に答える
2

ほとんどのVM言語では、変数自体がスタック上にある場合でも、変数はヒープ内のメモリへのポインター(または参照)として概念化できます。プリミティブ型(Javaのintやboolなど)を持つ言語の場合、それらもスタックに格納できますが、新しい型を動的に割り当てることはできません。

プリミティブ型を無視すると、スタックに存在するすべての変数の実際の値がヒープに格納されます。したがって、値を動的に再割り当てすると、元の値は破棄され(そして、ガベージコレクションアルゴリズムによってメモリがクリーンアップされ)、新しい値がメモリの新しいビットに割り当てられます。

于 2009-05-29T21:09:34.763 に答える
2

VM は言語とは何の関係もありません。VM 上で任意の言語を実行できます (Java VM には既に数百の言語があります)。

VM を使用すると、別の種類の「アセンブリ言語」を実行できます。これは、コンパイラを適応させるのにより適したものです。VM で実行されることはすべて CPU で実行できるため、VM を CPU のように考えてください。(一部は実際にハードウェアに実装されています)。

これは非常に低レベルであり、多くの場合、重度のスタック ベースです。レジスタではなく、マシン レベルの計算はすべて、現在のスタック ポインターに関連する位置に関連しています。

通常のコンパイル済み言語では、1 つのステップに多くの命令が必要です。a + は次のように見えるかもしれません。「スタック ポインターに関連するポイントからアイテムを reg a にグラブし、別のアイテムを reg b にグラブします。reg a と b を追加します。reg a をスタック ポインターに相対的な場所に配置します。

VM はこれらすべてを単一の短い命令で行います。機械語の命令ごとに 4 または 8 バイト (32 ビットまたは 64 ビットのアーキテクチャによって異なります) ではなく、おそらく 1 バイトまたは 2 バイトです。 1 ~ 2 バイトのマシン コード用。(私が間違っている可能性があります。私の最後の x86 コーディングは 80286 時代でした。)

Microsoft は、コードの量を減らすために、オフィス製品で VM を使用しました (おそらく今でも使用しています)。

VM コードを作成する手順は、機械語を作成する場合と同じで、プロセッサの種類が本質的に異なるだけです。

VM は、言語に非常に密接に関連する独自のセキュリティ、エラー リカバリ、およびメモリ メカニズムを実装することもできます。

ここでの私の説明の一部は要約であり、記憶からのものです。バイトコードの定義を自分で調べたい場合は、ちょっと楽しいです:

http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html

于 2009-05-29T22:09:24.660 に答える
1

「VMがこのような変数をどのように処理するか」の多くの鍵は、実際にはメタデータにあります...格納されてから更新されるメタ情報により、VMは、割り当てて正しいことを行う方法をより適切に処理できます。変数。

多くの場合、これは実際にパフォーマンスの妨げになる可能性のあるタイプのオーバーヘッドです。しかし、現代の実装などは、正しいことを行う上で長い道のりを歩んできました。

特定の質問(変数をバニラオブジェクトとして扱うなど)については、新しい割り当てのメタ情報を再割り当て/再評価することになります。そのため、xはある方向から次の方向に見える可能性があります。

于 2009-05-29T21:10:55.527 に答える
1

あなたの質問の一部に答えるために、私はPythonについてのグーグルテックトークをお勧めします。そこでは動的言語に関するあなたの質問のいくつかが答えられます。たとえば、変数とは何か(ポインターでも参照でもありませんが、Pythonの場合はラベルです)。

于 2009-05-29T21:12:17.910 に答える