[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