Format of Z-Machine property tables for objects?

ZMS 1.1 section 12.4 says:

Each object has its own property table. Each of these can be anywhere in dynamic
memory (indeed, a game can legally change an object's properties table address in
play, provided the new address points to another valid properties table). The
header of a property table is as follows:

   text-length     text of short name of object
  -----byte----   --some even number of bytes---

where the text-length is the number of 2-byte words making up the text, which is
stored in the usual format. (This means that an object's short name is limited to
765 Z-characters.) After the header, the properties are listed in descending
numerical order. (This order is essential and is not a matter of convention.) 

and section 12.4.2 says:

In Versions 4 and later, a property block instead has the form

   size and number       the actual property data
  --1 or 2 bytes---     --between 1 and 64 bytes--

The property number occupies the bottom 6 bits of the first size byte.

With additional information in the subpoints of 12.4.2 about how to interpret the size and number byte(s) depicted in 12.4.2.

How can this structure be reconciled with, for example, the routine IndivTable() provided in ITM 9.6?

[ IndivTable obj x n;
  x = obj.3;
  if (x == 0) rfalse;
  print "Table for ", (object) obj, " is at ", (hex) x, "^";
  while (x-->0 ~= 0)
  {   print (hex) x-->0, " (", (property) x-->0, ")  length ", x->2, ": ";
      for (n = 0: n< (x->2)/2: n++)
          print (hex) (x+3)-->n, " ";
      new_line;
      x = x + x->2 + 3;
  }
];

Looking at that routine’s algorithm, it seems as though:

  1. obj.3 evaluates to the address of the first property block in the data section of obj's property table, not the header of obj's property table
  2. the first word (-->0) of the property block contains a property ID
  3. the third byte (->2) of the property block contains the (even) number of bytes of property data storage
  4. the for loop expects there to always be a three-byte block header (i.e. first word plus third byte) in addition to property data

While the structure implicit in the IndivTable() routine definition makes sense, it does not seem to match the description from ZMS 12.4.2 at all. Which of points 1 through 4 above are incorrect? If none of them, what am I missing?

As I understand it…

The ZMS describes how the Z-Machine handles properties. But since properties are a limited resource, Inform implements its own “individual properties” on top of that. Yo’ll note that IndivTable looks at obj.3. The Inform Technical Manual has this to say about property number 3:

    property 3: a byte address pointing to the individual properties table
        for this object; property 3 is absent if it has no individual
        properties.

So properties in Inform are not necessarily implemented as Z-Machine properties. Handling these individual properties is one of the services provided by the “run-time veneer”.

2 Likes

This is correct.

A happy side-effect of this is that individual property arrays have a maximum length of 32 words even in z3, whereas common properties are limited to 4 words in z3.

So the “property table” discussed in ZMS 12.4 is only for what are designated “common properties” in ITM and DM4?

Most definitely.