Files
mercury/mdbcomp/prim_data.m
Ian MacLarty 87dc81843f Tell the declarative debugger that private_builtin predicates don't generate
Estimated hours taken: 1
Branches: main

Tell the declarative debugger that private_builtin predicates don't generate
any events.  When a program is compiled in a .decldebug grade the
declarative debugger performs a sanity check when doing subterm dependency
tracking.  It checks that each interface event matches up to the correct
atomic goal in the procedure body.  This sanity check was failing when
a call to a predicate from private_builtin was encountered, since such calls
don't generate any events.

compiler/prog_util.m:
mdbcomp/prim_data.m:

Move the definition of any_mercury_builtin_module and all related predicates
from compiler/prog_util.m to mdbcomp/prim_data.m, so that this code can be
shared by the compiler and the debugger.

compiler/simplify.m:
	Call mercury_public_builtin_module in mdbcomp/priv_data.

mdbcomp/program_representation.m:
	Call any_mercury_builtin_module when determining if a predicate call
	should be treated as a primitive or not.

tests/debugger/declarative/Mmakefile:
tests/debugger/declarative/priv_builtin_bug.exp:
tests/debugger/declarative/priv_builtin_bug.inp:
tests/debugger/declarative/priv_builtin_bug.m:
	Add a regression test.  Previously this test would result in the
	following exception being thrown:
	"match_atomic_goal_to_contour_event: name mismatch on call".
	The test should only be run in .decldebug grades, since this is
	the only time the sanity check is done (in other grades some
	events are allowed to be missing).
2005-06-14 08:15:07 +00:00

293 lines
10 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 2005 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
%
% File: prim_data.m.
% Main authors: fjh, zs.
%
% This module contains some types and predicates that are, or are planned to
% be, shared between the compiler and the debugger.
%-----------------------------------------------------------------------------%
:- module mdbcomp.prim_data.
:- interface.
% was in browser/util.m and compiler/prog_data.m
% This enumeration must be EXACTLY the same as the MR_PredFunc enum
% in runtime/mercury_stack_layout.h, and in the same order, since the
% code (in browser) assumes the representation is the same.
:- type pred_or_func
---> predicate
; function.
% was in browser/util.m and compiler/trace_params.m
% The kinds of events with which MR_trace may be called, either
% by compiler-generated code, or by code in the standard library
% referring to compiler-generated data structures.
%
% This enumeration must be EXACTLY the same as the MR_trace_port enum
% in runtime/mercury_trace_base.h, and in the same order, since the
% code (in browser) assumes the representation is the same.
:- type trace_port
---> call
; exit
; redo
; fail
; exception
; ite_cond
; ite_then
; ite_else
; neg_enter
; neg_success
; neg_failure
; disj
; switch
; nondet_pragma_first
; nondet_pragma_later
.
% was in compiler/prog_data.m
% The order that the sym_name function symbols appear in is
% significant for module dependency ordering.
:- type sym_name
---> unqualified(string)
; qualified(sym_name, string).
:- type module_name == sym_name.
% was in compiler/proc_label.m
% A proc_label is a data structure a backend can use to as the basis
% of the label used as the entry point of a procedure.
%
% The defining module is the module that provides the code for the
% predicate, the declaring module contains the `:- pred' declaration.
% When these are different, as for specialised versions of predicates
% from `.opt' files, the defining module's name may need to be added
% as a qualifier to the label.
:- type proc_label
---> proc(
module_name, % defining module
pred_or_func,
module_name, % declaring module
string, % name
int, % arity
int % mode number
)
; special_proc(
module_name, % defining module
special_pred_id,% indirectly defines pred name
module_name, % type module
string, % type name
int, % type arity
int % mode number
).
% was in compiler/special_pred.m
:- type special_pred_id
---> unify
; index
; compare
; initialise.
% special_pred_name_arity(SpecialPredType, GenericPredName, Arity):
% true iff there is a special predicate of category
% SpecialPredType, called builtin:GenericPredName/Arity.
:- pred special_pred_name_arity(special_pred_id, string, int).
:- mode special_pred_name_arity(in, out, out) is det.
:- mode special_pred_name_arity(out, in, out) is semidet.
% was in compiler/prog_util.m
% string_to_sym_name(String, Separator, SymName):
% Convert a string, possibly prefixed with
% module qualifiers (separated by Separator),
% into a symbol name.
%
:- pred string_to_sym_name(string::in, string::in, sym_name::out) is det.
% sym_name_to_string(SymName, Separator, String):
% convert a symbol name to a string,
% with module qualifiers separated by Separator.
:- pred sym_name_to_string(sym_name::in, string::in, string::out)
is det.
:- func sym_name_to_string(sym_name, string) = string.
% sym_name_to_string(SymName, String):
% convert a symbol name to a string,
% with module qualifiers separated by
% the standard Mercury module qualifier operator.
:- pred sym_name_to_string(sym_name::in, string::out) is det.
:- func sym_name_to_string(sym_name) = string.
% is_submodule(SymName1, SymName2).
% True iff SymName1 is a submodule of SymName2.
% For example mod1.mod2.mod3 is a submodule of mod1.mod2.
%
:- pred is_submodule(module_name::in, module_name::in) is semidet.
% insert_module_qualifier(ModuleName, SymName0, SymName):
% prepend the specified ModuleName onto the module
% qualifiers in SymName0, giving SymName.
:- pred insert_module_qualifier(string::in, sym_name::in, sym_name::out)
is det.
% Returns the name of the module containing public builtins;
% originally this was "mercury_builtin", but it later became
% just "builtin", and it may eventually be renamed "std:builtin".
% This module is automatically imported, as if via `import_module'.
:- pred mercury_public_builtin_module(sym_name::out) is det.
:- func mercury_public_builtin_module = sym_name.
% Returns the name of the module containing private builtins;
% traditionally this was "mercury_builtin", but it later became
% "private_builtin", and it may eventually be renamed
% "std:private_builtin".
% This module is automatically imported, as if via `use_module'.
:- pred mercury_private_builtin_module(sym_name::out) is det.
:- func mercury_private_builtin_module = sym_name.
% Returns the name of the module containing builtins for tabling;
% originally these were in "private_builtin", but they
% may soon be moved into a separate module.
% This module is automatically imported iff tabling is enabled.
:- pred mercury_table_builtin_module(sym_name::out) is det.
:- func mercury_table_builtin_module = sym_name.
% Returns the name of the module containing the builtins for
% deep profiling.
% This module is automatically imported iff deep profiling is
% enabled.
:- pred mercury_profiling_builtin_module(sym_name::out) is det.
:- func mercury_profiling_builtin_module = sym_name.
% Returns the name of the module containing the builtins for
% term size profiling.
% This module is automatically imported iff term size profiling is
% enabled.
:- pred mercury_term_size_prof_builtin_module(sym_name::out) is det.
:- func mercury_term_size_prof_builtin_module = sym_name.
% Returns the name of the module containing the public builtins
% used by the Aditi transaction interface, currently "aditi".
% This module is not automatically imported (XXX should it be?).
:- pred aditi_public_builtin_module(sym_name::out) is det.
:- func aditi_public_builtin_module = sym_name.
% Returns the name of the module containing the private builtins
% used by the Aditi transaction interface, currently
% "aditi_private_builtin".
% This module is automatically imported iff the Aditi interface
% is enabled.
:- pred aditi_private_builtin_module(sym_name::out) is det.
:- func aditi_private_builtin_module = sym_name.
% Succeeds iff the specified module is one of the
% builtin modules listed above which are automatically imported.
:- pred any_mercury_builtin_module(sym_name::in) is semidet.
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module int, string, list.
% This would be simpler if we had a string__rev_sub_string_search/3 pred.
% With that, we could search for underscores right-to-left,
% and construct the resulting symbol directly.
% Instead, we search for them left-to-right, and then call
% insert_module_qualifier to fix things up.
string_to_sym_name(String, ModuleSeparator, Result) :-
(
string__sub_string_search(String, ModuleSeparator, LeftLength),
LeftLength > 0
->
string__left(String, LeftLength, ModuleName),
string__length(String, StringLength),
string__length(ModuleSeparator, SeparatorLength),
RightLength = StringLength - LeftLength - SeparatorLength,
string__right(String, RightLength, Name),
string_to_sym_name(Name, ModuleSeparator, NameSym),
insert_module_qualifier(ModuleName, NameSym, Result)
;
Result = unqualified(String)
).
insert_module_qualifier(ModuleName, unqualified(PlainName),
qualified(unqualified(ModuleName), PlainName)).
insert_module_qualifier(ModuleName, qualified(ModuleQual0, PlainName),
qualified(ModuleQual, PlainName)) :-
insert_module_qualifier(ModuleName, ModuleQual0, ModuleQual).
sym_name_to_string(SymName, String) :-
sym_name_to_string(SymName, ".", String).
sym_name_to_string(SymName) = String :-
sym_name_to_string(SymName, String).
sym_name_to_string(SymName, Separator) = String :-
sym_name_to_string(SymName, Separator, String).
sym_name_to_string(unqualified(Name), _Separator, Name).
sym_name_to_string(qualified(ModuleSym, Name), Separator,
QualName) :-
sym_name_to_string(ModuleSym, Separator, ModuleName),
string__append_list([ModuleName, Separator, Name], QualName).
is_submodule(SymName, SymName).
is_submodule(qualified(SymNameA, _), SymNameB) :-
is_submodule(SymNameA, SymNameB).
special_pred_name_arity(unify, "unify", 2).
special_pred_name_arity(index, "index", 2).
special_pred_name_arity(compare, "compare", 3).
special_pred_name_arity(initialise, "initialise", 1).
% We may eventually want to put the standard library into a package "std":
% mercury_public_builtin_module = qualified(unqualified("std"), "builtin").
% mercury_private_builtin_module(M) =
% qualified(unqualified("std"), "private_builtin"))).
mercury_public_builtin_module = unqualified("builtin").
mercury_public_builtin_module(mercury_public_builtin_module).
mercury_private_builtin_module = unqualified("private_builtin").
mercury_private_builtin_module(mercury_private_builtin_module).
mercury_table_builtin_module = unqualified("table_builtin").
mercury_table_builtin_module(mercury_table_builtin_module).
mercury_profiling_builtin_module = unqualified("profiling_builtin").
mercury_profiling_builtin_module(mercury_profiling_builtin_module).
mercury_term_size_prof_builtin_module = unqualified("term_size_prof_builtin").
mercury_term_size_prof_builtin_module(mercury_term_size_prof_builtin_module).
aditi_public_builtin_module = unqualified("aditi").
aditi_public_builtin_module(aditi_public_builtin_module).
aditi_private_builtin_module = unqualified("aditi_private_builtin").
aditi_private_builtin_module(aditi_private_builtin_module).
any_mercury_builtin_module(Module) :-
( mercury_public_builtin_module(Module)
; mercury_private_builtin_module(Module)
; mercury_table_builtin_module(Module)
; mercury_profiling_builtin_module(Module)
; mercury_term_size_prof_builtin_module(Module)
; aditi_private_builtin_module(Module)
).