"抽象化は自由を与える。だがその自由は、物理との断絶によって成立している。"
コードは動作する。
だが「何の上で動作するか」によって、その意味はまるで異なる。
本章では、仮想マシン(VM)とネイティブコードという二つの実行モデルの対立構造を通じて、
抽象と物理、可搬性と即時性、そしてソフトウェアにおける実在の層構造を捉え直す。
仮想マシンとは何か?
仮想マシン(VM)は、“もう一つの抽象的コンピュータ”をソフトウェア上に再現した実行基盤である。
代表例:
- JVM(Java Virtual Machine)
- CLR(.NET Common Language Runtime)
- WASM(WebAssembly Runtime)
- V8(JavaScript エンジン)
- Lua VM、BEAM(Erlang)など
特徴:
- 実マシンと独立した命令セット(Bytecode)
- 抽象化された型、GC、例外機構を保持
- 中間層による安全性と可搬性の保証
ネイティブコードとは何か?
ネイティブコードとは、直接CPUの命令セットに対応する命令列で構成されるコードである。
- x86, ARM, RISC-Vなどアーキテクチャ依存
- 実行速度は極めて高い(中間抽象なし)
- 安全性や整合性の保証は完全に開発者の責任
例:
mov eax, 1
int 0x80 ; Linuxシステムコール(exit)
→ OSカーネル、ドライバ、ゲームエンジンの一部、ブートローダなどに多用される
哲学的断絶:実行環境の“存在論”の違い
概念 | 仮想マシン | ネイティブコード |
---|---|---|
実行単位 | 抽象命令(bytecode) | 機械語命令(machine code) |
ハード依存性 | 低い(VMが抽象化) | 高い(アーキテクチャに直結) |
安全性 | 管理・制御された環境 | 非管理環境、任意アクセス可能 |
動作原理 | シミュレーションまたはJITによる逐次変換 | 直接解釈(fetch-decode-execute) |
哲学的構造 | 抽象的・階層的・設計思想的 | 物理的・直截的・装置論的 |
→ 仮想マシンは**「動作の理想を設計する」ための構造、
ネイティブコードは「動作そのものを制御する」**ための構造。
抽象化の代償:制御の喪失と意味の遅延
VMによる実行は、以下のものを代償にしている:
- 即時性:動作は抽象解釈を経て遅延される
- 制御性:メモリ管理、割り込み、CPU制御にアクセスできない
- 物理性:キャッシュ挙動、命令列最適化などへの介入が困難
しかしそれによって得られるものもある:
- 安全性:例外、型、GCなどの構造的保証
- 移植性:アーキテクチャ非依存のコード実行
- 記述の自由:高レベル言語との親和性
ネイティブコードの「存在の重さ」
ネイティブコードは、抽象を剥いだ実行形態である。
それゆえに、あらゆる命令が**“即時に現実と接続”**する。
-
in
,out
命令でデバイスを直接制御 -
hlt
命令でCPUの停止を宣言 - セグメントレジスタやページテーブルの操作による、現実世界との構造的連結
→ ネイティブコードは、コードというより“硬直化された構造体”であり、
動作そのものが機械の延長である。
仮想マシンは「世界をもう一度設計する」
仮想マシンは、OSの上にもう一つの“言語宇宙”を作る行為である。
JVMは型とオブジェクトと例外のある世界を定義し、
WASMはWebにおける命令最小単位の宇宙を再設計する。
→ それは、ハードウェアではなく、**“設計思想が支配する世界”**である。
どちらが「本物」なのか?
この問いは無意味である。
仮想マシンもネイティブコードも、「何に最適化されているか」が異なるだけである。
- ネイティブ:現実との直接性と効率性
- 仮想:安全性、移植性、開発速度、分散実行
ただし一つ確かなのは、
仮想マシンは世界の“記述”を、ネイティブコードは世界の“実在”を扱っているという点だ。
結語:抽象と物理は、対立ではなく対話のためにある
仮想マシンとネイティブコードは、二項対立ではない。
それは実装者の意図と設計哲学の現れ方が異なるだけである。
- 記述の自由を取るか
- 実在の即時性を取るか
- 可搬性を取るか
- 制御の絶対性を取るか
いずれを選ぶにせよ、その構造を理解することは、“コードが動くとは何か”を問うことに他ならない。
"仮想マシンは思想を動かし、ネイティブコードは物質を動かす。コードとは、両者のあいだを彷徨う存在である。"