diff: bug fix for nondet pragma C code
Zoltan Somogyi
zs at cs.mu.OZ.AU
Thu Mar 25 16:12:46 AEDT 1999
Fix a bug in nondet pragma C codes.
compiler/pragma_c_gen.m:
Fix an off-by-one error that caused the C struct we define
(to hold the items that must be saved from one success of a
nondet pragma C code to the next) to start with the top word
in the next lower nondet stack frame, instead of the word
immediately after that. Therefore an assignment to the first
field of the struct was clobbering the previous stack frame.
tests/hard_coded/nondet_c.{m,exp}:
A new test case to check for this bug.
tests/hard_coded/Mmakefile:
Enable the new test case.
Zoltan.
cvs diff: Diffing compiler
Index: compiler/pragma_c_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/pragma_c_gen.m,v
retrieving revision 1.26
diff -u -b -u -r1.26 pragma_c_gen.m
--- pragma_c_gen.m 1999/01/27 08:34:30 1.26
+++ pragma_c_gen.m 1999/03/25 04:51:12
@@ -537,8 +537,8 @@
{ pragma_c_gen__struct_name(ModuleName, PredName, Arity, ProcId,
StructName) },
{ SaveStructDecl = pragma_c_struct_ptr_decl(StructName, "LOCALS") },
- { string__format("\tLOCALS = (struct %s *) (
- (char *) (curfr - MR_ORDINARY_SLOTS - MR_NONDET_FIXED_SIZE)
+ { string__format("\tLOCALS = (struct %s *) ((char *)
+ (MR_curfr + 1 - MR_ORDINARY_SLOTS - MR_NONDET_FIXED_SIZE)
- sizeof(struct %s));\n",
[s(StructName), s(StructName)],
InitSaveStruct) },
cvs diff: Diffing compiler/notes
cvs diff: Diffing tests/hard_coded/
Index: tests/hard_coded//Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.53
diff -u -b -u -r1.53 Mmakefile
--- Mmakefile 1999/03/24 04:22:17 1.53
+++ Mmakefile 1999/03/24 06:07:23
@@ -61,6 +61,7 @@
name_mangling \
no_fully_strict \
no_inline \
+ nondet_c \
nondet_ctrl_vn \
nullary_ho_func \
pragma_c_code \
Index: tests/hard_coded//nondet_c.exp
===================================================================
RCS file: nondet_c.exp
diff -N nondet_c.exp
--- /dev/null Thu Mar 25 16:05:00 1999
+++ nondet_c.exp Thu Mar 25 15:46:07 1999
@@ -0,0 +1,21 @@
+/abcdef
+a/bcdef
+ab/cdef
+abc/def
+abcd/ef
+abcde/f
+abcdef/
+/abcdef
+a/bcdef
+ab/cdef
+abc/def
+abcd/ef
+abcde/f
+abcdef/
+/abcdef
+a/bcdef
+ab/cdef
+abc/def
+abcd/ef
+abcde/f
+abcdef/
Index: tests/hard_coded//nondet_c.m
===================================================================
RCS file: nondet_c.m
diff -N nondet_c.m
--- /dev/null Thu Mar 25 16:05:00 1999
+++ nondet_c.m Thu Mar 25 16:03:51 1999
@@ -0,0 +1,179 @@
+% This test checks to see whether the compiler handles all three forms of
+% nondet C code OK.
+
+:- module nondet_c.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module std_util, list.
+
+main -->
+ { solutions(split_pairs1("abcdef"), Pairs1) },
+ print_pairs(Pairs1),
+ { solutions(split_pairs2("abcdef"), Pairs2) },
+ print_pairs(Pairs2),
+ { solutions(split_pairs3("abcdef"), Pairs3) },
+ print_pairs(Pairs3).
+
+:- pred print_pairs(list(pair(string))::in, io__state::di, io__state::uo)
+ is det.
+
+print_pairs([]) --> [].
+print_pairs([Left - Right | Pairs]) -->
+ io__write_string(Left),
+ io__write_string("/"),
+ io__write_string(Right),
+ io__write_string("\n"),
+ print_pairs(Pairs).
+
+:- pred split_pairs1(string::in, pair(string)::out) is multi.
+
+split_pairs1(Whole, Left - Right) :-
+ break_string1(Left, Right, Whole).
+
+:- pred split_pairs2(string::in, pair(string)::out) is multi.
+
+split_pairs2(Whole, Left - Right) :-
+ break_string2(Left, Right, Whole).
+
+:- pred split_pairs3(string::in, pair(string)::out) is multi.
+
+split_pairs3(Whole, Left - Right) :-
+ break_string3(Left, Right, Whole).
+
+:- pred break_string1(string, string, string).
+:- mode break_string1(out, out, in) is multi.
+
+:- pragma c_code(break_string1(LeftHalf::out, RightHalf::out, WholeString::in),
+will_not_call_mercury,
+local_vars("
+ /* here we declare any local variables that we need to save */
+ String s;
+ size_t len;
+ size_t count;
+"),
+first_code(/* This comment tests whether
+the context of the following code is computed correctly
+*/ "
+ /* this code gets executed on a call, but not on a retry */
+ LOCALS->s = WholeString;
+ LOCALS->len = strlen(WholeString);
+ LOCALS->count = 0;
+"),
+retry_code("
+ /* this code gets executed on a retry */
+ LOCALS->count++;
+"),
+shared_code("
+ Word temp;
+
+ /* this code gets executed for both calls and retries */
+ incr_hp_atomic(temp,
+ (LOCALS->count + sizeof(Word)) / sizeof(Word));
+ LeftHalf = (String) temp;
+ memcpy(LeftHalf, LOCALS->s, LOCALS->count);
+ LeftHalf[LOCALS->count] = '\\0';
+ incr_hp_atomic(temp,
+ (LOCALS->len - LOCALS->count + sizeof(Word))
+ / sizeof(Word));
+ RightHalf = (String) temp;
+ strcpy(RightHalf, LOCALS->s + LOCALS->count);
+
+ if (LOCALS->count < LOCALS->len) {
+ SUCCEED;
+ } else {
+ SUCCEED_LAST;
+ }
+")).
+
+:- pred break_string2(string, string, string).
+:- mode break_string2(out, out, in) is multi.
+
+:- pragma c_code(break_string2(LeftHalf::out, RightHalf::out, WholeString::in),
+will_not_call_mercury,
+local_vars("
+ /* here we declare any local variables that we need to save */
+ String s;
+ size_t len;
+ size_t count;
+"),
+first_code("
+ /* this code gets executed on a call, but not on a retry */
+ LOCALS->s = WholeString;
+ LOCALS->len = strlen(WholeString);
+ LOCALS->count = 0;
+"),
+retry_code("
+ /* this code gets executed on a retry */
+ LOCALS->count++;
+"),
+duplicated_code("
+ Word temp;
+
+ /* this code gets executed for both calls and retries */
+ incr_hp_atomic(temp,
+ (LOCALS->count + sizeof(Word)) / sizeof(Word));
+ LeftHalf = (String) temp;
+ memcpy(LeftHalf, LOCALS->s, LOCALS->count);
+ LeftHalf[LOCALS->count] = '\\0';
+ incr_hp_atomic(temp,
+ (LOCALS->len - LOCALS->count + sizeof(Word))
+ / sizeof(Word));
+ RightHalf = (String) temp;
+ strcpy(RightHalf, LOCALS->s + LOCALS->count);
+
+ if (LOCALS->count < LOCALS->len) {
+ SUCCEED;
+ } else {
+ SUCCEED_LAST;
+ }
+")).
+
+:- pred break_string3(string, string, string).
+:- mode break_string3(out, out, in) is multi.
+
+:- pragma c_code(break_string3(LeftHalf::out, RightHalf::out, WholeString::in),
+will_not_call_mercury,
+local_vars("
+ /* here we declare any local variables that we need to save */
+ String s;
+ size_t len;
+ size_t count;
+"),
+first_code("
+ /* this code gets executed on a call, but not on a retry */
+ LOCALS->s = WholeString;
+ LOCALS->len = strlen(WholeString);
+ LOCALS->count = 0;
+"),
+retry_code("
+ /* this code gets executed on a retry */
+ LOCALS->count++;
+"),
+common_code("
+ Word temp;
+
+ /* this code gets executed for both calls and retries */
+ incr_hp_atomic(temp,
+ (LOCALS->count + sizeof(Word)) / sizeof(Word));
+ LeftHalf = (String) temp;
+ memcpy(LeftHalf, LOCALS->s, LOCALS->count);
+ LeftHalf[LOCALS->count] = '\\0';
+ incr_hp_atomic(temp,
+ (LOCALS->len - LOCALS->count + sizeof(Word))
+ / sizeof(Word));
+ RightHalf = (String) temp;
+ strcpy(RightHalf, LOCALS->s + LOCALS->count);
+
+ if (LOCALS->count < LOCALS->len) {
+ SUCCEED;
+ } else {
+ SUCCEED_LAST;
+ }
+")).
cvs diff: Diffing tests/hard_coded//sub-modules
cvs diff: Diffing tests/hard_coded//typeclasses
More information about the developers
mailing list