#ifndef EXEC_H
#define EXEC_H
/*
* A compiled program consists of several data blocks, all allocated
* contiguos in memory to enhance the working set. At the compilation,
* the blocks will be allocated separately, as the final size is
* unknow. When compilation is done, the blocks will be copied into
* the one big area.
*
* There are 8 different blocks of information for each program:
* 1. The program itself. Consists of machine code instructions for a virtual
* stack machine. The size of the program must not be bigger than
* 65535 bytes, as 16 bit pointers are used. Who would ever need a bigger
* program :-)
* 2. Function names. All local functions that has been defined or called,
* with the address of the function in the program. Inherited functions
* will be found here too, with information of how far up the inherit
* chain that the function was defined.
* 3. String table. All strings used in the program. They are all pointers
* into the shared string area. Thus, they are easily found and deallocated
* when the object is destructed.
* 4. Table of variable names. They all point into the shared string table.
* 5. Line number information. A table which tells at what address every
* line belongs to. The table has the same number of entries as the
* programs has source lines. This is used at errors, to find out the
* line number of the error.
* 6. List of inherited objects.
*/
#include "machine.h"
/*
* When an new object inherits from another, all function definitions
* are copied, and all variable definitions.
* Flags with NAME_ can't explicitly declared. Flags that can be declared,
* are found with TYPE_ below.
*
* When an object is compiled with type testing (#pragma strict_types), all
* types are saved of the arguments for that function during compilation.
* If the #pragma save_types is specified, then the types are saved even
* after compilation, to be used when the object is inherited.
*/
#define NAME_INHERITED 0x80000000 /* Defined by inheritance */
#define TYPE_MOD_STATIC 0x40000000 /* Static function or variable */
#define TYPE_MOD_NO_MASK 0x20000000 /* The nomask => not redefineable */
#define TYPE_MOD_PRIVATE 0x10000000 /* Can't be inherited */
#define TYPE_MOD_PUBLIC 0x08000000 /* Force inherit through private */
#define TYPE_MOD_VARARGS 0x04000000 /* Used for type checking */
#define NAME_INITIALIZED 0x04000000 /* only used for variables */
#define TYPE_MOD_VIRTUAL 0x02000000 /* can be re- and cross- defined */
#define FUNSTART_MASK 0x000fffff
#define NAME_CROSS_DEFINED 0x00080000
#define INHERIT_MASK 0x0003ffff
#define NAME_HIDDEN 0x00000800 /* Not visible for inheritance */
#define NAME_PROTOTYPE 0x00000400 /* Defined by a prototype only */
#define NAME_UNDEFINED 0x00000200 /* Not defined yet */
#define NAME_TYPES_LOST 0x00000100 /* inherited, no save_types */
#define TYPE_MOD_PROTECTED 0
/* function header in program:
name : shared string (4 bytes)
return type (1)
-->num_arg (1)
num_local (1)
executable code
*/
struct function {
char *name; /* This is needed very often, therefore it should be first */
union {
uint32 pc; /* Address of function */
uint32 inherit; /* inherit table index when inherited. */
/*signed*/ int32 func; /* offset to first inherited function
* with this name.
* simul_efun also uses this field as a next
* index in the simul_efun function table for
* functions that have been discarded due to a
* change in the number of arguments.
*/
struct function *next; /* used for mergesort */
} offset;
uint32 flags;
unsigned short type; /* Return type of function. See below. */
unsigned char num_local; /* Number of local variables */
unsigned char num_arg; /* Number of arguments needed.
* -1 arguments for a simul_efun means VARARGS.
*/
};
struct variable {
char *name;
uint32 flags; /* All flags, also type of variable. */
};
struct inherit {
struct program *prog;
unsigned short function_index_offset;
unsigned short variable_index_offset;
};
struct program {
p_int ref; /* Reference count */
#ifdef DEBUG
p_int extra_ref; /* Used to verify ref count */
#endif
char *program; /* The binary instructions */
char *name; /* Name of file that defined prog */
int32 id_number; /* used to associate information with
this prog block without needing to
increase the reference count */
int32 load_time; /* When has it been compiled ? */
/*unsigned*/ char *line_numbers; /* Line number information */
unsigned short *function_names;
#define PROGRAM_END(prog) ((char *)(prog).function_names)
uint32 *functions;
char **strings; /* All strings uses by the program */
struct variable *variable_names; /* All variables defined */
struct inherit *inherit; /* List of inherited prgms */
p_int total_size; /* Sum of all data in this struct */
unsigned short flags;
short heart_beat; /* Index of the heart beat function.
* -1 means no heart beat
*/
/*
* The types of function arguments are saved where 'argument_types'
* points. It can be a variable number of arguments, so allocation
* is done dynamically. To know where first argument is found for
* function 'n' (number of function), use 'type_start[n]'.
* These two arrays will only be allocated if '#pragma save_types' has
* been specified. This #pragma should be specified in files that are
* commonly used for inheritance. There are several lines of code
* that depends on the type length (16 bits) of 'type_start' (sorry !).
*/
unsigned short *argument_types;
#define INDEX_START_NONE 65535
unsigned short *type_start;
/*
* And now some general size information.
*/
unsigned short program_size; /* size of this instruction code */
unsigned short num_function_names;
unsigned short num_functions;
unsigned short num_strings;
unsigned short num_variables;
unsigned short num_inherited;
};
extern struct program *current_prog;
/*
* Types available. The number '0' is valid as any type. These types
* are only used by the compiler, when type checks are enabled. Compare with
* the run-time types, named T_ interpret.h.
*/
#define TYPE_UNKNOWN 0 /* This type must be casted */
#define TYPE_NUMBER 1
#define TYPE_STRING 2
#define TYPE_VOID 3
#define TYPE_OBJECT 4
#define TYPE_MAPPING 5
#define TYPE_FLOAT 6
#define TYPE_ANY 7 /* Will match any type */
#define TYPE_SPACE 8
#define TYPE_CLOSURE 9
#define TYPE_SYMBOL 10
#define TYPE_QUOTED_ARRAY 11
#define TYPE_TERM 12
#define TYPEMAP_SIZE 13
/*
* These are or'ed in on top of the basic type.
*/
#define TYPE_MOD_POINTER 0x0040 /* Pointer to a basic type */
#define TYPE_MOD_REFERENCE 0x0080
#define TYPE_MOD_MASK 0x000000ff
#define TYPE_MOD_RMASK (TYPE_MOD_MASK & ~TYPE_MOD_REFERENCE)
#define P_REPLACE_ACTIVE 0x0001
#define VIRTUAL_VAR_TAG 0x4000
extern struct simul_efun_table_s {
unsigned char *funstart;
struct program *program;
p_int function_index_offset;
p_int variable_index_offset;
} simul_efun_table[];
/*
* How the information about all instructions is stored . This information is
* generated by make_func.
*/
struct instr {
short /* Can't use char to represent -1 */
max_arg, /* Maximum number of arguments. */
min_arg; /* Minimum number of arguments. */
char type[2]; /* Types of arguments 1 and 2 */
short Default; /* An efun to use as default for last argument.
* -1 for internal stackmachine codes
*/
short ret_type; /* The return type used by the compiler */
short arg_index; /* Indexes the efun_arg_types[] array. */
char *name;
};
#endif /* EXEC_H */