diff --git a/externals/Makefile.am b/externals/Makefile.am index 55c09bd78f..2a6c6ba182 100644 --- a/externals/Makefile.am +++ b/externals/Makefile.am @@ -46,6 +46,7 @@ $(ATERM).tar.gz: $(ATERM): $(ATERM).tar.gz gunzip < $(srcdir)/$(ATERM).tar.gz | tar xvf - + (cd $(ATERM) && patch -p1) < $(srcdir)/aterm-aliasing.patch have-aterm: $(MAKE) $(ATERM) @@ -101,7 +102,7 @@ endif all: build-db build-aterm build-bzip2 -EXTRA_DIST = $(DB).tar.gz $(ATERM).tar.gz $(BZIP2).tar.gz bdb-cygwin.patch +EXTRA_DIST = $(DB).tar.gz $(ATERM).tar.gz $(BZIP2).tar.gz bdb-cygwin.patch aterm-aliasing.patch ext-clean: $(RM) -f have-db build-db have-aterm build-aterm diff --git a/externals/aterm-aliasing.patch b/externals/aterm-aliasing.patch new file mode 100644 index 0000000000..c1dfc3e0e7 --- /dev/null +++ b/externals/aterm-aliasing.patch @@ -0,0 +1,224 @@ +diff -rc aterm-1142707243.10633/aterm/aterm.c aterm/aterm/aterm.c +*** aterm-1142707243.10633/aterm/aterm.c 2006-02-08 11:35:28.000000000 +0100 +--- aterm/aterm/aterm.c 2006-04-25 17:10:52.000000000 +0200 +*************** +*** 193,198 **** +--- 193,199 ---- + /* that have char == 2 bytes, and sizeof(header_type) == 2 */ + assert(sizeof(header_type) == sizeof(ATerm *)); + assert(sizeof(header_type) >= 4); ++ assert(sizeof(ATerm) == sizeof(MachineWord)); + + /*}}} */ + /*{{{ Initialize buffer */ +diff -rc aterm-1142707243.10633/aterm/memory.c aterm/aterm/memory.c +*** aterm-1142707243.10633/aterm/memory.c 2006-03-09 15:02:56.000000000 +0100 +--- aterm/aterm/memory.c 2006-04-25 18:22:00.000000000 +0200 +*************** +*** 119,130 **** + hash_number(tmp,3)) + */ + + #define HASHNUMBER3(t)\ +! FINISH(COMBINE(START(((MachineWord*)t)[0]), ((MachineWord*)t)[2])) + + #define HASHNUMBER4(t)\ +! FINISH(COMBINE(COMBINE(START(((MachineWord*)t)[0]), \ +! ((MachineWord*)t)[2]),((MachineWord*)t)[3])) + + #define HASHINT(val) \ + FINISH(COMBINE(START( (AT_INT<header = header; ++ ++ and then read it through a MachineWord*, e.g., ++ ++ hnr = hash_number((ATerm) protoAppl, 2); ++ ++ (hash_number walks over the term by casting it to a MachineWord*). ++ ++ However, the same clause of the C standard also specifies that you ++ *can* read the memory location through a union type that contains ++ both the original type (e.g. ATermAppl) and the type used to read ++ the memory location (e.g. MachineWord). That's what we do ++ below: we have a union of all the types that occur in the various ++ ATerm types. We then read the "w" element of the union. The ++ compiler is not allowed to assume absence of aliasing with the ++ other types in the union. ++ ++ A better solution would be to hash the term through a character ++ pointer (since *any* memory location can be legally read as a ++ character), but I'm too lazy right now. Performance might also ++ suffer if we do that. */ ++ ++ typedef union ++ { ++ MachineWord w; ++ header_type header; ++ ATerm term; ++ ATermList list; ++ int i; ++ double d; ++ void* p; ++ } Aliaser; ++ ++ #define GET_WORD(t, n) (((Aliaser*) (((MachineWord*) t) + n))->w) ++ + #define HASHNUMBER3(t)\ +! FINISH(COMBINE(START(GET_WORD(t, 0)), GET_WORD(t, 2))) + + #define HASHNUMBER4(t)\ +! FINISH(COMBINE(COMBINE(START(GET_WORD(t, 0)), \ +! GET_WORD(t, 2)), GET_WORD(t, 3))) + + #define HASHINT(val) \ + FINISH(COMBINE(START( (AT_INT<header = header; + CHECK_HEADER(protoAppl->header); + +! if (args != PROTO_APPL_ARGS) { + for (i=0; iheader = header; + CHECK_HEADER(protoAppl->header); + +! if (args != (ATerm *) PROTO_APPL_ARGS) { + for (i=0; i