Thursday, 16 April 2009

Coding the QCode virtual Machine

So I've been busying myself with the QCode virtual machine to interprete OPO applications, the only problem is there are very few resources about it. Really the only info I have is part of the psionics files (OPO.fmt)

Currently the only big problem I have is with arrays. I used to have problems with the way the interpreter handled globals but then I reread the document and realised how the applications were stored in the DataStackFrame

<-- Globals -->
<-- Proc 1 Local Variables -->
<-- Proc 2 Local Variables -->
<-- ALLOC free space -->

When a local variable is accessed the offset in procedures offset in the DataStackFrame must be added, fine enough.

Now the thing with Arrays is that information gets stored in both the procedures variable section and array section, even worse if its a global array of strings... information gets stored in the globals section, array section and string section.

So say we are going to process OpCode 0x1B - push$ the value of EE+(pop%)

First we need to get the EE value, which is the pointer to the Global Variable, this is a Int16 stored after the OpCode.

The FieldVal which is the array index is popped from the stack as an Int16

We go through all the EE values in the Procedure which are stored in the following order:

Global Variables defined in the procedure
Procedures Called
Global Variables referenced by the procedure

For what we need it will be the first and the last, from there we get the name of the variable (this is stored in the applications QCode - performance tip: use short names for globals)

Now find out where in the DataStackFrame the global variable is stored now we know the name of it (look through each procedure - if the procedure didn't define the global itself)

So once we have done that the real fun begins, due to the way QCode and OpCodes use DataStackFrame addresses to variables differently.

Ssuppose we declare x$(2,4), and set the two elementsto "abc" and "x" respectively, and the variable is placed at location 22within the data stack frame. Then the memory will contain:

Location: 22 23 24 25 26 27 28 29 30 31 32 33 34
Value: $0002 4 3 'a' 'b' 'c' ? 1 'x' ? ? ?

The array control section will contain 22 as the location, the string control section will contain 24, and the q-code will use 25.
However we need to find the string at the index popped off the stack, so we have to move along the indexed repititions of the maximum string length (found in the string control section) however doing array bounds checks so we don't overrun memory (size found in the array control section) and then we work out the value of the string


No comments: