Since universal-parser and prism support, prelude code used functions
inaccessible from outside libruby shared library.

```
linking goruby
/usr/bin/ld: goruby.o: in function `prelude_eval':
/home/runner/work/ruby/ruby/build/golf_prelude.c:221: undefined reference to `rb_ruby_prism_ptr'
/usr/bin/ld: goruby.o: in function `pm_prelude_load':
/home/runner/work/ruby/ruby/build/golf_prelude.c:192: undefined reference to `pm_options_line_set'
/usr/bin/ld: /home/runner/work/ruby/ruby/build/golf_prelude.c:193: undefined reference to `pm_parse_string'
/usr/bin/ld: goruby.o: in function `prelude_eval':
/home/runner/work/ruby/ruby/build/golf_prelude.c:224: undefined reference to `pm_iseq_new_with_opt'
/usr/bin/ld: /home/runner/work/ruby/ruby/build/golf_prelude.c:226: undefined reference to `pm_parse_result_free'
/usr/bin/ld: goruby.o: in function `prelude_ast_value':
/home/runner/work/ruby/ruby/build/golf_prelude.c:181: undefined reference to `rb_ruby_ast_data_get'
/usr/bin/ld: goruby.o: in function `prelude_eval':
/home/runner/work/ruby/ruby/build/golf_prelude.c:231: undefined reference to `rb_ruby_ast_data_get'
/usr/bin/ld: goruby.o: in function `pm_prelude_load':
/home/runner/work/ruby/ruby/build/golf_prelude.c:196: undefined reference to `pm_parse_result_free'
collect2: error: ld returned 1 exit status
```
This commit is contained in:
Nobuyoshi Nakada 2024-09-08 21:18:20 +09:00
Родитель 70871fa6e3
Коммит ecb58a8d08
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 3582D74E1FEE4465
6 изменённых файлов: 61 добавлений и 80 удалений

Просмотреть файл

@ -6,7 +6,7 @@ bin: $(PROGRAM) $(WPROGRAM)
lib: $(LIBRUBY)
dll: $(LIBRUBY_SO)
.SUFFIXES: .rbinc .rb .inc .h .c .y .i .$(ASMEXT) .$(DTRACE_EXT)
.SUFFIXES: .rbinc .rbbin .rb .inc .h .c .y .i .$(ASMEXT) .$(DTRACE_EXT)
# V=0 quiet, V=1 verbose. other values don't work.
V = 0
@ -291,7 +291,7 @@ DEFAULT_PRELUDES = $(GEM_PRELUDE)
PRELUDE_SCRIPTS = $(DEFAULT_PRELUDES)
GEM_PRELUDE =
PRELUDES = {$(srcdir)}miniprelude.c
GOLFPRELUDES = {$(srcdir)}golf_prelude.c
GOLFPRELUDES = golf_prelude.rbbin
SCRIPT_ARGS = --dest-dir="$(DESTDIR)" \
--extout="$(EXTOUT)" \
@ -1304,10 +1304,7 @@ $(MINIPRELUDE_C): $(COMPILE_PRELUDE) $(BUILTIN_RB_SRCS)
$(Q) $(BASERUBY) $(tooldir)/generic_erb.rb -I$(srcdir) -o $@ \
$(srcdir)/template/prelude.c.tmpl $(BUILTIN_RB_SRCS)
$(GOLF_PRELUDE_C): $(COMPILE_PRELUDE) {$(srcdir)}golf_prelude.rb
$(ECHO) generating $@
$(Q) $(BASERUBY) $(tooldir)/generic_erb.rb -I$(srcdir) -c -o $@ \
$(srcdir)/template/prelude.c.tmpl golf_prelude.rb
golf_prelude.rbbin: {$(srcdir)}golf_prelude.rb $(tooldir)/mk_rbbin.rb $(PREP)
MAINCPPFLAGS = $(ENABLE_DEBUG_ENV:yes=-DRUBY_DEBUG_ENV=1)
@ -1325,7 +1322,10 @@ probes.h: {$(VPATH)}probes.$(DTRACE_EXT)
prereq: incs srcs preludes PHONY
preludes: {$(VPATH)}miniprelude.c
preludes: {$(srcdir)}golf_prelude.c
{$(srcdir)}.rb.rbbin:
$(ECHO) making $@
$(Q) $(MINIRUBY) $(tooldir)/mk_rbbin.rb $< > $@
{$(srcdir)}.rb.rbinc:
$(ECHO) making $@
@ -7565,7 +7565,7 @@ goruby.$(OBJEXT): {$(VPATH)}config.h
goruby.$(OBJEXT): {$(VPATH)}constant.h
goruby.$(OBJEXT): {$(VPATH)}defines.h
goruby.$(OBJEXT): {$(VPATH)}encoding.h
goruby.$(OBJEXT): {$(VPATH)}golf_prelude.c
goruby.$(OBJEXT): {$(VPATH)}golf_prelude.rbbin
goruby.$(OBJEXT): {$(VPATH)}goruby.c
goruby.$(OBJEXT): {$(VPATH)}id.h
goruby.$(OBJEXT): {$(VPATH)}id_table.h

Просмотреть файл

@ -1,4 +1,4 @@
static void Init_golf(void);
static void Init_golf_prelude(void);
static void *goruby_options(int argc, char **argv);
static int goruby_run_node(void *arg);
#define ruby_options goruby_options
@ -17,14 +17,13 @@ static int goruby_run_node(void *arg);
RUBY_EXTERN void *ruby_options(int argc, char **argv);
RUBY_EXTERN int ruby_run_node(void*);
RUBY_EXTERN void ruby_init_ext(const char *name, void (*init)(void));
#include "golf_prelude.c"
#include "golf_prelude.rbbin"
static VALUE
init_golf(VALUE arg)
{
Init_golf();
Init_golf_prelude();
rb_provide("golf.so");
return arg;
}

Просмотреть файл

@ -252,7 +252,6 @@ INSTALLED_LIST= .installed.list
NEWLINE_C = enc/trans/newline.c
MINIPRELUDE_C = miniprelude.c
GOLF_PRELUDE_C= golf_prelude.c
RBCONFIG = .rbconfig.time
MAINSRC = $(MAINOBJ:.$(OBJEXT)=.c)

Просмотреть файл

@ -21,16 +21,11 @@ class Prelude
def initialize(output, preludes, vpath)
@output = output
@vpath = vpath
@prelude_count = 0
@builtin_count = 0
@preludes = {}
@mains = preludes.map do |filename|
if prelude = filename.end_with?("golf_prelude.rb")
@prelude_count += 1
else
@builtin_count += 1
end
translate(filename, (filename unless prelude))[0]
@builtin_count += 1
translate(filename, filename)[0]
end
@preludes.delete_if {|_, (_, _, lines, sub)| sub && lines.empty?}
end
@ -137,7 +132,6 @@ static const struct {
COMPILER_WARNING_POP
% 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))
@ -166,64 +160,10 @@ rb_builtin_find(const char *feature_name, VALUE *name_str, int *start_line)
return Qnil;
}
% end
% if @prelude_count > 0
COMPILER_WARNING_PUSH
#if GCC_VERSION_SINCE(4, 2, 0)
COMPILER_WARNING_ERROR(-Wmissing-field-initializers)
#endif
static void
prelude_eval(VALUE code, VALUE name, int line)
{
static const rb_compile_option_t optimization = {
TRUE, /* unsigned int inline_const_cache; */
TRUE, /* unsigned int peephole_optimization; */
FALSE,/* unsigned int tailcall_optimization; */
TRUE, /* unsigned int specialized_instruction; */
TRUE, /* unsigned int operands_unification; */
TRUE, /* unsigned int instructions_unification; */
TRUE, /* unsigned int frozen_string_literal; */
FALSE, /* unsigned int debug_frozen_string_literal; */
FALSE, /* unsigned int coverage_enabled; */
0, /* int debug_level; */
};
if (*rb_ruby_prism_ptr()) {
pm_parse_result_t result = { 0 };
pm_prelude_load(&result, name, code, line);
rb_iseq_eval(pm_iseq_new_with_opt(&result.node, name, name, Qnil, line,
NULL, 0, ISEQ_TYPE_TOP, &optimization));
pm_parse_result_free(&result);
}
else {
rb_ast_t *ast;
VALUE ast_value = prelude_ast_value(name, code, line);
ast = rb_ruby_ast_data_get(ast_value);
rb_iseq_eval(rb_iseq_new_with_opt(ast_value, name, name, Qnil, line,
NULL, 0, ISEQ_TYPE_TOP, &optimization,
Qnil));
rb_ast_dispose(ast);
}
}
COMPILER_WARNING_POP
% end
%end
% init_name = @output && @output[/\w+(?=_prelude.c\b)/] || 'prelude'
void
Init_<%=init_name%><%=%>(void)
{
%unless @prelude_count.zero?
% preludes.each do |i, prelude, lines, sub, start_line|
% next if sub
prelude_eval(PRELUDE_CODE(<%=i%><%=%>), PRELUDE_NAME(<%=i%><%=%>), <%=start_line%><%=%>);
% end
#if 0
% preludes.length.times {|i|
printf("%.*s", (int)sizeof(prelude_code<%=i%><%=%>), prelude_code<%=i%><%=%>.L0);
% }
#endif
%end
}
<%end -%>

48
tool/mk_rbbin.rb Executable file
Просмотреть файл

@ -0,0 +1,48 @@
#!ruby -s
OPTIMIZATION = {
inline_const_cache: true,
peephole_optimization: true,
tailcall_optimization: false,
specialized_instruction: true,
operands_unification: true,
instructions_unification: true,
frozen_string_literal: true,
debug_frozen_string_literal: false,
coverage_enabled: false,
debug_level: 0,
}
file = File.basename(ARGV[0], ".rb")
name = "<internal:#{file}>"
iseq = RubyVM::InstructionSequence.compile(ARGF.read, name, name, **OPTIMIZATION)
puts <<C
/* -*- C -*- */
static const char #{file}_builtin[] = {
C
iseq.to_binary.bytes.each_slice(8) do |b|
print " ", b.map {|c| "0x%.2x," % c}.join(" ")
if $comment
print " /* ", b.pack("C*").gsub(/([[ -~]&&[^\\]])|(?m:.)/) {
(c = $1) ? "#{c} " : (c = $&.dump).size == 2 ? c : ". "
}, "*/"
end
puts
end
puts <<C
};
#include "ruby/ruby.h"
#include "vm_core.h"
void
Init_#{file}(void)
{
const char *builtin = #{file}_builtin;
size_t size = sizeof(#{file}_builtin);
VALUE code = rb_str_new_static(builtin, (long)size);
VALUE iseq = rb_funcallv(rb_cISeq, rb_intern_const("load_from_binary"), 1, &code);
rb_funcallv(iseq, rb_intern_const("eval"), 0, 0);
}
C

Просмотреть файл

@ -547,11 +547,6 @@ MINIPRELUDE_C = $(srcdir)/miniprelude.c
!else
MINIPRELUDE_C = miniprelude.c
!endif
!if !exist(golf_prelude.c) && exist($(srcdir)/golf_prelude.c)
GOLF_PRELUDE_C = $(srcdir)/golf_prelude.c
!else
GOLF_PRELUDE_C = golf_prelude.c
!endif
RBCONFIG = ./.rbconfig.time
!if "$(GITHUB_ACTIONS)" == "true"