Support sub-library in builtin-loader
Previously, it was supported in prelude.c, but has not followed up the builtin-loader system.
This commit is contained in:
parent
56e5210cde
commit
9faa9ced96
Notes:
git
2022-09-09 15:47:48 +09:00
@ -20,7 +20,6 @@ class Prelude
|
|||||||
|
|
||||||
def initialize(output, preludes, vpath)
|
def initialize(output, preludes, vpath)
|
||||||
@output = output
|
@output = output
|
||||||
@have_sublib = false
|
|
||||||
@vpath = vpath
|
@vpath = vpath
|
||||||
@prelude_count = 0
|
@prelude_count = 0
|
||||||
@builtin_count = 0
|
@builtin_count = 0
|
||||||
@ -64,8 +63,10 @@ class Prelude
|
|||||||
end
|
end
|
||||||
path = translate("#{path}.rb", true) rescue nil
|
path = translate("#{path}.rb", true) rescue nil
|
||||||
if path
|
if path
|
||||||
@have_sublib = true
|
# This library will be loaded before this,
|
||||||
"TMP_RUBY_PREFIX.require(#{path[0]})"
|
# the order cannot be preserved
|
||||||
|
comment = "#{orig} #{comment}".rstrip
|
||||||
|
""
|
||||||
else
|
else
|
||||||
orig
|
orig
|
||||||
end
|
end
|
||||||
@ -131,24 +132,6 @@ static const struct {
|
|||||||
|
|
||||||
COMPILER_WARNING_POP
|
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?
|
% unless preludes.empty?
|
||||||
#define PRELUDE_NAME(n) rb_usascii_str_new_static(prelude_name##n, sizeof(prelude_name##n)-1)
|
#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))
|
#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;
|
rb_ast_t *ast = 0;
|
||||||
|
|
||||||
% @preludes.each_value do |i, prelude, lines, sub, start_line|
|
% @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;
|
if ((ast = PRELUDE_AST(<%=i%><%=%>, *name_str, <%=start_line%>)) != 0) return ast;
|
||||||
% end
|
% end
|
||||||
% end
|
% end
|
||||||
@ -216,36 +199,6 @@ prelude_eval(VALUE code, VALUE name, int line)
|
|||||||
}
|
}
|
||||||
COMPILER_WARNING_POP
|
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
|
||||||
%end
|
%end
|
||||||
% init_name = @output && @output[/\w+(?=_prelude.c\b)/] || 'prelude'
|
% init_name = @output && @output[/\w+(?=_prelude.c\b)/] || 'prelude'
|
||||||
@ -253,19 +206,6 @@ void
|
|||||||
Init_<%=init_name%><%=%>(void)
|
Init_<%=init_name%><%=%>(void)
|
||||||
{
|
{
|
||||||
%unless @prelude_count.zero?
|
%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|
|
% preludes.each do |i, prelude, lines, sub, start_line|
|
||||||
% next if sub
|
% next if sub
|
||||||
prelude_eval(PRELUDE_CODE(<%=i%><%=%>), PRELUDE_NAME(<%=i%><%=%>), <%=start_line%>);
|
prelude_eval(PRELUDE_CODE(<%=i%><%=%>), PRELUDE_NAME(<%=i%><%=%>), <%=start_line%>);
|
||||||
|
@ -4,6 +4,9 @@ require 'ripper'
|
|||||||
require 'stringio'
|
require 'stringio'
|
||||||
require_relative 'ruby_vm/helpers/c_escape'
|
require_relative 'ruby_vm/helpers/c_escape'
|
||||||
|
|
||||||
|
SUBLIBS = {}
|
||||||
|
REQUIRED = {}
|
||||||
|
|
||||||
def string_literal(lit, str = [])
|
def string_literal(lit, str = [])
|
||||||
while lit
|
while lit
|
||||||
case lit.first
|
case lit.first
|
||||||
@ -174,6 +177,21 @@ def collect_builtin base, tree, name, bs, inlines, locals = nil
|
|||||||
end
|
end
|
||||||
|
|
||||||
bs[func_name] = [argc, cfunc_name] if func_name
|
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
|
end
|
||||||
break unless tree = args
|
break unless tree = args
|
||||||
end
|
end
|
||||||
@ -242,7 +260,9 @@ def generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_nam
|
|||||||
end
|
end
|
||||||
|
|
||||||
def mk_builtin_header file
|
def mk_builtin_header file
|
||||||
|
@dir = File.dirname(file)
|
||||||
base = File.basename(file, '.rb')
|
base = File.basename(file, '.rb')
|
||||||
|
@base = base
|
||||||
ofile = "#{file}inc"
|
ofile = "#{file}inc"
|
||||||
|
|
||||||
# bs = { func_name => argc }
|
# bs = { func_name => argc }
|
||||||
@ -331,6 +351,14 @@ def mk_builtin_header file
|
|||||||
f.puts
|
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 "void Init_builtin_#{base}(void)"
|
||||||
f.puts "{"
|
f.puts "{"
|
||||||
|
|
||||||
@ -354,6 +382,14 @@ def mk_builtin_header file
|
|||||||
}
|
}
|
||||||
f.puts "COMPILER_WARNING_POP"
|
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
|
||||||
f.puts " // load"
|
f.puts " // load"
|
||||||
f.puts " rb_load_with_builtin_functions(#{base.dump}, #{table});"
|
f.puts " rb_load_with_builtin_functions(#{base.dump}, #{table});"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user