pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
cyclone: add a patch for cyclone issue 560
Module Name: pkgsrc-wip
Committed By: Yorick Hardy <yorickhardy%gmail.com@localhost>
Pushed By: yhardy
Date: Sat Oct 11 13:22:10 2025 +0000
Changeset: 4ef838e49148a7d489fc4527c96ec8b61b95c8ec
Modified Files:
cyclone/Makefile
cyclone/distinfo
Added Files:
cyclone/patches/patch-issue-560
Log Message:
cyclone: add a patch for cyclone issue 560
String and bytevector objects should be allocated from the heap
if their size exceeds the available stack space.
This issue is partially addressed in a branch:
https://github.com/justinethier/cyclone/compare/master...issue-560-compute-stack-limit
and further in the pull request:
https://github.com/justinethier/cyclone/pull/561
Bump the package revision because of the runtime changes.
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=4ef838e49148a7d489fc4527c96ec8b61b95c8ec
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
cyclone/Makefile | 1 +
cyclone/distinfo | 1 +
cyclone/patches/patch-issue-560 | 368 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 370 insertions(+)
diffs:
diff --git a/cyclone/Makefile b/cyclone/Makefile
index f6b882d1fc..1ae735e122 100644
--- a/cyclone/Makefile
+++ b/cyclone/Makefile
@@ -1,6 +1,7 @@
# $NetBSD$
DISTNAME= cyclone-${GITHUB_TAG:S,^v,,}
+PKGREVISION= 1
CATEGORIES= lang
MASTER_SITES= ${MASTER_SITE_GITHUB:=justinethier/}
GITHUB_TAG= v0.36.0
diff --git a/cyclone/distinfo b/cyclone/distinfo
index 93e3088867..8a336bb627 100644
--- a/cyclone/distinfo
+++ b/cyclone/distinfo
@@ -7,6 +7,7 @@ SHA1 (patch-Makefile) = d5e8d8a25d9472601708778ec9e220a987da4128
SHA1 (patch-Makefile.config) = 1cb1559cbe9779d5fa8bda998db14951af99716a
SHA1 (patch-cyclone.scm) = e624dd62369d92b88501f8770d3504e78e311321
SHA1 (patch-include_cyclone_types.h) = caf0f87ec67d42aad59d7041c50de12fac20c932
+SHA1 (patch-issue-560) = 8c46b08f5741622de75d26af6920d1f5ba31b39a
SHA1 (patch-scheme_base.sld) = b9aaeb494572eb4fddecf25d30eae7cafe77163f
SHA1 (patch-srfi_106.sld) = d8929991450c841fd00330d6b1e705a7290900bb
SHA1 (patch-tests_macro-hygiene.scm) = 3e640ae4e4f67f0d3e3be7670559748758ac66bc
diff --git a/cyclone/patches/patch-issue-560 b/cyclone/patches/patch-issue-560
new file mode 100644
index 0000000000..45e7738235
--- /dev/null
+++ b/cyclone/patches/patch-issue-560
@@ -0,0 +1,368 @@
+$NetBSD$
+
+Patches for cyclone issue 560
+https://github.com/justinethier/cyclone/compare/master...issue-560-compute-stack-limit
+https://github.com/justinethier/cyclone/pull/561
+
+--- include/cyclone/runtime.h
++++ include/cyclone/runtime.h
+@@ -47,6 +47,8 @@ extern const object Cyc_RECORD_MARKER;
+ */
+ void GC(void *, closure, object *, int);
+
++int Cyc_stack_remaining(gc_thread_data *td);
++
+ /**
+ * \ingroup gc_major
+ */
+--- include/cyclone/types.h
++++ include/cyclone/types.h
+@@ -500,6 +500,13 @@ void Cyc_make_shared_object(void *data, object k, object obj);
+ #define stack_overflow(x,y) ((x) > (y))
+ #endif
+
++/** Determine remaining stack size */
++#if STACK_GROWTH_IS_DOWNWARD
++#define stack_delta(x,y) (((char *)x) - ((char *)y))
++#else
++#define stack_delta(x,y) (((char *)y) - ((char *)x))
++#endif
++
+ /**
+ * Access an object's forwarding pointer.
+ * Note this is only applicable when objects are relocated
+@@ -998,10 +1005,13 @@ typedef struct {
+ * Allocate a new string, either on the stack or heap depending upon size
+ */
+ #define alloc_string(_data, _s, _len, _num_cp) \
+- if (_len >= MAX_STACK_OBJ) { \
++ { \
++ int stack_left = Cyc_stack_remaining(data); \
++ int alloc_required = sizeof(string_type) + _len + 1; \
++ if (alloc_required >= stack_left) { \
+ int heap_grown; \
+ _s = gc_alloc(((gc_thread_data *)data)->heap, \
+- sizeof(string_type) + _len + 1, \
++ alloc_required, \
+ boolean_f, /* OK to populate manually over here */ \
+ (gc_thread_data *)data, \
+ &heap_grown); \
+@@ -1021,16 +1031,20 @@ typedef struct {
+ ((string_type *)_s)->len = _len; \
+ ((string_type *)_s)->num_cp = _num_cp; \
+ ((string_type *)_s)->str = alloca(sizeof(char) * (_len + 1)); \
+- }
++ } \
++ }
+
+ /**
+ * Allocate a new bytevector, either on the stack or heap depending upon size
+ */
+ #define alloc_bytevector(_data, _bv, _len) \
+- if (_len >= MAX_STACK_OBJ) { \
++ { \
++ int stack_left = Cyc_stack_remaining(data); \
++ int alloc_required = sizeof(bytevector_type) + _len; \
++ if (alloc_required >= stack_left) { \
+ int heap_grown; \
+ _bv = gc_alloc(((gc_thread_data *)data)->heap, \
+- sizeof(bytevector_type) + _len, \
++ alloc_required, \
+ boolean_f, /* OK to populate manually over here */ \
+ (gc_thread_data *)data, \
+ &heap_grown); \
+@@ -1048,7 +1062,8 @@ typedef struct {
+ ((bytevector) _bv)->tag = bytevector_tag; \
+ ((bytevector) _bv)->len = _len; \
+ ((bytevector) _bv)->data = alloca(sizeof(char) * _len); \
+- }
++ } \
++ }
+
+ /** Get the length of a string, in characters (code points) */
+ #define string_num_cp(x) (((string_type *) x)->num_cp)
+--- runtime.c
++++ runtime.c
+@@ -2799,10 +2799,18 @@ void dispatch_string_91append(void *data, object clo, int _argc, object * _args)
+ {
+ int argc = _argc - 1; // Skip continuation
+ object *args = _args + 1; // Skip continuation
+- int i = 0, total_cp = 0, total_len = 1;
++ int i = 0, total_cp = 0, total_len = 0;
+ int *len = alloca(sizeof(int) * argc);
+- char *buffer, *bufferp, **str = alloca(sizeof(char *) * argc);
+- object tmp;
++ char *bufferp, **str = alloca(sizeof(char *) * argc);
++ object tmp, result;
++ if (argc == 0) {
++ make_string(r, "");
++ return_closcall1(data, clo, &r);
++ }
++ if (argc == 1) {
++ Cyc_check_str(data, args[0]);
++ return_closcall1(data, clo, args[0]);
++ }
+ for (i = 0; i < argc; i++) {
+ tmp = args[i];
+ Cyc_check_str(data, tmp);
+@@ -2811,32 +2819,39 @@ void dispatch_string_91append(void *data, object clo, int _argc, object * _args)
+ total_len += len[i];
+ total_cp += string_num_cp((tmp));
+ }
+- buffer = bufferp = alloca(sizeof(char) * total_len);
++ alloc_string(data, result, sizeof(char) * total_len, total_cp);
++ bufferp = ((string_type *) result)->str;
+ for (i = 0; i < argc; i++) {
+ memcpy(bufferp, str[i], len[i]);
+ bufferp += len[i];
+ }
+ *bufferp = '\0';
+- make_string(result, buffer);
+- string_num_cp((&result)) = total_cp;
+- return_closcall1(data, clo, &result);
++ return_closcall1(data, clo, result);
+ }
+
+ object Cyc_string_append(void *data, object cont, int argc, object str1, ...)
+ {
++ int i = 0, total_cp = 0, total_len = 0;
++ int *len;
++ char *bufferp, **str;
++ object tmp, result;
+ va_list ap;
+- va_start(ap, str1);
+- int i = 0, total_cp = 0, total_len = 1;
+- int *len = alloca(sizeof(int) * argc);
+- char *buffer, *bufferp, **str = alloca(sizeof(char *) * argc);
+- object tmp;
+- if (argc > 0) {
++ if (argc == 0) {
++ make_string(r, "");
++ _return_closcall1(data, cont, &r);
++ }
++ if (argc == 1) {
+ Cyc_check_str(data, str1);
+- str[i] = ((string_type *) str1)->str;
+- len[i] = string_len((str1));
+- total_len += len[i];
+- total_cp += string_num_cp((str1));
++ _return_closcall1(data, cont, str1);
+ }
++ len = alloca(sizeof(int) * argc);
++ str = alloca(sizeof(char *) * argc);
++ va_start(ap, str1);
++ Cyc_check_str(data, str1);
++ str[i] = ((string_type *) str1)->str;
++ len[i] = string_len((str1));
++ total_len += len[i];
++ total_cp += string_num_cp((str1));
+ for (i = 1; i < argc; i++) {
+ tmp = va_arg(ap, object);
+ Cyc_check_str(data, tmp);
+@@ -2845,16 +2860,15 @@ object Cyc_string_append(void *data, object cont, int argc, object str1, ...)
+ total_len += len[i];
+ total_cp += string_num_cp((tmp));
+ }
+- buffer = bufferp = alloca(sizeof(char) * total_len);
++ alloc_string(data, result, sizeof(char) * total_len, total_cp);
++ bufferp = ((string_type *) result)->str;
+ for (i = 0; i < argc; i++) {
+ memcpy(bufferp, str[i], len[i]);
+ bufferp += len[i];
+ }
+ *bufferp = '\0';
+- make_string(result, buffer);
+- string_num_cp((&result)) = total_cp;
+ va_end(ap);
+- _return_closcall1(data, cont, &result);
++ _return_closcall1(data, cont, result);
+ }
+
+ object Cyc_string_length(void *data, object str)
+@@ -3171,7 +3185,7 @@ object Cyc_make_vector(void *data, object cont, int argc, object len, ...)
+ object v = NULL;
+ object fill = boolean_f;
+ int i, ulen;
+- size_t element_vec_size;
++ size_t element_vec_size, alloc_required;
+ va_list ap;
+ make_pair(tmp_pair, NULL, NULL);
+ make_c_opaque(opq, NULL);
+@@ -3183,14 +3197,15 @@ object Cyc_make_vector(void *data, object cont, int argc, object len, ...)
+ Cyc_check_num(data, len);
+ ulen = unbox_number(len);
+ element_vec_size = sizeof(object) * ulen;
++ alloc_required = sizeof(vector_type) + element_vec_size;
+
+- if (element_vec_size >= MAX_STACK_OBJ) {
++ if (alloc_required >= Cyc_stack_remaining(data)) {
+ // If vector is too large to allocate on the stack, allocate on heap
+ //
+ // TODO: mark this thread as potentially blocking before doing
+ // the allocation????
+ int heap_grown;
+- v = gc_alloc(((gc_thread_data *) data)->heap, sizeof(vector_type) + element_vec_size, boolean_f, // OK to populate manually over here
++ v = gc_alloc(((gc_thread_data *) data)->heap, alloc_required, boolean_f, // OK to populate manually over here
+ (gc_thread_data *) data, &heap_grown);
+ ((vector) v)->hdr.mark = ((gc_thread_data *) data)->gc_alloc_color;
+ ((vector) v)->hdr.grayed = 0;
+@@ -3243,7 +3258,7 @@ object Cyc_make_bytevector(void *data, object cont, int argc, object len, ...)
+ Cyc_check_num(data, len);
+ length = unbox_number(len);
+
+- if (length >= MAX_STACK_OBJ) {
++ if (length >= Cyc_stack_remaining(data)) {
+ int heap_grown;
+ bv = gc_alloc(((gc_thread_data *) data)->heap, sizeof(bytevector_type) + length, boolean_f, // OK to populate manually over here
+ (gc_thread_data *) data, &heap_grown);
+@@ -3327,11 +3342,18 @@ void dispatch_bytevector_91append(void *data, object clo, int _argc,
+ int argc = _argc - 1; // Skip continuation
+ object *args = _args + 1; // Skip continuation
+ int i = 0, buf_idx = 0, total_length = 0;
+- object tmp;
++ object tmp, result;
+ char *buffer;
+ char **buffers = NULL;
+ int *lengths = NULL;
+- make_empty_bytevector(result);
++ if (argc == 0) {
++ make_empty_bytevector(r);
++ return_closcall1(data, clo, &r);
++ }
++ if (argc == 1) {
++ Cyc_check_bvec(data, args[0]);
++ return_closcall1(data, clo, args[0]);
++ }
+ if (argc > 0) {
+ buffers = alloca(sizeof(char *) * argc);
+ lengths = alloca(sizeof(int) * argc);
+@@ -3342,26 +3364,32 @@ void dispatch_bytevector_91append(void *data, object clo, int _argc,
+ lengths[i] = ((bytevector) tmp)->len;
+ buffers[i] = ((bytevector) tmp)->data;
+ }
+- buffer = alloca(sizeof(char) * total_length);
++ alloc_bytevector(data, result, total_length);
++ buffer = ((bytevector) result)->data;
+ for (i = 0; i < argc; i++) {
+ memcpy(&buffer[buf_idx], buffers[i], lengths[i]);
+ buf_idx += lengths[i];
+ }
+- result.len = total_length;
+- result.data = buffer;
+ }
+- return_closcall1(data, clo, &result);
++ return_closcall1(data, clo, result);
+ }
+
+ object Cyc_bytevector_append(void *data, object cont, int argc, object bv, ...)
+ {
+ int i = 0, buf_idx = 0, total_length = 0;
+ va_list ap;
+- object tmp;
++ object tmp, result;
+ char *buffer;
+ char **buffers = NULL;
+ int *lengths = NULL;
+- make_empty_bytevector(result);
++ if (argc == 0) {
++ make_empty_bytevector(r);
++ _return_closcall1(data, cont, &r);
++ }
++ if (argc == 1) {
++ Cyc_check_bvec(data, bv);
++ _return_closcall1(data, cont, bv);
++ }
+ if (argc > 0) {
+ buffers = alloca(sizeof(char *) * argc);
+ lengths = alloca(sizeof(int) * argc);
+@@ -3378,15 +3406,14 @@ object Cyc_bytevector_append(void *data, object cont, int argc, object bv, ...)
+ buffers[i] = ((bytevector) tmp)->data;
+ }
+ va_end(ap);
+- buffer = alloca(sizeof(char) * total_length);
++ alloc_bytevector(data, result, total_length);
++ buffer = ((bytevector) result)->data;
+ for (i = 0; i < argc; i++) {
+ memcpy(&buffer[buf_idx], buffers[i], lengths[i]);
+ buf_idx += lengths[i];
+ }
+- result.len = total_length;
+- result.data = buffer;
+ }
+- _return_closcall1(data, cont, &result);
++ _return_closcall1(data, cont, result);
+ }
+
+ object Cyc_bytevector_copy(void *data, object cont, object bv, object start,
+@@ -3411,7 +3438,7 @@ object Cyc_bytevector_copy(void *data, object cont, object bv, object start,
+ Cyc_rt_raise2(data, "bytevector-copy - invalid end", end);
+ }
+
+- if (len >= MAX_STACK_OBJ) {
++ if (len >= Cyc_stack_remaining(data)) {
+ int heap_grown;
+ object result = gc_alloc(((gc_thread_data *) data)->heap,
+ sizeof(bytevector_type) + len,
+@@ -3495,7 +3522,7 @@ object Cyc_string2utf8(void *data, object cont, object str, object start,
+ }
+ // Fast path
+ if (string_num_cp(str) == string_len(str)) {
+- if (len >= MAX_STACK_OBJ) {
++ if (len >= Cyc_stack_remaining(data)) {
+ int heap_grown;
+ object bv = gc_alloc(((gc_thread_data *) data)->heap,
+ sizeof(bytevector_type) + len,
+@@ -3540,7 +3567,7 @@ object Cyc_string2utf8(void *data, object cont, object str, object start,
+ }
+ }
+ len = end_i - start_i;
+- if (len >= MAX_STACK_OBJ) {
++ if (len >= Cyc_stack_remaining(data)) {
+ int heap_grown;
+ object bv = gc_alloc(((gc_thread_data *) data)->heap,
+ sizeof(bytevector_type) + len,
+@@ -3622,16 +3649,17 @@ object Cyc_list2vector(void *data, object cont, object l)
+ object len_obj;
+ object lst = l;
+ int len, i = 0;
+- size_t element_vec_size;
++ size_t element_vec_size, alloc_required;
+
+ make_c_opaque(opq, NULL);
+ Cyc_check_pair_or_null(data, l);
+ len_obj = Cyc_length(data, l);
+ len = obj_obj2int(len_obj);
+ element_vec_size = sizeof(object) * len;
+- if (element_vec_size >= MAX_STACK_OBJ) {
++ alloc_required = sizeof(vector_type) + element_vec_size;
++ if (alloc_required >= Cyc_stack_remaining(data)) {
+ int heap_grown;
+- v = gc_alloc(((gc_thread_data *) data)->heap, sizeof(vector_type) + element_vec_size, boolean_f, // OK to populate manually over here
++ v = gc_alloc(((gc_thread_data *) data)->heap, alloc_required, boolean_f, // OK to populate manually over here
+ (gc_thread_data *) data, &heap_grown);
+ ((vector) v)->hdr.mark = ((gc_thread_data *) data)->gc_alloc_color;
+ ((vector) v)->hdr.grayed = 0;
+@@ -8930,3 +8958,11 @@ object Cyc_exact_no_cps(void *data, object ptr, object z)
+ }
+ return obj_int2obj(i);
+ }
++
++int Cyc_stack_remaining(gc_thread_data *td)
++{
++ int i;
++ int stack_remaining = stack_delta(&i, td->stack_limit);
++ //printf("JAE DEBUG stack remaining = %ld\n", stack_remaining);
++ return stack_remaining;
++}
+--- scheme/base.sld
++++ scheme/base.sld
+@@ -1132,7 +1132,8 @@
+ }
+ num_cp = obj_obj2int(count);
+ len = num_cp * buflen;
+- if (len >= MAX_STACK_OBJ) {
++ int stack_left = Cyc_stack_remaining(data);
++ if (len >= stack_left) {
+ int heap_grown;
+ s = gc_alloc(((gc_thread_data *)data)->heap,
+ sizeof(string_type) + len + 1,
Home |
Main Index |
Thread Index |
Old Index