Search code examples
forth

PAD offset from HERE


The version of Forth I am using (Mecrisp) lacks the PAD word. However, it has HERE. Now, I guess I could define PAD myself using something like:

hex deadbeef constant offset
: pad here offset + ;

My question is how can I find a safe value of the offset? Indeed, is it safe for the offset to be zero bytes - which I guess makes PAD equivalent to HERE?


Solution

  • A safe way is to allocate a dedicated buffer for PAD in the dictionary (via ALLOT) or dynamically in memory (via ALLOCATE).

    An example:

    1024 constant pad-size
    create pad pad-size allocate
    

    The standard guarantees only 84 characters for PAD size, see the section 3.3.3.6 Other transient regions:

    The size of the scratch area whose address is returned by PAD shall be at least 84 characters.

    A good Forth-system should certainly provide the available size for PAD (see environmental queries) and a good program should either be limited by 84 chars or determines the available size. Using the buffers that indeterminate in length is a bad practice that can lead to the memory corruption bugs or even a vulnerability in general case.

    The free space in the dictionary can be determined via UNUSED word. But this space cannot be safely used without allocating — since many Forth implementations use this space by themselves. For example, all the buffers mentioned in the section 3.3.3.6 can be located in the dictionary free space region. But, by the standard, PAD buffer must not overlap with other buffers in memory. So it is need to know the particular Forth-system implementation details to determine the safe offset value and define PAD that will use the dictionary free space. The most reliable way to know these details — read the particular Forth-system source codes.

    Even in that case it is also good to define something like:

    : pad-size ( -- u ) unused offset - ; \ assuming that no other buffers after PAD
    : pad-buf ( -- addr u ) pad pad-size ;