Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native support of mruby-cli in mruby build system. #3956

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
42 changes: 42 additions & 0 deletions Rakefile
Expand Up @@ -25,6 +25,8 @@ end
load "#{MRUBY_ROOT}/src/mruby_core.rake"
load "#{MRUBY_ROOT}/mrblib/mrblib.rake"

load "#{MRUBY_ROOT}/tasks/cli.rake"

load "#{MRUBY_ROOT}/tasks/mrbgems.rake"
load "#{MRUBY_ROOT}/tasks/libmruby.rake"

Expand Down Expand Up @@ -65,6 +67,46 @@ MRuby.each_target do |target|
exec = exefile("#{build_dir}/bin/#{bin}")
objs = Dir.glob("#{current_dir}/tools/#{bin}/*.{c,cpp,cxx,cc}").map { |f| objfile(f.pathmap("#{current_build_dir}/tools/#{bin}/%n")) }

rbfiles = Dir.glob("#{current_dir}/tools/#{bin}/*.rb").sort
unless rbfiles.empty?
main_script = "#{current_dir}/tools/#{bin}/main.rb"
has_main_script = rbfiles.find { |v| v == main_script }
rbfiles.reject { |v| v == main_script }
rbfiles << main_script if has_main_script

irep_file = "#{current_build_dir}/tools/#{bin}/tool__#{bin}__init.c"
file exec => libfile("#{build_dir}/lib/libmruby_cli_main") if objs.empty?
objs << objfile(irep_file.pathmap("#{current_build_dir}/tools/#{bin}/%n"))
file objs.last => irep_file

gem_table = target.gems.generate_gem_table target

file irep_file => rbfiles do |t|
FileUtils.mkdir_p File.dirname irep_file
open(irep_file, 'w') do |f|
f.puts '#include <mruby.h>'
sym_name = 'mrb_main_irep'
mrbc.run f, t.prerequisites, sym_name

dep_list = target.gems.tsort_dependencies([gem.name], gem_table).select(&:generate_functions)
dep_list.each do |d|
f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);]
f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);]
end
f.puts 'mrb_state *mrb_open_cli() {'
f.puts ' mrb_state *mrb = mrb_open_core(mrb_default_allocf, NULL);'
f.puts ' int ai = mrb_gc_arena_save(mrb);'
dep_list.each do |d|
f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb);]
f.puts %Q[ mrb_state_atexit(mrb, GENERATED_TMP_mrb_#{d.funcname}_gem_final);]
end
f.puts ' mrb_gc_arena_restore(mrb, ai);'
f.puts ' return mrb;'
f.puts '}'
end
end
end

file exec => objs + [libfile("#{build_dir}/lib/libmruby")] do |t|
gem_flags = gems.map { |g| g.linker.flags }
gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries }
Expand Down
5 changes: 5 additions & 0 deletions include/mruby/class.h
Expand Up @@ -89,6 +89,11 @@ void mrb_gc_mark_mt(mrb_state*, struct RClass*);
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
void mrb_gc_free_mt(mrb_state*, struct RClass*);

extern mrb_int
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry these corresponds to those in CRuby:
https://github.com/ruby/ruby/blob/421a73f51a39ff6829f9715b423a928782ec8ec3/vm.c#L339-L341
And it should be mrb_state specific.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should be optional like VM hooks.

mrb_vm_global_method_state,
mrb_vm_global_constant_state,
mrb_vm_class_serial;

MRB_END_DECL

#endif /* MRUBY_CLASS_H */
4 changes: 4 additions & 0 deletions include/mruby/dump.h
Expand Up @@ -22,6 +22,9 @@ MRB_BEGIN_DECL
#define DUMP_ENDIAN_NAT 6
#define DUMP_ENDIAN_MASK 6

#define MRB_READ_FLAG_SRC_MALLOC 1
#define MRB_READ_FLAG_SRC_STATIC 0

int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
#ifndef MRB_DISABLE_STDIO
int mrb_dump_irep_binary(mrb_state*, mrb_irep*, uint8_t, FILE*);
Expand All @@ -31,6 +34,7 @@ MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*);
MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*);
#endif
MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
MRB_API mrb_irep *mrb_read_irep_flags(mrb_state*, const uint8_t*, uint8_t flags);

/* dump/load error code
*
Expand Down
5 changes: 5 additions & 0 deletions mrbgems/mruby-bin-strip/mrbgem.rake
Expand Up @@ -3,4 +3,9 @@ MRuby::Gem::Specification.new('mruby-bin-strip') do |spec|
spec.author = 'mruby developers'
spec.summary = 'irep dump debug section remover command'
spec.bins = %w(mruby-strip)

add_dependency 'mruby-mrubyvm'
add_dependency 'mruby-exit'
add_dependency 'mruby-io'
add_dependency 'mruby-array-ext'
end
155 changes: 0 additions & 155 deletions mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c

This file was deleted.

45 changes: 45 additions & 0 deletions mrbgems/mruby-bin-strip/tools/mruby-strip/strip.rb
@@ -0,0 +1,45 @@
def print_usage_exit msg = nil
$stderr.write msg if msg
$stderr.write "Usage: #{$0} [switches] irepfiles\n"
$stderr.write "switches:\n"
$stderr.write " -l, --lvar remove LVAR section too.\n"
exit 1
end

print_usage_exit "no files to strip\n" if ARGV.empty?

$remove_lvar = false
targets = []

ARGV.each do |v|
case v
when '-l', '--lvar'
$remove_lvar = true
next
else
print_usage_exit "invalid flag: #{v}" if v[0] == '-'
end

targets << v
end

targets.each do |fname|
iseq = nil

# load
begin
iseq = MRubyVM::InstructionSequence.load_from_binary File.read(fname, mode: 'rb')
iseq.remove_lvar if $remove_lvar
rescue ScriptError
$stderr.write "can't read irep file #{fname}\n"
exit 1
rescue
$stderr.write "can't open file for reading #{fname}\n"
exit 1
end

# re-dump
File.open fname, 'wb' do |f|
f.write iseq.to_binary mrb_debug_info: false
end
end
8 changes: 8 additions & 0 deletions mrbgems/mruby-mrubyvm/mrbgem.rake
@@ -0,0 +1,8 @@
MRuby::Gem::Specification.new 'mruby-mrubyvm' do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'mruby implementation of `RubyVM`'

add_dependency 'mruby-compiler'
end