gnusto 
| resources: | Home Installation Mailing list Source code Bugs Screenshots Nightlies |
|---|---|
| reference: | Roadmap Error messages Code overview Debugger (prototype only) Playthroughs |
Felapton - gnusto-lib.js
gnusto-lib.js is Gnusto's engine, the Z-machine itself. It's currently fairly readable, although it's large enough to be unwieldy; it needs to be split into smaller pieces by function.
gnusto-lib.js will be renamed to felapton.js at some point.
An overview of Felapton's operation
JIT compilation: Gnusto is a virtual machine (a Z-machine) running on a virtual machine (Mozilla's JavaScript engine), just as a Z-machine for Emacs or Java is. However, Gnusto uses an interesting technique called just in time compilation-- it does not interpret Z-code at all, but rather compiles it down to JavaScript functions. Strings of opcodes are converted to JavaScript function objects, which are stored in an array and executed the next time without having to re-read the code.
Execution cycle: After Felapton is set up, the user calls its go method with a dummy parameter. Felapton will then go off and do its work. go() will return when:
- The machine needs input of some kind from the user.
- The machine needs to affect the outside world somehow: it may want to save, restore, restart, quit, verify the game's integrity, make a sound, move the cursor, and so on. Simple writes to screen or transcript don't cause such breaks; for those, see below.
- The machine has done a certain amount of work. To allow for UI updates, and to let the system break infinite loops,
go()will return after a few thousand opcodes whatever happens. This is called "wimping out". - The machine hit a breakpoint (if you're debugging).
The return value of go() is known as an "effect". All effects have symbolic names of the form GNUSTO_EFFECT_*.
For some effects, Felapton needs an answer. (For example, when it stops for user input, it needs to know what the input was.) You should supply the answer as the parameter of go() next time you call it; if the effect you were given doesn't need an answer, just supply 0.
Simple writes to screen or transcript don't cause go() to return. Instead, they get stored in a buffer ready to be read the next time the machine stops; when it does, you should call engine_console_text() and engine_transcript_text() to see what you should print. See the descriptions of those functions below.
The future: All JIT data is lost when Gnusto is closed. We should cache it somehow (can functions be serialised?) so that games play faster after the first time.
Exported functions
The future: We should possibly make the whole of Felapton a class; "setup" would then become the constructor and "go" would be a method.
setup
Resets the z-machine. Must be called before you call go().
The future: Should be renamed to engine_setup!
go
The do-everything function. Its use is described above.
engine_console_text, engine_transcript_text
Return all text written to the screen, or the transcript, respectively, since you last called them. This applies before the current effect: for example, if the font is currently italic, and go() returns with an effect that wants to change the font to bold, then this text should be printed in italic.
Calling either of these functions clears that function's internal buffer, so if you call it again without a call to go() in between, you'll get an empty string. If you don't call these functions between calls to go(), any data in the buffers won't be lost (but don't do this, especially not with engine_console_text() because it will lead to text formatting problems).
No text should ever be returned by engine_transcript_text() unless transcribing has been successfully turned on. You don't need to check it unless you know that's happened.
engine_effect_parameters
Some effects need parameters; the effect's documentation will say whether it does. If it does, calling this function will return them. You may call it as many times as you like between calls to go(), with the same result. Calling this when you've got an effect which doesn't have parameters yields undefined results.
Identifier prefixes
The identifier prefixes for gnusto-lib are:
- Most identifiers are not prefixed.
engine, in newer identifiers.- The handler function for the opcode
@foo is namedZ_foo. - JIT functions constructed by gnusto-lib are named
Jpc, where pc is the value of the program counter at the start of the function.