Re: Z-machine abbreviations are broken

45 views
Skip to first unread message

Dannii Willis

unread,
Mar 28, 2013, 8:06:22 PM3/28/13
to parc...@googlegroups.com
Thank you for reporting the problem, it's a serious one indeed!

On Friday, 29 March 2013 08:25:02 UTC+10, Tom Hargreaves wrote:
Hi.  Parchment/ZVM fails to handle abbreviations table entries moving.
Here's a test case:

[ main;
  string 05 "bar";
  print "foo @05 baz^";
];

This should print "foo bar baz" according to spec, and indeed does so
in Bocsel, Nitfol, and Frotz.

But not here, where it prints "foo     baz":

This isn't a theoretical problem: such abbreviation twiddling is used
by _Suveh Nux_ and _Large Machine_ among other games[1], and is even
mentioned in the DM4.

Tom.

[1] Oddly enough, _69105 Keys_, which was top of my list of games likely
to do this, doesn't use this trick.

Tom Hargreaves

unread,
Mar 29, 2013, 7:16:46 AM3/29/13
to parc...@googlegroups.com
On Thu, Mar 28, 2013 at 05:06:22PM -0700, Dannii Willis wrote:
> Thank you for reporting the problem, it's a serious one indeed!
>
[...]

What I admit is unclear to me is why zvm takes the approach it does to
optimization.

There seem two possible approaches: be naive and don't cache anything,
which is simple and robust, if slow. Or cache everything and check
meticulously for when cached things should be refreshed, to avoid
breaking on all of the possible corner cases (such as this one).

While either works, the second requires a Lot More Effort[1], and I'm
not sure that a superfast Z-machine emulator is worth it. After all,
even in javascript, a stupid emulator is surely plenty fast enough for
the not-even-slightly-speed-critical application at hand. (Maybe this
was less true in the past, before people started caring about
javascript performance?)

Tom.

[1] After all, there are (allegedly) only two hard things in computer
science, and cache invalidation is one of them.

Dannii Willis

unread,
Mar 29, 2013, 8:20:32 AM3/29/13
to parc...@googlegroups.com
Prior to this, I hadn't been aware of any cases that changed cached strings, and I'm still not aware of any cases of using functions in dynamic memory. So it seemed like a valid risk, though I was anticipating problems would arise eventually. In the short term I'll stop caching strings in dynamic memory.

In the long term I do have ideas for a cache invalidation system. Luckily there are only 7 opcodes which can write to arbitrary addresses.

Dannii Willis

unread,
Mar 29, 2013, 8:43:07 AM3/29/13
to parc...@googlegroups.com
Hmm... this is going to be trickier than I anticipated. It's not simply enough to stop caching the abbreviations, because the abbreviations are inserted into the texts in static memory. I don't want to have to stop caching those! I'll have to come up with something to insert the abbreviations as those strings are used. Ugh.

Dannii Willis

unread,
Mar 30, 2013, 11:57:32 PM3/30/13
to parc...@googlegroups.com
Okay, this is fixed now.

Tom Hargreaves

unread,
Apr 3, 2013, 12:20:49 PM4/3/13
to parc...@googlegroups.com
On Fri, Mar 29, 2013 at 05:20:32AM -0700, Dannii Willis wrote:
> Prior to this, I hadn't been aware of any cases that changed cached
> strings, and I'm still not aware of any cases of using functions in dynamic
> memory. So it seemed like a valid risk, though I was anticipating problems
> would arise eventually. In the short term I'll stop caching strings in
> dynamic memory.
>
> In the long term I do have ideas for a cache invalidation system. Luckily
> there are only 7 opcodes which can write to arbitrary addresses.

Thanks for fixing this. However, "I was anticipating problems would
arise eventually" worries me: it reads to me as "I don't trust this
code".

Just to make your day brighter, here's another test case:
[ printit;
print_ret "foo";
];

[ main;
printit();
printit();
];

This should print two lines, each containing "foo".

Parchment prints "foofoo":
http://iplayif.com/?story=http://sphere.chronosempire.org.uk/~HEx/print_ret.z5

Tom.

Dannii Willis

unread,
Apr 3, 2013, 9:47:18 PM4/3/13
to parc...@googlegroups.com
On Thursday, April 4, 2013 2:20:49 AM UTC+10, Tom Hargreaves wrote:
On Fri, Mar 29, 2013 at 05:20:32AM -0700, Dannii Willis wrote:
> Prior to this, I hadn't been aware of any cases that changed cached
> strings, and I'm still not aware of any cases of using functions in dynamic
> memory. So it seemed like a valid risk, though I was anticipating problems
> would arise eventually. In the short term I'll stop caching strings in
> dynamic memory.
>
> In the long term I do have ideas for a cache invalidation system. Luckily
> there are only 7 opcodes which can write to arbitrary addresses.

Thanks for fixing this.  However, "I was anticipating problems would
arise eventually" worries me: it reads to me as "I don't trust this
code".

Haha no, it's more like "I can't help breaking the law even though I know it will catch up with me eventually." https://github.com/curiousdannii/ifvms.js/blob/master/src/zvm/intro.js lists a few other ways in which it deliberately ignores the standard.
 
Just to make your day brighter, here's another test case:
[ printit;
  print_ret "foo";
];

[ main;
  printit();
  printit();
];

This should print two lines, each containing "foo".

Parchment prints "foofoo":
http://iplayif.com/?story=http://sphere.chronosempire.org.uk/~HEx/print_ret.z5

Tom.

Oops! Fixed that too. 
Reply all
Reply to author
Forward
0 new messages