スレッデッドコード
スレッド内のアドレス群は機械語コードのアドレスである。単純だが、そのマシンのアドレスのみがスレッドに羅列されるため、何らかのパラメータが必要でもそれらはメモリから間接的にロードするしかない。したがって若干オーバーヘッドがある。一部のForth処理系は直接スレッデッドコードを生成する。多くのマシンにおいて、直接スレッディングは後述するサブルーチン・スレッディングよりも高速である。
例として、スタックマシンで "push A, push B, add" を実行する場合を見てみよう。直接スレッディングでは次のようなスレッドとルーチンに変換される。ここで ip は &thread というアドレスに初期化されるものとする。
また、オペランドをスレッドに含める方式もある。スレッドは大きくなるが、ルーチンは少なくなる。
バイトコードは歴史的に、8ビットの命令コードを使用し、スタックに基づく仮想機械で実行される。典型的なインタプリタはデコード&ディスパッチ・インタプリタと呼ばれ、次のような形式である。
仮想機械が1バイトの命令しか使わない場合、decode() は単に bytecode から1つフェッチするだけだが、1バイト命令を基本として多バイト命令も持つ場合があり、そのときは decode() がさらに複雑になる。1バイト命令コードのデコードは非常に単純で、命令コードをインデックスとしてジャンプテーブルを参照するだけでよい。
各命令の行う操作や演算は "push" や "add" などのように単純で、それらを実際に実行するコストよりもどれを実行するかを選択するオーバーヘッドの方が大きい。そのためこのようなインタプリタは単純に機械語コードを実行するよりも遅いことが多い。しかし、命令の処理内容がより複雑になれば、オーバーヘッドの割合は小さくなる。
メモリを節約するため、一連のサブルーチンコールからサブルーチンのアドレスのリストを作り、小さなループを使って次々にサブルーチンを呼び出す。例えば次のようになる。
この場合、バイトコードのデコードは1回だけ、コンパイル時かプログラムロード時になされ、実行時に毎回デコードするわけではない。実行コストに比べてデコードとディスパッチのオーバーヘッドが大きい場合、これで時間と領域を節約できる。
なお、バイトコードのデコードとディスパッチを同時に行うインタプリタにおいては解釈すべき命令はそれぞれ1バイトだが、上記のスレッデッドコードのthread内の&pushAや&pushBといったアドレスは2バイト以上ということが普通である。一般にデコード&ディスパッチ・インタプリタにおける命令のサイズは一定ではない。例えば、そのようなインタプリタで Intel Pentium のシミュレーションを行う場合、デコードすべき命令の大きさは1バイトから16バイトまで様々である。しかし、バイトコード化システムは最も一般的な操作に1バイトのコードを割り当てる。従ってこのスレッデッドコードはバイトコードよりスペースコストがやや高い。多くの用途では、デコードコストの縮小はスペースコストの増加に優る。
また、バイトコードは名目上マシンから独立しているが、スレッド内のポインタの形式や値はインタプリタを実行するターゲットマシンに依存しているのが一般的である。