http://www.ifarchive.org/indexes/if-archiveXprogrammingXglulxXinterpretersXgit.html
At the above is the source code, and a new Windows build.
This new version implements the new "Inform veneer acceleration" opcodes in
version 3.1.1 of the Glulx specification, bringing Git back to to parity
with Glulxe 0.4.4. Although these opcodes are currently only usable with
some Inform 6 hackery, the next Inform 7 release will use them automatically.
David
Thanks so much David. I've updated CellarDoor and have sent it around
for some testing...
jb
Yeh, I mean the byte/word access opcodes and in general the byte/worde
memory access. Sorry to insist :P
Carlos
What do you mean? Git supports the @copys and @copyb opcodes, as well
as @astores and @astoreb. I've been testing both Git and Glulxe as I
work through my new interpreter, and I've only found one obscure bug,
which isn't related to memory access.
I believe Git doesn't support 2-byte and 1-byte local variables. This
is a known problem. I6 can only compile functions with full-size
(4-byte) locals; I'm guessing that you've run into this with your
assembler.
--Z
--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*
Yes, I found it with glulxa assembler (which btw is not "my"
assembler, but Simon Stapleton's one) about 3 or 4 years ago, but does
that mean is less important? I mean, if it's a bug, is a bug. Is it so
hard to solve? Can I help some way?
I really thought it didn't support the @astoreb, @aloadb, etc.
opcodes, I don't see any reason to use them if no 1/2 bytes vars can
be used anyway, but I'm glad to know it does, cause then maybe the
solution may be closer.
When I say Git doesn't support even the first glk specs I mean, if it
does not support 1/2 byte vars, is not a Glulx implementation, and so
it's not following even the Glulx 1.0 specs. Yeh, I know it's kinda
brickheaded thoughts, but imho gestal+version opcode should return
0x00000000 in Git ;)
Well, I say it again, I can try to help solving that bug if needed,
but I would appreciate the help of someone who knows the code already.
Well, yes, it is less important. It doesn't break any existing game
files, and it's prominent enough to deter people from making games
that require this feature.
The feature (small local variables) doesn't block any development as
far as I know. I threw it into the spec without any obvious use case.
I think I was thinking that some other VM might be ported to Glulx,
and might want to use smaller values everywhere for efficient's sake.
But you can get the same effect with 4-byte locals if you throw in
some judicious "x & $FFFF".
So, I would be happy if the bug were fixed, but it's not on my
priority list.
> I mean, if it's a bug, is a bug. Is it so
> hard to solve? Can I help some way?
You will have to ask the Git maintainers about that.
> I really thought it didn't support the @astoreb, @aloadb, etc.
> opcodes, I don't see any reason to use them if no 1/2 bytes vars can
> be used anyway
That logic doesn't hold up. I6 uses @astoreb/@aloadb heavily --
everywhere it accesses a byte array (an "Array->index" expression in
I6). The I6 object structure has some two-byte fields, so the veneer
library uses @astores/@aloads as well. (In the object property table,
actually.) Git handles all of that correctly, because they're small
values in main memory. It's only the local variables that can't be
accessed at small sizes.
> When I say Git doesn't support even the first glk specs I mean, if it
> does not support 1/2 byte vars, is not a Glulx implementation, and so
> it's not following even the Glulx 1.0 specs. Yeh, I know it's kinda
> brickheaded thoughts, but imho gestal+version opcode should return
> 0x00000000 in Git ;)
Yeah, well, forcing the version number to reflect known bugs worked
out really poorly for the Z-machine. :)
Good news, David! :D
Great work!
Saludos!
Eliuk Blau.
Well, that's not true, it breaks all the games made with Superglus, as
Superglus uses that capability at least one year before Git did even
exist. That is, Git is rarely used in spanish IF scene, as people (in
general) prefer to have only one interpreter, not one for Inform and
one for Superglus games.
I fully understand though it's not in priority list, but I've been
really expecting it to climb up the priority list for long. After 3/4
years I think I'll give up. This afternoon I started to check
Superglus code to find a way to avoid the use of that kind of
variables, something that I've been long trying to avoid, as 140k
source file of glulx assembler is hard to check, and over that is hard
to be sure you are not introducing new bugs just to make a uncomplete
interpreter to work, but well, as I said, I gave up.
> The feature (small local variables) doesn't block any development as
> far as I know.
Well, now you know it does :)
>I threw it into the spec without any obvious use case.
That's true, and I don't know why the original writer of Superglus
decided to use them, but the fact is it was in the spec and he did
> So, I would be happy if the bug were fixed, but it's not on my
> > I mean, if it's a bug, is a bug. Is it so
> > hard to solve? Can I help some way?
> You will have to ask the Git maintainers about that.
Yeh, I was answering you, but it was actually a call to comunity, I'm
not really sure if Iain or David is taking care of taht atm :)
> That logic doesn't hold up. I6 uses @astoreb/@aloadb heavily --
> everywhere it accesses a byte array (an "Array->index" expression in
> I6). The I6 object structure has some two-byte fields, so the veneer
Yep, it seems I never understood the bug completely, I allways thought
Git was unable in general to manage anyhting that was not 4-bytes
wide. In fact, knowing that opcodes are supported, is the reason why
I'm looking at the way to avoid the bug, till now I wouldn't even have
tried, would have been no use :D
> Yeah, well, forcing the version number to reflect known bugs worked
> out really poorly for the Z-machine. :)
Well, I said it was a brickhead though :D
So I do. I apologize for not paying enough attention to the community
outside of RAIF.
Well, you cannot read spanish so you actually cannot, I could have
also insisted more on the problem and I did not (probably cause anyway
we have glulxe and zag to run games, so is not a critical problem).
Anyway, my work on Superglus is going well and it seems I have avoided
the 4-byte problem (it will require a deep test though, I don't wanna
introduce new bugs). Sadly, now I'm getting messages about writing out
of bounds I don't get why are happening. If I don't find a
solutionI'll try to post glulx asm code raising the error (there error
doesn't raise on glulxe).
It needs someone to spend the time thinking about how Git's stack is held,
and how 1 and 2 byte local variables can be introduced without slowing down
the rest of the interpreter. It's on my list of things to look at, but this
is a big list, and this particular problem is a fair way down it ...
David
Apparently, I'm getting rid of that problem, so maybe we can forget
about it for the time being, at least till I can confirm the problem
has been passed by. Anyway, thanks for the answer.
At the moment I cannot confirm it cause after changing the headers
other problem has arised with Git, now I'm getting an "Out-of-bounds
memory access" message in return to a glk_select when the event
received is 0x03. It happens both with last version of Git usign
winglk, and with previous version using gargoyleglk.
I have to set up the enviroment to be able to compile and debug Git
step by step to be able to define that properly, at the moment I only
have Visual Studio and it seems the makefile is prepared for gcc, so
I'll have a look at it, I have never used gcc on win, only on linux.
Git (or any Glulx interpreter) doesn't handle glk_select() (or any Glk
function) directly - that will be passed to the Glk library.
Since multiple Glk libraries show the same behaviour, and it's a
widely
used feature, I strongly suspect that there's a mistake somewhere in
your generated Glulx file, not in the interpreter.
David
David
Yes, I agree, that's why I will try to run Git on debugger to try to
identify what is exactly trying to execute. It's weird though, as it
only happens with Git (no matter if it used gargoyle or winglk), and
never happens in Glulxe or Zag, but well, I stil lhave to investigate
it closely to get a conclusion. I bet for Glulxa doing something wrong
though, uses to be the main problem.
I hope vaporware can upload that corrected version he has, I would be
very happy to have an inproved Glulxa.
I considered using 1- and 2-byte locals in Snack's veneer, until I
realized they couldn't be used as operands for most instructions. All
instructions except copyb and copys access the local frame 4 bytes at
a time, regardless of the actual local variable sizes.
That seems to negate any efficiency gain that might otherwise result
from using small locals: to do anything with them, you need to
surround your code with copyb/copys instructions. You save a little
bit of space on the stack, at the cost of a lot of performance and
space in the story file.
vw
No, an instruction which refers to a local will access the local frame
at a width defined by the local's size. (As defined by the function
header.)
The inherent width of the instruction (1 for copys, 2 for copyb, 4 for
all the others) only affects how it accesses main memory.
But this stuff has barely been tested even in glulxe. Yes, I'll get it
into the unit test eventually.
Of course I still have to check it deeply, cause still it's possible
it fails somewhere else, but at least I've been able to run a simple
one room, one item, Superglus game for a while without problems :)
Thanks for all the comments on this threads, many have been very
helpful.
I've checked in a fix in Glulxe that will detect writing to ROM (as a
fatal error) if memory-range checking is compiled in. It'll be in the
next release.
Glad you found your problem.
In that case, I suggest clarifying the spec at 1.5:
<quote>
The indirect modes (all except "constant") access 32-bit fields,
either in the stack or in memory. This means four bytes starting at
the given address. A few opcodes are exceptions: copyb and copys (copy
byte and copy short) access 8-bit and 16-bit fields (one or two bytes
starting at the given address.)
The "call frame local" modes access a field on the stack, starting at
byte ((FramePtr+LocalsPos) + address). As described in section 1.3.1,
"The Call Frame", this must be aligned with (and the same size as) one
of the fields described in the function's locals format. It must not
point outside the range of the current function's locals segment.
</quote>
I took these two paragraphs to mean that only copyb and copys may
access 8-bit or 16-bit fields in the local frame: other instructions
would attempt to access a 32-bit field (first paragraph) which is
illegal if the local at that offset is not 32 bits wide (second
paragraph).
Also, at 1.3.1:
<quote>
The "format of locals" information is needed by the terp in two
places: when calling a function (to write in function arguments), and
when saving the game (to fix byte-ordering of the locals.) The
formatting is not enforced by the terp while a function is executing.
</quote>
I took this to mean the interpreter only ever needs to look at the
"format of locals" when passing in function arguments or saving the
game state, not when accessing operand values.
vw
I'll look at the wording, yeah. Thanks.
Hmm, now that I look at the glulxe source code, it seems to behave the
same as my reading of the spec: parse_operands() always reads 4 bytes
from a local, unless oplist->arg_size is 1 or 2, which is only the
case for copyb/copys. The comments there mention that the local
address is supposed to be aligned on a 4-byte boundary. And
store_operand() always writes 4 bytes; there are alternate versions
for 1 and 2 bytes, store_operand_b() and store_operand_s(), which
again are only used for copyb/copys.
Personally, I'd be happy to see 1 and 2 byte locals just disappear:
operand size seems like something that should be controlled by the
addressing mode, not a table in memory, and searching through that
table for every local access is an annoying overhead for a feature
that's so rarely used. (On the other hand, there are two unused
addressing modes...)
vw
Well, that kind of sucks.
In that case, all those glus game files are doing something which is
unintended by anybody, and which is certainly no more powerful than
just using 4-byte locals in the first place.
> Personally, I'd be happy to see 1 and 2 byte locals just disappear
It is looking like the sanest way out, at this point.
Sorry, folks. I'm sure I would have noticed this ten years ago if I'd
written any compiler code to generate this stuff.
Atm I have no problems with that, I don't know what lead to the
original creator of Superglus code to use those parameters, but I've
got rid of them, so if nor Snack, nor Inform nor Superglus uses them,
I think it's the better to remove them asap (before someone else
decides to use by any reason). About the old Superglus games, I'll try
to push authors to recompile them using the new version as soon I
release it.
@David Kinder: btw while testing Superglus under Git (once the 1 byte
locals where removed) I was getting the "Out-of-bounds memory access".
While that message is telling what happens it would be nice it the
details of the operation failing are described in the error window,
like "Out-of-bounds memory access while writing at 0x0023", it would
be helpful for compiler developers. Sames goes for glulxe or any oter
interprete when compiled with the rom check define.
Basically, for Git, is just changing this two functions at the bottom
of memory.c:
git_uint32 memReadError (git_uint32 address)
{
fatalError ("Out-of-bounds memory access");
return 0;
}
void memWriteError (git_uint32 address)
{
fatalError ("Out-of-bounds memory access");
}
as you see, they receive the address already so I don't think it would
be a problem.
Before you removed them, was Superglus using short local variables
with all opcodes? Or only with @copys and @copyb?
There were no 2 byte parameters, all were 4 or 1 byte long. Those
using 1 byte were used with @copyb, @storeb and @aloadb
Anyway, there were about 10 functions using 1 byte parameters, and of
those, 5 were not actually using them, I mean, they were on the call
frame, but later they were not used (probably, reminds of a previous
use not properly cleaned).
The other 5, 4 where only using copyb, and the last one, the hardes to
correct, was using aloadb and storeb to copy two arrays of byte, using
the local var as temporary storage.
Note: the original coder of Superglus could not use @mcopy, as Glulxa
was unable to use that opcode till I added it this week.
Okay, that's good. That's within the limited range of use that's
consistent with both the spec, the spec I *thought* I wrote, and
glulxe's behavior.
I will update the spec to say that short locals are deprecated, but
that limited use (@copys and @copyb) may be supported for historical
reasons. I can get my javascript interpreter to do that much -- it
should already, since I ported glulxe's logic.
Are you making a javascript port of Glulxe and Glk? That sounds nice :D
Yes. But it's a long way from being done.
Well, Time will see. At least is started :)