Copies a stack item to another position
item count OP_PLACE => item?
OP_PLACE is defined as the single byte 0xe9.
This opcode is the inverse of OP_PICK. When combined with pick, it allows stack items to be essentially used as RAM locations – script authors or compilers can implement read-modify-write semantics on “variables” that were previously bound to a stack position.
For example, the following diagram shows how OP_PICK and OP_PLACE are used to grab two “variable” from deep in the stack, add them, overwrite one variable and use the result. In pseudo-code:
B = A + B if (B != 0) ...
If A is located 10 below the stack top, and B 5 below, the BCH script would look like:
10 PICK 6 PICK ADD 6 PLACE IF ... ENDIF
count must be a BigNum, CScriptNum, or little-endian encoded sign-magnitude number (T.O1). count is popped from the stack. The BMD is not applied during this operation (T.0.8).
If count is positive, fail if the stack is <= count (T.O2). Otherwise, set stack item[stack length - 1 - count] to item, assuming zero-based array indexing (T.O3). For clarity, if count == 0, this opcode overwrites item with itself.
If count is < 0 (treat -0 as 0: T.O4), set stack item[abs(count)-1] to item (T.O5). Fail if abs(count) > stack length (T.O6).
Note that item MUST be popped from the stack before any stack length checks are made (T.O7).
In some scripts or situations it may be simpler to count forward from the beginning of the stack. Access in this manner is analogous to using “global variables”. However, doing so for “local variables” would complicate macro instantiation since one would need to identify the stack depth at compile or runtime to properly index items.
Given two different access semantics, it makes sense to have two different access methods.
Note that it may be desired to pass the index of a “local variable” into the instantiation of a macro (effectively passing a pointer to that variable to the macro). To accomplish this elegantly, one would need an opcode that return the current stack length. However, to avoid this opcode, it is possible to pass the local variable’s current stack depth, and have the macro add its stack usage. Or use N OP_PICK to place the variable on the stack top (essentially pass-by-value), instantiate the macro, and use N OP_PLACE OP_DROP to copy it back.
The indexing direction was chosen to be compatible with OP_PICK.