/* * $Id: bytecode.h,v 1.6 1997-02-01 13:35:53 aet Exp $ * * Copyright: The University of Melbourne, 1996 */ #if ! defined(BYTECODE_H) #define BYTECODE_H /* * XXX: We should make bytecode portable from platform to platform. * * Hence we assume the following: * sizeof(byte) = 1 * sizeof(short) = 2 * sizeof(int) = 4 * sizeof(long) = 8 * sizeof(float) = 4 (IEEE) * sizeof(double) = 8 (IEEE) * * We should have platform-dependent #defines to ensure that each of * these types has identical size on all platforms. * We also need to specify a consistent byteorder, say bigendian, * MSB first in bytecode file. */ typedef unsigned char Byte; typedef int Word; typedef int Int; typedef short Short; typedef long Long; typedef float Float; typedef double Double; typedef char* CString; typedef unsigned short ushort; typedef struct Tag { Byte id; union { Byte primary; struct { Byte primary; Word secondary; } pair; Word enum_tag; } opt; } Tag; /* * Possible values for Tag.id ... */ #define SIMPLE_TAG 0 #define COMPLICATED_TAG 1 #define COMPLICATED_CONSTANT_TAG 2 #define ENUM_TAG 3 #define NO_TAG 4 typedef Byte Determinism; /* * Possible values for Determinism ... */ #define DET 0 #define SEMIDET 1 #define MULTIDET 2 #define NONDET 3 #define CC_MULTIDET 4 #define CC_NONDET 5 #define ERRONEOUS 6 #define FAILURE 7 typedef struct Op_arg { Byte id; union { short var; Int int_const; Float float_const; } opt; } Op_arg; /* * Possible values for Op_arg.id */ #define ARG_VAR 0 #define ARG_INT_CONST 1 #define ARG_FLOAT_CONST 2 typedef Byte Direction; typedef struct Var_dir { short var; Direction dir; } Var_dir; /* * Possible values for Direction ... */ #define TO_ARG 0 #define TO_VAR 1 #define TO_NONE 2 typedef struct Cons_id { Byte id; union { struct { CString string; short arity; Tag tag; } cons; Int int_const; CString string_const; Float float_const; struct { CString module_id; CString pred_id; short arity; Byte proc_id; } pred_const; struct { CString module_id; CString pred_id; short arity; Byte proc_id; } code_addr_const; struct { CString module_id; CString type_name; Byte type_arity; } base_type_info_const; } opt; } Cons_id; /* * Possible values for Cons_id.id ... */ #define CONSID_CONS 0 #define CONSID_INT_CONST 1 #define CONSID_STRING_CONST 2 #define CONSID_FLOAT_CONST 3 #define CONSID_PRED_CONST 4 #define CONSID_CODE_ADDR_CONST 5 #define CONSID_BASE_TYPE_INFO_CONST 6 typedef struct Bytecode { Byte id; /* Which bytecode instruction. e.g. BC_fail */ union { struct { CString pred_name; /* XXX: malloc */ short proc_count; } enter_pred; /* endof_pred */ struct { Byte proc_id; Determinism det; short label_count; short temp_count; short list_length; CString *var_info_list; /* XXX: malloc */ } enter_proc; struct { short label; } label; struct { short end_label; } enter_disjunction; /* endof_disjunction */ struct { short next_label; } enter_disjunct; struct { short label; /* XXX: what's label for? */ } endof_disjunct; struct { short var; short end_label; } enter_switch; /* endof_switch */ struct { Cons_id cons_id; short next_label; } enter_switch_arm; struct { short label; /* XXX: what's this label for? */ } endof_switch_arm; struct { short else_label; short end_label; short frame_ptr_tmp; } enter_if; struct { short frame_ptr_tmp; } enter_then; struct { short follow_label; } endof_then; /* XXX: should rename to enter_else */ /* endof_if */ struct { short end_label; } enter_negation; /* endof_negation */ struct { short temp; } enter_commit; struct { short temp; } endof_commit; struct { short to_var; short from_var; } assign; struct { short var1; short var2; } test; struct { short to_var; Cons_id consid; short list_length; short *var_list; /* XXX: malloc */ } construct; struct { short from_var; Cons_id consid; short list_length; short *var_list; /* XXX: malloc */ } deconstruct; struct { short to_var; Cons_id consid; short list_length; Var_dir *var_dir_list;/* XXX: malloc */ } complex_construct; struct { short from_var; Cons_id consid; short list_length; Var_dir *var_dir_list;/* XXX: malloc */ } complex_deconstruct; struct { Byte to_reg; short from_var; } place_arg; struct { Byte from_reg; short to_var; } pickup_arg; struct { CString module_id; /* XXX: malloc */ CString pred_id; /* XXX: malloc */ short arity; Byte proc_id; } call; struct { short pred_var; short in_var_count; short out_var_count; Determinism det; } higher_order_call; struct { Byte binop; Op_arg arg1; Op_arg arg2; short to_var; } builtin_binop; struct { Byte unop; Op_arg arg; short to_var; } builtin_unop; struct { Byte binop; Op_arg arg1; Op_arg arg2; } builtin_bintest; struct { Byte unop; Op_arg arg; } builtin_untest; /* semidet_succeed */ /* semidet_success_check */ /* fail */ struct { /* XXX: is this int or short?? */ short line_number; } context; /* not_supported */ } opt; } Bytecode; /* * Possible values for Bytecode.id ... * * We use #defines rather than an enumeration here since * C enumeration constant must be of type int whereas we * want byte (unsigned char). */ #define BC_enter_pred 0 #define BC_endof_pred 1 #define BC_enter_proc 2 #define BC_endof_proc 3 #define BC_label 4 #define BC_enter_disjunction 5 #define BC_endof_disjunction 6 #define BC_enter_disjunct 7 #define BC_endof_disjunct 8 #define BC_enter_switch 9 #define BC_endof_switch 10 #define BC_enter_switch_arm 11 #define BC_endof_switch_arm 12 #define BC_enter_if 13 #define BC_enter_then 14 /* XXX: enter_else would be a better name than endof_then */ #define BC_endof_then 15 #define BC_endof_if 16 #define BC_enter_negation 17 #define BC_endof_negation 18 #define BC_enter_commit 19 #define BC_endof_commit 20 #define BC_assign 21 #define BC_test 22 #define BC_construct 23 #define BC_deconstruct 24 #define BC_complex_construct 25 #define BC_complex_deconstruct 26 #define BC_place_arg 27 #define BC_pickup_arg 28 #define BC_call 29 #define BC_higher_order_call 30 #define BC_builtin_binop 31 #define BC_builtin_unop 32 #define BC_builtin_bintest 33 #define BC_builtin_untest 34 #define BC_semidet_succeed 35 #define BC_semidet_success_check 36 #define BC_fail 37 #define BC_context 38 #define BC_not_supported 39 /* * Read the next bytecode from the stream fp. * If no bytecode can be read, return FALSE. * Otherwise, return TRUE. */ Bool read_bytecode(FILE *fp, Bytecode *bc_p); /* * Read the bytecode version number from the stream fp. * If the version number cannot be read, return FALSE. * Otherwise, return TRUE. */ Bool read_bytecode_version_number(FILE *fp, short *version_number_p); #endif /* BYTECODE_H */