From 73b2e0bf766ece2ec66a443d3d16294320941eb7 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 2 Apr 2023 20:28:14 +0900 Subject: [PATCH] Shrink `/mrbgems/gem_init.c` if possible If none of the GEMs have `mrblib/` or `src/` directories, generate `mrb_init_mrbgems()` which does nothing, and omit `mrb_final_mrbgems()`. The impetus was to avoid `gem_funcs[]` becoming a zero-length array, which is not allowed by the C standard. The problem is caused by #5938. --- tasks/mrbgems.rake | 94 ++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake index 26d736bfd..686facb25 100644 --- a/tasks/mrbgems.rake +++ b/tasks/mrbgems.rake @@ -38,53 +38,57 @@ MRuby.each_target do f.puts %Q[#include ] f.puts %Q[#include ] f.puts %Q[] - f.write gem_func_decls - f.puts %Q[] - f.puts %Q[static const struct {] - f.puts %Q[ void (*init)(mrb_state*);] - f.puts %Q[ void (*final)(mrb_state*);] - f.puts %Q[} gem_funcs[] = {] - f.write gem_funcs - f.puts %Q[};] - f.puts %Q[] - f.puts %Q[#define NUM_GEMS ((int)(sizeof(gem_funcs) / sizeof(gem_funcs[0])))] - f.puts %Q[] - f.puts %Q[struct final_mrbgems {] - f.puts %Q[ int i;] - f.puts %Q[ int ai;] - f.puts %Q[};] - f.puts %Q[] - f.puts %Q[static mrb_value] - f.puts %Q[final_mrbgems_body(mrb_state *mrb, void *ud) {] - f.puts %Q[ struct final_mrbgems *p = (struct final_mrbgems*)ud;] - f.puts %Q[ for (; p->i >= 0; p->i--) {] - f.puts %Q[ gem_funcs[p->i].final(mrb);] - f.puts %Q[ mrb_gc_arena_restore(mrb, p->ai);] - f.puts %Q[ }] - f.puts %Q[ return mrb_nil_value();] - f.puts %Q[}] - f.puts %Q[] - f.puts %Q[static void] - f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] - f.puts %Q[ struct final_mrbgems a = { NUM_GEMS - 1, mrb_gc_arena_save(mrb) };] - f.puts %Q[ for (; a.i >= 0; a.i--) {] - f.puts %Q[ mrb_protect_error(mrb, final_mrbgems_body, &a, NULL);] - f.puts %Q[ mrb_gc_arena_restore(mrb, a.ai);] - f.puts %Q[ }] - f.puts %Q[}] - f.puts %Q[] + unless gem_funcs.empty? + f.write gem_func_decls + f.puts %Q[] + f.puts %Q[static const struct {] + f.puts %Q[ void (*init)(mrb_state*);] + f.puts %Q[ void (*final)(mrb_state*);] + f.puts %Q[} gem_funcs[] = {] + f.write gem_funcs + f.puts %Q[};] + f.puts %Q[] + f.puts %Q[#define NUM_GEMS ((int)(sizeof(gem_funcs) / sizeof(gem_funcs[0])))] + f.puts %Q[] + f.puts %Q[struct final_mrbgems {] + f.puts %Q[ int i;] + f.puts %Q[ int ai;] + f.puts %Q[};] + f.puts %Q[] + f.puts %Q[static mrb_value] + f.puts %Q[final_mrbgems_body(mrb_state *mrb, void *ud) {] + f.puts %Q[ struct final_mrbgems *p = (struct final_mrbgems*)ud;] + f.puts %Q[ for (; p->i >= 0; p->i--) {] + f.puts %Q[ gem_funcs[p->i].final(mrb);] + f.puts %Q[ mrb_gc_arena_restore(mrb, p->ai);] + f.puts %Q[ }] + f.puts %Q[ return mrb_nil_value();] + f.puts %Q[}] + f.puts %Q[] + f.puts %Q[static void] + f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] + f.puts %Q[ struct final_mrbgems a = { NUM_GEMS - 1, mrb_gc_arena_save(mrb) };] + f.puts %Q[ for (; a.i >= 0; a.i--) {] + f.puts %Q[ mrb_protect_error(mrb, final_mrbgems_body, &a, NULL);] + f.puts %Q[ mrb_gc_arena_restore(mrb, a.ai);] + f.puts %Q[ }] + f.puts %Q[}] + f.puts %Q[] + end f.puts %Q[void] f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {] - f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] - f.puts %Q[ for (int i = 0; i < NUM_GEMS; i++) {] - f.puts %Q[ gem_funcs[i].init(mrb);] - f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] - f.puts %Q[ mrb_vm_ci_env_clear(mrb, mrb->c->cibase);] - f.puts %Q[ if (mrb->exc) {] - f.puts %Q[ mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));] - f.puts %Q[ }] - f.puts %Q[ }] - f.puts %Q[ mrb_state_atexit(mrb, mrb_final_mrbgems);] + unless gem_funcs.empty? + f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] + f.puts %Q[ for (int i = 0; i < NUM_GEMS; i++) {] + f.puts %Q[ gem_funcs[i].init(mrb);] + f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] + f.puts %Q[ mrb_vm_ci_env_clear(mrb, mrb->c->cibase);] + f.puts %Q[ if (mrb->exc) {] + f.puts %Q[ mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));] + f.puts %Q[ }] + f.puts %Q[ }] + f.puts %Q[ mrb_state_atexit(mrb, mrb_final_mrbgems);] + end f.puts %Q[}] end end