sima/autoconf/
sima/hosts/i386/
sima/mudlib/
sima/mudlib/kernel/
sima/mudlib/obj/
sima/mudlib/sys/
sima/synhash/mips/
/* Data structures and constants to represent executable code */
#ifndef EXEC_H
#define EXEC_H

#include "alloc.h"
#include "mudlib/sys/driver_hook.h"

#define TYPE_ANY		 0
#define TYPE_NUMBER		 1
#define TYPE_FLOAT		 2
#define TYPE_STRING		 3
#define TYPE_OBJECT		 4
#define TYPE_MAPPING		 5
#define TYPE_CLOSURE		 6
#define TYPE_STRUCT_BUILTIN	 7
#define TYPE_LONG		(TYPE_STRUCT_BUILTIN+0)
#define TYPE_QUOTED_ARRAY	(TYPE_STRUCT_BUILTIN+1)
#define TYPE_REGEXP		(TYPE_STRUCT_BUILTIN+2)
#define TYPE_SPACE		(TYPE_STRUCT_BUILTIN+3)
#define TYPE_SYMBOL		(TYPE_STRUCT_BUILTIN+4)
#define TYPE_TERM		(TYPE_STRUCT_BUILTIN+5)

#define TYPE_UNKNOWN		15
#define TYPE_REFERENCE		31

#define TYPE_VOID		32 /* The number zero from a 'void' lfun' */
#define TYPE_NIL		33 /* No return from a void efun. */

#define TYPEMAP_SIZE	15

#define TYPE__ARRAY		0x0010  /* Pointer to a basic type        */
#define TYPE__REFERENCE		0x0080

#define TYPE__MASK		0x000000ff

#define TYPE__RMASK		(TYPE__MASK & ~TYPE__REFERENCE)

#define TYPE__STATIC		0x80
#define TYPE__NOMASK		0x40 /* Not redefineable               */
#define TYPE__PRIVATE		0x20 /* Can't be inherited             */
#define TYPE__PUBLIC		0x10 /* Force inherit through private  */
#define TYPE__VARARGS		0x08 /* Used for type checking         */
#define TYPE__INITIALIZED	0x08 /* only used for variables        */
#define TYPE__VIRTUAL		0x04 /* can be re- and cross- defined  */
#define TYPE__PROTECTED		0x02 /* cannot be called externally    */
#define TYPE__SHARED		0x02
#define TYPE__CONST		0x01

#define FUNSTART_MASK		0x000fffff
#define TYPE__CROSS_DEFINED	0x00080000
#define INHERIT_MASK		0x0003ffff


#define TYPE__HIDDEN		0x00000800 /* Not visible for inheritance    */
#define TYPE__PROTOTYPE		0x00000400 /* Defined by a prototype only    */
#define TYPE__UNDEFINED		0x00000200 /* Not defined yet                */
#define TYPE__TYPES_LOST	0x00000100 /* inherited, no save_types       */

#define PROG_FUNSTART2NAME(prog,flags) \
 (((svalue *)(prog+(flags & (FUNSTART_MASK & ~((sizeof(uint8 *)) - 1)))))[-1])
#define FUNSTART2NARGS(funstart) (funstart[-2])
#define FUNSTART2NLOCAL(funstart) (funstart[-1])

/* Data-structure imposed maximum number of named parameters.  */
#define MAX_PARAM 0x100

/*
 * The RESWORD macros in alloc.h depend on 0x800 being left free from
 * TYPE_ stuff that appears as value of a keyword ( see lex.c::reswords[] )
 */

#define VIRTUAL_VAR_TAG 0x4000

#define TYPE__EXCL_MASK (TYPE__VARARGS|TYPE__CONST|TYPE__SHARED|TYPE__PROTECTED)

enum use_lvalue_code{
  ULV_ERROR,
  ULV_PRE_DEC,	/* needed: inc/dec code & 4 is 4 for inc. */
  ULV_POST_DEC,
  ULV_DEC,	/* needed: ULV_x_DEC + 4 == ULV_x_INC */
  ULV_NOP,    /* needed: same offsets between pre/post/void inc/dec operators */
  ULV_PRE_INC,
  ULV_POST_INC,
  ULV_INC,
  ULV_ASSIGN,
  ULV_VOID_ASSIGN,
  ULV_HAIRY_ASSIGN,
  ULV_VOID_HAIRY_ASSIGN,
  ULV_ADD,
  ULV_VOID_ADD,
  ULV_SUB,
  ULV_VOID_SUB,
  ULV_AND,
  ULV_VOID_AND,
  ULV_OR,
  ULV_VOID_OR,
  ULV_XOR,
  ULV_VOID_XOR,
  ULV_MUL,
  ULV_VOID_MUL,
  ULV_DIV,
  ULV_VOID_DIV,
  ULV_MOD,
  ULV_VOID_MOD,
  ULV_RSH,
  ULV_VOID_RSH,
  ULV_LSH,
  ULV_VOID_LSH,
  ULV_INDEX,
  ULV_RINDEX,
  ULV_CINDEX,
  ULV_CRINDEX,
  ULV_SINDEX,
  ULV_SRINDEX,
  ULV_MAP_INDEX,
  ULV_MAP_CINDEX,
  ULV_NN_RANGE,
  ULV_NR_RANGE,
  ULV_RN_RANGE,
  ULV_RR_RANGE,
  ULV_LV_INDEX,
  ULV_LV_RINDEX,
  ULV_LV_CINDEX,
  ULV_LV_CRINDEX,
  ULV_LV_SINDEX,
  ULV_LV_SRINDEX,
  ULV_LV_MAP_INDEX,
  ULV_LV_MAP_CINDEX,
  /* range values have lvalue lifetime protection by default */
  ULV_LV_NN_RANGE,
  ULV_LV_NR_RANGE,
  ULV_LV_RN_RANGE,
  ULV_LV_RR_RANGE,
  ULV_CBR,	/* pack an ordinary lvalue for call by reference */
  ULV_PLV_INDEX,
  ULV_PLV_RINDEX, /* needed: same (R)INDEX - LV_(R)INDEX - LV_PLV_(R)INDEX
		   * offsets.						   */
  ULV_PLV_MAP_INDEX,
  ULV_PRE_DEC_BBRANCH,
};

#define ULV_INDEX_FETCH_REQUIRED(code) ((code) < (ULV_LV_INDEX))
#define ULV_ASS_IS_VOID(code) ((code) & 1)

#define ULV_CLOSURE_OFFSET 42 /* FIXME */

extern svalue driver_hook[NUM_DRIVER_HOOKS];

#define F_ESCAPE_BITS 7

struct instr {
    unsigned char
      ret_type;		/* The return type used by the compiler */
    unsigned char is_const;
    short
      max_arg,		/* Maximum number of arguments.         */
      min_arg,		/* Minimum number of arguments.         */
      check_arg;
    short Default;	/* An efun to use as default for last argument.
			 * -1 for internal stackmachine codes
			 */
    short arg_index;	/* Indexes the efun_arg_types[] array.  */
    char *name;
};

struct variable {
    svalue name;
    uint32 flags;		/* All flags, also type of variable. */
};

struct new_function {
    svalue name;
    unsigned flags: 8;
    unsigned start: 24;
};

struct program_flags {
    uint8 many_inherits : 1;
    uint8 leaf_inherit : 1;
    uint8 line_numbers_integrated : 1;
    /* one free flag */
    uint8 language : 4;
};

struct program {
    uint8 type, subtype;	/* T_INTERNAL IT_PROGRAM */
    uint16 global_variables;
    struct program_flags flag;
    uint8 auto_variables;
    uint16 redefine_offset;
    /* Keep the pointer to the list the of inherited programs right after
       flag, so that it is likely to be in the same cache line. */
    struct inherit *inherit;
#define PR_INHERIT_END(p)	((struct inherit *)(p)->variable_names)
    uint32 ref;
    svalue dirname;
    svalue basename;
    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 ?	*/
    p_int swap_num;             /* Swap file offset. -1 is not swapped yet. */


/* All variables defined */
    struct variable *variable_name;
#define PR_VARIABLE_NAME_END(p) ((struct variable *)(p)->shared)

    svalue *shared;
#define PR_SHARED_END(p)	((svalue *)(p)->new_function)

#define PR_FUNCTION_END_8(p)	((uint8 *)(p)->inherit)

    union {
	uint16 *name;
	struct { uint16 base, offset; } search;
    } function;
#define PR_FUNCTION_NAME_SIZE(p)	((p)[-1])

    struct new_function *new_function;
#define PR_NEW_FUNCTION_END(p)	((struct new_function *)(p)->type_indizes)

    /* start indizes for arguments into type_block */
#define INDEX_START_NONE                65535
    uint16 *type_indizes;
#define PR_TYPE_INDIZES_END(p)	((uint16 *)(p)->type_block)

    uint8 *type_block;
#define PR_TYPE_BLOCK_END(p)	((p)->pcode)
#define PR_PCODE(p) (uint8 *)p

    /* The compiled P-code */
    uint8 *pcode;
#define PR_PROGRAM_END(p) ((p)->line_numbers_integrated ? \
	(p)->line_numbers : (p)->end)

    /* Line number information */
    uint8 *line_numbers;
#define PR_LINE_NUMBER_END(p)	((p)->end)

    uint8 *end;
    union {
	uint8 function_8[1]; uint16 function_16[1]; uint16 variable[1];
    } virtual;
};

struct inherit {
    p_int program; /* struct program * with low bits used for static */
    uint16 virtual_offset;
    uint16 variable_offset;
};

struct variable_modifier {
    uint16 modifier, variable;
};
struct function_modifier {
    uint16 modifier, function;
};
struct inherit_modifiers {
    uint16 kind, inherit, variable, function;
};

extern struct simul_efun_table_s {
    union {
	uint8 *start;
	svalue name;
    } fun;
    struct program *program;
    uint16 function_offset;
    uint16 variable_offset;
    int16  num_arg;	/* -1 for varargs */
    uint8 type;
    uint8 nomask;
} *simul_efun_table;

struct program *compile_file(uint8 *namestart, mp_int namelen, int language);
int find_function(struct program *, svalue);
int leaf_inherit_find_function(struct program *, svalue);

extern struct program nil_program;

#endif /* EXEC_H */