== Stack Machine Commands ==

This document describes the commands that are defined in Graphite’s stack
machine, which are used to run rules and test their constraints. By default
arguments are 8-bits wide unless stated as being short (16-bit) or long
(32-bit). Angle brackets (<arg>) indicate a signed value, curly braces ({arg})
indicate an unsigned value. All values larger than a byte are stored big endian
with the most significant byte first. <offset> is a slot offset relative to the
current slot that opcodes act upon. Any opcode with a value outside the range of
opcodes listed here (currently 0x00-0x3E) is considered illegal and will cause
the font to fail to load.

=== General arithmetic operations ===
[cols="1,2,1,11",options="unbreakable,header,compact",width="100%",frame="topbot",grid="none"]
|===============================================================================
|Code|Name       |Param    |Description

|00  |NOP        |         |Do nothing.
|01  |PushByte   |<byte>   |Push the 8-bit signed number onto the stack.
|02  |PushByteU  |\{byte\} |Push the 8-bit unsigned number onto the stack.
|03  |PushShort  |<short>  |Push the 16-bit signed number onto the stack.
|04  |PushShortU |\{short\}|Push the 16-bit signed number onto the stack.
|05  |PushLong   |<long>   |Push the 32-bit signed number onto the stack. +
                            No sign extension means no unsigned opcode needed.
|06  |Add        |         |Pop two items, add them, and push the result.
|07  |Sub        |         |Pop two items, subtract (top-most) from the next,
                            and push the result.
|08  |Mul        |         |Pop two items, multiply, and push the result.
|09  |Div        |         |Pop two items, divide the second by the first
                            (top-most), and push the result.
|0A  |Min        |         |Pop two items and push the minimum.
|0B  |Max        |         |Pop two items and push the maximum.
|0C  |Neg        |         |Pop item and push the negation.
|0D  |Trunc8     |         |Pop item and push the value truncated to 8 bits.
|0E  |Trunc16    |         |Pop item and push the value truncated to 16 bits.
|0F  |Cond       |         |Pop three items. If the first == 0 (false),
                            push the third back on, otherwise push the second
                            back on.
|10  |And        |         |Pop two items and push their *logical and*.
                            footnoteref:[Bool, Zero is false; Non-Zero is true.]
|11  |Or         |         |Pop two items and push their *logical or*.
                            footnoteref:[Bool]
|12  |Not        |         |Pop item and push its *logical negation*.
                            footnoteref:[Bool]
|13  |Equal      |         |Pop two items and if equal push 1, 0 if not.
|14  |NotEqu     |         |Pop two items and if equal push 0, 1 if not.
|15  |Less       |         |Pop two items and if 2nd is less than 1st
                            push 1, otherwise push 0
|16  |Gtr        |         |Pop two items and if 2nd is greater than 1st
                            push 1, otherwise push 0
|17  |LessEq     |         |Pop two items and if 2nd is less than or equal to
                            1st push 1, otherwise push 0
|18  |GtrEq      |         |Pop two items and if 2nd is greater than or equal to
                            1st push 1, otherwise push 0
|===============================================================================

=== Rule processing and constraints ===
[cols="1,4,3,3,3,22",options="unbreakable,header,compact",width="100%",frame="topbot",grid="none"]
|===============================================================================
|Code|Name                 |Param           |Param         |Param         |
      Description

|19  |Next                 |                |              |              |
      Move the current slot pointer forward one slot (used after we have
      finished processing that slot).

|1A  |NextN                |<count>         |              |              |
      Not Implemented: Move the current slot pointer by the given number of
      slots (used after we have finished processing the current slot). The count
      may be positive or negative. Should not be used to copy a range of slots;
      CopyNext is needed for that.

|1B  |CopyNext             |                |              |              |
      Copy the current slot from the input to the output and move the current
      slot pointer forward one slot.

|1C  |PutGlyph             |\{outclass\}    |              |              |
      Put the first glyph of the specified class into the output. Normally used
      when there is only one member of the class, and when inserting.

|1D  |PutSubs              |<offset>        |\{inclass\}   |\{outclass\}  |
      Determine the index of the glyph that was the input in the given slot
      within the input class, and place the corresponding glyph from the output
      class in the current slot. The slot number is relative to the current
      input position.

|1E  |PutCopy              |<offset>        |              |              |
      Copy the glyph that was in the input in the given slot into the current
      output slot. The slot number is relative to the current input position.

|1F  |Insert               |                |              |              |
      Insert a new slot before the current slot and make the new slot the
      current one.

|20  |Delete               |                |              |              |
      Delete the current item in the input stream.

|21  |Assoc                |\{count\}       |<slot-1> ...  |<slot-count>  |
      Set the associations for the current slot to be the given slot(s) in the
      input. The first argument indicates how many slots follow. The slot
      offsets are relative to the current input slot.

|22  |ContextItem          |<offset>        |\{byte-count\}|              |
      If the slot currently being tested is not the slot specified by the
      <offset> argument (relative to the stream position, the first modified
      item in the rule), skip the given number of bytes of stack-machine code.
      These bytes represent a test that is irrelevant for this slot.

|23  |AttrSet              |\{slotattr\}    |              |              |
      Pop the stack and set the value of the given attribute to the resulting
      numerical value.

|24  |AttrAdd              |\{slotattr\}    |              |              |
      Pop the stack and adjust the value of the given attribute by adding the
      popped value.

|25  |AttrSub              |\{slotattr\}    |              |              |
      Pop the stack and adjust the value of the given attribute by subtracting
      the popped value.

|26  |AttrSetSlot          |\{slotattr\}    |              |              |
      Pop the stack and set the given attribute to the value, which is a
      reference to another slot, making an adjustment for the stream position.
      The value is relative to the current stream position. [Note that
      corresponding add and subtract operations are not needed since it never
      makes sense to add slot references.]

|27  |IAttrSetSlot         |\{slotattr\}    |\{index\}     |              |
      Pop the stack and set the given indexed attribute of the current slot to
      the value, which is a reference to another slot, making an adjustment for
      the stream position. The value is relative to the current stream position.
      [Currently the only indexed slot attributes are component.X.ref.]

|28  |PushSlotAttr         |\{slotattr\}    |<offset>      |              |
      Look up the value of the given slot attribute of the given slot and push
      the result on the stack. The slot offset is relative to the current input
      position.

|29  |PushGlyph-Attr       |\{glyphattr\}   |<offset>      |              |
      Look up the value of the given glyph attribute of the given slot and push
      the result on the stack. The slot offset is relative to the current input
      position.

|2A  |PushGlyph-Metric     |\{glyph-metric\}|<offset>      |<level>       |
      Look up the value of the given glyph metric of the given slot and push the
      result on the stack. The slot offset is relative to the current input
      position. The level indicates the attachment level for cluster metrics.

|2B  |PushFeat             |\{feat\}        |<offset>      |              |
      Push the value of the given feature for the current slot onto the stack.

|2C  |PushAttrTo-GlyphAttr |\{glyphattr\}   |<offset>      |              |
      Look up the value of the given glyph attribute for the slot indicated by
      the given slot’s attach.to attribute. Push the result on the stack.

|2D  |PushAttTo-GlyphMetric|\{glyph-metric\}|<offset>      |<level>       |
      Look up the value of the given glyph metric for the slot indicated by the
      given slot’s attach.to attribute. Push the result on the stack.

|2E  |PushISlotAttr        |\{slotattr\}    |<offset>      |<index>       |
      Push the value of the indexed slot attribute onto the stack. [The current
      indexed slot attributes are component.X.ref and userX.]

|2F  |PushIGlyph-Attr      |\{glyphattr\}   |<offset>      |<index>       |
      Not Implemented: Push the value of the indexed glyph attribute onto the
      stack. [Examples of indexed glyph attributes are component.X.box.top,
      component.X.box.bottom, etc.]

|30  |PopRet               |                |              |              |
      No more processing is needed for this rule. Pop the top of the stack and
      return that value. For rule action code, the return value is the number of
      positions to move the stream position forward (or backward, if the number
      is negative) for the next rule. For constraint code, the return value is a
      boolean indicating whether the constraint succeeded.

|31  |RetZero              |                |              |              |
      Terminate the processing and return zero.

|32  |RetTrue              |                |              |              |
      Terminate the processing and return true (1).

|33  |IAttrSet             |\{slotattr\}    |\{index\}     |              |
      Pop the stack and set the value of the given indexed attribute to the
      resulting numerical value. Not to be used for attributes whose value is a
      slot reference. [Currently the only non-slot-reference indexed slot
      attributes are userX.] Not  supported in version 1.0 of the font tables.

|34  |IAttrAdd             |\{slotattr\}    |\{index\}     |              |
      Pop the stack and adjust the value of the given indexed slot attribute by
      adding the popped value. Not to be used for attributes whose value is a
      slot reference. [Currently the only non-slot-reference indexed slot
      attributes are userX.] Not  supported in version 1.0 of the font tables.

|35  |IAttrSub             |\{slotattr\}    |\{index\}     |              |
      Pop the stack and adjust the value of the given indexed slot attribute by
      subtracting the popped value. Not to be used for attributes whose value is
      a slot reference. [Currently the only non-slot-reference indexed slot
      attributes are userX.]

|36  |PushProcState        |\{byte\}        |              |              |
      Not Implemented: Pushes the processor state value identifier by the
      argument onto the stack.

|37  |PushVersion          |                |              |              |
      Pushes the version of the engine onto the stack as a 32 bit number. The
      stack holds 32 bit values.

|38  |PutSubs              |<offset>        |\{inclass16\} |\{outclass16\}|
      Equivalent to PutSubs (0x1D) but with 16-bit class identifiers.

|39  |PutSubs2             |                |              |              |
      Not Implemented

|3A  |PutSubs3             |                |              |              |
      Not Implemented

|3B  |PutGlyph             |\{outclass16\}  |              |              |
      Equivalent to PutGlyph (0x1C) but with 16-bit class identifier.

|3C  |PushGlyph-Attr       |\{glyphattr16\} |<offset>      |              |
      Equivalent to PushGlyphAttr (0x29) but with 16-bit glyph attribute
      identifier.

|3D  |PushAttTo-GlyphAttr  |\{glyphattr16\} |<offset>      |              |
      Equivalent to PushAttToGlyphAttr (0x2C) but with 16-bit glyph attribute
      identifier.

|3E  |BitAnd               |                |              |              |
      Pop the top two items off the stack, perform a bitwise AND, and push the
      result.

|3F  |BitOr                |                |              |              |
      Pop the top two items off the stack, perform a bitwise OR, and push the
      result.

|40  |BitNot               |                |              |              |
      Pop the top item off the stack, perform a bitwise NOT, and push the
      result.

|41  |SetBits              |<mask16>        |<value16>     |              |
      Pop the top item off the stack, clear the mask bits, set the value bits,
      and push the result.

|42  |SetFeat              |\{feat\}        |<offset>      |              |
      Pop a value off the stack and set the given feature on referenced slot to
      that value. The value is clipped at the maximum permissible value for that
      feature.
|===============================================================================
