el runtime: prototype + fix channel/mutex seed ABI for modern clang
el_runtime.h declared only __thread_create/__thread_join; the mutex and channel seed primitives (__mutex_*, __channel_*) were defined in el_runtime.c but never prototyped. Under Apple clang 21 (C11) the missing prototypes became implicit-declaration errors, and the void-returning __channel_send/__channel_close mis-typed el_val_t (long long) returns, so any El program using runtime/channel.el failed to compile. - add prototypes for __mutex_new/lock/unlock and all __channel_* to el_runtime.h - make __channel_send/__channel_close return el_val_t nil so elc's trailing-expression codegen for the void El wrappers type-checks Additive; unbreaks native channels for every downstream El program.
This commit is contained in:
@@ -11743,9 +11743,9 @@ el_val_t __channel_new(el_val_t capacity_v) {
|
||||
return EL_INT(slot);
|
||||
}
|
||||
|
||||
void __channel_send(el_val_t ch_v, el_val_t msg_v) {
|
||||
el_val_t __channel_send(el_val_t ch_v, el_val_t msg_v) {
|
||||
int slot = (int)(int64_t)ch_v;
|
||||
if (slot < 0 || slot >= EL_CHANNEL_MAX) return;
|
||||
if (slot < 0 || slot >= EL_CHANNEL_MAX) return EL_STR("");
|
||||
ElChannel* ch = &_channels[slot];
|
||||
|
||||
const char* msg = EL_CSTR(msg_v);
|
||||
@@ -11758,7 +11758,7 @@ void __channel_send(el_val_t ch_v, el_val_t msg_v) {
|
||||
/* Send on closed channel is a no-op (drop the message). */
|
||||
pthread_mutex_unlock(&ch->mu);
|
||||
free(copy);
|
||||
return;
|
||||
return EL_STR("");
|
||||
}
|
||||
|
||||
if (ch->cap > 0) {
|
||||
@@ -11769,7 +11769,7 @@ void __channel_send(el_val_t ch_v, el_val_t msg_v) {
|
||||
if (ch->closed) {
|
||||
pthread_mutex_unlock(&ch->mu);
|
||||
free(copy);
|
||||
return;
|
||||
return EL_STR("");
|
||||
}
|
||||
ch->buf[ch->tail] = copy;
|
||||
ch->tail = (ch->tail + 1) % ch->cap;
|
||||
@@ -11783,7 +11783,7 @@ void __channel_send(el_val_t ch_v, el_val_t msg_v) {
|
||||
pthread_mutex_unlock(&ch->mu);
|
||||
free(copy);
|
||||
fprintf(stderr, "[__channel_send] out of memory growing channel\n");
|
||||
return;
|
||||
return EL_STR("");
|
||||
}
|
||||
/* The circular buffer may have wrapped. Linearise it first.
|
||||
* In unbounded mode head is always 0 (we append at tail, drain
|
||||
@@ -11807,6 +11807,7 @@ void __channel_send(el_val_t ch_v, el_val_t msg_v) {
|
||||
|
||||
pthread_cond_signal(&ch->not_empty);
|
||||
pthread_mutex_unlock(&ch->mu);
|
||||
return EL_STR("");
|
||||
}
|
||||
|
||||
el_val_t __channel_recv(el_val_t ch_v) {
|
||||
@@ -11864,9 +11865,9 @@ el_val_t __channel_try_recv(el_val_t ch_v) {
|
||||
return EL_STR(msg);
|
||||
}
|
||||
|
||||
void __channel_close(el_val_t ch_v) {
|
||||
el_val_t __channel_close(el_val_t ch_v) {
|
||||
int slot = (int)(int64_t)ch_v;
|
||||
if (slot < 0 || slot >= EL_CHANNEL_MAX) return;
|
||||
if (slot < 0 || slot >= EL_CHANNEL_MAX) return EL_STR("");
|
||||
ElChannel* ch = &_channels[slot];
|
||||
|
||||
pthread_mutex_lock(&ch->mu);
|
||||
@@ -11875,6 +11876,7 @@ void __channel_close(el_val_t ch_v) {
|
||||
pthread_cond_broadcast(&ch->not_empty);
|
||||
pthread_cond_broadcast(&ch->not_full);
|
||||
pthread_mutex_unlock(&ch->mu);
|
||||
return EL_STR("");
|
||||
}
|
||||
|
||||
/* ── DHARMA runtime additions ────────────────────────────────────────────────
|
||||
|
||||
@@ -803,6 +803,19 @@ el_val_t emit_event(el_val_t name, el_val_t duration_ms);
|
||||
el_val_t __thread_create(el_val_t fn_name_v, el_val_t arg_v);
|
||||
el_val_t __thread_join(el_val_t tid_v);
|
||||
|
||||
/* Mutex + channel seed primitives (defined in el_runtime.c). Declared here so
|
||||
* that compiled El programs which use runtime/thread.el's with_mutex helper or
|
||||
* runtime/channel.el's Go-style channels see real prototypes instead of an
|
||||
* implicit int-return declaration (which the C11 ABI mis-truncates el_val_t). */
|
||||
el_val_t __mutex_new(void);
|
||||
void __mutex_lock(el_val_t m_v);
|
||||
void __mutex_unlock(el_val_t m_v);
|
||||
el_val_t __channel_new(el_val_t capacity_v);
|
||||
el_val_t __channel_send(el_val_t ch_v, el_val_t msg_v);
|
||||
el_val_t __channel_recv(el_val_t ch_v);
|
||||
el_val_t __channel_try_recv(el_val_t ch_v);
|
||||
el_val_t __channel_close(el_val_t ch_v);
|
||||
|
||||
/* ── __ prefixed aliases (self-hosting compiler ABI) ─────────────────────────
|
||||
* The El self-hosting compiler emits calls to __-prefixed names. These are
|
||||
* forwarding wrappers around the existing el_runtime functions above. */
|
||||
|
||||
Reference in New Issue
Block a user