I7 - Cannot resize inextensible block

This works when compiled for Z-Machine, but not for Glulx. Any ideas?

I don’t think it’s the Glk stream stuff, because it works perfectly if you “say the captured output buffer”. It’s when it tries to fill the indexed text that it stops working. But that works fine in Z-Machine…

[spoiler][code]There is a room.

When play begins:
begin output capturing;
say “hello!”;
assert the captured output is “hello!”;

Chapter - Output capturing

To decide what indexed text is the captured output:
let the result be an indexed text;
end output capturing;
[say the captured output buffer;]
now the result is “[the captured output buffer]”;
[ Strip whitespace at the beginning and end ]
replace the regular expression “^\s+|\s+$” in the result with “”;
decide on “[the result]”;

Section - I6 functions unindexed

Include (- Global capture_active = 0; -).

To begin output capturing:
(- Begin_Unit_Test_Buffering(); -).

To end output capturing:
(- End_Unit_Test_Buffering(); -).

To say the captured output buffer:
(- Print_Unit_test_Buffer(); -).

Section for (for Z-machine only)

Include (-

Array unit_test_buffer -> IT_MemoryBufferSize + 3;

[ Begin_Unit_Test_Buffering;
if ( capture_active == 1 )
return;
capture_active = 1;
@output_stream 3 unit_test_buffer;
];

[ End_Unit_Test_Buffering;
if ( capture_active == 0 )
return;
capture_active = 0;
@output_stream -3;
if (unit_test_buffer–>0 > IT_MemoryBufferSize)
print “Error: Overflow in End_Unit_Test_Buffering.^”;
];

[ Print_Unit_test_Buffer len i;
len = unit_test_buffer–>0;
for ( i = 0 : i < len : i++ )
print (char) unit_test_buffer->(i + 2);
];

-).

Section for (for Glulx only)

Include (-

Array unit_test_buffer buffer IT_MemoryBufferSize;

Global unit_test_oldstr;
Global unit_test_newstr;

[ Begin_Unit_Test_Buffering;
if ( capture_active == 1 )
return;
capture_active = 1;
unit_test_oldstr = glk_stream_get_current();
unit_test_newstr = glk_stream_open_memory_uni(unit_test_buffer + WORDSIZE, IT_MemoryBufferSize, 1, 0);
glk_stream_set_current(unit_test_newstr);
];

[ End_Unit_Test_Buffering len;
if ( capture_active == 0 )
return;
capture_active = 0;
glk_stream_set_current(unit_test_oldstr);
@copy $ffffffff sp;
@copy unit_test_newstr sp;
@glk $0044 2 0; ! stream_close
@copy sp len;
@copy sp 0;
unit_test_buffer–>0 = len;
if (len > IT_MemoryBufferSize)
{
unit_test_buffer–>0 = IT_MemoryBufferSize;
}
];

[ Print_Unit_test_Buffer len i;
len = unit_test_buffer–>0;
for ( i = 0 : i < len : i++ )
{
glk_put_char_uni(unit_test_buffer–>(i + 1));
}
];

-).

Chapter - The assert phrase

To assert that/-- (A - a value) is (B - a value):
unless A is B:
say “Failure! Expected: [B], Got [A]^”;[/code][/spoiler]

It works if you explicitly “end output capturing” before the assert. I’m not sure yet why that makes a difference. I see that the assert line indirectly invokes the “end output capturing”, but there’s a bunch of block manipulation between the two calls (due to the way I7 passes around indexed text values) so there’s room for something to go wrong.

Got it. You’re calling

glk_stream_open_memory_uni(unit_test_buffer + WORDSIZE, IT_MemoryBufferSize, 1, 0);

This dedicates an array of IT_MemoryBufferSize words, but unit_test_buffer is only IT_MemoryBufferSize bytes. (Plus four for the buffer length.) So when you close the stream, you stomp over some memory.

Thanks. Obviously I had forgotten how buffer arrays worked, and it was just a coincidence that the memory that got corrupted was for indexed text. I changed it to Array unit_test_buffer --> IT_MemoryBufferSize + 1; and it works.