mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-30 00:34:40 +00:00
Estimated hours taken: 30
Branches: main
Consider types of the form
:- type x ---> f.
to be dummy types, since they contain no information. Optimize them the same
way we currently optimize io.state and store.store.
runtime/mercury_type_info.h:
Add a new type_ctor_rep for dummy types.
runtime/mercury_tabling.h:
Add a representation for "tabled" dummy types, which don't actually
have a level in the trie, so that the runtime system can handle that
fact.
runtime/mercury_ml_expand_body.h:
When deconstructing a value of a dummy type, ignore the actual value
(since it will contain garbage) and instead return the only possible
value of the type.
runtime/mercury_construct.c:
runtime/mercury_deconstruct.c:
runtime/mercury_deep_copy_body.c:
runtime/mercury_tabling.c:
runtime/mercury_unify_compare_body.h:
library/rtti_implementation.m:
Handle the type_ctor_rep of dummy types.
runtime/mercury_builtin_types.c:
Provide a place to record profiling information about unifications and
comparisons for dummy types.
runtime/mercury_mcpp.h:
java/runtime/TypeCtorRep.java:
library/private_builtin.m:
Add a new type_ctor_rep for dummy types, and fix some previous
discrepancies in type_ctor_reps.
mdbcomp/prim_data.m:
Move a bunch of predicates for manipulating special_pred_ids here from
the browser and compiler directories.
Rename the function symbols of the special_pred_id type to avoid the
need to parenthesize the old `initialise' function symbol.
Convert to four-space indentation.
mdbcomp/rtti_access.m:
Don't hardcode the names of special preds: use the predicates in
prim_data.m.
Convert to four-space indentation.
browser/declarative_execution.m:
Delete some predicates whose functionality is now in
mdbcomp/prim_data.m.
compiler/hlds_data.m:
Replace the part of du type that says whether a type an enum, which
used to be a bool, with something that also says whether the type is a
dummy type.
Convert to four-space indentation.
compiler/make_tags.m:
Compute the value for the new field of du type definitions.
compiler/hlds_out.m:
Write out the new field of du type definitions.
compiler/rtti.m:
Modify the data structures we use to create type_ctor_infos to allow
for dummy types.
Convert to four-space indentation.
compiler/type_ctor_info.m:
Modify the code that generates type_ctor_infos to handle dummy types.
compiler/type_util.m:
Provide predicates for recognizing dummy types.
Convert to four-space indentation.
compiler/unify_proc.m:
Generate the unify and compare predicates of dummy types using a new
code scheme that avoids referencing arguments that contain garbage.
When generating code for unifying or comparing other types, ignore
any arguments of function symbols that are dummy types.
Don't use DCG style access predicates.
compiler/higher_order.m:
Specialize the unification and comparison of values of dummy types.
Break up an excessively large predicate, and factor out common code
from the conditions of a chain of if-then-elses.
compiler/llds.m:
For each input and output of a foreign_proc, include a field saying
whether the value is of a dummy type.
compiler/pragma_c_gen.m:
Fill in the new fields in foreign_proc arguments.
compiler/hlds_goal.m:
Rename some predicates for constructing unifications to avoid
unnecessary ad-hoc overloading. Clarify their documentation.
Rename a predicate to make clear the restriction on its use,
and document the restriction.
Add a predicate for creating simple tests.
Add a utility predicate for setting the context of a goal directly.
compiler/modules.m:
Include dummy types interface files, even if they are private to the
module. This is necessary because with the MLDS backend, the generated
code inside the module and outside the module must agree whether a
function returning a value of the type returns a real value or a void
value, and this requires them to agree on whether the type is dummy
or not.
The impact on interface files is minimal, since very few types are
dummy types, and changing a type from a dummy type to a non-dummy type
or vice versa is an ever rarer change.
compiler/hlds_pred.m:
Provide a representation in the compiler of the trie step for dummy
types.
compiler/layout_out.m:
Print the trie step for dummy types.
compiler/table_gen.m:
Don't table values of dummy types, and record the fact that we don't
by including a dummy trie step in the list of trie steps.
compiler/add_pragma.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/aditi_builtin_ops.m:
compiler/bytecode.m:
compiler/bytecode_gen.m:
compiler/code_gen.m:
compiler/code_info.m:
compiler/continuation_info.m:
compiler/cse_detection.m:
compiler/det_report.m:
compiler/exception_analysis.m:
compiler/inst_match.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/llds_out.m:
compiler/middle_rec.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_il.m:
compiler/modecheck_unify.m:
compiler/modes.m:
compiler/opt_util.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/qual_info.m:
compiler/rl.m:
compiler/rl_exprn.m:
compiler/rl_key.m:
compiler/rtti_out.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/term_constr_initial.m:
compiler/term_constr_util.m:
compiler/term_norm.m:
compiler/termination.m:
compiler/trace.m:
compiler/typecheck.m:
compiler/unify_gen.m:
Conform to the changes above.
compiler/export.m:
compiler/exprn_aux.m:
compiler/foreign.m:
compiler/polymorphism.m:
compiler/proc_label.m:
compiler/rtti_to_mlds.m:
compiler/special_pred.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/state_var.m:
compiler/switch_util.m:
compiler/trace_params.m:
Conform to the changes above.
Convert to four-space indentation.
compiler/mlds_to_java.m:
compiler/var_locn.m:
Conform to the changes above, which requires threading the module_info
through the module.
Convert to four-space indentation.
compiler/mercury_compile.m:
Pass the module_info to mlds_to_java.m.
compiler/ml_util.m:
compiler/polymorphism.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
Delete some previously missed references to the temporary types used
to bootstrap the change to the type_info type's arity.
compiler/polymorphism.m:
Turn back on an optimization that avoids passing parameters (such as
type_infos) to foreign_procs if they are not actually referred to.
compiler/prog_data.m:
Convert to four-space indentation.
library/svvarset.m:
Add a missing predicate.
trace/mercury_trace.c:
Delete the unused function that used to check for dummy types.
tests/debugger/field_names.{m,inp,exp}:
Add to this test case a test of the handling of dummy types. Check that
their values can be printed out during normal execution, and that the
debugger doesn't consider them live nondummy variables, just as it
doesn't consider I/O states live nondummy variables.
287 lines
9.8 KiB
C++
287 lines
9.8 KiB
C++
//
|
|
// Copyright (C) 2000-2005 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.
|
|
//
|
|
|
|
// mercury_mcpp.h - This file defines the system runtime types and
|
|
// macros that are used when generating code for the .NET backend.
|
|
// It is written using Managed Extensions for C++ (usually called Managed C++
|
|
// or MC++).
|
|
|
|
// We need a definition of NULL
|
|
#include <stddef.h>
|
|
|
|
namespace mercury {
|
|
|
|
typedef int MR_Integer;
|
|
typedef unsigned int MR_Unsigned;
|
|
typedef System::Int32 MR_BoxedInt;
|
|
typedef System::Boolean MR_Bool;
|
|
typedef System::Boolean MR_bool;
|
|
|
|
typedef System::Char MR_Char; // `Char' is MS's name for unicode characters
|
|
|
|
typedef double MR_Float;
|
|
// XXX using a typedef doesn't seem to work properly when we want
|
|
// to use methods -- MR_BoxedFloat::somemethod() doesn't seem to work.
|
|
// This might be an issue with value classes and typedefs.
|
|
#define MR_BoxedFloat System::Double
|
|
|
|
typedef System::String *MR_String;
|
|
typedef void (*MR_Cont) (void *);
|
|
|
|
// Should these be MR_ qualified?
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#define MR_TRUE 1
|
|
#define MR_FALSE 0
|
|
|
|
typedef __gc public class System::Object * MR_Word[];
|
|
typedef __gc public class System::Object * MR_Box;
|
|
typedef __gc public class System::Array * MR_Array;
|
|
|
|
#define MR_Ref(type) type __gc *
|
|
typedef MR_Ref(MR_Box) MR_Box_Ref;
|
|
typedef MR_Ref(MR_Word) MR_Word_Ref;
|
|
|
|
/*
|
|
#ifdef MR_HIGHLEVEL_DATA
|
|
typedef __gc public class mercury::private_builtin::type_info_1* MR_TypeInfo;
|
|
typedef __gc public class mercury::rtti_implementation::type_info_0* MR_TypeInfo_0;
|
|
typedef __gc public class mercury::builtin::comparison_result_0 *MR_ComparisonResult;
|
|
typedef __gc public class mercury::std_util::univ_0 *MR_Univ;
|
|
#else
|
|
*/
|
|
typedef __gc public class System::Object * MR_TypeInfo[];
|
|
typedef __gc public class System::Object * MR_TypeInfo_0[];
|
|
typedef __gc public class System::Object * MR_ComparisonResult[];
|
|
typedef __gc public class System::Object * MR_Univ[];
|
|
// #endif
|
|
|
|
typedef __gc public class System::Object * MR_TypeCtorInfo[];
|
|
typedef __gc public class System::Object * MR_TypeInfoParams[];
|
|
typedef __gc public class System::Object * MR_TypeClassInfo[];
|
|
|
|
// XXX This code is duplicated in mercury_type_info.h.
|
|
// We should factor out these definitions and use a shared version.
|
|
|
|
#define MR_COMPARE_EQUAL 0
|
|
#define MR_COMPARE_LESS 1
|
|
#define MR_COMPARE_GREATER 2
|
|
|
|
#define MR_STRINGIFY(x) MR_STRINGIFY_2(x)
|
|
#define MR_STRINGIFY_2(x) #x
|
|
|
|
#define MR_PASTE2(a,b) MR_PASTE2_2(a,b)
|
|
#define MR_PASTE2_2(a,b) a##b
|
|
#define MR_PASTE3(a,b,c) MR_PASTE3_2(a,b,c)
|
|
#define MR_PASTE3_2(a,b,c) a##b##c
|
|
#define MR_PASTE4(a,b,c,d) MR_PASTE4_2(a,b,c,d)
|
|
#define MR_PASTE4_2(a,b,c,d) a##b##c##d
|
|
#define MR_PASTE5(a,b,c,d,e) MR_PASTE5_2(a,b,c,d,e)
|
|
#define MR_PASTE5_2(a,b,c,d,e) a##b##c##d##e
|
|
#define MR_PASTE6(a,b,c,d,e,f) MR_PASTE6_2(a,b,c,d,e,f)
|
|
#define MR_PASTE6_2(a,b,c,d,e,f) a##b##c##d##e##f
|
|
#define MR_PASTE7(a,b,c,d,e,f,g) MR_PASTE7_2(a,b,c,d,e,f,g)
|
|
#define MR_PASTE7_2(a,b,c,d,e,f,g) a##b##c##d##e##f##g
|
|
|
|
// The code to generate RTTI structures is somewhat complicated.
|
|
// For each RTTI symbol, we generate an initializer method,
|
|
// and a field. The initializer method returns a value for the field.
|
|
// Since it is a static field, the initializer will be run in the class
|
|
// constructor.
|
|
//
|
|
// This code is intended to be more general than the macros in
|
|
// mercury_typeinfo.h -- by conditionally defining the appropriate
|
|
// #defines for MR_CLASS_INIT* and MR_STRUCT_INIT* you should be able to
|
|
// re-use this code, however this has not been done yet.
|
|
|
|
// In the .NET backend, we don't need to forward declare RTTI structures.
|
|
#define MR_Declare_entry(a)
|
|
#define MR_Declare_struct(a)
|
|
|
|
// We have to jump through a few hoops to get function pointers -- we do
|
|
// it in IL currently. We treat function pointers as integers and have
|
|
// to box them.
|
|
#define MR_BOX_INT(a) __box(a)
|
|
#define MR_MAYBE_STATIC_CODE(a) \
|
|
MR_BOX_INT(mercury::runtime::TempHack::get_ftn_ptr_##a())
|
|
#define MR_ENTRY(a) a
|
|
// XXX MR_ENTRY appears to be unused
|
|
|
|
// Code to handle initialization of fields.
|
|
#define MR_STRUCT_INIT(a)
|
|
#define MR_STRUCT_INIT_END(a)
|
|
#define MR_CLASS_INIT(a) \
|
|
static MR_Word a(void) { \
|
|
System::Object *arr[] = {
|
|
#define MR_CLASS_INIT_END(m, f, i) \
|
|
}; \
|
|
return arr; \
|
|
} \
|
|
static MR_Word f = i(); \
|
|
static MR_Word MR_PASTE2(m, f) = i();
|
|
|
|
#define MR_string_const(a, s) ((MR_String) a)
|
|
#define MR_TYPECTOR_REP(a) MR_BOX_INT(mercury::runtime::Constants::a)
|
|
|
|
// XXX This is hardcoded
|
|
#define MR_RTTI_VERSION MR_BOX_INT(9)
|
|
|
|
// XXX It is intended that we eventually define the constants in
|
|
// private_builtin.m and mercury_mcpp.cpp in terms of these #defines
|
|
// instead of hard-coding the values.
|
|
#define MR_TYPECTOR_REP_ENUM_val 0
|
|
#define MR_TYPECTOR_REP_ENUM_USEREQ_val 1
|
|
#define MR_TYPECTOR_REP_DU_val 2
|
|
#define MR_TYPECTOR_REP_DU_USEREQ_val 3
|
|
#define MR_TYPECTOR_REP_NOTAG_val 4
|
|
#define MR_TYPECTOR_REP_NOTAG_USEREQ_val 5
|
|
#define MR_TYPECTOR_REP_EQUIV_val 6
|
|
#define MR_TYPECTOR_REP_FUNC_val 7
|
|
#define MR_TYPECTOR_REP_INT_val 8
|
|
#define MR_TYPECTOR_REP_CHAR_val 9
|
|
#define MR_TYPECTOR_REP_FLOAT_val 10
|
|
#define MR_TYPECTOR_REP_STRING_val 11
|
|
#define MR_TYPECTOR_REP_PRED_val 12
|
|
#define MR_TYPECTOR_REP_SUBGOAL_val 13
|
|
#define MR_TYPECTOR_REP_VOID_val 14
|
|
#define MR_TYPECTOR_REP_C_POINTER_val 15
|
|
#define MR_TYPECTOR_REP_TYPEINFO_val 16
|
|
#define MR_TYPECTOR_REP_TYPECLASSINFO_val 17
|
|
#define MR_TYPECTOR_REP_ARRAY_val 18
|
|
#define MR_TYPECTOR_REP_SUCCIP_val 19
|
|
#define MR_TYPECTOR_REP_HP_val 20
|
|
#define MR_TYPECTOR_REP_CURFR_val 21
|
|
#define MR_TYPECTOR_REP_MAXFR_val 22
|
|
#define MR_TYPECTOR_REP_REDOFR_val 23
|
|
#define MR_TYPECTOR_REP_REDOIP_val 24
|
|
#define MR_TYPECTOR_REP_TRAIL_PTR_val 25
|
|
#define MR_TYPECTOR_REP_TICKET_val 26
|
|
#define MR_TYPECTOR_REP_NOTAG_GROUND_val 27
|
|
#define MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ_val 28
|
|
#define MR_TYPECTOR_REP_EQUIV_GROUND_val 29
|
|
#define MR_TYPECTOR_REP_TUPLE_val 30
|
|
#define MR_TYPECTOR_REP_RESERVED_ADDR_val 31
|
|
#define MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ_val 32
|
|
#define MR_TYPECTOR_REP_TYPECTORINFO_val 33
|
|
#define MR_TYPECTOR_REP_BASETYPECLASSINFO_val 34
|
|
#define MR_TYPECTOR_REP_TYPEDESC_val 35
|
|
#define MR_TYPECTOR_REP_TYPECTORDESC_val 36
|
|
#define MR_TYPECTOR_REP_FOREIGN_val 37
|
|
#define MR_TYPECTOR_REP_REFERENCE_val 38
|
|
#define MR_TYPECTOR_REP_STABLE_C_POINTER_val 39
|
|
#define MR_TYPECTOR_REP_STABLE_FOREIGN_val 40
|
|
#define MR_TYPECTOR_REP_PSEUDOTYPEDESC_val 41
|
|
#define MR_TYPECTOR_REP_DUMMY_val 42
|
|
#define MR_TYPECTOR_REP_UNKNOWN_val 43
|
|
|
|
// XXX we should integrate this macro in with the version in
|
|
// mercury_typeinfo.h
|
|
#define MR_DEFINE_BUILTIN_TYPE_CTOR_INFO_FULL(m, n, a, cr, u, c) \
|
|
MR_Declare_entry(u) \
|
|
MR_Declare_entry(c) \
|
|
MR_Declare_struct(MR_STATIC_CODE_CONST struct MR_TypeCtorInfo_Struct) \
|
|
MR_STRUCT_INIT(MR_PASTE5(mercury_data_, __type_ctor_info_, n, _, a) = {) \
|
|
MR_CLASS_INIT(MR_PASTE4(type_ctor_init_, n, _, a)) \
|
|
MR_BOX_INT(a), \
|
|
MR_RTTI_VERSION, \
|
|
MR_BOX_INT(-1), \
|
|
MR_TYPECTOR_REP(cr), \
|
|
MR_MAYBE_STATIC_CODE(n##_unify), \
|
|
MR_MAYBE_STATIC_CODE(n##_compare), \
|
|
MR_string_const(MR_STRINGIFY(m), sizeof(MR_STRINGIFY(m))-1), \
|
|
MR_string_const(MR_STRINGIFY(n), sizeof(MR_STRINGIFY(n))-1), \
|
|
MR_BOX_INT(-1), \
|
|
MR_BOX_INT(-1), \
|
|
MR_BOX_INT(-1), \
|
|
MR_BOX_INT(0) \
|
|
MR_STRUCT_INIT_END(}) \
|
|
MR_CLASS_INIT_END(m, MR_PASTE5(__, type_ctor_info_, n, _, a), MR_PASTE4(type_ctor_init_, n, _, a))
|
|
|
|
#define MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(m, n, a, cr) \
|
|
MR_DEFINE_BUILTIN_TYPE_CTOR_INFO_FULL(m, n, a, cr, \
|
|
MR_PASTE7(mercury::, m, ::do_unify__, n, _, a, _0), \
|
|
MR_PASTE7(mercury::, m, ::do_compare__, n, _, a, _0))
|
|
|
|
// Some definitions for writing code by hand that constructs lists.
|
|
// Note that this is very dependent on the data representation chosen
|
|
// by the compiler.
|
|
|
|
#ifdef MR_HIGHLEVEL_DATA
|
|
#define MR_list_nil(List) \
|
|
List = mercury::list::mercury_code::ML_empty_list(NULL)
|
|
|
|
#define MR_list_cons(List, Head, Tail) \
|
|
List = mercury::list::mercury_code::ML_cons(NULL, Head, Tail)
|
|
#else
|
|
#define MR_list_cons(List, Head, Tail) \
|
|
do { \
|
|
MR_Word _tmp; \
|
|
MR_newobj((_tmp), 1, 2); \
|
|
MR_objset((_tmp), 1, (Head)); \
|
|
MR_objset((_tmp), 2, (Tail)); \
|
|
List = _tmp; \
|
|
} while (0)
|
|
|
|
#define MR_list_nil(List) \
|
|
MR_newobj(List, 0, 0);
|
|
#endif
|
|
|
|
#define MR_list_is_cons(List) \
|
|
(System::Convert::ToInt32((List)->GetValue(0)))
|
|
|
|
#define MR_list_is_nil(List) \
|
|
(System::Convert::ToInt32((List)->GetValue(0)) == 0)
|
|
|
|
#define MR_list_head(List) \
|
|
((List)->GetValue(1))
|
|
|
|
#define MR_list_tail(List) \
|
|
(dynamic_cast<MR_Word>((List)->GetValue(2)))
|
|
|
|
// Some definitions for writing code by hand that constructs any type.
|
|
|
|
#define MR_newobj(Obj, Tag, Size) \
|
|
do { \
|
|
(Obj) = new System::Object __gc * __gc[(Size + 1)]; \
|
|
(Obj)[0] = MR_BOX_INT(Tag); \
|
|
} while (0)
|
|
|
|
#define MR_untagged_newobj(Obj, Size) \
|
|
do { \
|
|
(Obj) = new System::Object __gc * __gc[(Size)]; \
|
|
} while (0)
|
|
|
|
#define MR_newobj_preboxed_tag(Obj, Tag, Size) \
|
|
do { \
|
|
(Obj) = new System::Object __gc * __gc[(Size + 1)]; \
|
|
(Obj)[0] = (Tag); \
|
|
} while (0)
|
|
|
|
#define MR_objset(Obj, Offset, Element) \
|
|
do { \
|
|
(Obj)[(Offset)] = Element; \
|
|
} while (0)
|
|
|
|
#define MR_c_pointer_to_word(Obj, CPointer) \
|
|
MR_newobj_preboxed_tag(Obj, CPointer, 0)
|
|
|
|
#define MR_word_to_c_pointer(CPointer) \
|
|
( (CPointer)[0] )
|
|
|
|
#define MR_newenum(Obj, Tag) \
|
|
MR_newobj(Obj, Tag, 0)
|
|
|
|
// A few macros to define some RTTI slots.
|
|
// At the moment RTTI support in the .NET backend is very minimal.
|
|
|
|
#define MR_TYPEINFO_TYPE_CTOR_INFO_SLOT 0
|
|
|
|
#define MR_TYPE_CTOR_INFO_ARITY_SLOT 0
|
|
#define MR_TYPE_CTOR_INFO_UNIFY_PRED_SLOT 5
|
|
#define MR_TYPE_CTOR_INFO_COMPARE_PRED_SLOT 6
|
|
|
|
} /* end namespace mercury */
|