/* * 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; 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 /* * 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 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; };