mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-13 12:53:53 +00:00
Estimated hours taken: 4 Branches: main Prepare to make type_info and typeclass_info foreign types by eliminating the compiler's dependence on their function symbols. At the moment, the compiler generates type_intos and typeclass_infos by using the function symbols of these types as cons_ids. However, the function symbols have fake arities, which demanded special treatment in many places. This change makes the compiler use the cons_ids type_into_cell_constructor and typeclass_into_cell_constructor instead, except in insts, which need to know the arity of the constructor. compiler/hlds_data.m: Add the two new cons_ids. compiler/polymorphism.m: Use the two new cons_ids instead of the function symbols of the type_info and typeclass_info types, since those function symbols will soon be deleted. compiler/type_util.m: Add a type and some predicates to control the representation of type_info and typeclass_info cells in one place. Since we no longer depend on the representations of the function symbols of the type_info and typeclass_info types, do not special case their representation. compiler/hlds_code_util.m: Implement the representation of the two new function symbols. compiler/bytecode.m: Add two new cons_ids to parallel the ones in hlds_data.m. compiler/higher_order.m: Look for the two new cons_ids, instead of the old ones. Make the code more maintainable. compiler/*.m: Minor changes to conform to the changes above. library/private_builtin.m: Delete the statement that the compiler depends on the functors of the type_info and type_ctor_info types. bytecode/mb_bytecode.h: Document that some bytecodes generated by the compiler are not yet implemented by the bytecode interpreter.
506 lines
9.6 KiB
C
506 lines
9.6 KiB
C
|
|
/*
|
|
** Copyright (C) 1997,2000-2001, 2003 The University of Melbourne.
|
|
** This file may only be copied under the terms of the GNU Library General
|
|
** Public License - see the file COPYING.LIB in the Mercury distribution.
|
|
**
|
|
** This file contains the bytecode format and data types
|
|
** This must be the same as that in compiler/bytecode.m
|
|
*/
|
|
|
|
#ifndef MB_BYTECODE_H
|
|
#define MB_BYTECODE_H
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "mercury_type_info.h"
|
|
|
|
#include "mb_basetypes.h"
|
|
#include "mb_util.h"
|
|
|
|
typedef struct MB_Tag_Struct {
|
|
MB_Byte id;
|
|
union {
|
|
MB_Byte primary;
|
|
struct {
|
|
MB_Byte primary;
|
|
MB_Word secondary;
|
|
} pair;
|
|
MB_Byte enum_tag;
|
|
} opt;
|
|
} MB_Tag;
|
|
|
|
/*
|
|
** Possible values for Tag.id ...
|
|
*/
|
|
#define MB_TAG_SIMPLE 0
|
|
#define MB_TAG_COMPLICATED 1
|
|
#define MB_TAG_COMPLICATED_CONSTANT 2
|
|
#define MB_TAG_ENUM 3
|
|
#define MB_TAG_NONE 4
|
|
|
|
typedef MB_Byte
|
|
MB_Determinism;
|
|
/*
|
|
** Possible values for Determinism ...
|
|
*/
|
|
#define MB_DET_DET 0
|
|
#define MB_DET_SEMIDET 1
|
|
#define MB_DET_MULTIDET 2
|
|
#define MB_DET_NONDET 3
|
|
#define MB_DET_CC_MULTIDET 4
|
|
#define MB_DET_CC_NONDET 5
|
|
#define MB_DET_ERRONEOUS 6
|
|
#define MB_DET_FAILURE 7
|
|
/*
|
|
** Unusable is used to indicate that there is something wrong with
|
|
** this predicate (probably contains foreign code) and the bytecode
|
|
** version cannot be used
|
|
*/
|
|
#define MB_DET_UNUSABLE 99
|
|
|
|
/* Return true if determinism model is the same as that specified */
|
|
#define MB_model_det(x) (\
|
|
((x) == MB_DET_DET) || \
|
|
((x) == MB_DET_CC_MULTIDET) || \
|
|
((x) == MB_DET_ERRONEOUS))
|
|
|
|
#define MB_model_semi(x) (\
|
|
((x) == MB_DET_SEMIDET) || \
|
|
((x) == MB_DET_CC_NONDET) || \
|
|
((x) == MB_DET_FAILURE))
|
|
|
|
#define MB_model_nondet(x) (\
|
|
((x) == MB_DET_NONDET) || \
|
|
((x) == MB_DET_MULTIDET))
|
|
|
|
|
|
typedef struct MB_Op_arg_struct {
|
|
MB_Byte id;
|
|
union {
|
|
MB_Short var;
|
|
MB_Integer int_const;
|
|
MB_Float float_const;
|
|
} opt;
|
|
} MB_Op_arg;
|
|
|
|
/*
|
|
** Possible values for Op_arg.id
|
|
*/
|
|
#define MB_ARG_VAR 0
|
|
#define MB_ARG_INT_CONST 1
|
|
#define MB_ARG_FLOAT_CONST 2
|
|
|
|
|
|
typedef MB_Byte
|
|
MB_Direction;
|
|
|
|
typedef struct MB_Var_dir_struct {
|
|
MB_Short var;
|
|
MB_Direction dir;
|
|
} MB_Var_dir;
|
|
|
|
/*
|
|
** Possible values for Direction ...
|
|
*/
|
|
#define MB_DIR_TO_ARG 0
|
|
#define MB_DIR_TO_VAR 1
|
|
#define MB_DIR_TO_NONE 2
|
|
|
|
typedef struct {
|
|
/* Whether call is a native code call */
|
|
MB_Bool is_native;
|
|
/* code address to call */
|
|
union {
|
|
MB_Bytecode_Addr bc;
|
|
MB_Native_Addr native;
|
|
} addr;
|
|
} MB_Code_Addr;
|
|
|
|
typedef struct MB_Cons_id_struct {
|
|
MB_Byte id;
|
|
union {
|
|
struct {
|
|
MB_CString module_name;
|
|
MB_CString string;
|
|
MB_Short arity;
|
|
MB_Tag tag;
|
|
} cons;
|
|
MB_Integer int_const;
|
|
MB_CString string_const;
|
|
MB_Float float_const;
|
|
struct {
|
|
MB_CString module_name;
|
|
MB_CString pred_name;
|
|
MB_Short arity;
|
|
MB_Bool is_func;
|
|
MB_Byte mode_num;
|
|
/* Cached call address (may be NULL) */
|
|
MB_Native_Addr native_addr;
|
|
} pred_const;
|
|
struct {
|
|
MB_CString module_name;
|
|
MB_CString pred_name;
|
|
MB_Short arity;
|
|
MB_Byte mode_num;
|
|
} code_addr_const;
|
|
struct {
|
|
MB_CString module_name;
|
|
MB_CString type_name;
|
|
MB_Byte type_arity;
|
|
/* Cached type info address (may be NULL) */
|
|
MR_TypeCtorInfo type_info;
|
|
} base_type_info_const;
|
|
struct {
|
|
MB_Byte ch;
|
|
} char_const;
|
|
} opt;
|
|
} MB_Cons_id;
|
|
|
|
/*
|
|
** Possible values for Cons_id.id ...
|
|
*/
|
|
#define MB_CONSID_CONS 0
|
|
#define MB_CONSID_INT_CONST 1
|
|
#define MB_CONSID_STRING_CONST 2
|
|
#define MB_CONSID_FLOAT_CONST 3
|
|
#define MB_CONSID_PRED_CONST 4
|
|
#define MB_CONSID_CODE_ADDR_CONST 5
|
|
#define MB_CONSID_BASE_TYPE_INFO_CONST 6
|
|
#define MB_CONSID_CHAR_CONST 7
|
|
/* some more cons_ids generated by the compiler are not yet implemented */
|
|
|
|
/*
|
|
** Possible values for Test_id
|
|
*/
|
|
typedef MB_Byte MB_Test_id;
|
|
|
|
#define MB_TESTID_INT 0
|
|
#define MB_TESTID_CHAR 1
|
|
#define MB_TESTID_STRING 2
|
|
#define MB_TESTID_FLOAT 3
|
|
#define MB_TESTID_ENUM 4
|
|
|
|
/*
|
|
** Internal label structure. At load time the index is read from the file
|
|
** and stored. translate_labels translates indexes into actual memory
|
|
** addresses. The module load and label translation functions are the only
|
|
** only functions that should access index, the rest of the program should
|
|
** only use addr.
|
|
*/
|
|
typedef union {
|
|
MB_Short index;
|
|
MB_Bytecode_Addr addr;
|
|
} MB_Label;
|
|
|
|
typedef union MB_Bytecode_Arg_tag {
|
|
struct {
|
|
MB_CString pred_name;
|
|
MB_Short pred_arity;
|
|
MB_Bool is_func;
|
|
MB_Short proc_count;
|
|
} enter_pred;
|
|
|
|
struct {
|
|
} endof_pred;
|
|
|
|
struct {
|
|
MB_Byte mode_num;
|
|
MB_Determinism det;
|
|
MB_Short label_count;
|
|
MB_Label end_label;
|
|
MB_Short temp_count;
|
|
MB_Short list_length;
|
|
MB_CString *var_info;
|
|
|
|
/*
|
|
** index onto label heap for label indexes
|
|
** (not in the file)
|
|
*/
|
|
MB_Word label_index;
|
|
} enter_proc;
|
|
|
|
struct {
|
|
/* start of proc (not in file) */
|
|
MB_Bytecode_Addr proc_start;
|
|
} endof_proc;
|
|
|
|
struct {
|
|
MB_Short label;
|
|
} label;
|
|
|
|
struct {
|
|
MB_Label end_label;
|
|
} enter_disjunction;
|
|
|
|
struct {
|
|
} endof_disjunction;
|
|
|
|
struct {
|
|
MB_Label next_label;
|
|
} enter_disjunct;
|
|
|
|
struct {
|
|
MB_Label end_label;
|
|
} endof_disjunct;
|
|
|
|
struct {
|
|
MB_Short var;
|
|
MB_Label end_label;
|
|
} enter_switch;
|
|
|
|
struct {
|
|
|
|
} endof_switch;
|
|
|
|
struct {
|
|
MB_Cons_id cons_id;
|
|
MB_Label next_label;
|
|
|
|
/* filled in at load time */
|
|
MB_Short var;
|
|
} enter_switch_arm;
|
|
|
|
struct {
|
|
MB_Label end_label;
|
|
} endof_switch_arm;
|
|
|
|
struct {
|
|
MB_Label else_label;
|
|
MB_Label end_label;
|
|
MB_Short frame_ptr_tmp;
|
|
} enter_if;
|
|
|
|
/*
|
|
** identical to enter_else: if you change this, modify instr_else
|
|
** to reflect
|
|
*/
|
|
struct {
|
|
MB_Short frame_ptr_tmp;
|
|
} enter_then;
|
|
|
|
struct {
|
|
MB_Label follow_label;
|
|
} endof_then;
|
|
|
|
/*
|
|
** identical to enter_then: if you change this, modify instr_then
|
|
** to reflect
|
|
*/
|
|
struct {
|
|
MB_Short frame_ptr_tmp;
|
|
} enter_else;
|
|
|
|
struct {
|
|
|
|
} endof_if;
|
|
|
|
struct {
|
|
MB_Short frame_ptr_tmp;
|
|
MB_Label end_label;
|
|
} enter_negation;
|
|
|
|
struct {
|
|
MB_Short frame_ptr_tmp;
|
|
} endof_negation_goal;
|
|
|
|
struct {
|
|
} endof_negation;
|
|
|
|
struct {
|
|
MB_Short frame_ptr_tmp;
|
|
} enter_commit;
|
|
|
|
struct {
|
|
MB_Short frame_ptr_tmp;
|
|
} endof_commit;
|
|
|
|
struct {
|
|
MB_Short to_var;
|
|
MB_Short from_var;
|
|
} assign;
|
|
|
|
struct {
|
|
MB_Short var1;
|
|
MB_Short var2;
|
|
MB_Test_id id;
|
|
} test;
|
|
|
|
struct {
|
|
MB_Short to_var;
|
|
MB_Cons_id consid;
|
|
MB_Short list_length;
|
|
MB_Short *var_list;
|
|
} construct;
|
|
|
|
struct {
|
|
MB_Short from_var;
|
|
MB_Cons_id consid;
|
|
MB_Short list_length;
|
|
MB_Short *var_list;
|
|
} deconstruct;
|
|
|
|
struct {
|
|
MB_Short to_var;
|
|
MB_Cons_id consid;
|
|
MB_Short list_length;
|
|
MB_Var_dir *var_dir;
|
|
} complex_construct;
|
|
|
|
struct {
|
|
MB_Short from_var;
|
|
MB_Cons_id consid;
|
|
MB_Short list_length;
|
|
MB_Var_dir *var_dir;
|
|
} complex_deconstruct;
|
|
|
|
struct {
|
|
MB_Byte to_reg;
|
|
MB_Short from_var;
|
|
} place_arg;
|
|
|
|
struct {
|
|
MB_Byte from_reg;
|
|
MB_Short to_var;
|
|
} pickup_arg;
|
|
|
|
struct {
|
|
MB_CString module_name;
|
|
MB_CString pred_name;
|
|
MB_Short arity;
|
|
MB_Bool is_func;
|
|
MB_Byte mode_num;
|
|
/* actual call address */
|
|
MB_Code_Addr addr;
|
|
} call;
|
|
|
|
struct {
|
|
MB_Short pred_var;
|
|
MB_Short in_var_count;
|
|
MB_Short out_var_count;
|
|
MB_Determinism det;
|
|
} higher_order_call;
|
|
|
|
struct {
|
|
MB_Byte binop;
|
|
MB_Op_arg arg1;
|
|
MB_Op_arg arg2;
|
|
MB_Short to_var;
|
|
} builtin_binop;
|
|
|
|
struct {
|
|
MB_Byte unop;
|
|
MB_Op_arg arg;
|
|
MB_Short to_var;
|
|
} builtin_unop;
|
|
|
|
struct {
|
|
MB_Byte binop;
|
|
MB_Op_arg arg1;
|
|
MB_Op_arg arg2;
|
|
} builtin_bintest;
|
|
|
|
struct {
|
|
MB_Byte unop;
|
|
MB_Op_arg arg;
|
|
} builtin_untest;
|
|
|
|
struct {
|
|
} semidet_succeed;
|
|
|
|
struct {
|
|
} semidet_success_check;
|
|
|
|
struct {
|
|
} fail;
|
|
|
|
struct {
|
|
/* XXX: is this int or short?? */
|
|
MB_Short line_number;
|
|
} context;
|
|
|
|
struct {
|
|
} not_supported;
|
|
|
|
} MB_Bytecode_Arg;
|
|
|
|
typedef struct MB_Bytecode_struct {
|
|
MB_Byte id; /* Which bytecode instruction. e.g. BC_fail */
|
|
MB_Bytecode_Arg opt;
|
|
} MB_Bytecode;
|
|
|
|
/*
|
|
** Possible Bytecode.id values
|
|
*/
|
|
#define MB_BC_enter_pred 0
|
|
#define MB_BC_endof_pred 1
|
|
#define MB_BC_enter_proc 2
|
|
#define MB_BC_endof_proc 3
|
|
#define MB_BC_label 4
|
|
#define MB_BC_enter_disjunction 5
|
|
#define MB_BC_endof_disjunction 6
|
|
#define MB_BC_enter_disjunct 7
|
|
#define MB_BC_endof_disjunct 8
|
|
#define MB_BC_enter_switch 9
|
|
#define MB_BC_endof_switch 10
|
|
#define MB_BC_enter_switch_arm 11
|
|
#define MB_BC_endof_switch_arm 12
|
|
#define MB_BC_enter_if 13
|
|
#define MB_BC_enter_then 14
|
|
#define MB_BC_endof_then 15
|
|
#define MB_BC_endof_if 16
|
|
#define MB_BC_enter_negation 17
|
|
#define MB_BC_endof_negation 18
|
|
#define MB_BC_enter_commit 19
|
|
#define MB_BC_endof_commit 20
|
|
#define MB_BC_assign 21
|
|
#define MB_BC_test 22
|
|
#define MB_BC_construct 23
|
|
#define MB_BC_deconstruct 24
|
|
#define MB_BC_complex_construct 25
|
|
#define MB_BC_complex_deconstruct 26
|
|
#define MB_BC_place_arg 27
|
|
#define MB_BC_pickup_arg 28
|
|
#define MB_BC_call 29
|
|
#define MB_BC_higher_order_call 30
|
|
#define MB_BC_builtin_binop 31
|
|
#define MB_BC_builtin_unop 32
|
|
#define MB_BC_builtin_bintest 33
|
|
#define MB_BC_builtin_untest 34
|
|
#define MB_BC_semidet_succeed 35
|
|
#define MB_BC_semidet_success_check 36
|
|
#define MB_BC_fail 37
|
|
#define MB_BC_context 38
|
|
#define MB_BC_not_supported 39
|
|
#define MB_BC_enter_else 40
|
|
#define MB_BC_endof_negation_goal 41
|
|
|
|
/* These are used internally by the interpreter */
|
|
/* all codes above MB_BC_debug are debugging values */
|
|
#define MB_BC_debug 0x3d
|
|
#define MB_BC_debug_trap 0x3e
|
|
#define MB_BC_debug_invalid 0x3f
|
|
/*
|
|
** Note that the limit to these is determined in mb_module.c by the
|
|
** number of bits allocated to an id
|
|
*/
|
|
|
|
/*
|
|
** Read the next bytecode from the stream fp.
|
|
** If no bytecode can be read, return FALSE.
|
|
** Otherwise, return TRUE.
|
|
*/
|
|
MB_Bool
|
|
MB_read_bytecode(FILE *fp, MB_Bytecode *bc_p);
|
|
|
|
/*
|
|
** Read the bytecode version number from the stream fp.
|
|
** If the version number cannot be read, return FALSE.
|
|
** Otherwise, return TRUE.
|
|
*/
|
|
MB_Bool
|
|
MB_read_bytecode_version_number(FILE *fp, MB_Short *version_number_p);
|
|
|
|
#endif /* MB_BYTECODE_H */
|
|
|