mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Shrink <BUILD-DIR>/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.
This commit is contained in:
+49
-45
@@ -38,53 +38,57 @@ MRuby.each_target do
|
||||
f.puts %Q[#include <mruby/error.h>]
|
||||
f.puts %Q[#include <mruby/proc.h>]
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user