6.31.3 Threading Words

The terminology used here stems from indirect threaded Forth systems; in such a system, the XT of a word is represented by the CFA (code field address) of a word; the CFA points to a cell that contains the code address. The code address is the address of some machine code that performs the run-time action of invoking the word (e.g., the dovar: routine pushes the address of the body of the word (a variable) on the stack).

These words provide access to code fields, code addresses and other threading stuff in Gforth. It more or less abstracts away the differences between direct and indirect threading.

Up to and including Gforth 0.7, the code address (plus, for does>-defined words, the address returned by >does-code) was sufficient to know the type of the word. However, since Gforth-1.0 the behaviour or at least implementation of words like compile, and name>compile can be determined independently as described in Header methods.

The following words for create a code field and at the same time initialize the header methods:

hmcopy, ( xt –  ) gforth-experimental “hmcopy-comma”

While constructing a header, allocate the code field, and use xt as prototype for setting the code field and the header methods.

docol, ( ) gforth-1.0 “docol,”

The code address of a colon definition.

docon, ( ) gforth-1.0 “docon,”

The code address of a CONSTANT.

dovar, ( ) gforth-1.0 “dovar,”

The code address of a CREATEd word.

douser, ( ) gforth-1.0 “douser,”

The code address of a USER variable.

dodefer, ( ) gforth-1.0 “dodefer,”

The code address of a defered word.

dofield, ( ) gforth-1.0 “dofield,”

The code address of a field.

dovalue, ( ) gforth-1.0 “dovalue,”

The code address of a CONSTANT.

doabicode, ( ) gforth-1.0 “doabicode,”

The code address of a ABI-CODE definition.

For does>-defined words, use hmcopy,.

Or you use a higher-level word like create-from (see Creating from a prototype).

The following words were designed before the introduction of header methods, and are therefore not the best (and recommended) way to deal with different word types in Gforth.

In an indirect threaded Forth, you can get the code address of name with ' name @; in Gforth you can get it with ' name >code-address, independent of the threading method.

threading-method ( – n ) gforth-0.2 “threading-method”

0 if the engine is direct threaded. Note that this may change during the lifetime of an image.

>code-address ( xt – c_addr  ) gforth-0.2 “>code-address”

c-addr is the code address of the word xt.

code-address! ( c_addr xt –  ) gforth-obsolete “code-address!”

Change a code field with code address c-addr at xt.

The code addresses produced by various defining words are produced by the following words:

docol: ( – addr  ) gforth-0.2 “docol:”

The code address of a colon definition.

docon: ( – addr  ) gforth-0.2 “docon:”

The code address of a CONSTANT.

dovar: ( – addr  ) gforth-0.2 “dovar:”

The code address of a CREATEd word.

douser: ( – addr  ) gforth-0.2 “douser:”

The code address of a USER variable.

dodefer: ( – addr  ) gforth-0.2 “dodefer:”

The code address of a defered word.

dofield: ( – addr  ) gforth-0.2 “dofield:”

The code address of a field.

dovalue: ( – addr  ) gforth-0.7 “dovalue:”

The code address of a CONSTANT.

dodoes: ( – addr  ) gforth-0.6 “dodoes:”

The code address of a DOES>-defined word.

doabicode: ( – addr  ) gforth-1.0 “doabicode:”

The code address of a ABI-CODE definition.

For a word X defined with set-does>, the code address points to dodoes:, and the >hmextra field of the header methods contains the xt of the word that is called after pushing the body addres of X.

If you want to know whether a word is a DOES>-defined word, and what Forth code it executes, >does-code tells you that:

>does-code ( xt1 – xt2  ) gforth-0.2 “>does-code”

If xt1 is the execution token of a child of a set-does>-defined word, xt2 is the xt passed to set-does>, i.e, the xt of the word that is executed when executing xt1 (but first the body address of xt1 is pushed). If xt1 does not belong to a set-does>-defined word, xt2 is 0.

You can use the resulting xt2 with set-does> (preferred) to change the latest word or with

does-code! ( xt2 xt1 –  ) gforth-0.2 “does-code!”

Change xt1 to be a xt2 set-does>-defined word.

to change an arbitrary word.

The following two words generalize >code-address, >does-code, code-address!, and does-code!:

>definer ( xt – definer  ) gforth-0.2 “>definer”

Definer is a unique identifier for the way the xt was defined. Words defined with different does>-codes have different definers. The definer can be used for comparison and in definer!.

definer! ( definer xt –  ) gforth-obsolete “definer!”

The word represented by xt changes its behaviour to the behaviour associated with definer.

Code-address!, does-code!, and definer! update the opt-compile, method to a somewhat generic compiler for that word type (in particular, primitives get the slow general-compile, method rather than the primitive-specific peephole-compile,).