Read generator tags through a pointer the generator runtime installs

scr_json.c and scr_inspect.c called scr_gen_tag, which lives in
scr_async.c. Libraries and the runtime's unit tests link those units
without scr_async.c, so their links failed on the undefined symbol.

Both now read the tag through scr_gen_tag_reader, defined in scr_json.c
and set at startup by scr_async.c. A generator capsule only exists when
the generator runtime is linked, so the pointer is always set when read.
This commit is contained in:
Chris Tate
2026-10-19 02:40:22 -05:00
parent 496cf577c7
commit 192ea32474
4 changed files with 12 additions and 2 deletions
+4
View File
@@ -5556,6 +5556,10 @@ const char *scr_gen_tag(const ScrGen *g) {
return g->tag ? g->tag : g->is_async ? "AsyncGenerator" : "Generator";
}
__attribute__((constructor)) static void scr_gen_tag_reader_init(void) {
scr_gen_tag_reader = scr_gen_tag;
}
void scr_gen_close(ScrGen *g) {
scr_gen_slot_reset(&g->ret);
scr_gen_resume_return(g);
+4
View File
@@ -73,6 +73,10 @@ void scr_gen_set_tag(ScrGen *g, const char *tag);
/* An adapter generator prints with the tag of the generator it adapts. */
void scr_gen_copy_tag(ScrGen *g, const ScrGen *from);
const char *scr_gen_tag(const ScrGen *g);
/* scr_gen_tag for units that also link without the generator runtime (a
* library links none): the generator runtime sets it at startup, and only
* then can a generator capsule exist. */
extern const char *(*scr_gen_tag_reader)(const ScrGen *g);
ScrGen *scr_gen_retain(ScrGen *g);
void scr_gen_release(ScrGen *g); /* NULL-tolerant */
void *scr_gen_retain_v(void *g);
+1 -1
View File
@@ -1138,7 +1138,7 @@ static bool scr_insp_is_generator(const ScrDyn *d) {
}
static ScrStr *scr_insp_generator(const ScrDyn *d) {
const char *tag = scr_gen_tag(d->v.typed_ref.ptr);
const char *tag = scr_gen_tag_reader(d->v.typed_ref.ptr);
if (tag[0] == '!') {
static const char message[] = "util.inspect of this iterator object is not supported yet";
scr_throw_error_msg(SCR_ERR_ERROR, message, sizeof message - 1);
+3 -1
View File
@@ -1678,6 +1678,8 @@ ScrDyn *scr_dyn_symbol_get(const ScrDyn *value, const ScrStr *key) {
* later, and it neither grows nor owns heap references. */
static ScrDyn scr_dyn_small_ints[384];
const char *(*scr_gen_tag_reader)(const ScrGen *g) = NULL;
__attribute__((constructor)) static void scr_dyn_small_ints_init(void) {
for (int i = 0; i < 384; i++) {
scr_dyn_small_ints[i].rc = SIZE_MAX;
@@ -6228,7 +6230,7 @@ ScrStr *scr_dyn_object_tag(const ScrDyn *d) {
if (d->kind == SCR_DYN_TYPED_REF) {
if (scr_dyn_ref_is_error(d)) return scr_str_new("[object Error]", 14);
if (scr_dyn_generator(d)) {
const char *gen_tag = scr_gen_tag(d->v.typed_ref.ptr);
const char *gen_tag = scr_gen_tag_reader(d->v.typed_ref.ptr);
if (gen_tag[0] == '!') {
static const char message[] = "Object.prototype.toString of this iterator is not supported yet";
scr_throw_error_msg(SCR_ERR_ERROR, message, sizeof message - 1);