ruby-changes:58676
From: Nobuyoshi <ko1@a...>
Date: Sat, 9 Nov 2019 19:40:29 +0900 (JST)
Subject: [ruby-changes:58676] dfaac2b372 (master): Embed builtin ruby scripts in miniprelude.c
https://git.ruby-lang.org/ruby.git/commit/?id=dfaac2b372 From dfaac2b37253ff25ec873c2fbd93abfa7f789248 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Sat, 9 Nov 2019 19:28:45 +0900 Subject: Embed builtin ruby scripts in miniprelude.c Instead of reading from the files by the full-path at runtime. As rbinc files need to be included in distributed tarballs, the full-paths at the packaging are unavailable at compilation times. diff --git a/common.mk b/common.mk index 56eba97..6996ae5 100644 --- a/common.mk +++ b/common.mk @@ -1072,7 +1072,7 @@ vm_call_iseq_optimized.inc: $(srcdir)/tool/mk_call_iseq_optimized.rb https://github.com/ruby/ruby/blob/trunk/common.mk#L1072 $(MINIPRELUDE_C): $(COMPILE_PRELUDE) $(ECHO) generating $@ $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -o $@ \ - $(srcdir)/template/prelude.c.tmpl + $(srcdir)/template/prelude.c.tmpl $(BUILTIN_RB_SRCS) $(PRELUDE_C): $(COMPILE_PRELUDE) \ $(PRELUDE_SCRIPTS) diff --git a/mini_builtin.c b/mini_builtin.c index dc95919..290a4b3 100644 --- a/mini_builtin.c +++ b/mini_builtin.c @@ -5,55 +5,21 @@ https://github.com/ruby/ruby/blob/trunk/mini_builtin.c#L5 // include from miniinits.c -static const char * -read_file(const char *fname, size_t *psize) -{ - struct stat st; - char *code; - FILE *fp; - - if (stat(fname, &st) != 0) { - rb_bug("stat fails: %s", fname); - } - - size_t fsize = st.st_size; - if ((code = malloc(fsize + 1)) == NULL) { - rb_bug("can't allocate memory: %s (%d)", fname, (int)fsize); - } - - if ((fp = fopen(fname, "rb")) == NULL) { - rb_bug("can't open file: %s", fname); - } - - size_t read_size = fread(code, 1, fsize, fp); - if (read_size != fsize) { - rb_bug("can't read file enough: %s (expect %d but was %d)", fname, (int)fsize, (int)read_size); - } - - code[fsize] = 0; - *psize = fsize; - return code; -} - static struct st_table *loaded_builtin_table; +rb_ast_t *rb_builtin_ast(const char *feature_name, VALUE *name_str); + void rb_load_with_builtin_functions(const char *feature_name, const char *fname, const struct rb_builtin_function *table) { - size_t fsize; - const char *code = read_file(fname, &fsize); - VALUE code_str = rb_utf8_str_new_static(code, fsize); - VALUE name_str = rb_sprintf("<internal:%s>", feature_name); - rb_obj_hide(code_str); - - rb_ast_t *ast = rb_parser_compile_string_path(rb_parser_new(), name_str, code_str, 1); + VALUE name_str = 0; + rb_ast_t *ast = rb_builtin_ast(feature_name, &name_str); GET_VM()->builtin_function_table = table; const rb_iseq_t *iseq = rb_iseq_new(&ast->body, name_str, name_str, Qnil, NULL, ISEQ_TYPE_TOP); GET_VM()->builtin_function_table = NULL; rb_ast_dispose(ast); - free((void *)code); // code_str becomes broken. // register (loaded iseq will not be freed) st_insert(loaded_builtin_table, (st_data_t)feature_name, (st_data_t)iseq); diff --git a/template/prelude.c.tmpl b/template/prelude.c.tmpl index 4b3a38e..33f6a68 100644 --- a/template/prelude.c.tmpl +++ b/template/prelude.c.tmpl @@ -34,8 +34,17 @@ class Prelude https://github.com/ruby/ruby/blob/trunk/template/prelude.c.tmpl#L34 @output = output @have_sublib = false @vpath = vpath + @prelude_count = 0 + @builtin_count = 0 @preludes = {} - @mains = preludes.map {|filename| translate(filename)[0]} + @mains = preludes.map do |filename| + if prelude = filename.end_with?("prelude.rb") + @prelude_count += 1 + else + @builtin_count += 1 + end + translate(filename, (filename unless prelude))[0] + end @preludes.delete_if {|_, (_, _, lines, sub)| sub && lines.empty?} end @@ -134,11 +143,47 @@ prelude_prefix_path(VALUE self) https://github.com/ruby/ruby/blob/trunk/template/prelude.c.tmpl#L143 struct prelude_env *ptr = DATA_PTR(self); return ptr->prefix_path; } -% end +% end % unless preludes.empty? #define PRELUDE_NAME(n) rb_usascii_str_new_static(prelude_name##n, sizeof(prelude_name##n)-1) #define PRELUDE_CODE(n) rb_utf8_str_new_static(prelude_code##n.L0, sizeof(prelude_code##n)) + +static rb_ast_t * +prelude_ast(VALUE name, VALUE code, int line) +{ + rb_ast_t *ast = rb_parser_compile_string_path(rb_parser_new(), name, code, line); + if (!ast->body.root) { + rb_ast_dispose(ast); + rb_exc_raise(rb_errinfo()); + } + return ast; +} + +% end +% if @builtin_count > 0 +#define PRELUDE_AST(n, name_str) \ + (((sizeof(prelude_name<%='##'%><%=%>n) - prefix_len - 2) == namelen) && \ + (strncmp(prelude_name<%='##'%><%=%>n + prefix_len, feature_name, namelen) == 0) ? \ + prelude_ast((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), 1) : 0) + +rb_ast_t * +rb_builtin_ast(const char *feature_name, VALUE *name_str) +{ + const size_t prefix_len = rb_strlen_lit("<internal:"); + size_t namelen = strlen(feature_name); + rb_ast_t *ast = 0; + +% @preludes.each_value do |i, prelude, lines, sub| +% if sub and sub != true + if ((ast = PRELUDE_AST(<%=i%><%=%>, *name_str)) != 0) return ast; +% end +% end + return ast; +} + +% end +% if @prelude_count > 0 COMPILER_WARNING_PUSH #if GCC_VERSION_SINCE(4, 2, 0) COMPILER_WARNING_ERROR(-Wmissing-field-initializers) @@ -160,18 +205,14 @@ prelude_eval(VALUE code, VALUE name, int line) https://github.com/ruby/ruby/blob/trunk/template/prelude.c.tmpl#L205 0, /* int debug_level; */ }; - rb_ast_t *ast = rb_parser_compile_string_path(rb_parser_new(), name, code, line); - if (!ast->body.root) { - rb_ast_dispose(ast); - rb_exc_raise(rb_errinfo()); - } + rb_ast_t *ast = prelude_ast(name, code, line); rb_iseq_eval(rb_iseq_new_with_opt(&ast->body, name, name, Qnil, INT2FIX(line), NULL, ISEQ_TYPE_TOP, &optimization)); rb_ast_dispose(ast); } COMPILER_WARNING_POP -% end +% end % if @have_sublib static VALUE prelude_require(VALUE self, VALUE nth) @@ -185,7 +226,7 @@ prelude_require(VALUE self, VALUE nth) https://github.com/ruby/ruby/blob/trunk/template/prelude.c.tmpl#L226 ptr->loaded[n] = 1; switch (n) { % @preludes.each_value do |i, prelude, lines, sub| -% if sub +% if sub == true case <%=i%><%=%>: code = PRELUDE_CODE(<%=i%><%=%>); name = PRELUDE_NAME(<%=i%><%=%>); @@ -205,7 +246,7 @@ prelude_require(VALUE self, VALUE nth) https://github.com/ruby/ruby/blob/trunk/template/prelude.c.tmpl#L246 void Init_<%=init_name%><%=%>(void) { -%unless @preludes.empty? +%unless @prelude_count.zero? % if @have_sublib struct prelude_env memo; ID name = rb_intern("TMP_RUBY_PREFIX"); -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/