From c9e7cc39d6c5a11e354bd3f73d667566a55dba7a Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Thu, 22 Nov 2018 07:56:33 +0100 Subject: [PATCH 01/23] Update algos.h --- CosBase/include/cos/cpp/algos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CosBase/include/cos/cpp/algos.h b/CosBase/include/cos/cpp/algos.h index c31f7a16..ba55440a 100644 --- a/CosBase/include/cos/cpp/algos.h +++ b/CosBase/include/cos/cpp/algos.h @@ -64,7 +64,7 @@ COS_PP_RES_(COS_PP_EVAL(COS_PP_LEN(T1), \ ((),(COS_PP_ID T1,),(COS_PP_ID T2,),(COS_PP_ID T3,),F),COS_PP_MAP3_0)) -// flatten tuple T to sequence using s as separator, i.e. (a,b,c) -> a b c +// flatten tuple T to sequence using space as separator, i.e. (a,b,c) -> a b c #define COS_PP_SEP(T) \ COS_PP_FOLDL(T,,COS_PP_PAIR) From 1c5237cbffbf3d4f64b2abeedc872de4f8f1898a Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Thu, 22 Nov 2018 08:12:09 +0100 Subject: [PATCH 02/23] Update README --- README | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README b/README index 5224bdae..d167c479 100644 --- a/README +++ b/README @@ -77,6 +77,9 @@ or on arXiv.org Wiki on CLOS: http://en.wikipedia.org/wiki/Common_Lisp_Object_System +Wiki on multiple dispatch: +http://en.wikipedia.org/wiki/Multiple_dispatch#C + Makefile examples: ------------------ From daa6130d63b64753cb95ed8c222fa128365e903f Mon Sep 17 00:00:00 2001 From: uprego Date: Fri, 23 Nov 2018 10:39:21 +0000 Subject: [PATCH 03/23] Update README.C89 Fix typo. --- README.C89 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.C89 b/README.C89 index 32caf2cf..7515f2ff 100644 --- a/README.C89 +++ b/README.C89 @@ -25,7 +25,7 @@ COS core generates code conform to ISO C89 but it requires a ISO C99 preprocesso CosBase (core) can be compiled with a standalone C99 preprocessor and a C89 compiler. CosStd and other modules require a C99 compiler or a compiler which supports at least - - compound litterals (automatic constructors) + - compound literals (automatic constructors) - flexible arrays (some class cluster definition like Array) - 64 bits integers on non 64 bits architectures (class Long) - complex numbers (class Complex) From 3d0f196a22a9d6f6ddb9e702ea90b2fea3c21114 Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Sat, 15 Dec 2018 13:15:16 -0900 Subject: [PATCH 04/23] Emit operation summaries as comments when SHOW=yes --- CosBase/include/cos/prologue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CosBase/include/cos/prologue b/CosBase/include/cos/prologue index 36126cd6..8ad91871 100644 --- a/CosBase/include/cos/prologue +++ b/CosBase/include/cos/prologue @@ -98,7 +98,7 @@ endif # set command echo _ := $(if $(call eq,$(SHOW),yes),,@) -E := $(if $(call eq,$(SHOW),yes),@ \#,@ echo) +E := $(if $(call eq,$(SHOW),yes),@ echo '\#',@ echo) # debug ifneq ($(SHOW),yes) From 8527d0efba2b861b8d16cbc66ffcbe3b66911fdf Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Mon, 7 Jan 2019 10:56:56 -0900 Subject: [PATCH 05/23] Remove useclass() of some unused classes --- CosStd/src/File.c | 2 +- CosStd/src/String.c | 2 +- CosStd/src/String_alg.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CosStd/src/File.c b/CosStd/src/File.c index 30b87032..2deac3f1 100644 --- a/CosStd/src/File.c +++ b/CosStd/src/File.c @@ -42,7 +42,7 @@ makclass(OutputInputFile, OutputFile); // ----- useclass(InputFile, OutputFile, InputOutputFile, OutputInputFile); -useclass(ExBadStream, ExBadAlloc, AutoRelease, Array, String); +useclass(ExBadStream, String); // ----- diff --git a/CosStd/src/String.c b/CosStd/src/String.c index 9f9008ca..dcd2348b 100644 --- a/CosStd/src/String.c +++ b/CosStd/src/String.c @@ -37,7 +37,7 @@ makclass(StringN, String); // ----- -useclass(String, ExBadAlloc, ExOverflow); +useclass(String, ExOverflow); // --- getters diff --git a/CosStd/src/String_alg.c b/CosStd/src/String_alg.c index 5c248280..fccc1bec 100644 --- a/CosStd/src/String_alg.c +++ b/CosStd/src/String_alg.c @@ -33,7 +33,7 @@ // ----- -useclass(String, View, Array, ExBadAlloc); +useclass(String, View, Array); useclass(Lesser,Equal,Greater); // ----- equality From 5e66480d3f55b506b91a24be4999ec29635da9e9 Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Tue, 8 Jan 2019 13:36:46 -0900 Subject: [PATCH 06/23] Remove useclass() of classes getting defmethod() --- CosStd/src/File.c | 4 ++-- CosStd/src/String_alg.c | 2 +- CosStd/src/String_dyn.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CosStd/src/File.c b/CosStd/src/File.c index 2deac3f1..d641ac1c 100644 --- a/CosStd/src/File.c +++ b/CosStd/src/File.c @@ -41,8 +41,8 @@ makclass(OutputInputFile, OutputFile); // ----- -useclass(InputFile, OutputFile, InputOutputFile, OutputInputFile); -useclass(ExBadStream, String); +useclass(InputFile, OutputFile); +useclass(ExBadStream); // ----- diff --git a/CosStd/src/String_alg.c b/CosStd/src/String_alg.c index fccc1bec..9c5e2bd4 100644 --- a/CosStd/src/String_alg.c +++ b/CosStd/src/String_alg.c @@ -33,7 +33,7 @@ // ----- -useclass(String, View, Array); +useclass(View, Array); useclass(Lesser,Equal,Greater); // ----- equality diff --git a/CosStd/src/String_dyn.c b/CosStd/src/String_dyn.c index 012296b4..94e630cb 100644 --- a/CosStd/src/String_dyn.c +++ b/CosStd/src/String_dyn.c @@ -36,7 +36,7 @@ makclass(StringDyn, StringFix); // ----- -useclass(String, StringDyn, ExBadAlloc, ExOverflow); +useclass(StringDyn, ExBadAlloc, ExOverflow); // ----- getter From 851639a7ac9ae9708d7aa2777102d1291700cc22 Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Tue, 8 Jan 2019 14:20:57 -0900 Subject: [PATCH 07/23] Use -Wno-unused-local-typedefs for all cfg --- CosBase/include/cos/cfg/FreeBSD | 3 ++- CosBase/include/cos/cfg/Linux | 3 ++- CosBase/include/cos/cfg/SunOS | 3 ++- INSTALL | 3 ++- README | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CosBase/include/cos/cfg/FreeBSD b/CosBase/include/cos/cfg/FreeBSD index 9907c67a..8b91df35 100644 --- a/CosBase/include/cos/cfg/FreeBSD +++ b/CosBase/include/cos/cfg/FreeBSD @@ -100,7 +100,8 @@ SYSLIBS := pthread dl CCFLAGS += -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \ -Wchar-subscripts -Wformat-nonliteral -Wwrite-strings \ -Wpointer-arith -Wbad-function-cast -Wcast-align -Wcast-qual \ - -Wfloat-equal -Wconversion -Wno-conversion -Winline + -Wfloat-equal -Wconversion -Wno-conversion -Winline \ + -Wno-unused-local-typedefs # CCFLAGS += --param large-function-growth=400 --param inline-unit-growth=200 diff --git a/CosBase/include/cos/cfg/Linux b/CosBase/include/cos/cfg/Linux index dc2d0f19..b26eac4f 100644 --- a/CosBase/include/cos/cfg/Linux +++ b/CosBase/include/cos/cfg/Linux @@ -100,7 +100,8 @@ SYSLIBS := pthread dl CCFLAGS += -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \ -Wchar-subscripts -Wformat-nonliteral -Wwrite-strings \ -Wpointer-arith -Wbad-function-cast -Wcast-align -Wcast-qual \ - -Wfloat-equal -Wconversion -Wno-conversion -Winline + -Wfloat-equal -Wconversion -Wno-conversion -Winline \ + -Wno-unused-local-typedefs # CCFLAGS += --param large-function-growth=400 --param inline-unit-growth=200 diff --git a/CosBase/include/cos/cfg/SunOS b/CosBase/include/cos/cfg/SunOS index d19a3e2e..272f6e70 100644 --- a/CosBase/include/cos/cfg/SunOS +++ b/CosBase/include/cos/cfg/SunOS @@ -100,7 +100,8 @@ SYSLIBS := pthread dl CCFLAGS += -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \ -Wchar-subscripts -Wformat-nonliteral -Wwrite-strings \ -Wpointer-arith -Wbad-function-cast -Wcast-align -Wcast-qual \ - -Wfloat-equal -Wconversion -Wno-conversion -Winline + -Wfloat-equal -Wconversion -Wno-conversion -Winline \ + -Wno-unused-local-typedefs # CCFLAGS += --param large-function-growth=400 --param inline-unit-growth=200 diff --git a/INSTALL b/INSTALL index 2efcbbfe..0b316e0f 100644 --- a/INSTALL +++ b/INSTALL @@ -48,11 +48,12 @@ Tested platforms: # System & Architectures Linux Ubuntu 8.04, 8.10, 9.04, 9.10 (Debian) on i386 (32-bit) Core2 Duo Linux Ubuntu 8.04, 8.10, 9.04, 9.10 (Debian) on x86_64 (64-bit) Core2 Duo +Linux Debian 8.11 on x86_64 (64-bit) Intel 8-core Xeon Linux SLC 4.0, 5.0 (RedHat) on x86_64 (64-bit) Quad Xeon Mac OS X Leopard (Darwin) on x86_64 (64-bit) Core2 Duo # Compilers -gcc 3.2.3, 3.4.6, 4.1.2, 4.2.4, 4.3.2, 4.3.3 +gcc 3.2.3, 3.4.6, 4.1.2, 4.2.4, 4.3.2, 4.3.3, 7.2.0 Other available platforms (untested): ------------------------------------- diff --git a/README b/README index d167c479..d53e609c 100644 --- a/README +++ b/README @@ -132,7 +132,7 @@ Mac OSX from Leopard to El Capitan on x86_64 multicore Windows from 7 to 10 on x86_64 multicore using MSys2 (mingw64) # Compilers -gcc from 3.2.3 to 4.8.5 +gcc from 3.2.3 to 4.8.5 and 7.2.0 Other available platforms (untested): ------------------------------------- From 5f996c1e16a10fd94d35c90a01459c47a0d2ffb7 Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Tue, 8 Jan 2019 14:53:57 -0900 Subject: [PATCH 08/23] Prevent intional fallthrough warnings on gcc --- CosBase/src/cos_symbol.c | 4 ++++ CosBase/tools/src/coscmt.c | 1 + 2 files changed, 5 insertions(+) diff --git a/CosBase/src/cos_symbol.c b/CosBase/src/cos_symbol.c index 2a552eaf..207f6b96 100644 --- a/CosBase/src/cos_symbol.c +++ b/CosBase/src/cos_symbol.c @@ -670,6 +670,7 @@ sym_init(void) case cos_tag_pclass : ++n_pcl; pcl_stinit((void*)tbl_sym[t][s]); break; case cos_tag_generic: ++n_gen; gen_stinit((void*)tbl_sym[t][s]); break; case cos_tag_alias : als_stinit((void*)tbl_sym[t][s]); + /* intentional fall through */ case cos_tag_method : ++n_mth; break; case cos_tag_docstr : ++n_doc; break; default: cos_abort("invalid COS symbol"); @@ -702,12 +703,15 @@ sym_init(void) if (sym.bhv[i]) { switch (bhv->Object.Any._rc) { case cos_tag_class : + /* intentional fall through */ case cos_tag_pclass: + /* intentional fall through */ case cos_tag_mclass: { struct Class *cls = CAST(struct Class*, bhv); cos_abort("class '%s' at (%s,%d) slot %u already assigned", cls_name(cls), cls_file(cls), cls_line(cls), i); } + /* intentional fall through */ case cos_tag_generic: { struct Generic *gen = CAST(struct Generic*, bhv); cos_abort("generic '%s' at (%s,%d) slot %u already assigned", diff --git a/CosBase/tools/src/coscmt.c b/CosBase/tools/src/coscmt.c index ce204536..0dcd767b 100644 --- a/CosBase/tools/src/coscmt.c +++ b/CosBase/tools/src/coscmt.c @@ -95,6 +95,7 @@ remove_cmt(FILE *in , FILE *out) if (c == '/') { skip_line(in); break; } if (c == '*') { skip_cmt (in); break; } fputc('/', out); + /* intentional fall through */ default : fputc(c , out); } } From e41466f9051848ddb3dc735a6d71ebc1f1d13a66 Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Thu, 17 Jan 2019 15:05:41 -0900 Subject: [PATCH 09/23] cos_functor_clearContext() in cos_deinit() --- CosBase/src/cos_symbol.c | 1 + 1 file changed, 1 insertion(+) diff --git a/CosBase/src/cos_symbol.c b/CosBase/src/cos_symbol.c index 207f6b96..4c3483a3 100644 --- a/CosBase/src/cos_symbol.c +++ b/CosBase/src/cos_symbol.c @@ -907,6 +907,7 @@ cos_deinit(void) t1 = clock(); deinit_duration = (t1-t0)/CLOCKS_PER_SEC; + cos_functor_clearContext(); cos_method_clearCaches(); } } From c5597c30e2ce4f97465cb31dfaad66a2d5efd063 Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Fri, 8 Feb 2019 13:55:37 -0900 Subject: [PATCH 10/23] Prevent function type cast warnings on gcc-8 --- CosBase/include/cos/cos/method.h | 2 +- README | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CosBase/include/cos/cos/method.h b/CosBase/include/cos/cos/method.h index e201e482..dff1c9e4 100644 --- a/CosBase/include/cos/cos/method.h +++ b/CosBase/include/cos/cos/method.h @@ -369,7 +369,7 @@ static void COS_MTH_MNAME(COS_FCT_NAME(NAME,CS),TAG,T) \ /* indirect invocation, normal */ \ _cos_mth_nxt_g(__VA_ARGS__,_cos_mth_nxt_sel,_ret,_cos_mth_nxt_p) : \ /* direct invocation, if GUM */ \ - ((_cos_mth_nxt_d)_cos_mth_nxt_p)(_sel,__VA_ARGS__,_arg,_ret))) + ((_cos_mth_nxt_d)(void (*)(void))_cos_mth_nxt_p)(_sel,__VA_ARGS__,_arg,_ret))) #define COS_MTH_NXT_P \ /* next_method check */ \ diff --git a/README b/README index d53e609c..cf6419e2 100644 --- a/README +++ b/README @@ -132,7 +132,7 @@ Mac OSX from Leopard to El Capitan on x86_64 multicore Windows from 7 to 10 on x86_64 multicore using MSys2 (mingw64) # Compilers -gcc from 3.2.3 to 4.8.5 and 7.2.0 +gcc from 3.2.3 to 4.8.5, 7.2.0, and 8.2.0 Other available platforms (untested): ------------------------------------- From c75da3b2ab3d137c6a9a6095c5842369a78ef6cb Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Tue, 12 Feb 2019 11:27:32 +0100 Subject: [PATCH 11/23] Update method.h --- CosBase/include/cos/cos/method.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CosBase/include/cos/cos/method.h b/CosBase/include/cos/cos/method.h index dff1c9e4..e7a9d174 100644 --- a/CosBase/include/cos/cos/method.h +++ b/CosBase/include/cos/cos/method.h @@ -369,7 +369,7 @@ static void COS_MTH_MNAME(COS_FCT_NAME(NAME,CS),TAG,T) \ /* indirect invocation, normal */ \ _cos_mth_nxt_g(__VA_ARGS__,_cos_mth_nxt_sel,_ret,_cos_mth_nxt_p) : \ /* direct invocation, if GUM */ \ - ((_cos_mth_nxt_d)(void (*)(void))_cos_mth_nxt_p)(_sel,__VA_ARGS__,_arg,_ret))) + ((_cos_mth_nxt_d)(FCT)_cos_mth_nxt_p)(_sel,__VA_ARGS__,_arg,_ret))) #define COS_MTH_NXT_P \ /* next_method check */ \ From 013e005d840667fe8c0b6b21ef690d73315fb42a Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Sun, 17 Feb 2019 05:19:30 -0900 Subject: [PATCH 12/23] Fix inverted logic in bounds check --- CosStd/src/Array_vw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CosStd/src/Array_vw.c b/CosStd/src/Array_vw.c index 4c7ec93c..b22e6dc2 100644 --- a/CosStd/src/Array_vw.c +++ b/CosStd/src/Array_vw.c @@ -38,7 +38,7 @@ useclass(ArrayView, ArraySubView, ExBadRange); // ----- initializer (weaker than constructors: no retain) defmethod(OBJ, ginitWith2, ArrayView, Array, Slice) // array view - if ( Slice_first(self3) < self2->size && Slice_last(self3) < self2->size) { + if ( Slice_first(self3) >= self2->size || Slice_last(self3) >= self2->size) { self->ref = 0; THROW( gnewWithStr(ExBadRange, "slice out of range") ); } @@ -58,7 +58,7 @@ defmethod(OBJ, ginitWith2, ArrayView, Array, Range) // array view endmethod defmethod(OBJ, ginitWith2, ArraySubView, Array, Slice) // array subview - if ( Slice_first(self3) < self2->size && Slice_last(self3) < self2->size) { + if ( Slice_first(self3) >= self2->size || Slice_last(self3) >= self2->size) { self->ArrayView.ref = 0; THROW( gnewWithStr(ExBadRange, "slice out of range") ); } From 0b278891188710ff375585819b3df6d05aaf03b4 Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Tue, 19 Feb 2019 23:22:29 -0900 Subject: [PATCH 13/23] Fix implicit conversion to unsigned bugs... This makes e.g. negatively strided views work as intended: OBJ ary = aArray(aInt(1), aInt(2), aInt(3)); OBJ ary_view = aArrayView(ary, aRange(-1, 1, -1)); for ( unsigned ii = 0 ; ii < gsize(ary_view); ii++ ) { printf (" %u: %i\n", ii, gint(ggetAt(ary_view, aInt(ii)))); won't seg fault now. As usual fully fixing this problem for all pointer widths is excruciating and inefficient, so we don't. Using ptrdiff_t gives decent results on 32 bit and works for all realistic offsets on 64 bit. It's tempting to use I64 rather than ptrdiff_t to make the operation explicit, but that might not work right on 32 bit (I'm not sure). This probably isn't all the bugs of this sort. At least the following look suspicious: src/Array_alg.c:547:35: warning: conversion from 'long int' to 'U32' {aka 'unsigned int'} may change value [-Wconversion] src/./tmpl/Vector_alg.c:406:35: warning: conversion from 'long int' to 'U32' {aka 'unsigned int'} may change value [-Wconversion] src/String_alg.c:308:35: warning: conversion from 'long int' to 'U32' {aka 'unsigned int'} may change value [-Wconversion] The fixes for those look a little harder though, as the suspicious intermediate results get sent off to an unsigned argument to KnuthMorrisPratt() (which function would also likely need to be fixed). The Range_index() function in Range.h seems to work right and it looks like the mechanism is well-defined even if it is a little scary. I added an explicit cast and comment to make it clear what's going on. --- CosStd/include/cos/Range.h | 3 ++- CosStd/src/Array_acc.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CosStd/include/cos/Range.h b/CosStd/include/cos/Range.h index 80444c0f..4e42ced4 100644 --- a/CosStd/include/cos/Range.h +++ b/CosStd/include/cos/Range.h @@ -88,7 +88,8 @@ endclass */ static cos_inline U32 Range_index(I32 index, U32 seq_size) { - return index + (index < 0) * seq_size; + // OK because signed=>unsigned cast and unsigned overflow are well defined: + return (U32)index + (index < 0) * seq_size; } /*********************************************************** diff --git a/CosStd/src/Array_acc.c b/CosStd/src/Array_acc.c index 1f989e0d..910a987e 100644 --- a/CosStd/src/Array_acc.c +++ b/CosStd/src/Array_acc.c @@ -49,10 +49,10 @@ endmethod defmethod(OBJ, ggetAtIdx, Array, (I32)idx) U32 i = Range_index(idx, self->size); - + ensure( i < self->size, "index out of range" ); - retmethod( self->object[i*self->stride] ); + retmethod( self->object[(ptrdiff_t)i*self->stride] ); endmethod defmethod(OBJ, ggetAt, Array, Int) @@ -60,7 +60,7 @@ defmethod(OBJ, ggetAt, Array, Int) ensure( i < self->size, "index out of range" ); - retmethod( self->object[i*self->stride] ); + retmethod( self->object[(ptrdiff_t)i*self->stride] ); endmethod defmethod(OBJ, ggetAt, Array, Slice) @@ -87,7 +87,7 @@ defmethod(OBJ, gputAtIdx, Array, (I32)idx, Object) ensure( i < self->size, "index out of range" ); - OBJ *dst = self->object + i*self->stride; + OBJ *dst = self->object + (ptrdiff_t)i*self->stride; assign(dst, _2); retmethod(_1); @@ -98,7 +98,7 @@ defmethod(OBJ, gputAt, Array, Int, Object) ensure( i < self->size, "index out of range" ); - OBJ *dst = self->object + i*self->stride; + OBJ *dst = self->object + (ptrdiff_t)i*self->stride; assign(dst, _3); retmethod(_1); @@ -112,7 +112,7 @@ BODY U32 dst_n = Slice_size (self2); I32 dst_s = Slice_stride(self2)*self->stride; OBJ *dst = Slice_start (self2)*self->stride + self->object; - OBJ *end = dst + dst_s*dst_n; + OBJ *end = dst + dst_s*(ptrdiff_t)dst_n; while (dst != end) { assign(dst, _3); @@ -136,7 +136,7 @@ defmethod(OBJ, gputAt, Array, IntVector, Object) U32 idx_n = self2->size; I32 idx_s = self2->stride; I32 *idx = self2->value; - I32 *end = idx + idx_s*idx_n; + I32 *end = idx + idx_s*(ptrdiff_t)idx_n; while (idx != end) { U32 i = Range_index(*idx, dst_n); @@ -168,7 +168,7 @@ BODY OBJ *dst = Slice_start (self2)*self->stride + self->object; I32 src_s = self3->stride; OBJ *src = self3->object; - OBJ *end = dst + dst_s*dst_n; + OBJ *end = dst + dst_s*(ptrdiff_t)dst_n; while (dst != end) { assign(dst, *src); @@ -199,7 +199,7 @@ BODY I32 *idx = self2->value; I32 src_s = self3->stride; OBJ *src = self3->object; - I32 *end = idx + idx_s*idx_n; + I32 *end = idx + idx_s*(ptrdiff_t)idx_n; while (idx != end) { U32 i = Range_index(*idx, dst_n); From 52282e8ac30ac4dc5d75909872278702e1dfd14a Mon Sep 17 00:00:00 2001 From: Britton Leo Kerin Date: Wed, 20 Feb 2019 13:00:14 -0900 Subject: [PATCH 14/23] Many more implicit conversion bugs... I haven't tested all these obviously but they fit the pattern and look safe. Still not done: cases that show up or propagate into qsortFun()/ iqsortSFun()/KnuthMorrisPratt() (statics which show up in multiple places), many in Vector_* because I'm not sure they have the same issue. There are a lot of these. Perhaps Range_index() and Array should return/use I32 and COS be documented to only support Arrays of ~INT32_MAX (maybe -1 or something), which is effectively the case for much of the API anyway. But that's a breaking change to existing simple uses of large arrays. --- CosStd/src/Array.c | 4 +- CosStd/src/Array_acc.c | 4 +- CosStd/src/Array_alg.c | 12 +++--- CosStd/src/Array_fun.c | 88 +++++++++++++++++++++--------------------- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/CosStd/src/Array.c b/CosStd/src/Array.c index a02b34bf..b95e0030 100644 --- a/CosStd/src/Array.c +++ b/CosStd/src/Array.c @@ -283,7 +283,7 @@ defmethod(OBJ, ginitWith2 , pmArray, Array, IntVector) // random seque while (dst != end) { U32 i = Range_index(*idx, val_n); ensure( i < val_n, "index out of range" ); - *dst++ = gretain(val[i*val_s]), ++*dst_n; + *dst++ = gretain(val[(ptrdiff_t)i*val_s]), ++*dst_n; idx += idx_s; } @@ -339,7 +339,7 @@ defmethod(void, ginvariant, Array, (STR)file, (int)line) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; while (val != end && *val) val += val_s; diff --git a/CosStd/src/Array_acc.c b/CosStd/src/Array_acc.c index 910a987e..6cc5298d 100644 --- a/CosStd/src/Array_acc.c +++ b/CosStd/src/Array_acc.c @@ -141,7 +141,7 @@ defmethod(OBJ, gputAt, Array, IntVector, Object) while (idx != end) { U32 i = Range_index(*idx, dst_n); ensure( i < dst_n, "index out of range" ); - assign(dst + i*dst_s, _3); + assign(dst + (ptrdiff_t)i*dst_s, _3); idx += idx_s; } @@ -204,7 +204,7 @@ BODY while (idx != end) { U32 i = Range_index(*idx, dst_n); ensure( i < dst_n, "index out of range" ); - assign(dst + i*dst_s, *src); + assign(dst + (ptrdiff_t)i*dst_s, *src); src += src_s; idx += idx_s; } diff --git a/CosStd/src/Array_alg.c b/CosStd/src/Array_alg.c index 8b6be70a..8cc6fc8f 100644 --- a/CosStd/src/Array_alg.c +++ b/CosStd/src/Array_alg.c @@ -54,7 +54,7 @@ defmethod(OBJ, gisEqual, Array, Array) OBJ *val = self->object; I32 val2_s = self2->stride; OBJ *val2 = self2->object; - OBJ *end = val + val_s*val_n; + OBJ *end = val + val_s*(ptrdiff_t)val_n; while (val != end) { if (gisEqual(*val,*val2) != True) @@ -80,7 +80,7 @@ defmethod(OBJ, gcompare, Array, Array) OBJ *val = self->object; I32 val2_s = self2->stride; OBJ *val2 = self2->object; - OBJ *end = val + val_s*val_n; + OBJ *end = val + val_s*(ptrdiff_t)val_n; OBJ res; while (val != end) { @@ -111,7 +111,7 @@ defmethod(OBJ, greverse, Array) U32 val_n = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*(val_n-1); + OBJ *end = val + val_s*(ptrdiff_t)(val_n-1); if (val_s > 0) while (val < end) { @@ -155,7 +155,7 @@ defmethod(OBJ, gpermute, Array, IntVector) for (cur = buf; cur != end; cur++) { i = Range_index(*idx, size); if ( !(i < size && flg[i]) ) break; - *cur = val[i*val_s], flg[i] = 0; + *cur = val[(ptrdiff_t)i*val_s], flg[i] = 0; idx += idx_s; } @@ -173,7 +173,7 @@ defmethod(OBJ, gpermute, Array, IntVector) while (cur != buf) { idx -= idx_s; i = Range_index(*idx, size); - val[i*val_s] = *--cur; + val[(ptrdiff_t)i*val_s] = *--cur; } CARRAY_DESTROY(buf); @@ -450,7 +450,7 @@ findVal(OBJ *val, U32 val_n, I32 val_s, OBJ _2) { if (!val_n) return 0; - OBJ *end = val + val_s*val_n; + OBJ *end = val + val_s*(ptrdiff_t)val_n; while (val != end) { if (gisEqual(_2, *val) == True) diff --git a/CosStd/src/Array_fun.c b/CosStd/src/Array_fun.c index ae6d6057..d74cdabc 100644 --- a/CosStd/src/Array_fun.c +++ b/CosStd/src/Array_fun.c @@ -40,7 +40,7 @@ defmethod(void, gforeachWhile, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; while (val != end && geval(_2, *val) != Nil) val += val_s; @@ -50,7 +50,7 @@ defmethod(void, gforeach, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; while (val != end) { geval(_2, *val); @@ -64,7 +64,7 @@ defmethod(void, gforeach2, Array, Array, Functor) OBJ *val = self->object; I32 val2_s = self2->stride; OBJ *val2 = self2->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; while (val != end) { geval(_3, *val, *val2); @@ -82,7 +82,7 @@ defmethod(void, gforeach3, Array, Array, Array, Functor) OBJ *val2 = self2->object; I32 val3_s = self3->stride; OBJ *val3 = self3->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; while (val != end) { geval(_4, *val, *val2, *val3); @@ -104,7 +104,7 @@ defmethod(void, gforeach4, Array, Array, Array, Array, Functor) OBJ *val3 = self3->object; I32 val4_s = self4->stride; OBJ *val4 = self4->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; while (val != end) { geval(_5, *val, *val2, *val3, *val4); @@ -121,7 +121,7 @@ defmethod(OBJ, gapplyWhile, Functor, Array) U32 size = self2->size; I32 val_s = self2->stride; OBJ *val = self2->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res, old; while (val != end) { @@ -139,7 +139,7 @@ defmethod(OBJ, gapplyIf, Functor, Array) U32 size = self2->size; I32 val_s = self2->stride; OBJ *val = self2->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res, old; while (val != end) { @@ -156,7 +156,7 @@ defmethod(OBJ, gapply, Functor, Array) U32 size = self2->size; I32 val_s = self2->stride; OBJ *val = self2->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res, old; while (val != end) { @@ -175,7 +175,7 @@ defmethod(OBJ, gapply2, Functor, Array, Array) OBJ *val = self2->object; I32 val2_s = self3->stride; OBJ *val2 = self3->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res, old; while (val != end) { @@ -198,7 +198,7 @@ defmethod(OBJ, gapply3, Functor, Array, Array, Array) OBJ *val2 = self3->object; I32 val3_s = self4->stride; OBJ *val3 = self4->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res, old; while (val != end) { @@ -225,7 +225,7 @@ defmethod(OBJ, gapply4, Functor, Array, Array, Array, Array) OBJ *val3 = self4->object; I32 val4_s = self5->stride; OBJ *val4 = self5->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res, old; while (val != end) { @@ -247,7 +247,7 @@ defmethod(OBJ, gmapWhile, Functor, Array) U32 size = self2->size; I32 val_s = self2->stride; OBJ *val = self2->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res; OBJ _arr = gautoRelease(gnewWith(Array,aInt(size))); @@ -270,7 +270,7 @@ defmethod(OBJ, gmapIf, Functor, Array) U32 size = self2->size; I32 val_s = self2->stride; OBJ *val = self2->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res; OBJ _arr = gautoRelease(gnewWith(Array,aInt(size))); @@ -293,7 +293,7 @@ defmethod(OBJ, gmap, Functor, Array) U32 size = self2->size; I32 val_s = self2->stride; OBJ *val = self2->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res; struct Array* arr = Array_alloc(size); @@ -317,7 +317,7 @@ defmethod(OBJ, gmap2, Functor, Array, Array) OBJ *val = self2->object; I32 val2_s = self3->stride; OBJ *val2 = self3->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res; struct Array* arr = Array_alloc(size); @@ -345,7 +345,7 @@ defmethod(OBJ, gmap3, Functor, Array, Array, Array) OBJ *val2 = self3->object; I32 val3_s = self4->stride; OBJ *val3 = self4->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res; struct Array* arr = Array_alloc(size); @@ -377,7 +377,7 @@ defmethod(OBJ, gmap4, Functor, Array, Array, Array, Array) OBJ *val3 = self4->object; I32 val4_s = self5->stride; OBJ *val4 = self5->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res; struct Array* arr = Array_alloc(size); @@ -404,7 +404,7 @@ defmethod(OBJ, gselect, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ _arr = gautoRelease(gnewWith(Array,aInt(size))); struct Array* arr = dbgcast(Array, _arr); @@ -425,7 +425,7 @@ defmethod(OBJ, greject, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ _arr = gautoRelease(gnewWith(Array,aInt(size))); struct Array* arr = dbgcast(Array, _arr); @@ -446,7 +446,7 @@ defmethod(OBJ, gselectWhile, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ _arr = gautoRelease(gnewWith(Array,aInt(size))); struct Array* arr = dbgcast(Array, _arr); @@ -468,7 +468,7 @@ defmethod(OBJ, grejectWhile, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ _arr = gautoRelease(gnewWith(Array,aInt(size))); struct Array* arr = dbgcast(Array, _arr); @@ -505,7 +505,7 @@ defmethod(OBJ, greduce, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = gautoRelease(gclone(*val)); val += val_s; @@ -522,7 +522,7 @@ defmethod(OBJ, greduce1, Array, Functor, Object) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = _3; while (val != end) { @@ -546,7 +546,7 @@ defmethod(OBJ, greduce2, Array, Functor, Object, Object) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = _3; if (size) { @@ -578,7 +578,7 @@ defmethod(OBJ, grreduce, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = gautoRelease(gclone(*(end-val_s))); end -= val_s; @@ -595,7 +595,7 @@ defmethod(OBJ, grreduce1, Array, Functor, Object) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = _3; while (val != end) { @@ -621,7 +621,7 @@ defmethod(OBJ, grreduce2, Array, Functor, Object, Object) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = _3; if (size) { @@ -662,7 +662,7 @@ defmethod(OBJ, gaccumulate1, Array, Functor, Object) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = _3; struct Array* arr = Array_alloc(size); @@ -693,7 +693,7 @@ defmethod(OBJ, gaccumulate2, Array, Functor, Object, Object) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = _3; struct Array* arr = Array_alloc(size); @@ -740,7 +740,7 @@ defmethod(OBJ, graccumulate1, Array, Functor, Object) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = _3; struct Array* arr = Array_alloc(size); @@ -772,7 +772,7 @@ defmethod(OBJ, graccumulate2, Array, Functor, Object, Object) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res = _3; struct Array* arr = Array_alloc(size); @@ -804,7 +804,7 @@ defmethod(OBJ, gall, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; while (val != end) { if (geval(_2, *val) != True) @@ -819,7 +819,7 @@ defmethod(OBJ, gany, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; while (val != end) { if (geval(_2, *val) == True) @@ -834,7 +834,7 @@ defmethod(U32, gcount, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; U32 cnt = 0; while (val != end) { @@ -857,7 +857,7 @@ defmethod(OBJ, gunique, Array, Functor) OBJ *val = self->object; U32 *dst_n = &arr->size; OBJ *dst = arr->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; if (val != end) { *dst = gretain(*val), ++*dst_n; @@ -881,7 +881,7 @@ defmethod(OBJ, gsplit, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ *beg = val; while (val != end) { @@ -917,7 +917,7 @@ defmethod(OBJ, ggroup, Array, Functor) U32 size = self->size; I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ res; while (val != end) { @@ -980,7 +980,7 @@ defmethod(OBJ, gdiff, Array, Collection, Functor) OBJ *val = self->object; U32 *dst_n = &arr->size; OBJ *dst = arr->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ fun = aFun(gfind, _2, aFun(geval2, _3, __2, __1)); while (val != end) { @@ -1003,7 +1003,7 @@ defmethod(OBJ, gmatch, Array, Collection, Functor) OBJ *val = self->object; U32 *dst_n = &arr->size; OBJ *dst = arr->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ fun = aLzy(_3); OBJ res; @@ -1029,7 +1029,7 @@ defmethod(OBJ, gintersect, Array, Collection, Functor) OBJ *val = self->object; U32 *dst_n = &arr->size; OBJ *dst = arr->object; - OBJ *end = val + val_s*size; + OBJ *end = val + val_s*(ptrdiff_t)size; OBJ fun = aFun(gfind, _2, aFun(geval2, _3, __2, __1)); while (val != end) { @@ -1055,7 +1055,7 @@ findFun(OBJ *val, U32 val_n, I32 val_s, OBJ _2) // linear search if (res == False) { - OBJ *end = val + val_s*val_n; + OBJ *end = val + val_s*(ptrdiff_t)val_n; val += val_s; while (val != end) { @@ -1073,10 +1073,10 @@ findFun(OBJ *val, U32 val_n, I32 val_s, OBJ _2) while (lo <= hi) { U32 i = (lo + hi) / 2; - res = geval(_2, val[i*val_s]); + res = geval(_2, val[(ptrdiff_t)i*val_s]); if (res == Equal) - return val + i*val_s; // found + return val + (ptrdiff_t)i*val_s; // found if (res == Lesser) hi = i-1; @@ -1389,7 +1389,7 @@ defmethod(OBJ, gisSorted, Array, Functor) I32 val_s = self->stride; OBJ *val = self->object; - OBJ *end = val + val_s*(size-1); + OBJ *end = val + val_s*(ptrdiff_t)(size-1); OBJ res; while (val != end) { From a8920c098646731599f8862b4966275102606933 Mon Sep 17 00:00:00 2001 From: uprego Date: Sat, 29 Aug 2020 20:19:08 +0200 Subject: [PATCH 15/23] Remove extra whitespace at end of lines. --- CosBase/examples/ex01/File.c | 2 +- CosBase/examples/ex01/Makefile | 6 +++--- CosBase/examples/ex01/String.c | 2 +- CosBase/examples/ex01/main.c | 2 +- CosStd/examples/ex01/Makefile | 8 ++++---- CosStd/examples/ex01/main.c | 32 ++++++++++++++++---------------- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/CosBase/examples/ex01/File.c b/CosBase/examples/ex01/File.c index 06975ece..91979a5c 100644 --- a/CosBase/examples/ex01/File.c +++ b/CosBase/examples/ex01/File.c @@ -28,7 +28,7 @@ defmethod(OBJ, ginitWithStr, File, (STR)str) self->file = str ? fopen(str,"r+") : stdout; if (!self->file) test_errno(); // THROW - + retmethod(_1); endmethod diff --git a/CosBase/examples/ex01/Makefile b/CosBase/examples/ex01/Makefile index 92ebcacd..2f88f24e 100644 --- a/CosBase/examples/ex01/Makefile +++ b/CosBase/examples/ex01/Makefile @@ -1,15 +1,15 @@ # # C Object System # COS Example -# +# # Copyright 2007+ Laurent Deniau -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/CosBase/examples/ex01/String.c b/CosBase/examples/ex01/String.c index d9da5060..27ef7f8e 100644 --- a/CosBase/examples/ex01/String.c +++ b/CosBase/examples/ex01/String.c @@ -39,7 +39,7 @@ defmethod(OBJ, ginitWithStr, String, (STR)str) self->str = str_dup(str); if (!self->str) THROW(ExBadAlloc); - + retmethod(_1); endmethod diff --git a/CosBase/examples/ex01/main.c b/CosBase/examples/ex01/main.c index 2e4a83e9..5bdc2bd2 100644 --- a/CosBase/examples/ex01/main.c +++ b/CosBase/examples/ex01/main.c @@ -30,7 +30,7 @@ int main(void) gprint(strm, str1); gprint(strm, str2); - + grelease(str1); grelease(str2); grelease(strm); diff --git a/CosStd/examples/ex01/Makefile b/CosStd/examples/ex01/Makefile index 6bc16e72..22c4150d 100644 --- a/CosStd/examples/ex01/Makefile +++ b/CosStd/examples/ex01/Makefile @@ -1,15 +1,15 @@ # # C Object System # COS example -# +# # Copyright 2007+ Laurent Deniau -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -32,7 +32,7 @@ targets := release.run # debug.run # files & modules sources := *.c -defgens := +defgens := defprps := # project dependencies (as with -lname) diff --git a/CosStd/examples/ex01/main.c b/CosStd/examples/ex01/main.c index a44a732e..e11a0216 100644 --- a/CosStd/examples/ex01/main.c +++ b/CosStd/examples/ex01/main.c @@ -59,11 +59,11 @@ sum_rep(I32 n) grelease(pool); F64 t3 = clock(); - printf("count [n] = %d [%d]\n" , x, n); - printf("time init = %.2f sec\n", (t1-t0)/CLOCKS_PER_SEC); - printf("time eval = %.2f sec\n", (t2-t1)/CLOCKS_PER_SEC); - printf("time fini = %.2f sec\n", (t3-t2)/CLOCKS_PER_SEC); - printf("time all = %.2f sec\n", (t3-t0)/CLOCKS_PER_SEC); + printf("count [n] = %d [%d]\n" , x, n); + printf("time init = %.2f sec\n", (t1-t0)/CLOCKS_PER_SEC); + printf("time eval = %.2f sec\n", (t2-t1)/CLOCKS_PER_SEC); + printf("time fini = %.2f sec\n", (t3-t2)/CLOCKS_PER_SEC); + printf("time all = %.2f sec\n", (t3-t0)/CLOCKS_PER_SEC); } static void @@ -81,17 +81,17 @@ sum_itr(I32 n) grelease(pool); F64 t3 = clock(); - printf("count [n] = %d [%d]\n" , x, n); - printf("time init = %.2f sec\n", (t1-t0)/CLOCKS_PER_SEC); - printf("time eval = %.2f sec\n", (t2-t1)/CLOCKS_PER_SEC); - printf("time fini = %.2f sec\n", (t3-t2)/CLOCKS_PER_SEC); - printf("time all = %.2f sec\n", (t3-t0)/CLOCKS_PER_SEC); + printf("count [n] = %d [%d]\n" , x, n); + printf("time init = %.2f sec\n", (t1-t0)/CLOCKS_PER_SEC); + printf("time eval = %.2f sec\n", (t2-t1)/CLOCKS_PER_SEC); + printf("time fini = %.2f sec\n", (t3-t2)/CLOCKS_PER_SEC); + printf("time all = %.2f sec\n", (t3-t0)/CLOCKS_PER_SEC); } static void sum_oop(I32 n) { - printf("*** object-oriented sum (repeat + foldl)\n"); + printf("*** object-oriented sum (repeat + foldl)\n"); OBJ pool = gnew(AutoRelease); OBJ ini = gautoRelease(aInt(1)); @@ -103,11 +103,11 @@ sum_oop(I32 n) grelease(pool); F64 t3 = clock(); - printf("count [n] = %d [%d]\n" , x, n); - printf("time init = %.2f sec\n", (t1-t0)/CLOCKS_PER_SEC); - printf("time eval = %.2f sec\n", (t2-t1)/CLOCKS_PER_SEC); - printf("time fini = %.2f sec\n", (t3-t2)/CLOCKS_PER_SEC); - printf("time all = %.2f sec\n", (t3-t0)/CLOCKS_PER_SEC); + printf("count [n] = %d [%d]\n" , x, n); + printf("time init = %.2f sec\n", (t1-t0)/CLOCKS_PER_SEC); + printf("time eval = %.2f sec\n", (t2-t1)/CLOCKS_PER_SEC); + printf("time fini = %.2f sec\n", (t3-t2)/CLOCKS_PER_SEC); + printf("time all = %.2f sec\n", (t3-t0)/CLOCKS_PER_SEC); } int main(int argc, char *argv[]) From f4645cdb0740ce5a3fa63d6d192e414e081daf36 Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Tue, 3 Jan 2023 19:05:03 +0100 Subject: [PATCH 16/23] fix warning --- CosBase/include/cos/cos/cosapi.h | 108 +++++++++++++++---------------- CosBase/src/cos_symbol.c | 6 +- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/CosBase/include/cos/cos/cosapi.h b/CosBase/include/cos/cos/cosapi.h index db0ee275..4016b6e9 100644 --- a/CosBase/include/cos/cos/cosapi.h +++ b/CosBase/include/cos/cos/cosapi.h @@ -41,67 +41,67 @@ struct Class* cos_class_get(U32); struct Class* cos_class_getWithStr(STR); struct Class* cos_property_getWithStr(STR); -BOOL cos_class_isSubclassOf (const struct Class*, const struct Class*); -U32 cos_class_readProperties (const struct Class*,U32,const struct Class**,U32); -U32 cos_class_writeProperties(const struct Class*,U32,const struct Class**,U32); - -IMP1 cos_method_get1(SEL,U32); -IMP2 cos_method_get2(SEL,U32,U32); -IMP3 cos_method_get3(SEL,U32,U32,U32); -IMP4 cos_method_get4(SEL,U32,U32,U32,U32); -IMP5 cos_method_get5(SEL,U32,U32,U32,U32,U32); -IMP1 cos_method_lookup1(SEL,U32); -IMP2 cos_method_lookup2(SEL,U32,U32); -IMP3 cos_method_lookup3(SEL,U32,U32,U32); -IMP4 cos_method_lookup4(SEL,U32,U32,U32,U32); -IMP5 cos_method_lookup5(SEL,U32,U32,U32,U32,U32); +BOOL cos_class_isSubclassOf (const struct Class*, const struct Class*); +U32 cos_class_readProperties (const struct Class*,U32,const struct Class**,U32); +U32 cos_class_writeProperties(const struct Class*,U32,const struct Class**,U32); + +IMP1 cos_method_get1(SEL,U32); +IMP2 cos_method_get2(SEL,U32,U32); +IMP3 cos_method_get3(SEL,U32,U32,U32); +IMP4 cos_method_get4(SEL,U32,U32,U32,U32); +IMP5 cos_method_get5(SEL,U32,U32,U32,U32,U32); +IMP1 cos_method_lookup1(SEL,U32); +IMP2 cos_method_lookup2(SEL,U32,U32); +IMP3 cos_method_lookup3(SEL,U32,U32,U32); +IMP4 cos_method_lookup4(SEL,U32,U32,U32,U32); +IMP5 cos_method_lookup5(SEL,U32,U32,U32,U32,U32); /* inlined functions (see cos/cos/dispatch.h) -IMP1 cos_method_fastLookup1(SEL,U32); -IMP2 cos_method_fastLookup2(SEL,U32,U32); -IMP3 cos_method_fastLookup3(SEL,U32,U32,U32); -IMP4 cos_method_fastLookup4(SEL,U32,U32,U32,U32); -IMP5 cos_method_fastLookup5(SEL,U32,U32,U32,U32,U32); -BOOL cos_method_understand1(SEL,U32); -BOOL cos_method_understand2(SEL,U32,U32); -BOOL cos_method_understand3(SEL,U32,U32,U32); -BOOL cos_method_understand4(SEL,U32,U32,U32,U32); -BOOL cos_method_understand5(SEL,U32,U32,U32,U32,U32); +IMP1 cos_method_fastLookup1(SEL,U32); +IMP2 cos_method_fastLookup2(SEL,U32,U32); +IMP3 cos_method_fastLookup3(SEL,U32,U32,U32); +IMP4 cos_method_fastLookup4(SEL,U32,U32,U32,U32); +IMP5 cos_method_fastLookup5(SEL,U32,U32,U32,U32,U32); +BOOL cos_method_understand1(SEL,U32); +BOOL cos_method_understand2(SEL,U32,U32); +BOOL cos_method_understand3(SEL,U32,U32,U32); +BOOL cos_method_understand4(SEL,U32,U32,U32,U32); +BOOL cos_method_understand5(SEL,U32,U32,U32,U32,U32); */ -char* cos_method_name(const struct Method*,char*,U32); -char* cos_method_call(SEL,OBJ*,char*,U32); -char* cos_method_callName(const struct Method*,OBJ*,char*,U32); -void (*cos_method_trace)(STR,int,BOOL,const struct Method*,OBJ*); -void cos_method_clearCache1(void); -void cos_method_clearCache2(void); -void cos_method_clearCache3(void); -void cos_method_clearCache4(void); -void cos_method_clearCache5(void); -void cos_method_clearCaches(void); - -void cos_contract_invariant1(OBJ,STR,int); -void cos_contract_invariant2(OBJ,OBJ,STR,int); -void cos_contract_invariant3(OBJ,OBJ,OBJ,STR,int); -void cos_contract_invariant4(OBJ,OBJ,OBJ,OBJ,STR,int); -void cos_contract_invariant5(OBJ,OBJ,OBJ,OBJ,OBJ,STR,int); -int cos_contract_setLevel (int lvl); // return previous level - -void cos_exception_assert (STR,STR,int) __attribute__((__noreturn__)); -void cos_exception_errno (int,STR,int) __attribute__((__noreturn__)); -void cos_exception_badcast(OBJ,const struct Class*,STR,int) +char* cos_method_name(const struct Method*,char*,U32); +char* cos_method_call(SEL,OBJ*,char*,U32); +char* cos_method_callName(const struct Method*,OBJ*,char*,U32); +void cos_method_trace(STR,int,BOOL,const struct Method*,OBJ*); +void cos_method_clearCache1(void); +void cos_method_clearCache2(void); +void cos_method_clearCache3(void); +void cos_method_clearCache4(void); +void cos_method_clearCache5(void); +void cos_method_clearCaches(void); + +void cos_contract_invariant1(OBJ,STR,int); +void cos_contract_invariant2(OBJ,OBJ,STR,int); +void cos_contract_invariant3(OBJ,OBJ,OBJ,STR,int); +void cos_contract_invariant4(OBJ,OBJ,OBJ,OBJ,STR,int); +void cos_contract_invariant5(OBJ,OBJ,OBJ,OBJ,OBJ,STR,int); +int cos_contract_setLevel (int lvl); // return previous level + +void cos_exception_assert (STR,STR,int) __attribute__((__noreturn__)); +void cos_exception_errno (int,STR,int) __attribute__((__noreturn__)); +void cos_exception_badcast(OBJ,const struct Class*,STR,int) __attribute__((__noreturn__)); -void cos_exception_throw (OBJ,STR,int) __attribute__((__noreturn__)); -BOOL cos_exception_catch (OBJ,OBJ); -BOOL cos_exception_uncaught(void); -void cos_exception_initContext(struct cos_exception_context*); -void cos_exception_deinitContext(struct cos_exception_context*); +void cos_exception_throw (OBJ,STR,int) __attribute__((__noreturn__)); +BOOL cos_exception_catch (OBJ,OBJ); +BOOL cos_exception_uncaught(void); +void cos_exception_initContext(struct cos_exception_context*); +void cos_exception_deinitContext(struct cos_exception_context*); cos_exception_handler cos_exception_setTerminate(cos_exception_handler); -void cos_functor_overflow(void); -void cos_functor_underflow(void) __attribute__((__noreturn__)); -void cos_functor_clearContext(void); +void cos_functor_overflow(void); +void cos_functor_underflow(void) __attribute__((__noreturn__)); +void cos_functor_clearContext(void); -void cos_module_load(STR*); // null terminated array of module names +void cos_module_load(STR*); // null terminated array of module names /* NOTE-INFO: loggers - prototype: void cos_xxx(STR fmt, ...); diff --git a/CosBase/src/cos_symbol.c b/CosBase/src/cos_symbol.c index 4c3483a3..9f749989 100644 --- a/CosBase/src/cos_symbol.c +++ b/CosBase/src/cos_symbol.c @@ -1536,8 +1536,8 @@ cos_method_callName(const struct Method *mth, OBJ obj[], char *str, U32 sz) return str; } -static void -mth_trace(STR file, int line, BOOL enter, const struct Method *mth, OBJ *obj) +void +cos_method_trace(STR file, int line, BOOL enter, const struct Method *mth, OBJ *obj) { char buf[256]; @@ -1547,8 +1547,6 @@ mth_trace(STR file, int line, BOOL enter, const struct Method *mth, OBJ *obj) cos_logmsg(COS_LOGMSG_TRALL,file,line,"<- %s",cos_method_name (mth, buf,sizeof buf)); } -void (*cos_method_trace)(STR,int,BOOL,const struct Method*,OBJ*) = mth_trace; - void cos_symbol_showSummary(FILE *fp) { From 4da2a40e82cee3f84d4a0910979c319d3f1099c0 Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Wed, 4 Jan 2023 15:28:04 +0100 Subject: [PATCH 17/23] fix justified warning about dangling pointer to temporary --- CosStd/include/cos/Slice.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CosStd/include/cos/Slice.h b/CosStd/include/cos/Slice.h index 7874d4cd..d0d6a140 100644 --- a/CosStd/include/cos/Slice.h +++ b/CosStd/include/cos/Slice.h @@ -184,10 +184,11 @@ Slice_addTo(struct Slice *s1, const struct Slice *s2) { static cos_inline struct Slice* Slice_fromRange(struct Slice *s, const struct Range *r, const U32 *size) { - if (size) // ask for normalization - r = Range_normalize(Range_copy(atRange(0), r), *size); + struct Range *r2 = Range_copy(atRange(0), r); - return Slice_init(s, Range_start(r), Range_size(r), Range_stride(r)); + if (size) r2 = Range_normalize(r2, *size); // ask for normalization + + return Slice_init(s, Range_start(r2), Range_size(r2), Range_stride(r2)); } #endif // COS_SLICE_H From 0b17359e7ea855f5b5891fc1c0fbd242a604b7ed Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Wed, 4 Jan 2023 17:45:16 +0100 Subject: [PATCH 18/23] fix warnings, new COS allocator frontend --- CHANGELOG | 4 +- CREDITS | 2 +- CosBase/examples/README | 5 +- CosBase/examples/ex01/String.c | 6 +- CosBase/examples/ex01/main.c | 9 +- CosBase/include/cos/cos/cosmem.h | 276 +++++-------------------------- CosBase/src/Any.c | 6 +- CosBase/src/Exception.c | 4 +- CosBase/src/cos_memory.c | 272 ++++++++++++++++++++++++------ CosBase/tests/src/st_methods.c | 8 +- INSTALL | 7 +- Makefile | 2 +- 12 files changed, 298 insertions(+), 303 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9f757252..8170eb90 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,7 +7,7 @@ # | # | C Object System # | -# | Copyright (c) 2007+ Laurent Deniau, laurent.deniau@cern.ch +# | Copyright (c) 2007+ Laurent Deniau, laurent.deniau@gmail.com # | # | For more information, see: # | http://cern.ch/laurent.deniau/cos.html @@ -37,6 +37,8 @@ - docstring system finished and based on Sphinx (Python) for the html/pdf output. - documentation is ongoing + - moved to GitHub + - License moved to Apache ** 0.9 [2009-2010] - "Any" class resurrected. Useful to factorize some "Core" message. No diff --git a/CREDITS b/CREDITS index 1439c91c..7b928103 100644 --- a/CREDITS +++ b/CREDITS @@ -1,5 +1,5 @@ Authors: -Laurent Deniau -- laurent.deniau@cern.ch +Laurent Deniau -- laurent dot deniau at gmail dot com Contributors: Any help is welcome. diff --git a/CosBase/examples/README b/CosBase/examples/README index 6f9cb2a5..fd481dce 100644 --- a/CosBase/examples/README +++ b/CosBase/examples/README @@ -55,7 +55,6 @@ TRACE will show the value of important variables Project information: -------------------- - - web page: http:/cern.ch/laurent.deniau/cos.html - - web site: http:/sf.net/projects/cos - - contact : laurent.deniau@cern.ch + - web site: https://github.com/CObjectSystem/COS + - contact : laurent dot deniau at gmail dot com diff --git a/CosBase/examples/ex01/String.c b/CosBase/examples/ex01/String.c index 27ef7f8e..ca894f85 100644 --- a/CosBase/examples/ex01/String.c +++ b/CosBase/examples/ex01/String.c @@ -20,15 +20,15 @@ #include "String.h" #include "generics.h" -#include #include +#include makclass(String); static char* str_dup(STR str) { size_t len = strlen(str); - char *s = malloc(len+1); + char *s = cos_malloc(len+1); if (s) memcpy(s, str, len+1); return s; } @@ -44,7 +44,7 @@ defmethod(OBJ, ginitWithStr, String, (STR)str) endmethod defmethod(OBJ, gdeinit, String) - free(self->str), self->str = 0; + cos_free(self->str), self->str = 0; retmethod(_1); endmethod diff --git a/CosBase/examples/ex01/main.c b/CosBase/examples/ex01/main.c index 5bdc2bd2..d073b155 100644 --- a/CosBase/examples/ex01/main.c +++ b/CosBase/examples/ex01/main.c @@ -17,14 +17,21 @@ * limitations under the License. */ + +/* NOTE-USER: to load the shared libraries + linux: export LD_LIBRARY_PATH="path-to/CosBase/Darwin/lib/" + macos: export DYLD_LIBRARY_PATH="path-to/CosBase/Darwin/lib/" +*/ + #include "generics.h" + #include useclass(Stream, String); int main(void) { - OBJ strm = gnewWithStr(Stream, 0); + OBJ strm = gnewWithStr(Stream, NULL); OBJ str1 = gnewWithStr(String, "string one\n"); OBJ str2 = gnewWithStr(String, "string two\n"); diff --git a/CosBase/include/cos/cos/cosmem.h b/CosBase/include/cos/cos/cosmem.h index 85c582f3..1dd21629 100644 --- a/CosBase/include/cos/cos/cosmem.h +++ b/CosBase/include/cos/cos/cosmem.h @@ -35,266 +35,76 @@ Information: - parameters ending with an underscope can be null. - - cos_mem_free does not free the memory, it just returns it to the pool. - - cos_mem_xxx_n are ~50% faster, but objects must have the SAME cos_mem_size. - - cos_mem_alloc_n returns the number of objects effectively allocated. + - cos_free does not free the memory, it just returns it to the pool. - cos_mem_collect does free the unused memory of the thread specific pool. - - cos_mem_collect and cos_mem_unused can be called for a specific cos_mem_size. Errors: - - cos_mem_free_n on objects of different cos_mem_size is undefined. - - cos_mem_free[_n] on objects not allocated by cos_mem_alloc[_n] is undefined. + - cos_free on objects not allocated by cos_malloc is undefined. Compilation: - - set cos_mem_AS_DEFAULT to 1 to activate it for the standard allocator. + - set COS_MEM_STD to 1 to use the standard C allocator instead. */ -// --- interface -------------------------------------------------------------- +#include -// allocator -static void* cos_mem_alloc (size_t size); -static void* cos_mem_calloc (size_t count, size_t size); -static void* cos_mem_realloc (void *ptr_, size_t new_size); -static void cos_mem_free (void *ptr_); -static size_t cos_mem_size (void *ptr_); +// --- interface --------------------------------------------------------------- + +// local buffer (macros) +#define cos_alloc_tmp(type,name,nslot) +#define cos_free_tmp( name) -// allocator, array versions -static int cos_mem_alloc_n (void *ptr_[], int n, size_t size); -static void cos_mem_free_n (void *ptr_[], int n); +// allocator +void* cos_malloc (size_t size); +void* cos_calloc (size_t count, size_t size); +void* cos_realloc (void *ptr_ , size_t size_); +void cos_free (void *ptr_); -// tuning -extern size_t cos_mem_unused (int *count_, size_t *only_); -extern size_t cos_mem_collect (int *percent_, size_t *only_); +// utils +size_t cos_mem_collect (void); +size_t cos_mem_cached (void); +void cos_mem_mdump (FILE*); // --- configuration ----------------------------------------------------------- -// set COS_MEM_AS_DEFAULT to 1 to activate this front-end for the standard allocator. -#ifndef COS_MEM_AS_DEFAULT -#define COS_MEM_AS_DEFAULT 1 +// set COS_MEM_STD to 1 to use the standard C allocator instead. +#ifndef COS_MEM_STD +#define COS_MEM_STD 0 #endif // --- inline implementation --------------------------------------------------- -#include -#include - -// memory node -union cos_mem_node_ { - struct { - union cos_mem_node_ *next; - } free; - - struct { - unsigned slot; - union { - long n, *np; - size_t s, *sp; - double d, *dp; - void (*fp)(void); - } data[1]; - } used; -}; +#undef cos_alloc_tmp +#define cos_alloc_tmp(T,NAME,N) \ + T NAME##_local_tmp__[sizeof(T)*(N) < 8192 ? (N) : 1]; \ + T *NAME = (sizeof(T)*(N) < 8192 ? \ + NAME##_local_tmp__ : cos_malloc(sizeof(T)*(N)) ) -struct cos_mem_slot_ { - union cos_mem_node_ *list; -}; +#undef cos_free_tmp +#define cos_free_tmp(NAME) \ + (NAME != NAME##_local_tmp__ ? cos_free(NAME) : (void)0) -// pool size -enum { - cos_mem_node_size_ = offsetof(union cos_mem_node_, used.data), - cos_mem_slot_size_ = sizeof(struct cos_mem_slot_), - cos_mem_slot_max_ = (1<<16)/cos_mem_slot_size_, // max pool size: ~64kB/thread -}; +// --- global redefinition ----------------------------------------------------- -// memory pool -struct cos_mem_pool_ { - size_t size; - struct cos_mem_slot_ slot[cos_mem_slot_max_]; -}; +#if COS_MEM_STD -// pool (per thread) -extern struct cos_mem_pool_ cos_mem_pool_; -// max unused memory (per thread), default ~32MB -extern size_t cos_mem_pool_max_; +#define cos_malloc( sz ) malloc (sz) +#define cos_calloc( cnt , sz ) calloc (cnt , sz ) +#define cos_realloc(ptr_, sz_) realloc(ptr_, sz_) +#define cos_free( ptr_ ) free (ptr_) -#ifdef _OPENMP -#pragma omp threadprivate (cos_mem_pool_) -#endif - -#if !defined(__GNUC__) && !defined(__attribute__) -#define __attribute__(a) -#endif +#define cos_mem_collect() 0 +#define cos_mem_cached() 0 +#define cos_mem_mdump(f) -#ifdef __cplusplus -# define restrict -# define ATT __attribute__((always_inline)) inline #else -# define ATT __attribute__((always_inline)) static inline -#endif - -// -- utils - -ATT __attribute__((pure)) -union cos_mem_node_* cos_mem_get_base_ (void *ptr) -{ - return (union cos_mem_node_*)((char*)ptr - cos_mem_node_size_); -} - -ATT __attribute__((pure)) -unsigned cos_mem_get_slot_ (size_t size) -{ - return (size + cos_mem_node_size_-1) / cos_mem_node_size_; -} - -ATT __attribute__((pure)) -void* cos_mem_node_init_ (union cos_mem_node_ *ptr, unsigned slot) -{ - ptr->used.slot = slot; - return ptr->used.data; -} - -// -- allocator - -ATT __attribute__((malloc)) -void* cos_mem_alloc (size_t size) -{ - unsigned slot = cos_mem_get_slot_(size); - struct cos_mem_pool_ *restrict pool = &cos_mem_pool_; - struct cos_mem_slot_ *restrict pptr = pool->slot+slot; - union cos_mem_node_ *ptr; - - if (slot < cos_mem_slot_max_ && pptr->list) { - pool->size -= slot*cos_mem_node_size_; - ptr = pptr->list, pptr->list = ptr->free.next; - } - else { - if (pool->size > cos_mem_pool_max_) cos_mem_collect(0,0); - ptr = (union cos_mem_node_*)malloc((slot+1) * cos_mem_node_size_); - if (!ptr) return 0; - } - return cos_mem_node_init_(ptr, slot); -} - -ATT __attribute__((malloc)) -void* cos_mem_calloc (size_t count, size_t size) -{ - size_t sz = count*size; - assert(count < 2 || size < 2 || (sz > count && sz > size)); - - void *ptr = cos_mem_alloc(sz); - if (ptr) memset(ptr, 0, sz); - - return ptr; -} - -ATT __attribute__((malloc)) -void* cos_mem_realloc (void* ptr_, size_t size) -{ - unsigned slot = cos_mem_get_slot_(size); - union cos_mem_node_ *ptr = ptr_ ? cos_mem_get_base_(ptr_) : (union cos_mem_node_*)ptr_; - ptr = (union cos_mem_node_*)realloc(ptr, (slot+1) * cos_mem_node_size_); - if (!ptr) return 0; - - ptr->used.slot = slot; - return ptr->used.data; -} - -ATT -void cos_mem_free (void* ptr_) -{ - if (!ptr_) return; - - union cos_mem_node_ *ptr = cos_mem_get_base_(ptr_); - unsigned slot = ptr->used.slot; - - if (slot < cos_mem_slot_max_) { - struct cos_mem_pool_ *restrict pool = &cos_mem_pool_; - struct cos_mem_slot_ *restrict pptr = pool->slot+slot; - pool->size += slot*cos_mem_node_size_; - ptr->free.next = pptr->list, pptr->list = ptr; - } - else free(ptr); -} - -// -- allocator, array versions - -ATT -int cos_mem_alloc_n (void* ptr_[], int n, size_t size) -{ - unsigned slot = cos_mem_get_slot_(size); - union cos_mem_node_ *ptr; - int i = 0; - - if (slot < cos_mem_slot_max_) { - struct cos_mem_pool_ *restrict pool = &cos_mem_pool_; - struct cos_mem_slot_ *restrict pptr = pool->slot+slot; - - for (; i < n && pptr->list; i++) { - ptr = pptr->list, pptr->list = ptr->free.next; - ptr_[i] = cos_mem_node_init_(ptr, slot); - } - - pool->size -= i*slot*cos_mem_node_size_; - if (i < n && pool->size > cos_mem_pool_max_) cos_mem_collect(0,0); - - for (; i < n; i++) { - ptr = (union cos_mem_node_*)malloc((slot+1) * cos_mem_node_size_); - if (ptr) ptr_[i] = cos_mem_node_init_(ptr, slot); - else break; - } - } else { - for (; i < n; i++) { - ptr = (union cos_mem_node_*)malloc((slot+1) * cos_mem_node_size_); - if (ptr) ptr_[i] = cos_mem_node_init_(ptr, slot); - else break; - } - } - return i; -} - -ATT -void cos_mem_free_n (void* ptr_[], int n) -{ - if (n > 0) { - unsigned slot = cos_mem_get_base_(ptr_[n-1])->used.slot; - - if (slot < cos_mem_slot_max_) { - struct cos_mem_pool_ *restrict pool = &cos_mem_pool_; - struct cos_mem_slot_ *restrict pptr = pool->slot+slot; - int i = n; - - while (n--) { - union cos_mem_node_ *ptr = cos_mem_get_base_(ptr_[n]); - ptr->free.next = pptr->list, pptr->list = ptr; - } - pool->size += i*slot*cos_mem_node_size_; - } - else - while (n--) free(cos_mem_get_base_(ptr_[n])); - } -} - -// -- tuning - -ATT __attribute__((pure)) -size_t cos_mem_size (void* ptr_) -{ - return ptr_ ? cos_mem_get_base_(ptr_)->used.slot * cos_mem_node_size_ : 0; -} - -#undef ATT - -// --- global redefinition ---------------------------------------------------- - -#if COS_MEM_AS_DEFAULT -#define malloc(size) cos_mem_alloc(size) -#define calloc(count,size) cos_mem_calloc(count,size) -#define realloc(ptr,size) cos_mem_realloc(ptr,size) -#define free(ptr) cos_mem_free(ptr) +void* cos_malloc (size_t) __attribute__((hot,malloc(cos_free,1),malloc,returns_nonnull)); +void* cos_calloc (size_t,size_t) __attribute__((hot,malloc(cos_free,1),malloc,returns_nonnull)); +void* cos_realloc(void* ,size_t) __attribute__((hot,malloc(cos_free,1))); +void cos_free (void* ) __attribute__((hot)); #endif -// ---------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- #endif // COS_COS_COSMEM_H diff --git a/CosBase/src/Any.c b/CosBase/src/Any.c index 5b62c1a2..7d38b1a4 100644 --- a/CosBase/src/Any.c +++ b/CosBase/src/Any.c @@ -42,7 +42,7 @@ endmethod // ----- allocator defmethod(OBJ, galloc, mAny) - struct Any *obj = malloc(self->isz); + struct Any *obj = cos_malloc(self->isz); if (!obj) THROW(ExBadAlloc); // throw the class (no allocation) @@ -60,7 +60,7 @@ defmethod(OBJ, gallocWithSize, mAny, (size_t)extra) if (size - extra != self->isz) THROW(gnewWithStr(ExOverflow, "extra size is too large")); - if (!(obj = malloc(size))) + if (!(obj = cos_malloc(size))) THROW(ExBadAlloc); // throw the class (no allocation) obj->_id = cos_class_id(self); @@ -72,7 +72,7 @@ endmethod // ----- deallocator defmethod(void, gdealloc, Any) - free(_1); + cos_free(_1); endmethod // ----- clone diff --git a/CosBase/src/Exception.c b/CosBase/src/Exception.c index 9c059465..cfe804e3 100644 --- a/CosBase/src/Exception.c +++ b/CosBase/src/Exception.c @@ -62,7 +62,7 @@ str_dup(STR str) { useclass(ExBadAlloc); - char *cpy = malloc(strlen(str)+1); + char *cpy = cos_malloc(strlen(str)+1); if (!cpy) THROW(ExBadAlloc); return strcpy(cpy, str); } @@ -93,7 +93,7 @@ endmethod defmethod(OBJ, gdeinit, Exception) if (self->str) - free(self->str), self->str = 0; + cos_free(self->str), self->str = 0; if (self->obj) grelease(self->obj), self->obj = 0; diff --git a/CosBase/src/cos_memory.c b/CosBase/src/cos_memory.c index 5b1c3230..c33a0c0d 100644 --- a/CosBase/src/cos_memory.c +++ b/CosBase/src/cos_memory.c @@ -17,78 +17,256 @@ * limitations under the License. */ -// --- declarations ----------------------------------------------------------- +// --- declarations ------------------------------------------------------------ #include -// --- definitions ------------------------------------------------------------ +#include +#include +#include +#include +#include -struct cos_mem_pool_ cos_mem_pool_; -size_t cos_mem_pool_max_ = 1<<25; +#define COS_MEM_UTEST 0 // 1 -> run standalone unit tests in main(). +#define DBGMEM(P) // P // uncomment for verbose debugging output +// --- types & constants ------------------------------------------------------- + +// constant sizes enum { - static_assert__node_size_must_be_a_power_of_2 - = 1/!(cos_mem_node_size_&(cos_mem_node_size_-1)) + stp_slot = sizeof(double), // memblk unit of size increment, don't touch + max_slot = 8192, // max 2^16-2, default 8192 slots -> max obj size is 64KB + max_mblk = 2048, // max 2^16-2, default 2048 slots + max_mkch = 2097152, // max 2^32-1, default 2097152 stp_slot -> 16MB +}; + +// memory block +struct memblk { + uint16_t slot; // slot index (i.e. rounded size). + uint16_t next; // index of next memblk (i.e. linked list). + uint32_t mark; // memory boundary marker + union { // alignment of data + ptrdiff_t s, *sp; + size_t u, *up; + double d, *dp; + void *vp; + void (*fp)(void); + } data[1]; }; -size_t __attribute__ ((noinline)) -cos_mem_unused (int *count_, size_t *only_) +// memory pool +struct pool { + uint32_t mkch; // amount of cached memory in stp_slot unit + uint16_t free; // index of first free slot in mblk + uint16_t _dum; // for alignment + uint16_t slot[max_slot]; // index+1 in mblk of first mbp for this size + union { + size_t nxt; // index in mblk of next free slot + struct memblk *mbp; + } mblk[max_mblk]; + char str[128]; // for debug, see pdump() +}; + +// macros +#define BASE(ptr) ((void*)((char*)(ptr)-stp_slot)) // ptr -> mbp +#define SIZE(idx) (((size_t)(idx)+2)*stp_slot) // sizeof(*mbp) +#define CACHED(p) ((size_t)(p)->mkch*stp_slot) +#define IDXMAX 0xFFFF +#define SLTMAX 0xFFFFFFFF +#define MARK 0xACCEDEAD + +// static sanity checks +enum { +//static_assert__max_slot_not_a_power_of_2 = 1/!(max_slot & (max_slot-1)), +//static_assert__max_mblk_not_a_power_of_2 = 1/!(max_mblk & (max_mblk-1)), +//static_assert__max_mkch_not_a_power_of_2 = 1/!(max_mkch & (max_mkch-1)), + static_assert__stp_slot_not_a_power_of_2 = 1/!(stp_slot & (stp_slot-1)), + static_assert__max_slot_not_lt_IDXMAX = 1/ (max_slot < IDXMAX), + static_assert__max_mblk_not_lt_IDXMAX = 1/ (max_mblk < IDXMAX), + static_assert__max_mkch_not_lt_SLTMAX = 1/ (max_mkch < SLTMAX), + static_assert__stp_slot_neq_sizeof = 1/ (stp_slot == sizeof(double)), + static_assert__stp_slot_neq_offsetof = 1/ (stp_slot == offsetof(struct memblk,data)), +}; + +// --- locals ------------------------------------------------------------------ + +typedef int32_t idx_t; + +static struct pool pool = {0,0,0,{0},{{0}},{0}}; + +#ifdef _OPENMP +#pragma omp threadprivate(pool) +#endif + +static inline char* +pdump(struct memblk *mbp) { - if (!count_ && !only_) return cos_mem_pool_.size; + struct pool *p = &pool; + snprintf(p->str, sizeof(p->str), "%p {slot=%4d(%5td), next=%4d, mark=%x}%s", + (void*)mbp, mbp->slot, + mbp->slot == IDXMAX ? -1 : (ptrdiff_t)SIZE(mbp->slot), + mbp->next-1, mbp->mark, mbp->mark == MARK ? "" : " (corrupted!)"); + return p->str; +} + +// --- implementation ---------------------------------------------------------o + +void* +(cos_malloc) (size_t size) +{ + struct pool *p = &pool; + size_t idx = size ? (size-1) / stp_slot : 0; + struct memblk *mbp; // mbp = mblk[slot[idx]-1] - int start = only_ ? cos_mem_get_slot_(*only_) : 0; - int end = only_ ? start+1 : cos_mem_slot_max_; + if (idx < max_slot && p->slot[idx]) { + idx_t slt = p->slot[idx]-1; + DBGMEM( printf("alloc: reuse mblk[[%d]=%d]", (int)idx, slt); ) + mbp = p->mblk[slt].mbp, p->mblk[slt].nxt = p->free; + p->free = p->slot[idx], p->slot[idx] = mbp->next; + p->mkch -= idx+2; + } else { + DBGMEM( printf("alloc: malloc(%2zu)", size); ) + mbp = malloc(SIZE(idx)); + mbp->slot = idx < max_slot ? idx : IDXMAX; + mbp->mark = MARK; + ensure((size_t)mbp > IDXMAX, "unexpected very low address"); // see collect + } - // sanity checks - assert(start < cos_mem_slot_max_); + DBGMEM( printf(" at %s\n", pdump(mbp)); ) + return mbp->data; +} - struct cos_mem_pool_ *restrict pool = &cos_mem_pool_; - struct cos_mem_slot_ *restrict pptr = pool->slot+start; - size_t size = 0; - int count = 0; +void +(cos_free) (void *ptr) +{ + if (!ptr) return; - for (int slot=start; slotslot; - for (union cos_mem_node_ *ptr=pptr->list; ptr; cnt++) - ptr = ptr->free.next; + ensure(mbp->mark == MARK, "invalid or corrupted allocated memory"); - size += slot * cnt * cos_mem_node_size_; - count += cnt; + if (idx == IDXMAX) { + DBGMEM( printf("free : free mblk at %s\n", pdump(mbp)); ) + free(mbp); return; } - if (count_) *count_ = count; - return size; + struct pool *p = &pool; + if (!p->free || p->mkch >= max_mkch) // no free slot (or init) or max cache + cos_mem_collect(); + + idx_t slt = p->free-1; + DBGMEM( printf("free : cache mblk[[%d]=%d]", idx, slt); ) + mbp->next = p->slot[idx], p->slot[idx] = p->free; // update slot + p->free = p->mblk[slt].nxt, p->mblk[slt].mbp = mbp; // store mblk + p->mkch += idx+2; + + DBGMEM( printf(" at %s\n", pdump(mbp)); ) } -size_t __attribute__ ((noinline)) // avoid bug slowing code with openmp -cos_mem_collect (int *percent_, size_t *only_) +void* +(cos_calloc) (size_t ecount, size_t esize) { - int start = only_ ? cos_mem_get_slot_(*only_) : 0; - int end = only_ ? start : cos_mem_slot_max_-1; + size_t size = ecount * esize; + void *ptr = (cos_malloc)(size); + return memset(ptr, 0, size); +} - // sanity checks - assert(start < cos_mem_slot_max_); - assert(!percent_ || (*percent_ >= 0 && *percent_ <= 100)); +void* +(cos_realloc) (void *ptr, size_t size) +{ + if (!size) return (cos_free)(ptr), NULL; + if (!ptr ) return (cos_malloc)(size); - struct cos_mem_pool_ *restrict pool = &cos_mem_pool_; - struct cos_mem_slot_ *restrict pptr = pool->slot+end; - size_t threshold = percent_ && *percent_ < 100 ? pool->size/100.0 * *percent_ : pool->size; - size_t size = 0; + DBGMEM( printf("alloc: realloc(%2zu)", size); ) + struct memblk *mbp = BASE(ptr); - for (int slot=end; slot>=start; slot--, pptr--) { - int cnt = 0; + ensure(mbp->mark == MARK, "invalid or corrupted allocated memory"); - for (union cos_mem_node_ *nxt, *ptr=pptr->list; ptr; ptr=nxt, cnt++) { - nxt = ptr->free.next; - free(ptr); - } + size_t idx = (size-1) / stp_slot; + mbp = realloc(mbp, SIZE(idx)); + mbp->slot = idx < max_slot ? idx : IDXMAX; - pptr->list = 0; - size += slot * cnt * cos_mem_node_size_; - if (size >= threshold) break; + DBGMEM( printf(" at %s\n", pdump(mbp)); ) + return mbp->data; +} + +// -- utils + +size_t +cos_mem_cached (void) +{ + struct pool *p = &pool; + size_t ccached = 0, cached = CACHED(p); + + for (idx_t i=0; i < max_mblk; i++) + if (p->mblk[i].nxt > IDXMAX) // ptr + ccached += SIZE(p->mblk[i].mbp->slot); + + ensure(ccached == cached, "corrupted cache, ccached == cached bytes"); + + return cached; +} + +size_t +cos_mem_collect (void) +{ + struct pool *p = &pool; + size_t cached = CACHED(p); + + DBGMEM(printf("collect/clear/init cache\n");) + DBGMEM(printf("collecting %zu bytes\n", cos_mem_cached()); cos_mem_mdump();) + + p->mkch = 0; + p->free = 1; + + for (idx_t i=0; i < max_slot; i++) + p->slot[i] = 0; + + for (idx_t i=0; i < max_mblk; i++) { + if (p->mblk[i].nxt > IDXMAX) // ptr + free(p->mblk[i].mbp); + p->mblk[i].nxt = i+2; + } + p->mblk[max_mblk-1].nxt = 0; // close linked list + + DBGMEM( printf("status after collect\n"); cos_mem_mdump(); ) + return cached; +} + +// -- debug + +void +cos_mem_mdump (FILE *fp) +{ + struct pool *p = &pool; + + if (!fp) fp = stdout; + + fprintf(fp, "mdump: %zu bytes\n", CACHED(p)); + + // display content of slot[] when used, i.e. link to mblk[] + linked list. + for (idx_t i=0; i < max_slot; i++) { + idx_t slt = p->slot[i]; + if (slt) { // from slot (size) to memblk (object) + fprintf(fp, " slot[%4d] -> mblk[%d]", i, slt-1); + struct memblk *mbp = p->mblk[slt-1].mbp; + while (mbp->next) { // linked list + fprintf(fp, "->[%d]", mbp->next-1); + mbp = p->mblk[mbp->next-1].mbp; + } + fprintf(fp, "\n"); + } } - pool->size -= size; - return size; + // display content of mblk[], i.e. object or not trivial link into mblk[] + for (idx_t i=0; i < max_mblk; i++) + if (p->mblk[i].nxt > IDXMAX) // ptr + fprintf(fp, " mblk[%4d] -> %s\n", i, pdump(p->mblk[i].mbp)); + else if (i+1 == p->free) // free + fprintf(fp, "->mblk[%4d] -> [%d]\n", i, (int)p->mblk[i].nxt-1); + else if (i+2 != (int)p->mblk[i].nxt) // idx + fprintf(fp, " mblk[%4d] -> [%d]\n", i, (int)p->mblk[i].nxt-1); } + +// --- end --------------------------------------------------------------------- diff --git a/CosBase/tests/src/st_methods.c b/CosBase/tests/src/st_methods.c index c5aa5f61..1735e727 100644 --- a/CosBase/tests/src/st_methods.c +++ b/CosBase/tests/src/st_methods.c @@ -166,16 +166,16 @@ st_memory(void) // allocator warm up for (i = 0; i < P; i++) - arr[i++] = malloc(sz); + arr[i++] = cos_malloc(sz); for (i = 0; i < P; i++) - free(arr[i++]); + cos_free(arr[i++]); i = 0; - STEST( "malloc", P, arr[i++] = malloc(sz) ); + STEST( "malloc", P, arr[i++] = cos_malloc(sz) ); i = 0; - STEST( "free", P, free(arr[i++]) ); + STEST( "free", P, cos_free(arr[i++]) ); i = 0; STEST( "alloc + init", P, arr[i++] = ginit(galloc(Counter)) ); diff --git a/INSTALL b/INSTALL index 0b316e0f..d65ad7c9 100644 --- a/INSTALL +++ b/INSTALL @@ -53,7 +53,7 @@ Linux SLC 4.0, 5.0 (RedHat) on x86_64 (64-bit) Quad Xeon Mac OS X Leopard (Darwin) on x86_64 (64-bit) Core2 Duo # Compilers -gcc 3.2.3, 3.4.6, 4.1.2, 4.2.4, 4.3.2, 4.3.3, 7.2.0 +gcc 3.2.3, 3.4.6, 4.1.2, 4.2.4, 4.3.2, 4.3.3, 7.2.0, 12.2.0 Other available platforms (untested): ------------------------------------- @@ -74,7 +74,6 @@ or on arXiv.org Project information: -------------------- - - web page: http:/cern.ch/laurent.deniau/cos.html - - web site: http:/sf.net/projects/cos - - contact : laurent.deniau@cern.ch + - web site: https://github.com/CObjectSystem/COS + - contact : laurent dot deniau at gmail dot com diff --git a/Makefile b/Makefile index eaa98c07..53307eb0 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ # | # | C Object System # | -# | Copyright (c) 2007+ Laurent Deniau, laurent.deniau@cern.ch +# | Copyright (c) 2007+ Laurent Deniau, laurent.deniau@gmail.com # | # | For more information, see: # | http://cern.ch/laurent.deniau/cos.html From 85c6d5ba6d69c1bb969625399ae7ed0ece2362b3 Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Wed, 4 Jan 2023 18:12:25 +0100 Subject: [PATCH 19/23] update to new allocator --- CosStd/include/cos/carray.h | 71 ------------------------------------ CosStd/src/Array_alg.c | 20 +++++----- CosStd/src/Array_dyn.c | 10 ++--- CosStd/src/String_alg.c | 8 ++-- CosStd/src/String_dyn.c | 10 ++--- CosStd/src/tmpl/Vector.c | 2 - CosStd/src/tmpl/Vector_alg.c | 18 ++++----- CosStd/src/tmpl/Vector_dyn.c | 8 ++-- 8 files changed, 34 insertions(+), 113 deletions(-) delete mode 100644 CosStd/include/cos/carray.h diff --git a/CosStd/include/cos/carray.h b/CosStd/include/cos/carray.h deleted file mode 100644 index 18c60135..00000000 --- a/CosStd/include/cos/carray.h +++ /dev/null @@ -1,71 +0,0 @@ -// multiple inclusion allowed - -/** - * C Object System - * COS C Array, C array utils - * - * Copyright 2006+ Laurent Deniau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef COS_CARRAY_H -#define COS_CARRAY_H - -#include - -#include - -/* NOTE-INFO: low level C array - the array is allocated on the stack if its size <= CARRAY_LIMIT - otherwise it is allocated on the heap. - - { - CARRAY_CREATE(OBJ, buf, 1000); - - buf[100] = gnew(Object); - grelease(buf[100]); - - CARRAY_DESTROY(buf); - } -*/ - -#define CARRAY_CREATE(T,name,nelem) \ - CARRAY_CREATE_(T,name,nelem, \ - /* local pointer */ COS_PP_CAT(_cos_tmp_carray_p_,name), \ - /* local array */ COS_PP_CAT(_cos_tmp_carray_a_,name), \ - /* local size */ COS_PP_CAT(_cos_tmp_carray_s_,name)) - -#define CARRAY_CREATE_(T,name,N,P,A,S) \ - U32 S = N; T *P, \ - A[S*sizeof(T) <= CARRAY_LIMIT ? S : 0]; \ - if (S*sizeof(T) <= CARRAY_LIMIT) P = A; \ - else { \ - useclass(ExBadAlloc); \ - if ( !(P = malloc(S * sizeof(T))) ) THROW(ExBadAlloc); \ - } \ - T *const name = P - -#define CARRAY_DESTROY(name) \ - if (name != COS_PP_CAT(_cos_tmp_carray_a_,name)) \ - free(name) - -#endif // COS_CARRAY_H - -// can be redefined between inclusion -#ifndef CARRAY_LIMIT -#define CARRAY_LIMIT (1024 * sizeof(void*)) -#endif - -// multiple inclusion allowed - diff --git a/CosStd/src/Array_alg.c b/CosStd/src/Array_alg.c index 8cc6fc8f..e47bb4b7 100644 --- a/CosStd/src/Array_alg.c +++ b/CosStd/src/Array_alg.c @@ -32,8 +32,6 @@ #include #include -#include - #include "Array_utl.h" #include @@ -143,8 +141,8 @@ defmethod(OBJ, gpermute, Array, IntVector) I32 idx_s = self2->stride; I32 *idx = self2->value; - CARRAY_CREATE(OBJ,buf,size); // OBJ buf[size]; - CARRAY_CREATE(U8 ,flg,size); // U8 flg[size]; + cos_alloc_tmp(OBJ,buf,size); // OBJ buf[size]; + cos_alloc_tmp(U8 ,flg,size); // U8 flg[size]; memset(flg,1,size); @@ -164,8 +162,8 @@ defmethod(OBJ, gpermute, Array, IntVector) for (cur = buf; cur != end; cur++) *val = *cur, val += val_s; - CARRAY_DESTROY(buf); - CARRAY_DESTROY(flg); + cos_free_tmp(buf); + cos_free_tmp(flg); } else { // rollback (error) BOOL iiir = i < size; // last index-is-in-range flag @@ -176,8 +174,8 @@ defmethod(OBJ, gpermute, Array, IntVector) val[(ptrdiff_t)i*val_s] = *--cur; } - CARRAY_DESTROY(buf); - CARRAY_DESTROY(flg); + cos_free_tmp(buf); + cos_free_tmp(flg); ensure( iiir, "index out of range" ); ensure( 0, "invalid cyclic permutation" ); } @@ -488,7 +486,7 @@ endmethod static OBJ* KnuthMorrisPratt(OBJ *val, U32 val_n, I32 val_s, OBJ *pat, I32 pat_n, I32 pat_s) { - CARRAY_CREATE(I32,kmpNext,pat_n); + cos_alloc_tmp(I32,kmpNext,pat_n); { // preprocessing I32 i = 0, j = kmpNext[0] = -1; @@ -515,13 +513,13 @@ KnuthMorrisPratt(OBJ *val, U32 val_n, I32 val_s, OBJ *pat, I32 pat_n, I32 pat_s) i++; j++; if (i >= pat_n) { // found - CARRAY_DESTROY(kmpNext); + cos_free_tmp(kmpNext); return val + (j - i)*val_s; } } } - CARRAY_DESTROY(kmpNext); + cos_free_tmp(kmpNext); return 0; // not found } diff --git a/CosStd/src/Array_dyn.c b/CosStd/src/Array_dyn.c index 92d34768..74054b39 100644 --- a/CosStd/src/Array_dyn.c +++ b/CosStd/src/Array_dyn.c @@ -26,8 +26,6 @@ #include #include -#include - #include "Array_utl.h" #include @@ -53,7 +51,7 @@ defmethod(OBJ, gdeinit, ArrayFix) next_method(self); if (self->_object) { // take care of protection cases - free(self->_object); + cos_free(self->_object); self->Array.object = 0; self->_object = 0; } @@ -95,7 +93,7 @@ defmethod(OBJ, ginitWith, ArrayDyn, Int) THROW(gnewWithStr(ExOverflow, "capacity is too large")); } - arrf->_object = malloc(size); + arrf->_object = cos_malloc(size); if (!arrf->_object && size) THROW(ExBadAlloc); @@ -146,7 +144,7 @@ defmethod(OBJ, genlarge, ArrayDyn, Int) // negative size means enlarge front if (size/sizeof *arrf->_object < capacity) THROW(gnewWithStr(ExOverflow, "extra size is too large")); - OBJ *_object = realloc(arrf->_object, size); + OBJ *_object = cos_realloc(arrf->_object, size); if (!_object && size) THROW(ExBadAlloc); @@ -175,7 +173,7 @@ defmethod(OBJ, gadjust, ArrayDyn) // shrink storage if (arr->size != self->capacity) { - OBJ *_object = realloc(arrf->_object, size); + OBJ *_object = cos_realloc(arrf->_object, size); if (!_object && size) THROW(ExBadAlloc); diff --git a/CosStd/src/String_alg.c b/CosStd/src/String_alg.c index 9c5e2bd4..d1fabeef 100644 --- a/CosStd/src/String_alg.c +++ b/CosStd/src/String_alg.c @@ -29,8 +29,6 @@ #include #include -#include - // ----- useclass(View, Array); @@ -249,7 +247,7 @@ endmethod static U8* KnuthMorrisPratt(U8 *str, U32 str_n, U8 *pat, I32 pat_n) { - CARRAY_CREATE(I32,kmpNext,pat_n); + cos_alloc_tmp(I32,kmpNext,pat_n); { // preprocessing I32 i = 0, j = kmpNext[0] = -1; @@ -276,13 +274,13 @@ KnuthMorrisPratt(U8 *str, U32 str_n, U8 *pat, I32 pat_n) i++; j++; if (i >= pat_n) { // found - CARRAY_DESTROY(kmpNext); + cos_free_tmp(kmpNext); return str + (j - i); } } } - CARRAY_DESTROY(kmpNext); + cos_free_tmp(kmpNext); return 0; } diff --git a/CosStd/src/String_dyn.c b/CosStd/src/String_dyn.c index 94e630cb..4fc5c9fb 100644 --- a/CosStd/src/String_dyn.c +++ b/CosStd/src/String_dyn.c @@ -50,9 +50,9 @@ defmethod(OBJ, gdeinit, StringFix) next_method(self); if (self->_value) { // take care of protection cases - free(self->_value); + cos_free(self->_value); self->String.value = 0; - self->_value = 0; + self->_value = 0; } retmethod(_1); @@ -91,7 +91,7 @@ defmethod(OBJ, ginitWith, StringDyn, Int) THROW(gnewWithStr(ExOverflow, "capacity is too large")); } - strf->_value = malloc(size); + strf->_value = cos_malloc(size); if (!strf->_value && size) THROW(ExBadAlloc); @@ -143,7 +143,7 @@ defmethod(OBJ, genlarge, StringDyn, Int) // negative size means enlarge front if (size/sizeof *strf->_value < capacity+1) THROW(gnewWithStr(ExOverflow, "extra size is too large")); - U8* _value = realloc(strf->_value, size); + U8* _value = cos_realloc(strf->_value, size); if (!_value && size) THROW(ExBadAlloc); @@ -172,7 +172,7 @@ defmethod(OBJ, gadjust, StringDyn) // shrink storage if (str->size != self->capacity) { - U8* _value = realloc(strf->_value, size); + U8* _value = cos_realloc(strf->_value, size); if (!_value && size) THROW(ExBadAlloc); diff --git a/CosStd/src/tmpl/Vector.c b/CosStd/src/tmpl/Vector.c index efec48ce..5f221b3c 100644 --- a/CosStd/src/tmpl/Vector.c +++ b/CosStd/src/tmpl/Vector.c @@ -36,8 +36,6 @@ // #include #include -#include - #include #include diff --git a/CosStd/src/tmpl/Vector_alg.c b/CosStd/src/tmpl/Vector_alg.c index b6725332..63627c56 100644 --- a/CosStd/src/tmpl/Vector_alg.c +++ b/CosStd/src/tmpl/Vector_alg.c @@ -88,8 +88,8 @@ defmethod(OBJ, gpermute, T, IntVector) I32 idx_s = self2->stride; I32 *idx = self2->value; - CARRAY_CREATE(VAL,buf,size); // VAL buf[size]; - CARRAY_CREATE(U8 ,flg,size); // U8 flg[size]; + cos_alloc_tmp(VAL,buf,size); // VAL buf[size]; + cos_alloc_tmp(U8 ,flg,size); // U8 flg[size]; memset(flg,1,size); @@ -109,8 +109,8 @@ defmethod(OBJ, gpermute, T, IntVector) for (cur = buf; cur != end; cur++) *val = *cur, val += val_s; - CARRAY_DESTROY(buf); - CARRAY_DESTROY(flg); + cos_free_tmp(buf); + cos_free_tmp(flg); } else { // rollback (error) BOOL iiir = i < size; // last index-is-in-range flag @@ -121,8 +121,8 @@ defmethod(OBJ, gpermute, T, IntVector) val[i*val_s] = *--cur; } - CARRAY_DESTROY(buf); - CARRAY_DESTROY(flg); + cos_free_tmp(buf); + cos_free_tmp(flg); ensure( iiir, "index out of range" ); ensure( 0, "invalid cyclic permutation" ); } @@ -347,7 +347,7 @@ endmethod static VAL* KnuthMorrisPratt(VAL *val, U32 val_n, I32 val_s, VAL *pat, I32 pat_n, I32 pat_s) { - CARRAY_CREATE(I32,kmpNext,pat_n); + cos_alloc_tmp(I32,kmpNext,pat_n); { // preprocessing I32 i = 0, j = kmpNext[0] = -1; @@ -374,13 +374,13 @@ KnuthMorrisPratt(VAL *val, U32 val_n, I32 val_s, VAL *pat, I32 pat_n, I32 pat_s) i++; j++; if (i >= pat_n) { // found - CARRAY_DESTROY(kmpNext); + cos_free_tmp(kmpNext); return val + (j - i)*val_s; } } } - CARRAY_DESTROY(kmpNext); + cos_free_tmp(kmpNext); return 0; // not found } diff --git a/CosStd/src/tmpl/Vector_dyn.c b/CosStd/src/tmpl/Vector_dyn.c index bc9f78c2..b8b8c9d0 100644 --- a/CosStd/src/tmpl/Vector_dyn.c +++ b/CosStd/src/tmpl/Vector_dyn.c @@ -63,7 +63,7 @@ defmethod(OBJ, ginitWith, TD, Int) ensure(self2->value >= 0, "negative " TS " capacity"); - vecf->_value = malloc(capacity*sizeof *vec->value); + vecf->_value = cos_malloc(capacity*sizeof *vec->value); if (!vecf->_value && capacity) THROW(ExBadAlloc); vec->size = 0; @@ -81,7 +81,7 @@ defmethod(OBJ, gdeinit, TF) next_method(self); if (self->_value) // take care of protection cases - free(self->_value); + cos_free(self->_value); retmethod(_1); endmethod @@ -140,7 +140,7 @@ defmethod(OBJ, genlarge, TD, Int) // negative size means enlarge front capacity += size = extra_size(capacity, size); - VAL *_value = realloc(vecf->_value, capacity*sizeof *vecf->_value); + VAL *_value = cos_realloc(vecf->_value, capacity*sizeof *vecf->_value); if (!_value && capacity) THROW(ExBadAlloc); vec -> value = _value + offset; @@ -166,7 +166,7 @@ defmethod(OBJ, gadjust, TD) // shrink storage if (size != vecf->capacity) { - VAL *_value = realloc(vecf->_value, size*sizeof *vecf->_value); + VAL *_value = cos_realloc(vecf->_value, size*sizeof *vecf->_value); if (!_value && size) THROW(ExBadAlloc); vec -> value = _value; From 962e67e5ed9f9877a85a54d44b41b9ef34387c44 Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Wed, 4 Jan 2023 18:47:54 +0100 Subject: [PATCH 20/23] avoid closing stdout --- CosBase/examples/ex01/File.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CosBase/examples/ex01/File.c b/CosBase/examples/ex01/File.c index 91979a5c..7e587609 100644 --- a/CosBase/examples/ex01/File.c +++ b/CosBase/examples/ex01/File.c @@ -33,7 +33,7 @@ defmethod(OBJ, ginitWithStr, File, (STR)str) endmethod defmethod(OBJ, gdeinit, File) - if (self->file) + if (self->file && self->file != stdout) fclose(self->file); retmethod(_1); From 90f4db91bfa326254de47af8cd54d47daedd4149 Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Sun, 8 Jan 2023 13:13:41 +0100 Subject: [PATCH 21/23] rename delete to release --- CHANGELOG | 2 +- CosStd/include/cos/gen/floatop.h | 2 +- CosStd/include/cos/gen/numop.h | 2 +- CosStd/src/tmpl/Vector_lzy.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8170eb90..627d4739 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -71,7 +71,7 @@ - all the language feature are there - moving from alpha to beta state - properties added - - gdelete and gautoDelete added (for semi-GC) + - grelease and gautoRelease added (for semi-GC) - more compile-time checks - module support - start of other modules (not provided) diff --git a/CosStd/include/cos/gen/floatop.h b/CosStd/include/cos/gen/floatop.h index d420847b..ead99e07 100644 --- a/CosStd/include/cos/gen/floatop.h +++ b/CosStd/include/cos/gen/floatop.h @@ -24,7 +24,7 @@ /* NOTE-USER: operators policy The policy of these messages is to return the operation result in a - new autoDelete object resulting from the promotion/coercion of _1 + new autoRelease object resulting from the promotion/coercion of _1 and _2 which follows the rules of C99 for primitive types. */ defgeneric(OBJ, (G_conj ) gconj , _1); // return _1^* diff --git a/CosStd/include/cos/gen/numop.h b/CosStd/include/cos/gen/numop.h index 1a685ab7..f2dedf00 100644 --- a/CosStd/include/cos/gen/numop.h +++ b/CosStd/include/cos/gen/numop.h @@ -24,7 +24,7 @@ /* NOTE-USER: operators policy The policy of these messages is to return the operation result in a - new autoDelete object resulting from the promotion/coercion of _1 + new autorelease object resulting from the promotion/coercion of _1 and _2 which follows the rules of C99 for primitive types. */ defgeneric(OBJ, (G_abs) gabs, _1); // return |_1| diff --git a/CosStd/src/tmpl/Vector_lzy.c b/CosStd/src/tmpl/Vector_lzy.c index ba0672cb..24d2654f 100644 --- a/CosStd/src/tmpl/Vector_lzy.c +++ b/CosStd/src/tmpl/Vector_lzy.c @@ -92,7 +92,7 @@ defmethod(OBJ, ggetAt, TL, Int) while (vec->size <= i) gappend(_1, geval(self->generator)); - retmethod( gautoDelete(VALOBJ(vec->value[i*vec->stride])) ); + retmethod( gautoRelease(VALOBJ(vec->value[i*vec->stride])) ); endmethod // NOTE-TODO: other getters? From efb1aa1a7560f4fbd1ffc6e86da460a213147317 Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Sun, 8 Jan 2023 16:05:30 +0100 Subject: [PATCH 22/23] use moddeps --- CosStd/examples/ex01/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CosStd/examples/ex01/Makefile b/CosStd/examples/ex01/Makefile index 22c4150d..d8d53135 100644 --- a/CosStd/examples/ex01/Makefile +++ b/CosStd/examples/ex01/Makefile @@ -36,11 +36,11 @@ defgens := defprps := # project dependencies (as with -lname) -moddeps := CosStd CosBase +moddeps := CosBase CosStd # project dependencies (as with -Ipath or -Lpath) -incdirs := ../../../CosBase/include ../../include . -libdirs := ../../../CosBase/$(OSNAME)/lib ../../$(OSNAME)/lib +incdirs := $(foreach m,$(moddeps),../../../$(m)/include) . +libdirs := $(foreach m,$(moddeps),../../../$(m)/$(OSNAME)/lib) include $(cos)/epilogue From fc2f3ed275d2291d3fb2499fa3572dcfe3dd9db2 Mon Sep 17 00:00:00 2001 From: Laurent Deniau Date: Sun, 8 Jan 2023 16:31:16 +0100 Subject: [PATCH 23/23] remove useless wildcard --- CosStd/tests/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CosStd/tests/Makefile b/CosStd/tests/Makefile index 87e58286..f24b3de8 100644 --- a/CosStd/tests/Makefile +++ b/CosStd/tests/Makefile @@ -31,8 +31,8 @@ program := testCosStd targets := debug.run # files and modules -sources := $(wildcard src/*.c) -headers := $(wildcard src/*.h) +sources := src/*.c +headers := src/*.h defgens := $(headers) defprps := $(headers)