﻿== 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 given 8-bit signed number onto the stack.
|02   |PushByteU |\{byte\} |Push the given 8-bit unsigned number onto the stack.
|03   |PushShort |<short> |Push the 2 byte number onto the stack.
|04   |PushShortU |\{short\} |Push the 2 byte unsigned number onto the stack.
|05   |PushLong  |<long> |Push the 4 byte number onto the stack. There is no sign extension so no need for an unsigned opcode
|06   |Add ||Pop the top two items off the stack, add them, and push the result.
|07   |Sub ||Pop the top two items off the stack, subtract the first (top-most) from the second, and push the result.
|08   |Mul ||Pop the top two items off the stack, multiply them, and push the result.
|09   |Div ||Pop the top two items off the stack, divide the second by the first (top-most), and push the result.
|0A   |Min ||Pop the top two items off the stack and push the minimum.
|0B   |Max ||Pop the top two items off the stack and push the maximum.
|0C   |Neg ||Pop the top item off the stack and push the negation.
|0D   |Trunc8 ||Pop the top item off the stack and push the value truncated to 8 bits.
|0E   |Trunc16 ||Pop the top item off the stack and push the value truncated to 16 bits.
|0F   |Cond ||Pop the top three items off the stack. If the first == 0 (false), push the third back on, otherwise push the second back on.
|10   |And ||Pop the top two items off the stack and push their logical and. Zero is treated as false; all other values are treated as true.
|11   |Or ||Pop the top two items off the stack and push their logical or. Zero is treated as false; all other values are treated as true.
|12   |Not ||Pop the top item off the stack and push its logical negation (1 if it equals zero, 0 otherwise.
|13   |Equal ||Pop the top two items off the stack and push 1 if they are equal, 0 if not.
|14   |NotEqu ||Pop the top two items off the stack and push 0 if they are equal, 1 if not.
|15   |Less ||Pop the top two items off the stack and push 1 if the next-to-the-top is less than the top-most; push 0 othewise.
|16   |Gtr ||Pop the top two items off the stack and push 1 if the next-to-the-top is greater than the top-most; push 0 othewise.
|17   |LessEq ||Pop the top two items off the stack and push 1 if the next-to-the-top is less than or equal to the top-most; push 0 otherwise.
|18   |GtrEq ||Pop the top two items off the stack and push 1 if the next-to-the-top is greater than or equal to the top-most; push 0 otherwise
|=======================================================================

=== 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> |\{inclass-short\} |\{outclass-short\} |Equivalent to PutSubs (0x1D) but with 16-bit class identifiers.
|39 |PutSubs2 ||||Not Implemented
|3A |PutSubs3 ||||Not Implemented
|3B |PutGlyph |\{outclass-short\} |||Equivalent to PutGlyph (0x1C) but with 16-bit class identifier.
|3C |PushGlyph-Attr |\{glyphattr-short\} |<offset> ||Equivalent to PushGlyphAttr (0x29) but with 16-bit glyph attribute identifier.
|3D |PushAttTo-GlyphAttr |\{glyphattr-short\} |<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 |<mask-short>|<value-short>||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.
|=======================================================================

