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.
> 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...
> > 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...
In rec.arts.int-fiction, Uto <csanche...@gmail.com> wrote:
> No ofence, but saying 'parity' when Git does not support even the > first glk specification it's saying too much :)
> Yeh, I mean the byte/word access opcodes and in general the byte/worde > memory access. Sorry to insist :P
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..." *
> 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.
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.
Here, Uto <csanche...@gmail.com> wrote: > > 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.
> 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?
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. :)
--Z
-- "And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..." *
> 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.
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. :)
> 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).
Uto wrote: > 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?
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 ...
> 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 ...
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.
> 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.
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.
Also, remember that Glulxe doesn't bounds check memory accesses unless it is compiled with VERIFY_MEMORY_ADDRESS, which is not the default. Just because the error doesn't show up under Glulxe doesn't mean it isn't there - it's just that Git is catching it, but Glulxe is not.
> 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.
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.
> Here, Uto <csanche...@gmail.com> wrote: > > > 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.
> > 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?
> 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".
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.
> On Apr 6, 10:48 am, Andrew Plotkin <erkyr...@eblong.com> wrote:
> > 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".
> 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.
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.
--Z
-- "And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..." *
Finally Superglus is apparently working with Git. The bug was a syntax error on assembler source code, and Glulxa seemed to bypass it producing wrong ulx file. It was not on the glk call actually, I got confused by the fact that after the glkacall nothing was written on screen, but it was actually 10 opcodes later, it was writing to address 0, that is, to ROM. This is a bug I never realized as nor glulxe nor zag seem to have any problems with writting to ROM, and cause the code never comes back to addres 0, so the corruption of code there was not evident.
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.
Here, Uto <csanche...@gmail.com> wrote: > Finally Superglus is apparently working with Git. The bug was a syntax > error on assembler source code, and Glulxa seemed to bypass it > producing wrong ulx file. It was not on the glk call actually, I got > confused by the fact that after the glkacall nothing was written on > screen, but it was actually 10 opcodes later, it was writing to > address 0, that is, to ROM. This is a bug I never realized as nor > glulxe nor zag seem to have any problems with writting to ROM, and > cause the code never comes back to addres 0, so the corruption of code > there was not evident.
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.
--Z
-- "And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..." *
> > On Apr 6, 10:48 am, Andrew Plotkin <erkyr...@eblong.com> wrote:
> > > 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".
> > 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.
> 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.
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.
> On Apr 7, 8:07 am, Andrew Plotkin <erkyr...@eblong.com> wrote: > > Here, Jesse McGrew <jmcg...@gmail.com> wrote:
> > > On Apr 6, 10:48 am, Andrew Plotkin <erkyr...@eblong.com> wrote:
> > > > 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".
> > > 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.
> > 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.
> In that case, I suggest clarifying the spec at 1.5:
I'll look at the wording, yeah. Thanks.
--Z
-- "And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..." *
> > On Apr 7, 8:07 am, Andrew Plotkin <erkyr...@eblong.com> wrote: > > > Here, Jesse McGrew <jmcg...@gmail.com> wrote:
> > > > On Apr 6, 10:48 am, Andrew Plotkin <erkyr...@eblong.com> wrote:
> > > > > 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".
> > > > 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.
> > > 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.
> > In that case, I suggest clarifying the spec at 1.5:
> 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...)
> 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.
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.
--Z
-- "And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..." *
> > 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.
> 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
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:
Here, Uto <csanche...@gmail.com> wrote: > > > 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.
> > 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
> 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.
Before you removed them, was Superglus using short local variables with all opcodes? Or only with @copys and @copyb?
--Z
-- "And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..." *