diff: changes to copy/2
Fergus Henderson
fjh at hydra.cs.mu.oz.au
Mon Oct 13 00:02:41 AEST 1997
Fix the handling of copy/2.
library/mercury_builtin.m:
Implement copy/2 properly, using deep_copy().
Add unsafe_promise_unique/2 with the same semantics
as the old copy/2.
library/io.m:
library/set_bbbtree.m:
compiler/handle_options.m:
compiler/typecheck.m:
compiler/mode_info.m:
Change some occurrences of copy/2 to call unsafe_promise_unique/2.
library/io.m:
Change io__get_stream_names and io__set_stream_names to not
use unique modes (this seems the simplest way for the moment
of avoiding some ugly calls to unsafe_promise_unique).
cvs diff compiler/handle_options.m compiler/mode_info.m compiler/typecheck.m library/io.m library/mercury_builtin.m library/set_bbbtree.m
Index: compiler/handle_options.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/handle_options.m,v
retrieving revision 1.29
diff -u -r1.29 handle_options.m
--- handle_options.m 1997/09/02 07:03:39 1.29
+++ handle_options.m 1997/10/12 07:22:06
@@ -177,7 +177,7 @@
[]
),
- { copy(OptionTable, OptionTable1) }, % XXX
+ { unsafe_promise_unique(OptionTable, OptionTable1) }, % XXX
globals__io_init(OptionTable1, GC_Method, TagsMethod, ArgsMethod,
TypeInfoMethod, PrologDialect),
Index: compiler/mode_info.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mode_info.m,v
retrieving revision 1.39
diff -u -r1.39 mode_info.m
--- mode_info.m 1997/07/27 15:01:05 1.39
+++ mode_info.m 1997/10/12 07:22:21
@@ -358,14 +358,14 @@
mode_info_get_io_state(mode_info(IOState0,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_),
IOState) :-
% XXX
- copy(IOState0, IOState).
+ unsafe_promise_unique(IOState0, IOState).
%-----------------------------------------------------------------------------%
mode_info_set_io_state( mode_info(_,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P), IOState0,
mode_info(IOState,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P)) :-
% XXX
- copy(IOState0, IOState).
+ unsafe_promise_unique(IOState0, IOState).
%-----------------------------------------------------------------------------%
Index: compiler/typecheck.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/typecheck.m,v
retrieving revision 1.214
diff -u -r1.214 typecheck.m
--- typecheck.m 1997/09/02 07:13:18 1.214
+++ typecheck.m 1997/10/12 12:12:56
@@ -2299,7 +2299,7 @@
map__init(TypeBindings),
FoundTypeError = no,
WarnedAboutOverloading = no,
- copy(IOState0, IOState), % XXX
+ unsafe_promise_unique(IOState0, IOState), % XXX
TypeCheckInfo = typecheck_info(
IOState, ModuleInfo, CallPredId, 0, PredId, Context,
unify_context(explicit, []),
@@ -2315,7 +2315,7 @@
typecheck_info_get_io_state(typecheck_info(IOState0,_,_,_,_,_,_,_,_,_,_,_,_),
IOState) :-
- copy(IOState0, IOState). % XXX
+ unsafe_promise_unique(IOState0, IOState). % XXX
%-----------------------------------------------------------------------------%
@@ -2325,7 +2325,7 @@
typecheck_info_set_io_state(typecheck_info(_,B,C,D,E,F,G,H,I,J,K,L,M), IOState0,
typecheck_info(IOState,B,C,D,E,F,G,H,I,J,K,L,M)) :-
- copy(IOState0, IOState). % XXX
+ unsafe_promise_unique(IOState0, IOState). % XXX
%-----------------------------------------------------------------------------%
Index: library/io.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/io.m,v
retrieving revision 1.140
diff -u -r1.140 io.m
--- io.m 1997/09/09 18:56:14 1.140
+++ io.m 1997/10/12 07:24:58
@@ -1794,31 +1794,27 @@
:- pred io__stream_name(io__stream, string, io__state, io__state).
:- mode io__stream_name(in, out, di, uo) is det.
- % XXX major design flaw with regard to unique modes
- % means that this is very inefficient.
io__stream_name(Stream, Name) -->
- io__get_stream_names(StreamNames0),
- { map__search(StreamNames0, Stream, Name1) ->
+ io__get_stream_names(StreamNames),
+ { map__search(StreamNames, Stream, Name1) ->
Name = Name1
;
Name = "<stream name unavailable>"
},
- { copy(StreamNames0, StreamNames) }, % is this necessary?
io__set_stream_names(StreamNames).
:- pred io__get_stream_names(io__stream_names, io__state, io__state).
-:- mode io__get_stream_names(uo, di, uo) is det.
+:- mode io__get_stream_names(out, di, uo) is det.
-:- pragma c_code(io__get_stream_names(StreamNames::uo, IO0::di, IO::uo), "
+:- pragma c_code(io__get_stream_names(StreamNames::out, IO0::di, IO::uo), "
StreamNames = ML_io_stream_names;
- ML_io_stream_names = 0; /* ensure uniqueness */
update_io(IO0, IO);
").
:- pred io__set_stream_names(io__stream_names, io__state, io__state).
-:- mode io__set_stream_names(di, di, uo) is det.
+:- mode io__set_stream_names(in, di, uo) is det.
-:- pragma c_code(io__set_stream_names(StreamNames::di, IO0::di, IO::uo), "
+:- pragma c_code(io__set_stream_names(StreamNames::in, IO0::di, IO::uo), "
ML_io_stream_names = StreamNames;
update_io(IO0, IO);
").
@@ -1836,9 +1832,7 @@
io__insert_stream_name(Stream, Name) -->
io__get_stream_names(StreamNames0),
- { copy(Stream, Stream1) },
- { copy(Name, Name1) },
- { map__set(StreamNames0, Stream1, Name1, StreamNames) },
+ { map__set(StreamNames0, Stream, Name, StreamNames) },
io__set_stream_names(StreamNames).
%-----------------------------------------------------------------------------%
Index: library/mercury_builtin.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/mercury_builtin.m,v
retrieving revision 1.83
diff -u -r1.83 mercury_builtin.m
--- mercury_builtin.m 1997/09/06 18:23:33 1.83
+++ mercury_builtin.m 1997/10/12 07:13:48
@@ -102,15 +102,22 @@
% PREDICATES.
-% copy/2 is used to make a `unique' copy of a data structure,
-% so that you can use destructive update.
-% At the moment it doesn't actually do any copying, since we
-% haven't implemented destructive update yet and so there is no need.
+% copy/2 makes a deep copy of a data structure. The resulting copy is a
+% `unique' value, so you can use destructive update on it.
:- pred copy(T, T).
:- mode copy(ui, uo) is det.
:- mode copy(in, uo) is det.
+% unsafe_promise_unique/2 is used to promise the compiler that you have a
+% `unique' copy of a data structure, so that you can use destructive update.
+% It is used to work around limitations in the current support for unique
+% modes. `unsafe_promise_unique(X, Y)' is the same as `Y = X' except that
+% the compiler will assume that `Y' is unique.
+
+:- pred unsafe_promise_unique(T, T).
+:- mode unsafe_promise_unique(in, uo) is det.
+
% We define !/0 (and !/2 for dcgs) to be equivalent to `true'. This is for
% backwards compatibility with Prolog systems. But of course it only works
% if all your cuts are green cuts.
@@ -640,20 +647,73 @@
%-----------------------------------------------------------------------------%
+/* unsafe_promise_unique/2
+ :- pred unsafe_promise_unique(T, T).
+ :- mode unsafe_promise_unique(in, uo) is det.
+*/
+
+/* This doesn't work, due to the lack of support for aliasing.
+:- pragma(c_code, unsafe_promise_unique(X::in, Y::uo), "Y = X;").
+*/
+
+:- external(unsafe_promise_unique/2).
+:- pragma(c_code, "
+Define_extern_entry(mercury__unsafe_promise_unique_2_0);
+
+BEGIN_MODULE(unsafe_promise_unique_module)
+ init_entry(mercury__unsafe_promise_unique_2_0);
+BEGIN_CODE
+
+Define_entry(mercury__unsafe_promise_unique_2_0);
+#ifdef COMPACT_ARGS
+ r1 = r2;
+#else
+ r3 = r2;
+#endif
+ proceed();
+
+END_MODULE
+
+/* Ensure that the initialization code for the above module gets run. */
+/*
+INIT sys_init_unsafe_promise_unique_module
+*/
+void sys_init_unsafe_promise_unique_module(void);
+ /* extra declaration to suppress gcc -Wmissing-decl warning */
+void sys_init_unsafe_promise_unique_module(void) {
+ extern ModuleFunc unsafe_promise_unique_module;
+ unsafe_promise_unique_module();
+}
+
+").
+
+%-----------------------------------------------------------------------------%
+
/* copy/2
:- pred copy(T, T).
:- mode copy(ui, uo) is det.
:- mode copy(in, uo) is det.
*/
- % XXX note that this is *not* deep copy, and so it is unsafe!
-
-/* This doesn't work, due to the lack of support for aliasing.
-:- pragma(c_code, copy(X::ui, Y::uo), "Y = X;").
-:- pragma(c_code, copy(X::in, Y::uo), "Y = X;").
-*/
+/*************
+Using `pragma c_code' doesn't work, due to the lack of support for
+aliasing, and in particular the lack of support for `ui' modes.
+:- pragma c_code(copy(Value::ui, Copy::uo), "
+ save_transient_registers();
+ Copy = deep_copy(Value, TypeInfo_for_T, NULL, NULL);
+ restore_transient_registers();
+").
+:- pragma c_code(copy(Value::in, Copy::uo), "
+ save_transient_registers();
+ Copy = deep_copy(Value, TypeInfo_for_T, NULL, NULL);
+ restore_transient_registers();
+").
+*************/
:- external(copy/2).
+
+:- pragma(c_header_code, "#include ""deep_copy.h""").
+
:- pragma(c_code, "
Define_extern_entry(mercury__copy_2_0);
Define_extern_entry(mercury__copy_2_1);
@@ -663,22 +723,41 @@
init_entry(mercury__copy_2_1);
BEGIN_CODE
+#ifdef PROFILE_CALLS
+ #define fallthru(target, caller) { tailcall((target), (caller)); }
+#else
+ #define fallthru(target, caller)
+#endif
+
Define_entry(mercury__copy_2_0);
+fallthru(ENTRY(mercury__copy_2_1), ENTRY(mercury__copy_2_0))
Define_entry(mercury__copy_2_1);
+{
+ Word value, copy, type_info;
+
+ type_info = r1;
+ value = r2;
+
+ save_transient_registers();
+ copy = deep_copy(value, type_info, NULL, NULL);
+ restore_transient_registers();
+
#ifdef COMPACT_ARGS
- r1 = r2;
+ r1 = copy;
#else
- r3 = r2;
+ r3 = copy;
#endif
- proceed();
+ proceed();
+}
END_MODULE
/* Ensure that the initialization code for the above module gets run. */
/*
INIT sys_init_copy_module
*/
-void sys_init_copy_module(void); /* suppress gcc -Wmissing-decl warning */
+void sys_init_copy_module(void);
+ /* extra declaration to suppress gcc -Wmissing-decl warning */
void sys_init_copy_module(void) {
extern ModuleFunc copy_module;
copy_module();
Index: library/set_bbbtree.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/set_bbbtree.m,v
retrieving revision 1.10
diff -u -r1.10 set_bbbtree.m
--- set_bbbtree.m 1997/07/27 15:07:11 1.10
+++ set_bbbtree.m 1997/10/12 07:14:32
@@ -394,7 +394,7 @@
set_bbbtree__insert(Set0, X, Set) :-
set_bbbtree__def_ratio(Ratio),
set_bbbtree__insert_r(Set0, X, Set1, Ratio),
- copy(Set1, Set).
+ unsafe_promise_unique(Set1, Set).
/* Uncomment this once destructive input and unique modes are fixed and detele
the one above.
@@ -488,7 +488,7 @@
;
Set2 = Set0
),
- copy(Set2, Set).
+ unsafe_promise_unique(Set2, Set).
%------------------------------------------------------------------------------%
@@ -890,7 +890,7 @@
set_bbbtree__size(R, RSize),
N is 1 + LSize + RSize,
Tree0 = tree(X, N, L, R),
- copy(Tree0, Tree).
+ unsafe_promise_unique(Tree0, Tree).
%------------------------------------------------------------------------------%
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list