[m-rev.] ssdb goal's argument generation at call and exit point
Peter Wang
novalazy at gmail.com
Thu Oct 18 13:10:34 AEST 2007
On 2007-10-18, Peter Ross <pro at missioncriticalit.com> wrote:
> On Wed, Oct 17, 2007 at 02:16:12PM +1000, Olivier Annet wrote:
>
> > %
> > % :- type var_name == string.
> > %
> > @@ -135,31 +135,38 @@
> > +
> > :- implementation.
> >
> > :- import_module check_hlds.mode_util.
> > +:- import_module check_hlds.polymorphism.
> > :- import_module hlds.goal_util.
> > :- import_module hlds.hlds_goal.
> > +:- import_module hlds.instmap.
> > :- import_module hlds.pred_table.
> > :- import_module hlds.quantification.
> > :- import_module mdbcomp.prim_data.
> > :- import_module parse_tree.prog_data.
> > :- import_module parse_tree.prog_type.
> > +:- import_module varset.
Move this import with the rest of the standard library imports.
> > + %
> > + % Get the updated InstMap.
> > + %
> > + update_instmap(Goal0, InitInstMap, UpdatedInstMap),
> > +
> > + %
> > + % Make the list argument at exit point, it's a new list instead reuse
> > + % the call list.
Make the variable list at the exit port. It's currently a completely new list
instead of adding on to the list generated for the call port.
> > + % XXX Optimization : Only output variables should be generated
> > + %
> > + make_arg_list(0, UpdatedInstMap, HeadVars, FullListExitVar,
> > + FullListExitGoals, !ModuleInfo, !ProcInfo, !PredInfo, !Varset,
> > + !Vartypes),
> > +
> > + %
> > + % Build the following two goals
> > + % ExitVar = ssdb_exit,
> > + % handle_event(ProcId, ssdb_exit, VarList).
> > + %
> > make_ssdb_event_type_construction(ssdb_exit,
> > ExitConstructor, ExitVar, !Varset, !Vartypes),
> >
> > goal_util.generate_simple_call(SSDBModule, "handle_event",
> > pf_predicate, only_mode, detism_det, purity_impure,
> > - [ProcIdVar, ExitVar],
> > + [ProcIdVar, ExitVar, FullListExitVar],
> > Features, InstMapSrc, !.ModuleInfo, Context, HandleExitEventGoal),
> > - %
> > - % Place the call and exit events around the initial goal.
> > - % XXX we still need to extend this to handle the other event types
> > - %
> > - ConjGoals = ProcIdGoals ++ [CallConstructor, HandleCallEventGoal,
> > - Goal0, ExitConstructor, HandleExitEventGoal],
> > + %
> > + % Place the call and exit events around the initial goal.
> > + % XXX we still need to extend this to handle the other event types
> > + %
> > + ConjGoals = ProcIdGoals ++ FullListCallGoals ++ [CallConstructor,
> > + HandleCallEventGoal, Goal0] ++ FullListExitGoals ++
Extra space.
> > +:- pred make_arg_list(int::in, instmap::in, list(prog_var)::in,
> > + prog_var::out, list(hlds_goal)::out, module_info::in, module_info::out,
> > + proc_info::in, proc_info::out, pred_info::in, pred_info::out,
> > + prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
> > +
> > +make_arg_list(_, _, [], Var, [Goal], !ModuleInfo, !ProcInfo, !PredInfo,
> > + !Varset, !Vartypes) :-
> > +
> > + svvarset.new_named_var("EmptyVarList", Var, !Varset),
> > + svmap.det_insert(Var, list_var_value_type, !Vartypes),
> > + ConsId = cons(qualified(unqualified("list"), "[]" ), 0),
> > + construct_functor(Var, ConsId, [], Goal).
> > +
> > +make_arg_list(Pos0, InstMap, [VarToInspect | ListCallVar], Var, Goals,
> > + !ModuleInfo, !ProcInfo, !PredInfo, !Varset, !Vartypes) :-
> > +
> > + Pos = Pos0 + 1,
> > +
> > + make_arg_list(Pos, InstMap, ListCallVar, Var0, Goals0,
Might as well write Pos + 1.
> > + !ModuleInfo, !ProcInfo, !PredInfo, !Varset, !Vartypes),
> > + make_var_value(InstMap, VarToInspect, VarDesc, Pos0, ValueGoals,
> > + !ModuleInfo, !ProcInfo, !PredInfo, !Varset, !Vartypes),
> > +%-----------------------------------------------------------------------------%
> > +
> > + %
> > + % Create the goal's argument description :
> > + % -> unbound_head_var(Name, Pos) if it is an unbound argument
> > + % -> bound_head_var(type_of_T, Name, Position, T) if it is a bound argument
> > + %
> > +:- pred make_var_value(instmap::in, prog_var::in, prog_var::out,
> > + int::in, list(hlds_goal)::out, module_info::in, module_info::out,
> > + proc_info::in, proc_info::out, pred_info::in, pred_info::out,
> > + prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
> > +
> > +
> > +make_var_value(InstMap, VarToInspect, VarDesc, VarPos, Goals,
> > + !ModuleInfo, !ProcInfo, !PredInfo, !VarSet, !VarTypes) :-
> > +
> > +
> > + SSDBModule = mercury_ssdb_builtin_module,
> > + TypeCtor = type_ctor(qualified(SSDBModule, "var_value"), 0),
> > +
> > + % Find the name of the prog_var.
> > + varset.lookup_name(!.VarSet, VarToInspect, VarName),
> >
> > + make_string_const_construction_alloc(VarName, yes("VarName"),
> > + ConstructVarName, VarNameVar, !VarSet, !VarTypes),
> > +
> > + make_int_const_construction_alloc(VarPos, yes("VarPos"),
> > + ConstructVarPos, VarPosVar, !VarSet, !VarTypes),
> > +
> > + ( var_is_ground_in_instmap(!.ModuleInfo, InstMap, VarToInspect) ->
> > +
> > + % Create dynamic constructor for the value of the argument.
> > + %
> > + % Call polymorphism.m to create the type_infos, add an hidden field
> > + % which is the polymorphic type of the value.
> > + %
> > + % some[T] bound_head_var(string, int, T) ---->
> > + % some[T] bound_head_var(type_of_T, string, int, T)
> > + %
> > + (
> > + %
> > + % Update proc_varset and proc_vartypes, without this, the
> > + % polymorphism_make_type_info_var use a prog_var already bound.
> > + %
>
> s/use a prog_var/uses a prog_var which is/
>
> > + proc_info_set_varset(!.VarSet, !ProcInfo),
> > + proc_info_set_vartypes(!.VarTypes, !ProcInfo),
> > +
> > + create_poly_info(!.ModuleInfo, !.PredInfo, !.ProcInfo,
> > + PolyInfo0),
> > + term.context_init(Context),
> > + map.lookup(!.VarTypes, VarToInspect, MerType),
> > + polymorphism_make_type_info_var(MerType, Context, TypeInfoVar,
> > + TypeInfoGoal, PolyInfo0, PolyInfo),
> > + poly_info_extract(PolyInfo, !PredInfo, !ProcInfo,
> > + !:ModuleInfo),
> > +
> > + %
> > + % Give a new prog_var to the polymorphic structure.
> > + %
> > + svvarset.new_named_var("VarType", VarTypo, !VarSet),
> > + svmap.det_insert(VarTypo, MerType, !VarTypes)
> > + ),
Extraneous brackets.
> >
> > Index: ssdb/ssdb.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/ssdb/ssdb.m,v
> > retrieving revision 1.5
> > diff -u -r1.5 ssdb.m
> > --- ssdb/ssdb.m 9 Oct 2007 01:22:13 -0000 1.5
> > +++ ssdb/ssdb.m 17 Oct 2007 03:38:52 -0000
> > @@ -20,7 +20,7 @@
> >
> > :- module ssdb.
> > :- interface.
> > -
> > +:- import_module list.
> >
> > :- type ssdb_proc_id
> > ---> ssdb_proc_id(
> > @@ -36,9 +36,33 @@
> > .
> >
> > %
> > + % Type use to contain all variable of a call
> > + %
> Reword this comment
>
> The list of all variables in use in a procedure.
>
> > +:- type list_var_value == list(var_value).
> > +
> > + %
> > + % Type use to represent variables of the debugged predicate/function
> > + %
>
> Reword this as:
>
> Record the instantiatedness and value of each variable used in a
> procedure.
>
> > +:- type var_value
> > + ---> unbound_head_var(var_name, pos)
> > + ; some [T] bound_head_var(var_name, pos, T)
> > + ; some [T] bound_other_var(var_name, T).
> > +
> > + %
> > + % Head variable name.
> > + %
>
> Delete the word Head, it's just a variable name.
>
> > +:- type var_name == string.
> > +
> > + %
> > + % This fields give the argument numbers of head variables.
> > + %
>
> Reword as
>
> The argument position of the head variable.
> Positions are numbered from 0.
Argument positions should be numbered from 1.
> > @@ -130,7 +156,9 @@
> > NextStop = ns_step,
> > Stack = stack.init,
> > Breakpoints = set.init,
> > - DbgState = state(EventNum, CSN, Depth, NextStop, Stack, Breakpoints).
> > + ListVarValue = [],
> > + DbgState = state(EventNum, CSN, Depth, NextStop, Stack, Breakpoints,
> > + ListVarValue).
> > :- mutable(debugger_state, debugger_state, init_debugger_state, ground,
> > [untrailed, attach_to_io_state]).
> > @@ -142,25 +170,31 @@
> > % Write the event out and call the prompt.
> > % XXX Not yet implemented : redo, fail.
> > %
> > -handle_event(ProcId, Event) :-
> > +handle_event(ProcId, Event, ListVarValue) :-
> > impure get_event_num_inc(EventNum),
> > impure update_depth(Event, PrintDepth),
> >
> > (
> > - Event = ssdb_call,
> > + Event = ssdb_call,
> > + % set the new CSN.
> > impure get_csn_inc(_),
> > + % set the list_var_value of the debugger state with the list received
> > + impure set_list_var_value(ListVarValue),
> >
> Again you indentation looks wrong. You are using tabs.
> Come and talk to me about how to fix this.
>
>
> > + % Push the actual state on the stack of the debugger state
Push the new stack frame on top of the shadow stack.
> > semipure get_debugger_state(InitialState),
> > StackFrame = elem(ProcId, InitialState),
> > stack.push(InitialState ^ ssdb_stack, StackFrame, FinalStack),
> > StateEv = InitialState ^ ssdb_stack := FinalStack,
> > impure set_debugger_state(StateEv)
> > ;
> > + % Just get the top frame, it will be pop at the end of the
> > + % handle_event because we need some information
> > + % Example : for printing variables at the exit point
Just get the top stack frame. It will be popped at the end of
handle_event. We need to leave the frame in place, e.g. for
printing variables.
[Eventually you should probably switch to having separate procedures for
each event type, as in the second proposed transformation.]
> > @@ -245,6 +279,25 @@
> > )
> > ;
> > Stop = no
> > + ),
> > +
> > + ( Event = ssdb_call
> > +
> > + ; Event = ssdb_exit,
> > + % Pop the frame
Sentences end with full stops. I don't think this comment adds much
anyway.
> > impure prompt(ShadowStack, Depth, WhatNext, !IO)
> > -
> > +
> > + ; Words = ["p"] ->
> > + CurrentFrame = stack.top_det(ShadowStack),
> > + ListVarValue = CurrentFrame ^ se_initial_state ^
> > + ssdb_list_var_value,
> > + print_vars(ListVarValue, !IO),
> > + impure prompt(ShadowStack, Depth, WhatNext, !IO)
> > +
> > + ; Words = ["pst"] ->
Rename this command to match mdb.
> > + print_frames_list(ShadowStack, Depth, !IO),
> > + impure prompt(ShadowStack, Depth, WhatNext, !IO)
> > +
> > ; Words = ["n"] ->
> > WhatNext = wn_next
> >
> > @@ -407,6 +506,28 @@
> > CSN = FrameStack ^ se_initial_state ^ ssdb_csn,
> > WhatNext = wn_finish(CSN)
> >
> > + ; Words = ["d"] ->
> > + (
> > + Depth0 = Depth - 1,
> > + Depth0 >= 0
Depth0 implies it is an old version of Depth. Maybe DownDepth.
> > + ->
> > + impure prompt(ShadowStack, Depth0, WhatNext, !IO)
> > + ;
> > + io.print("Impossible to go down\n", !IO),
> > + impure prompt(ShadowStack, Depth, WhatNext, !IO)
> > + )
> > +
> > + ; Words = ["u"] ->
> > + (
> > + Depth0 = Depth + 1,
> > + Depth0 < stack.depth(ShadowStack)
Ditto.
> > + ->
> > + impure prompt(ShadowStack, Depth0, WhatNext, !IO)
> > + ;
> > + io.print("Impossible to go up\n", !IO),
> > + impure prompt(ShadowStack, Depth, WhatNext, !IO)
> > + )
> > +
> > ;
> > io.write_string("huh?\n", !IO),
> > impure prompt(ShadowStack, Depth, WhatNext, !IO)
> > @@ -422,6 +543,93 @@
> >
> > %----------------------------------------------------------------------------%
> >
> > + %
> > + % Print the Stack Trace (command 'pst')
> > + %
> > +:- pred print_frames_list(stack(stack_elem)::in, int::in,
> > + io::di, io::uo) is det.
> > +
> > +print_frames_list(ShadowStack0, Depth, !IO) :-
> > + ( if not stack.is_empty(ShadowStack0) then
> > + stack.pop_det(ShadowStack0, PopFrame, ShadowStack),
> > + (if Depth = 0 then
> > + print_stack_frame(yes, PopFrame, !IO)
> > + else
> > + print_stack_frame(no, PopFrame, !IO)
> > + ),
> > + print_frames_list(ShadowStack, Depth - 1, !IO)
> > + else
> > + _N = 1
Replace "_N = 1" by "true".
> > + ).
> > +
> > +
> > +:- pred print_stack_frame(bool::in, stack_elem::in, io::di, io::uo) is det.
> > +
> > +print_stack_frame(Starred, Frame, !IO) :-
> > + Module = Frame ^ se_proc_id ^ module_name ,
> > + Procedure = Frame ^ se_proc_id ^ proc_name ,
> > +
> > + (
> > + Starred = yes,
> > + io.write_char('*', !IO)
> > + ;
> > + Starred = no,
> > + io.write_char(' ', !IO)
> > + ),
> > + io.format(" %s.%s(\n", [s(Module), s(Procedure)], !IO),
> > + ListVarValue = Frame ^ se_initial_state ^ ssdb_list_var_value,
> > + print_vars(ListVarValue, !IO),
> > + io.write_string(")\n", !IO).
> > +
> > + %
> > + % Print the Variables (command 'p').
Print the given list of variables and their values, if bound.
>
> > + io.write_char('\t', !IO),
> > + io.write_string("bound_head\t", !IO),
> > + io.write_string(Name, !IO),
> > + io.write_string(":\t", !IO),
> > + io.write_int(Pos, !IO),
> > + io.write_string("\t=\t", !IO),
> > + io.print(T, !IO),
> > + io.nl(!IO)
> > + else
> > + io.write_char('\t', !IO),
> > + io.write_string("bound_head\t", !IO),
> > + io.write_string(Name, !IO),
> > + io.nl(!IO).
Add brackets around the if-then-else.
> > +
> > +
> > :- impure pred invent_io(io::uo) is det.
> >
> > :- pragma foreign_proc("C",
> > @@ -440,6 +648,7 @@
> > invent_io(_IO::uo),
> > [will_not_call_mercury, thread_safe], "").
> >
> > +
> > :- impure pred consume_io(io::di) is det.
There are extraneous blank lines added in a few places.
Peter
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list