Estimated hours taken: 1
Branches: main
browser/collect_lib.m:
browser/declarative_debugger.m:
browser/declarative_execution.m:
browser/dl.m:
browser/interactive_query.m:
browser/io_action.m:
browser/mdb.m:
browser/name_mangle.m:
browser/util.m:
Add Mercury versions of code which has been defined only as
foreign procs so as to allow this directory to compile for
the non-C backends.
The Mercury versions just call private_builtin__sorry.
Estimated hours taken: 12
Branches: main
Until now, programmers could add `tabled_for_io' annotations to foreign_procs
that do I/O, which asks the compiler to make those foreign_procs idempotent,
i.e. ensures that they are performed at most once even in the presence of a
retry operation in the debugger. This change adds a compiler option,
--trace-table-io-require, which generates an error if a foreign_proc that does
I/O does not have this annotation. Specifying this option thus ensures
that all I/O done by the program is idempotent.
In the future, we may want to have this option turned on in all debugging
grades. Until we decide about, the new option is not yet documented.
compiler/options.m:
Add the new option --trace-table-io-require.
compiler/handle_options.m:
Make --trace-table-io-require imply --trace-table-io.
compiler/table_gen.m:
If --trace-table-io-require is enabled, require all I/O primitives
to have the tabled_for_io annotation.
compiler/mercury_compile.m:
Pass I/O states to table_gen.m, since it can now generate error
messages.
trace/mercury_trace_util.h:
trace/mercury_trace_vars.c:
When calling Mercury code from the trace directory, disable I/O
tabling, since any I/O actions executed by Mercury code in the browser
directory (or by library code called from there) should not be tabled,
not being part of the user program.
Due to the depth of nesting, make mercury_trace_vars.c use four-space
indentation.
browser/collect_lib.m:
browser/declarative_debugger.m:
browser/declarative_execution.m:
browser/dl.m:
browser/io_action.m:
browser/mdb.m:
browser/name_mangle.m:
browser/util.m:
compiler/gcc.m:
compiler/mercury_compile.m:
compiler/passes_aux.m:
compiler/process_util.m:
compiler/stack_layout.m:
library/io.m:
library/time.m:
tests/debugger/declarative/tabled_read_decl.m:
Add a whole lot of tabled_for_io annotations, to enable the compiler to
bootstrap with --trace-table-io-require enabled.
In many cases, this required turning old-style pragma c_code into
pragma foreign_proc. While doing that, I standardized the layouts
of pragma foreign_procs.
browser/util.m:
Turn an impure semidet predicate into a pure det predicate with I/O
states, to allow it to be tabled. Make it return a Mercury bool
to indicate success or failure.
library/bool.m:
Add functions that allow C code to get their hands on the constants
`yes' and `no', for communication with Mercury code.
library/table_builtin.m:
Add debugging code to the main primitive of I/O tabling. This is
controlled both by the macro for retry debugging and a boolean global.
library/mercury_trace_base.[ch]:
Add the boolean global variable to switch the new debugging code in
table_builtin.m on and off.
library/mercury_trace_internal.c:
When starting I/O tabling with retry debug enabled, turn on the switch.
tests/debugger/queens.exp3:
New expected output file that applies when the library is compiled with
--trace-table-io-require.
Estimated hours taken: 7
branches: main.
Add a post-process predicate in collect. This predicate is optional
and automatically added if the collect user do not define it.
browser/collect_lib.m:
Add support for dynamically link the post_process/2 predicates.
extras/morphine/source/collect.in:
extras/morphine/source/collect.op
Add support for automatically add a post_process predicate definition
as well as a accumulator_type definition.
trace/mercury_trace_external.h:
trace/mercury_trace_external.c:
Change the name of the accumulator variable type from
MR_collecting_variable to MR_accumulator variable. Also Add a new
variable type MR_collected_variable that contains the value that
is sent to the collect caller process (instead of
MR_collecting_variable).
Apply (post_process_ptr) (which points to
collect__post_process/2) to the accumulator variable before
sending the collect result.
extras/morphine/non-regression-tests/solutions:
Replace collected_type by accumulator_type.
extras/morphine/non-regression-tests/queens.exp:
extras/morphine/non-regression-tests/queens.in:
extras/morphine/non-regression-tests/test_ln:
Add a new test case entry to test line numbers and the use of
post_process/2 with collect.
Estimated hours taken: 3
branches: main.
Make line numbers available for collect.
browser/collect_lib.m:
Minor comment fixes.
extras/morphine/source/collect.in:
extras/morphine/source/collect.op
Add the line number event attribute.
trace/mercury_trace.h:
trace/mercury_trace.c:
Add the line number as argument of MR_COLLECT_filter.
trace/mercury_trace_external.h:
trace/mercury_trace_external.c:
Put the code that computes the line number in a function called
MR_get_line_number() to be able to call it in mercury_trace.c
to avoid duplicated code.
Estimated hours taken: 2
Get the compiler to bootstrap with -DMR_NO_BACKWARDS_COMPAT.
compiler/c_util.m:
compiler/rtti_out.m:
Add MR_ prefixes to various type names in generated code.
compiler/*.m:
browser/*.m:
library/*.m:
Add MR_prefixes to various type and function names in pragma C code.
runtime/*.[ch]:
trace/*.[ch]:
Add MR_prefixes to various type and function names in
hand-written code.
Estimated hours taken: 1
Make all the modules in the browser library sub-modules of
module `mdb', to avoid link errors when users use module names
such as `parse'.
browser/Mmakefile:
browser/browser_library.m:
browser/mdb.m:
Rename browser_library.m to mdb.m.
Change `:- import_module' declarations to
`:- include_module' declarations.
browser/Mmakefile:
Remove the special case rule for `mer_browser.init' --
it doesn't work when the file names are not the same
as the module name. Instead, the default rule for `mdb.init'
is used and the output is copied to `mer_browser.init'.
browser/.cvsignore:
Rename header files, etc.
browser/*.m:
Add a `mdb__' prefix to the names of modules in the browser library
in `:- module' and `:- import_module' declarations.
trace/*.c:
Rename the header files for the browser library in
`#include' statements.
tests/hard_coded/Mmakefile:
tests/hard_coded/parse.m:
tests/hard_coded/parse.exp:
Test case.
Estimated hours taken: 0.5
The option, --warn-interface-imports, wasn't respecting the
--halt-at-warn option.
compiler/module_qual.m:
If --halt-at-warn turned on, make sure the compiler exits with a
non-zero exit status.
browser/collect_lib.m:
Remove unused interface imports.
--
Estimated hours taken: 2
This change implements the Fergus suggestion; i.e. add an argument to filter
saying whether we stop collecting or not.
browser/debugger_interface.m:
Define two new debugger responses `execution_continuing' and
`execution_terminated' which respectively tell the debugger that
the execution continues or is terminated after the response to collect
has been sent.
browser/collect_lib.m:
Update comments.
trace/mercury_trace_external.c:
Opium-M/source/collect.in:
Opium-M/source/collect.op:
Add an new argument to filter that says saying whether we stop
collecting or not.
% Copyright (C) 1999 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.
%-----------------------------------------------------------------------------%
% File: collect_lib.m
% Author: jahier
% Purpose:
% This module defines functions that are needed to implement the
% `collect' primitive.
%
% `collect' collects runtime information from Mercury program executions.
% It is intended to let users easily implement their own monitors with
% acceptable performances.
%
% To use it, users just need to define 4 things in a file, using the
% Mercury syntax:
% 1) a `collected_type' which is the type of the collecting
% variable that will contain the result of the monitoring
% activity.
% 2) The predicate initialize/1 which initializes this
% collecting variable. initialize/1 should have the
% following declarations:
% :- pred initialize(collected_type).
% :- mode initialize(out) is det.
% 3) the predicate filter/3 which updates this collecting
% variable at each execution event. filter/3 should have the
% following declarations:
% :- pred filter(event, collected_type, collected_type).
% :- mode filter(in, di, uo) is det.
% 4) and eventually the mode definition of the second and the
% third arguments of filter/3: `acc_in' and `acc_out'. Those
% mode have `di' and `uo' respectively as default values.
%
% Then, this file is used to generate the Mercury module `collect.m',
% which is compiled and dynamically linked with the current execution.
% When a `collect' request is made from the external debugger, a variable
% of type collected_type is first initialized (with initialize/1) and
% then updated (with filter/3) for all the events of the remaining
% execution. When the end of the execution is reached, the last value of
% the collecting variable is send to the debugger.
:- module collect_lib.
:- interface.
:- import_module io, char, dl.
:- pred dummy_pred_to_avoid_warning_about_nothing_exported is det.
%------------------------------------------------------------------------------%
:- implementation.
:- import_module int, list, std_util, io, char.
:- import_module dl.
dummy_pred_to_avoid_warning_about_nothing_exported.
:- pragma export(link_collect(in, out, out, out, out, out, out, di, uo),
"ML_CL_link_collect").
:- pragma export(unlink_collect(in, di, uo), "ML_CL_unlink_collect").
% We need Handle to be able to close the shared object (dl__close) later on.
% When the link failed, we output NULL pointers instead of maybe pointers
% for performance reasons; indeed, filter will be called at every event
% so we don't want to pay the price of the maybe variable de-construction
% at each event.
% dynamically link the collect module;
:- pred link_collect(string, c_pointer, c_pointer, c_pointer, c_pointer,
dl__result(handle), char, io__state, io__state).
:- mode link_collect(in, out, out, out, out, out, out, di, uo) is det.
link_collect(ObjectFile, Filter, Initialize, SendResult, GetCollectType,
MaybeHandle, Result) -->
%
% Link in the object code for the module `collect' from ObjectFile.
%
dl__open(ObjectFile, lazy, local, MaybeHandle),
(
{ MaybeHandle = error(Msg) },
print("dlopen failed: "), print(Msg), nl,
{ set_to_null_pointer(Initialize) },
{ set_to_null_pointer(Filter) },
{ set_to_null_pointer(SendResult) },
{ set_to_null_pointer(GetCollectType) },
{ Result = 'n' }
;
{ MaybeHandle = ok(Handle) },
%
% Look up the address of the C functions corresponding to the
% initialize/1 and filter/14 predicates in the collect module.
%
dl__sym(Handle, "ML_COLLECT_initialize", MaybeInitialize),
dl__sym(Handle, "ML_COLLECT_filter", MaybeFilter),
dl__sym(Handle, "ML_COLLECT_send_collect_result", MaybeSendResult),
dl__sym(Handle, "ML_COLLECT_collecting_variable_type", MaybeType),
(
{ MaybeInitialize = ok(Initialize0) },
{ MaybeFilter = ok(Filter0) },
{ MaybeSendResult = ok(SendResult0) },
{ MaybeType = ok(Type0) }
->
{ Result = 'y' },
{ Initialize = Initialize0 },
{ Filter = Filter0 },
{ GetCollectType = Type0 },
{ SendResult = SendResult0 }
;
{ set_to_null_pointer(Initialize) },
{ set_to_null_pointer(Filter) },
{ set_to_null_pointer(SendResult) },
{ set_to_null_pointer(GetCollectType) },
{ Result = 'n' }
)
).
:- pred set_to_null_pointer(c_pointer::out) is det.
:- pragma c_code(set_to_null_pointer(Pointer::out),
[will_not_call_mercury, thread_safe],
"(Pointer = (Word) NULL)").
%------------------------------------------------------------------------------%
:- pred unlink_collect(dl__result(handle), io__state, io__state).
:- mode unlink_collect(in, di, uo) is det.
% Dynamically unlink a module that was dynamically linked in
% using `link_collect'.
unlink_collect(MaybeHandle) -->
(
{ MaybeHandle = error(_) }
% There is nothing to close since an error(_) here means that
% the dlopen failed.
;
{ MaybeHandle = ok(Handle) },
dl__close(Handle, Result),
display_close_result(Result)
).
:- pred display_close_result(dl__result, io__state, io__state).
:- mode display_close_result(in, di, uo) is det.
display_close_result(ok) --> [].
display_close_result(error(String)) -->
print(String),
nl.