6.2.0825 BUFFER: buffer-colon CORE EXT

( u "<spaces>name" -- )

Skip leading space delimiters. Parse name delimited by a space. Create a definition for name, with the execution semantics defined below. Reserve u address units at an aligned address. Contiguity of this region with any other region is undefined.

name Execution:

( -- a-addr )

a-addr is the address of the space reserved by BUFFER: when it defined name. The program is responsible for initializing the contents.

See:

Rationale:

BUFFER: provides a means of defining an uninitialized buffer. In systems that use a single memory space, this can effectively be defined as:

: BUFFER: ( u "<name>" -- ; -- addr )
   CREATE ALLOT
;

However, many systems profit from a separation of uninitialized and initialized data areas. Such systems can implement BUFFER: so that it allocates memory from a separate uninitialized memory area. Embedded systems can take advantage of the lack of initialization of the memory area while hosted systems are permitted to ALLOCATE a buffer. A system may select a region of memory for performance reasons. A detailed knowledge of the memory allocation within the system is required to provide a version of BUFFER: that can take advantage of the system.

It should be noted that the memory buffer provided by BUFFER: is not initialized by the system and that if the application requires it to be initialized, it is the responsibility of the application to initialize it.

Implementation:

This implementation depends on children of CREATE returning an aligned address. Other memory location techniques require implementation-specific knowledge of the underlying Forth system.

: BUFFER: \ u "<name>" -- ; -- addr
\ Create a buffer of u address units whose address is returned at run time.
   CREATE ALLOT
;

Testing:

DECIMAL
T{ 127 CHARS BUFFER: TBUF1 -> }T
T{ 127 CHARS BUFFER: TBUF2 -> }T \ Buffer is aligned
T{ TBUF1 ALIGNED -> TBUF1 }T \ Buffers do not overlap
T{ TBUF2 TBUF1 - ABS 127 CHARS < -> <FALSE> }T \ Buffer can be written to
1 CHARS CONSTANT /CHAR
: TFULL? ( c-addr n char -- flag )
   TRUE 2SWAP CHARS OVER + SWAP ?DO
     OVER I C@ = AND
   /CHAR +LOOP NIP
;

T{ TBUF1 127 CHAR * FILL   ->        }T
T{ TBUF1 127 CHAR * TFULL? -> <TRUE> }T

T{ TBUF1 127 0 FILL   ->        }T
T{ TBUF1 127 0 TFULL? -> <TRUE> }T

ContributeContributions

ruvavatar of ruv [69] the confusing namesRequest for clarification2018-09-11 18:09:27

What was the rationale to have BUFFER and BUFFER: words at the same time? It is confusing that so similar names refer to so different concepts. Perhaps BUFFER should have been made obsolete?

ruvavatar of ruv

Another issue with this name is a colon at the end. There are many standard parsing words that take one argument from the input. Some of them do not have a colon at the end, but some other (mostly new) have a colon. What is the rule? if CONSTANT does not have a colon in its name, why BUFFER: does?

It looks like a strange inconsistency in the naming conventions.

AntonErtlavatar of AntonErtl

All the new names with : at the end were introduced because the corresponding names without colon already have a conflicting meaning in a widely used system. I know this for sure for the field words and for {:, for BUFFER: I don't remember any discussion about the name.

StephenPelcavatar of StephenPelc

At the time (early 1990s) it was expected that BLOCK and friends would slowly die away. Especially with the rise of retro-computing BLOCK and friends remain healthy.

Reply New Version

AntonErtlavatar of AntonErtl [90] Revise Rationale of Buffer:Proposal2019-07-06 15:45:25

This contribution has been moved to the proposal section.

AntonErtlavatar of AntonErtl

This reply has been moved to the proposal section.

ruvavatar of ruv

This reply has been moved to the proposal section.

AntonErtlavatar of AntonErtl

This reply has been moved to the proposal section.

AntonErtlavatar of AntonErtl

This reply has been moved to the proposal section.

AntonErtlavatar of AntonErtl

This reply has been moved to the proposal section.
Formal
Reply New Version

ruvavatar of ruv [91] Address between runsRequest for clarification2019-07-09 12:54:28

It seems this word specification intents that a compiled program can be saved into an image and run from the image multiple times.

May a system provide different addresses between runs?

1024 BUFFER: foo

foo CONSTANT bar
\ use bar in the code further

This code is either standard or not standard depending on the answer. If it is not standard, an ambiguous condition should be mentioned in the specification.

AntonErtlavatar of AntonErtl

The code is standard.

Images are not standardized, so what a system does on image creation and restoration is up to the system.

I think that it would be too restrictive to not support this kind of code (at least if FOO was an address in the dictionary), so systems will support it in some way, either by always restoring the image to the same addresses, or by supporting relocatable images.

E.g., Gforth supports relocatable images, so even though the address of FOO may change across image saving and restoring, BAR will work as intended. Some not so common uses do not work across image saving and restoring, though, e.g., if you compute a hash value from data that includes an address.

StephenPelcavatar of StephenPelc

Good catch. IMHO it is entirely sensible that children of BUFFER: may return different addresses on different runs. Apart from Anton's example, consider a buffer allocated from the heap. Heap allocation may vary from run to run.

ruvavatar of ruv

The normative part says:

a-addr is the address of the space reserved by BUFFER: when it defined name.

And then a-addr should be a constant even between runs from a saved image (since name is defined only once).

But the rationale says:

hosted systems are permitted to ALLOCATE a buffer.

It means that a-addr can be different on every run from a saved image.

Requiring a-addr to be a constant between runs from an image makes implementations more difficult and provides almost nothing benefits for programs. So I suggest to relax implementations in this regard.

But a formal problem is that it's difficult to specify in the normative part that a-addr may change between runs due to lack of the corresponding model and terminology in the standard.

The irony is that BUFFER: is more demanded by programs that support embedded targets, when programs are often precompiled and saved into an image, but such usage scenario is out of the scope of the standard. And hence the corresponding behavior cannot be formally specified for this word.

Perhaps is should be informally stated in the rationale at least.

Reply New Version