[m-rev.] for review: do not generate trace events in private_builtin
Julien Fischer
juliensf at cs.mu.OZ.AU
Mon Nov 21 16:42:23 AEDT 2005
On Fri, 18 Nov 2005, Ian MacLarty wrote:
> Index: library/builtin.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/builtin.m,v
> retrieving revision 1.112
> diff -u -r1.112 builtin.m
> --- library/builtin.m 17 Oct 2005 11:35:16 -0000 1.112
> +++ library/builtin.m 17 Nov 2005 08:43:23 -0000
> @@ -368,15 +368,6 @@
>
> :- implementation.
>
> -:- import_module char.
> -:- import_module float.
> -:- import_module int.
> -:- import_module list.
> -:- import_module require.
> -:- import_module std_util.
> -:- import_module string.
> -:- import_module string.
> -
> %-----------------------------------------------------------------------------%
>
> false :-
> Index: library/exception.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/exception.m,v
> retrieving revision 1.100
> diff -u -r1.100 exception.m
> --- library/exception.m 20 Sep 2005 03:47:30 -0000 1.100
> +++ library/exception.m 16 Nov 2005 12:50:21 -0000
> @@ -720,10 +720,18 @@
>
> % builtin_throw and builtin_catch are implemented below using
> % hand-coded low-level C code.
> +% builtin_throw is exported, so that it can be called from private_builtin.
> +% private_builtin needs to call builtin_throw directly to avoid generating
> +% trace events.
> %
That should be marked with an XXX.
> :- pragma terminates(builtin_throw/1).
> +
> +:- interface.
> +
> :- pred builtin_throw(univ::in) is erroneous.
>
> +:- implementation.
> +
> :- /* impure */
> pred builtin_catch(pred(T), handler(T), T).
> :- mode builtin_catch(pred(out) is det, in(handler), out) is det.
> Index: library/private_builtin.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/private_builtin.m,v
> retrieving revision 1.148
> diff -u -r1.148 private_builtin.m
> --- library/private_builtin.m 17 Oct 2005 07:43:28 -0000 1.148
> +++ library/private_builtin.m 16 Nov 2005 12:57:58 -0000
> @@ -25,6 +25,11 @@
> % definitions because the compiler generates code for them inline. Some others
> % are implemented in the runtime.
>
> +% NOTE: This module is never traced, even in debugging grades. To avoid
> +% confusing the declarative debugger, all predicates and functions defined in
> +% this module should avoid calling predicates or functions in other modules
> +% which could be traced.
> +
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
>
> @@ -34,6 +39,8 @@
>
> :- interface.
>
> +:- import_module type_desc.
> +
> % This section of the module contains predicates that are used
> % by the compiler, to implement polymorphism. These predicates
> % should not be used by user programs directly.
> @@ -102,20 +109,31 @@
> %
> :- pred typed_compare(comparison_result::uo, T1::in, T2::in) is det.
>
> + % The function type_of/1 returns a representation of the type
> + % of its argument.
> + %
> + % (Note: it is not possible for the type of a variable to be an unbound
> + % type variable; if there are no constraints on a type variable, then the
> + % typechecker will use the type `void'. `void' is a special (builtin) type
> + % that has no constructors. There is no way of creating an object of
> + % type `void'. `void' is not considered to be a discriminated union, so
> + % get_functor/5 and construct/3 will fail if used upon a value of
> + % this type.)
> + %
> +:- func type_of(T::unused) = (type_desc__type_desc::out) is det.
> +
> % N.B. interface continued below.
>
> %-----------------------------------------------------------------------------%
>
> :- implementation.
>
> -:- import_module char.
> +:- import_module exception.
> :- import_module float.
> :- import_module int.
> :- import_module list.
> :- import_module require.
> :- import_module std_util.
> -:- import_module string.
> -:- import_module string.
>
> :- pragma foreign_code("C#", "
>
> @@ -147,8 +165,8 @@
> builtin_unify_character(C, C).
>
> builtin_compare_character(R, X, Y) :-
> - char__to_int(X, XI),
> - char__to_int(Y, YI),
> + private_builtin.to_int(X, XI),
> + private_builtin.to_int(Y, YI),
> ( XI < YI ->
> R = (<)
> ; XI = YI ->
> @@ -200,20 +218,20 @@
> ).
>
> builtin_unify_tuple(_, _) :-
> - ( semidet_succeed ->
> + ( private_builtin.semidet_succeed ->
> % The generic unification function in the runtime
> % should handle this itself.
> - error("builtin_unify_tuple called")
> + private_builtin.error("builtin_unify_tuple called")
> ;
> % The following is never executed.
> - semidet_succeed
> + private_builtin.semidet_succeed
> ).
>
> builtin_compare_tuple(Res, _, _) :-
> - ( semidet_succeed ->
> + ( private_builtin.semidet_succeed ->
> % The generic comparison function in the runtime
> % should handle this itself.
> - error("builtin_compare_tuple called")
> + private_builtin.error("builtin_compare_tuple called")
> ;
> % The following is never executed.
> Res = (<)
> @@ -221,17 +239,17 @@
>
> :- pragma no_inline(builtin_unify_pred/2).
> builtin_unify_pred(_X, _Y) :-
> - ( semidet_succeed ->
> - error("attempted higher-order unification")
> + ( private_builtin.semidet_succeed ->
> + private_builtin.error("attempted higher-order unification")
> ;
> % The following is never executed.
> - semidet_succeed
> + private_builtin.semidet_succeed
> ).
>
> :- pragma no_inline(builtin_compare_pred/3).
> builtin_compare_pred(Result, _X, _Y) :-
> - ( semidet_succeed ->
> - error("attempted higher-order comparison")
> + ( private_builtin.semidet_succeed ->
> + private_builtin.error("attempted higher-order comparison")
> ;
> % The following is never executed.
> Result = (<)
> @@ -240,10 +258,11 @@
> :- pragma no_inline(builtin_compare_non_canonical_type/3).
> builtin_compare_non_canonical_type(Res, X, _Y) :-
> % suppress determinism warning
> - ( semidet_succeed ->
> + ( private_builtin.semidet_succeed ->
> + % XXX The call to type_name below may generate trace events.
Wasn't the point of this diff to avoid this?
> Message = "call to compare/3 for non-canonical type `"
> - ++ type_name(type_of(X)) ++ "'",
> - error(Message)
> + ++ type_desc.type_name(private_builtin.type_of(X)) ++ "'",
> + private_builtin.error(Message)
> ;
> % The following is never executed.
> Res = (<)
> @@ -251,19 +270,19 @@
>
> :- pragma no_inline(compare_error/0).
> compare_error :-
> - error("internal error in compare/3").
> + private_builtin.error("internal error in compare/3").
>
> %-----------------------------------------------------------------------------%
>
> typed_unify(X, Y) :-
> - ( type_of(X) = type_of(Y) ->
> + ( private_builtin.type_of(X) = private_builtin.type_of(Y) ->
> unsafe_type_cast(X, Y)
> ;
> fail
> ).
>
> typed_compare(R, X, Y) :-
> - compare(R0, type_of(X), type_of(Y)),
> + compare(R0, private_builtin.type_of(X), private_builtin.type_of(Y)),
> ( R0 = (=) ->
> unsafe_type_cast(X, Z),
> compare(R, Z, Y)
> @@ -271,6 +290,26 @@
> R = R0
> ).
>
> +:- pragma foreign_proc("C",
> + type_of(_Value::unused) = (TypeInfo::out),
> + [will_not_call_mercury, thread_safe, promise_pure],
> +"{
> + TypeInfo = TypeInfo_for_T;
> +
> + /*
> + ** We used to collapse equivalences for efficiency here, but that's not
> + ** always desirable, due to the reverse mode of make_type/2, and efficiency
> + ** of type_infos probably isn't very important anyway.
> + */
> +#if 0
> + MR_save_transient_registers();
> + TypeInfo = (MR_Word) MR_collapse_equivalences(
> + (MR_TypeInfo) TypeInfo_for_T);
> + MR_restore_transient_registers();
> +#endif
> +
> +}").
> +
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
>
> @@ -901,13 +940,11 @@
> ").
>
> trailed_nondet_pragma_foreign_code :-
> - Msg = string__append_list([
> - "Sorry, not implemented:\n",
> - "for the MLDS back-end (`--high-level-code')\n",
> - "nondet `pragma c_code' or `pragma foreign_code'\n",
> - "is not supported when trailing (`--use-trail') is enabled."
> - ]),
> - error(Msg).
> + Msg = "Sorry, not implemented:\n\
> +for the MLDS back-end (`--high-level-code')\n\
> +nondet `pragma c_code' or `pragma foreign_code'\n\
> +is not supported when trailing (`--use-trail') is enabled.",
> + private_builtin.error(Msg).
>
> %-----------------------------------------------------------------------------%
>
> @@ -1076,13 +1113,11 @@
> ").
>
> reclaim_heap_nondet_pragma_foreign_code :-
> - Msg = string__append_list([
> - "Sorry, not implemented:\n",
> - "for the MLDS back-end (`--high-level-code')\n",
> - "nondet `pragma c_code' or `pragma foreign_code'\n",
> - "is not supported when `--reclaim-heap-on-failure' is enabled."
> - ]),
> - error(Msg).
> + Msg = "Sorry, not implemented:\n\
> +for the MLDS back-end (`--high-level-code')\n\
> +nondet `pragma c_code' or `pragma foreign_code'\n\
> +is not supported when `--reclaim-heap-on-failure' is enabled.",
> + private_builtin.error(Msg).
>
> %-----------------------------------------------------------------------------%
>
> @@ -1226,22 +1261,22 @@
> :- implementation.
>
> unused :-
> - ( semidet_succeed ->
> - error("attempted use of dead predicate")
> + ( private_builtin.semidet_succeed ->
> + private_builtin.error("attempted use of dead predicate")
> ;
> % the following is never executed
> true
> ).
>
> nyi_foreign_type_unify(_, _) :-
> - ( semidet_succeed ->
> + ( private_builtin.semidet_succeed ->
> sorry("unify for foreign types")
> ;
> - semidet_succeed
> + private_builtin.semidet_succeed
> ).
>
> nyi_foreign_type_compare(Result, _, _) :-
> - ( semidet_succeed ->
> + ( private_builtin.semidet_succeed ->
> sorry("compare for foreign types")
> ;
> Result = (=)
> @@ -1301,11 +1336,11 @@
> nonvar(_::unused) :- fail.
>
> sorry(PredName) :-
> - error("sorry, " ++ PredName ++ " not implemented\n" ++
> + private_builtin.error("sorry, " ++ PredName ++ " not implemented\n" ++
> "for this target language (or compiler back-end).").
>
> no_clauses(PredName) :-
> - error("no clauses for " ++ PredName).
> + private_builtin.error("no clauses for " ++ PredName).
>
> :- pragma foreign_proc(c,
> imp,
> @@ -1528,4 +1563,73 @@
> ").
>
> %-----------------------------------------------------------------------------%
> +%
> +% The following predicates are duplicates of their versions in the
> +% publically visible part of the standard library. They are duplicated here
s/publically/publicly/
> +% to guarantee that calls to procedures in private_builtin do not generate
> +% any trace events.
> +%
> +
> +:- pred semidet_succeed is semidet.
> +
> +:- pragma foreign_proc("C",
> + semidet_succeed,
> + [will_not_call_mercury, thread_safe, promise_pure],
> +"
> + SUCCESS_INDICATOR = MR_TRUE;
> +").
> +
> +:- pragma foreign_proc("C#",
> + semidet_succeed,
> + [will_not_call_mercury, thread_safe, promise_pure],
> +"
> + SUCCESS_INDICATOR = true;
> +").
> +
> +semidet_succeed :-
> + 0 + 0 = 0.
> +
> +:- pred to_int(character::in, int::out) is det.
> +
> +:- pragma foreign_proc("C",
> + to_int(Character::in, Int::out),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"
> + Int = (MR_UnsignedChar) Character;
> +").
> +
> +:- pragma foreign_proc("C#",
> + to_int(Character::in, Int::out),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"
> + Int = Character;
> +").
> +
> +:- pragma foreign_proc("Java",
> + to_int(Character::in, Int::out),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"
> + Int = (int) Character;
> +").
> +
> +:- func string ++ string = string.
> +:- mode in ++ in = uo is det.
> +
> +:- pragma foreign_proc("C",
> + (S1::in) ++ (S2::in) = (S3::uo),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"{
> + size_t len_1, len_2;
> + len_1 = strlen(S1);
> + len_2 = strlen(S2);
> + MR_allocate_aligned_string_msg(S3, len_1 + len_2, MR_PROC_LABEL);
> + strcpy(S3, S1);
> + strcpy(S3 + len_1, S2);
> +}").
> +
> +:- pred private_builtin.error(string::in) is erroneous.
> +
> +error(Message) :-
> + exception.builtin_throw('new univ_cons'(software_error(Message))).
> +
> %-----------------------------------------------------------------------------%
> Index: library/std_util.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
> retrieving revision 1.303
> diff -u -r1.303 std_util.m
> --- library/std_util.m 17 Oct 2005 11:35:20 -0000 1.303
> +++ library/std_util.m 16 Nov 2005 12:50:40 -0000
> @@ -1642,11 +1642,18 @@
>
> %-----------------------------------------------------------------------------%
>
> +:- interface.
> +
> % We call the constructor for univs `univ_cons' to avoid ambiguity
> % with the univ/1 function which returns a univ.
> + % The univ type is exported so that private_builtin can create
> + % univs without generating trace events.
> + %
> :- type univ
> ---> some [T] univ_cons(T).
>
> +:- implementation.
> +
> univ_to_type(Univ, X) :- type_to_univ(X, Univ).
>
See my comments in the log message.
> univ(X) = Univ :- type_to_univ(X, Univ).
> Index: library/type_desc.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/type_desc.m,v
> retrieving revision 1.33
> diff -u -r1.33 type_desc.m
> --- library/type_desc.m 19 Sep 2005 04:29:01 -0000 1.33
> +++ library/type_desc.m 16 Nov 2005 12:03:43 -0000
> @@ -391,25 +391,7 @@
> error("ground_pseudo_type_desc_to_type_desc_det: not ground")
> ).
>
> -:- pragma foreign_proc("C",
> - type_of(_Value::unused) = (TypeInfo::out),
> - [will_not_call_mercury, thread_safe, promise_pure],
> -"{
> - TypeInfo = TypeInfo_for_T;
> -
> - /*
> - ** We used to collapse equivalences for efficiency here, but that's not
> - ** always desirable, due to the reverse mode of make_type/2, and efficiency
> - ** of type_infos probably isn't very important anyway.
> - */
> -#if 0
> - MR_save_transient_registers();
> - TypeInfo = (MR_Word) MR_collapse_equivalences(
> - (MR_TypeInfo) TypeInfo_for_T);
> - MR_restore_transient_registers();
> -#endif
> -
> -}").
> +type_of(Value) = private_builtin.type_of(Value).
>
> :- pragma foreign_proc("C#",
> type_of(_Value::unused) = (TypeInfo::out),
The rest of that looks ok.
Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list