summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--template/prelude.c.tmpl70
-rw-r--r--tool/mk_builtin_loader.rb36
2 files changed, 41 insertions, 65 deletions
diff --git a/template/prelude.c.tmpl b/template/prelude.c.tmpl
index ac748704ed..58453636bf 100644
--- a/template/prelude.c.tmpl
+++ b/template/prelude.c.tmpl
@@ -20,7 +20,6 @@ class Prelude
def initialize(output, preludes, vpath)
@output = output
- @have_sublib = false
@vpath = vpath
@prelude_count = 0
@builtin_count = 0
@@ -64,8 +63,10 @@ class Prelude
end
path = translate("#{path}.rb", true) rescue nil
if path
- @have_sublib = true
- "TMP_RUBY_PREFIX.require(#{path[0]})"
+ # This library will be loaded before this,
+ # the order cannot be preserved
+ comment = "#{orig} #{comment}".rstrip
+ ""
else
orig
end
@@ -131,24 +132,6 @@ static const struct {
COMPILER_WARNING_POP
-% if @have_sublib
-#define PRELUDE_COUNT <%=preludes.size%>
-
-struct prelude_env {
- volatile VALUE prefix_path;
-#if PRELUDE_COUNT > 0
- char loaded[PRELUDE_COUNT];
-#endif
-};
-
-static VALUE
-prelude_prefix_path(VALUE self)
-{
- struct prelude_env *ptr = DATA_PTR(self);
- return ptr->prefix_path;
-}
-
-% 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))
@@ -179,7 +162,7 @@ rb_builtin_ast(const char *feature_name, VALUE *name_str)
rb_ast_t *ast = 0;
% @preludes.each_value do |i, prelude, lines, sub, start_line|
-% if sub and sub != true
+% if sub
if ((ast = PRELUDE_AST(<%=i%><%=%>, *name_str, <%=start_line%>)) != 0) return ast;
% end
% end
@@ -217,55 +200,12 @@ prelude_eval(VALUE code, VALUE name, int line)
COMPILER_WARNING_POP
% end
-% if @have_sublib
-static VALUE
-prelude_require(VALUE self, VALUE nth)
-{
- struct prelude_env *ptr = DATA_PTR(self);
- VALUE code, name;
- int n = FIX2INT(nth);
- int start_line;
-
- if (n > PRELUDE_COUNT) return Qfalse;
- if (ptr->loaded[n]) return Qfalse;
- ptr->loaded[n] = 1;
- switch (n) {
-% @preludes.each_value do |i, prelude, lines, sub, start_line|
-% if sub == true
- case <%=i%><%=%>:
- code = PRELUDE_CODE(<%=i%><%=%>);
- name = PRELUDE_NAME(<%=i%><%=%>);
- start_line = <%=start_line%>;
- break;
-% end
-% end
- default:
- return Qfalse;
- }
- prelude_eval(code, name, start_line);
- return Qtrue;
-}
-
-% end
%end
% init_name = @output && @output[/\w+(?=_prelude.c\b)/] || 'prelude'
void
Init_<%=init_name%><%=%>(void)
{
%unless @prelude_count.zero?
-% if @have_sublib
- struct prelude_env memo;
- ID name = rb_intern("TMP_RUBY_PREFIX");
- VALUE prelude = Data_Wrap_Struct(rb_cObject, 0, 0, &memo);
-
- memo.prefix_path = rb_const_remove(rb_cObject, name);
- rb_const_set(rb_cObject, name, prelude);
- rb_define_singleton_method(prelude, "to_s", prelude_prefix_path, 0);
-% end
-% if @have_sublib
- memset(memo.loaded, 0, sizeof(memo.loaded));
- rb_define_singleton_method(prelude, "require", prelude_require, 1);
-% end
% preludes.each do |i, prelude, lines, sub, start_line|
% next if sub
prelude_eval(PRELUDE_CODE(<%=i%><%=%>), PRELUDE_NAME(<%=i%><%=%>), <%=start_line%>);
diff --git a/tool/mk_builtin_loader.rb b/tool/mk_builtin_loader.rb
index 23e6a01017..784dd30dc1 100644
--- a/tool/mk_builtin_loader.rb
+++ b/tool/mk_builtin_loader.rb
@@ -4,6 +4,9 @@ require 'ripper'
require 'stringio'
require_relative 'ruby_vm/helpers/c_escape'
+SUBLIBS = {}
+REQUIRED = {}
+
def string_literal(lit, str = [])
while lit
case lit.first
@@ -174,6 +177,21 @@ def collect_builtin base, tree, name, bs, inlines, locals = nil
end
bs[func_name] = [argc, cfunc_name] if func_name
+ elsif /\Arequire(?:_relative)\z/ =~ mid and args.size == 1 and
+ (arg1 = args[0])[0] == :string_literal and
+ (arg1 = arg1[1])[0] == :string_content and
+ (arg1 = arg1[1])[0] == :@tstring_content and
+ sublib = arg1[1]
+ if File.exist?(f = File.join(@dir, sublib)+".rb")
+ puts "- #{@base}.rb requires #{sublib}"
+ if REQUIRED[sublib]
+ warn "!!! #{sublib} is required from #{REQUIRED[sublib]} already; ignored"
+ else
+ REQUIRED[sublib] = @base
+ (SUBLIBS[@base] ||= []) << sublib
+ end
+ ARGV.push(f)
+ end
end
break unless tree = args
end
@@ -242,7 +260,9 @@ def generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_nam
end
def mk_builtin_header file
+ @dir = File.dirname(file)
base = File.basename(file, '.rb')
+ @base = base
ofile = "#{file}inc"
# bs = { func_name => argc }
@@ -331,6 +351,14 @@ def mk_builtin_header file
f.puts
}
+ if SUBLIBS[base]
+ f.puts "// sub libraries"
+ SUBLIBS[base].each do |sub|
+ f.puts %[#include #{(sub+".rbinc").dump}]
+ end
+ f.puts
+ end
+
f.puts "void Init_builtin_#{base}(void)"
f.puts "{"
@@ -354,6 +382,14 @@ def mk_builtin_header file
}
f.puts "COMPILER_WARNING_POP"
+ if SUBLIBS[base]
+ f.puts
+ f.puts " // sub libraries"
+ SUBLIBS[base].each do |sub|
+ f.puts " Init_builtin_#{sub}();"
+ end
+ end
+
f.puts
f.puts " // load"
f.puts " rb_load_with_builtin_functions(#{base.dump}, #{table});"