> I'm looking for the internal structure of the calculated field's data in a
> record
> as well as the bytecode "language"...
Hmm. May I should make a document about this ;)
I will give you a quick overview, and then try to add details over
the weekend and send you the notes:
There are two important data structures for calculated fields, the
stored values themselvs which I believe is covered in the format.txt that
has been circulating, and the scripts. I'll just go into the scripts
here.
Scripts are stored in the AppInfoBlock, a normal script (i.e. one
that is associated with a field in the schema) is stored in the field's
CHUNK_FIELD_DATA chunk. This has the following format:
Int8 bytecode_sz;
Int8 version_flag (currently 0x20)
Int8 access_requirements (see below)
Int8 returnType (return type, if known)
Int8 bytecode[] (an array of bytecode_sz)
Access Requirements:
This indicates wht the script is going to do, it is a set of flags
selected from:
NO_EXTERNAL_ACCESS // is completely self contained
FIELD_READING // reads fields from a record
SINGLE_RECORD_READING // reads fields within a single 'current' record
MULTI_RECORD_READING // reads fields from multiple records
ARRANGING // may move/reorder records
All of the info in this structure is determined when the script is
compiled, and depends on the exact set of operations that are used in the
script.
Because I didn't want to store the text version of the script and the
bytecode, I made a bytecode compiler that would allow the original script
to be recovered after a decompilation process. This means that there are
some aspects of the bytecode that are perhaps redundant or overly verbose,
but in all does save space.
Basically, all the compiler does is map the text strings onto tokens in
the bytearray.
Tokens are delimilated by one of these flags:
ENTER_8_BIT (1) (a function pointer)
ENTER_16_BIT (2) (a function pointer, plus an 'invisible' argument)
EXIT (3) (end of function arguments)
FIELD_NAME_REFERENCE (4) (not used)
FIELD_ID_REFERENCE (5) (a reference to a field)
LITERAL_STRING (6)
LITERAL_INTEGER (7)
LITERAL_FLOAT (8)
LITERAL_DATE (9)
LITERAL_TIME (10)
Ok, I just realized this is a bit complicated for a quick
overview, and you're definitely going to need to look a bit at the C code.
This weekend, however, I will lay out an overview of how the bytecode is
generated, and illustrate some examples. I'll put this all into script.c
so it will be easy (hopefully) to see how things are working.
-Scott
|