diff options
32 files changed, 1016 insertions, 550 deletions
@@ -25,12 +25,11 @@ end # load custom rules load "#{MRUBY_ROOT}/tasks/core.rake" load "#{MRUBY_ROOT}/tasks/mrblib.rake" - load "#{MRUBY_ROOT}/tasks/mrbgems.rake" load "#{MRUBY_ROOT}/tasks/libmruby.rake" - +load "#{MRUBY_ROOT}/tasks/bin.rake" +load "#{MRUBY_ROOT}/tasks/presym.rake" load "#{MRUBY_ROOT}/tasks/benchmark.rake" - load "#{MRUBY_ROOT}/tasks/gitlab.rake" load "#{MRUBY_ROOT}/tasks/doc.rake" @@ -38,219 +37,19 @@ load "#{MRUBY_ROOT}/tasks/doc.rake" # generic build targets, rules task :default => :all -bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin" - -if MRuby.targets['host'] - target = MRuby.targets['host'] - depfiles = target.bins.map do |bin| - install_path = target.exefile("#{bin_path}/#{bin}") - source_path = target.exefile("#{target.build_dir}/bin/#{bin}") - - file install_path => source_path do |t| - install_D t.prerequisites.first, t.name - end - install_path - end -else - depfiles = [] -end - -cfiles = Dir.glob("#{MRUBY_ROOT}/src/*.c") -rbfiles = Dir.glob("#{MRUBY_ROOT}/mrblib/**/*.rb") -psfiles = [] -MRuby.each_target do |target| - gems.each do |gem| - current_dir = gem.dir.relative_path_from(Dir.pwd) - relative_from_root = gem.dir.relative_path_from(MRUBY_ROOT) - current_build_dir = File.expand_path "#{build_dir}/#{relative_from_root}" - - if current_build_dir !~ /^#{Regexp.escape(build_dir)}/ - current_build_dir = "#{build_dir}/mrbgems/#{gem.name}" - end - - gem.bins.each do |bin| - 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")) } - - file exec => objs + target.libraries do |t| - gem_flags = gems.map { |g| g.linker.flags } - gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries } - gem_flags_after_libraries = gems.map { |g| g.linker.flags_after_libraries } - gem_libraries = gems.map { |g| g.linker.libraries } - gem_library_paths = gems.map { |g| g.linker.library_paths } - linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries, gem_flags_after_libraries - end - - if target == MRuby.targets['host'] - install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}") - - file install_path => exec do |t| - install_D t.prerequisites.first, t.name - end - depfiles += [ install_path ] - else - depfiles += [ exec ] - end - end - - cfiles += Dir.glob(gem.dir+"/{src,core,tools/*}/*.c") - if gem.cdump? - rbfiles += Dir.glob(gem.dir+"/mrblib/**/*.rb") - psfiles += Dir.glob(gem.dir+"/**/presym") - end - end -end - -mkdir_p "#{MRUBY_ROOT}/build" -symbols = [] -psfiles.each do |file| - symbols += File.readlines(file).grep_v(/^# /) -end -symbols.each{|x| x.chomp!} -presym_file="#{MRUBY_ROOT}/build/presym" -presym_inc="#{presym_file}.inc" -op_table = { - "!" => "not", - "!=" => "neq", - "!~" => "nmatch", - "%" => "mod", - "&" => "and", - "&&" => "andand", - "*" => "mul", - "**" => "pow", - "+" => "add", - "+@" => "plus", - "-" => "sub", - "-@" => "minus", - "/" => "div", - "<" => "lt", - "<=" => "le", - "<<" => "lshift", - "<=>" => "cmp", - "==" => "eq", - "===" => "eqq", - "=~" => "match", - ">" => "gt", - ">=" => "ge", - ">>" => "rshift", - "[]" => "aref", - "[]=" => "aset", - "^" => "xor", - "`" => "tick", - "|" => "or", - "||" => "oror", - "~" => "neg", -} -macro_to_symbol = { -# Macro Symbol -# [prefix, suffix] => [prefix, suffix] - ["CV" , "" ] => ["@@" , "" ], - ["IV" , "" ] => ["@" , "" ], - ["" , "_B" ] => ["" , "!" ], - ["" , "_Q" ] => ["" , "?" ], - ["" , "_E" ] => ["" , "=" ], - ["" , "" ] => ["" , "" ], -} - -file presym_file => cfiles+rbfiles+psfiles+[__FILE__] do - prefix_re = Regexp.union(*macro_to_symbol.keys.map(&:first).uniq) - suffix_re = Regexp.union(*macro_to_symbol.keys.map(&:last).uniq) - macro_re = /MRB_(#{prefix_re})SYM(#{suffix_re})\((\w+)\)/o - csymbols = cfiles.map do |f| - src = File.read(f) - src.gsub!(/\/\/.+(\n|$)/, "\n") - [src.scan(/intern_lit\([^\n"]*"([^\n "]*)"/), - src.scan(/mrb_define_method\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_class_method\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_class\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_module\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_module_function\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_const\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_global_const\([^\n"]*"([^\n"]*)"/), - src.scan(macro_re).map{|prefix, suffix, name| - macro_to_symbol[[prefix, suffix]] * name - }] - end - csymbols += File.readlines("#{MRUBY_ROOT}/include/mruby.h").grep(/define E_/).join.scan(/MRB_SYM\((\w+)\)/) - - rbsymbols = rbfiles.map do |f| - src = File.read(f) - src.force_encoding(Encoding::BINARY) - [src.scan(/\bclass +([A-Z]\w*)/), - src.scan(/\bmodule +([A-Z]\w*)/), - src.scan(/\bdef +(\w+[!?=]?)/), - src.scan(/\balias +(\w+[!?]?)/), - src.scan(/\b([A-Z]\w*) *=[^=]/), - src.scan(/(\$[a-zA-Z_]\w*)/), - src.scan(/(\$[$!?0-9]\w*)/), - src.scan(/(@@?[a-zA-Z_]\w*)/), - src.scan(/[^.]\.([a-zA-Z_]\w*[!?]?)/), - src.scan(/\.([a-zA-Z_]\w* *=)/).map{|x|x.map{|s|s.gsub(' ', '')}}, - src.scan(/\b([a-zA-Z_]\w*):/), - src.scan(/:([a-zA-Z_]\w*[!?=]?)/), - src.scan(/[\(\[\{ ]:"([^"]+)"/).map{|x|x.map{|s|s.gsub('\#', '#')}}, - src.scan(/[ \(\[\{]:'([^']+)'/) - ] - end - symbols = (symbols+csymbols+rbsymbols+op_table.keys).flatten.compact.uniq.grep_v(/#/).map{|x| x.gsub("\n", '\n')}.sort_by!{|x| [x.bytesize, x]} - presyms = File.readlines(presym_file) rescue [] - presyms.each{|x| x.chomp!} - if presyms != symbols - _pp "GEN", presym_file.relative_path - File.write(presym_file, symbols.join("\n")) - Rake::Task[presym_inc].invoke - end -end - -task presym_inc do - presyms = File.readlines(presym_file) - presyms.each{|x| x.chomp!} - symbol_to_macro = macro_to_symbol.invert - prefix_re = Regexp.union(*symbol_to_macro.keys.map(&:first).uniq) - suffix_re = Regexp.union(*symbol_to_macro.keys.map(&:last).uniq) - sym_re = /\A(#{prefix_re})?([\w&&\D]\w*)(#{suffix_re})?\z/o - _pp "GEN", presym_inc.relative_path - File.open(presym_inc, "w") do |f| - f.puts "/* MRB_PRESYM_NAMED(lit, num, type, name) */" - f.puts "/* MRB_PRESYM_UNNAMED(lit, num) */" - presyms.each.with_index(1) do |sym, num| - if sym_re =~ sym && (affixes = symbol_to_macro[[$1, $3]]) - f.puts %|MRB_PRESYM_NAMED("#{sym}", #{num}, #{affixes * 'SYM'}, #{$2})| - elsif name = op_table[sym] - f.puts %|MRB_PRESYM_NAMED("#{sym}", #{num}, OPSYM, #{name})| - elsif - f.puts %|MRB_PRESYM_UNNAMED("#{sym}", #{num})| - end - end - f.print "#define MRB_PRESYM_MAX #{presyms.size}" - end -end - -desc "preallocated symbols" -task :gensym => presym_file - -depfiles += MRuby.targets.map { |n, t| - t.libmruby_enabled? ? t.libraries : t.libmruby_core_static -}.flatten - -depfiles += MRuby.targets.reject { |n, t| n == 'host' }.map { |n, t| - t.bins.map { |bin| t.exefile("#{t.build_dir}/bin/#{bin}") } -}.flatten - desc "build all targets, install (locally) in-repo" -task :all => :build do +task :all => :gensym do + Rake::Task[:build].invoke puts puts "Build summary:" puts - MRuby.each_target do - print_build_summary + MRuby.each_target do |build| + build.print_build_summary end MRuby::Lockfile.write end -task :build => :gensym do - depfiles.each {|dep| Rake::Task[dep].invoke} -end +task :build => MRuby.targets.flat_map{|_, build| build.products} desc "run all mruby tests" task :test @@ -274,19 +73,17 @@ end desc "clean all built and in-repo installed artifacts" task :clean do - MRuby.each_target do |t| - rm_rf t.build_dir + MRuby.each_target do |build| + rm_rf build.products + rm_rf build.build_dir end - rm_f depfiles - rm_f presym_file - rm_f presym_inc puts "Cleaned up target build folder" end desc "clean everything!" task :deep_clean => ["clean", "clean_doc"] do - MRuby.each_target do |t| - rm_rf t.gem_clone_dir + MRuby.each_target do |build| + rm_rf build.gem_clone_dir end puts "Cleaned up mrbgems build folder" end diff --git a/build_config/ci/msvc.rb b/build_config/ci/msvc.rb index e084a6a36..2df2d4864 100644 --- a/build_config/ci/msvc.rb +++ b/build_config/ci/msvc.rb @@ -1,6 +1,6 @@ def setup_option(conf) - conf.cc.flags[0].delete("/Zi") unless ENV['CFLAGS'] - conf.cxx.flags[0].delete("/Zi") unless ENV['CFLAGS'] || ENV['CXXFLAGS'] + conf.cc.compile_options.sub!(%r{/Zi }, "") unless ENV['CFLAGS'] + conf.cxx.compile_options.sub!(%r{/Zi }, "") unless ENV['CFLAGS'] || ENV['CXXFLAGS'] conf.linker.flags << "/DEBUG:NONE" unless ENV['LDFLAGS'] end diff --git a/build_config/mrbc.rb b/build_config/mrbc.rb new file mode 100644 index 000000000..95444b936 --- /dev/null +++ b/build_config/mrbc.rb @@ -0,0 +1,11 @@ +MRuby::Build.new do |conf| + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + conf.toolchain :visualcpp + else + conf.toolchain :gcc + end + + conf.build_mrbc_exec + conf.disable_libmruby + conf.disable_presym +end diff --git a/include/mruby.h b/include/mruby.h index 0d0a0a1e1..ccb76ebe4 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -93,7 +93,6 @@ #include <mruby/common.h> #include <mruby/value.h> #include <mruby/gc.h> -#include <mruby/presym.h> #include <mruby/version.h> #ifndef MRB_NO_FLOAT @@ -1410,6 +1409,8 @@ MRB_API void mrb_show_copyright(mrb_state *mrb); MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...); +#include <mruby/presym.h> + #if 0 /* memcpy and memset does not work with gdb reverse-next on my box */ /* use naive memcpy and memset instead */ diff --git a/include/mruby/presym.h b/include/mruby/presym.h index fd08a24da..fd326c758 100644 --- a/include/mruby/presym.h +++ b/include/mruby/presym.h @@ -7,42 +7,36 @@ #ifndef MRUBY_PRESYM_H #define MRUBY_PRESYM_H -#undef MRB_PRESYM_MAX -#ifdef MRB_USE_ALL_SYMBOLS -#define MRB_PRESYM_NAMED(lit, num, type, name) MRB_##type##__##name = (num), +#if defined(MRB_PRESYM_SCANNING) +# include <mruby/presym/scanning.h> +#elif defined(MRB_NO_PRESYM) +# include <mruby/presym/disable.h> #else -#define MRB_PRESYM_NAMED(lit, num, type, name) MRB_##type##__##name = (num<<1), +# include <mruby/presym/enable.h> #endif -#define MRB_PRESYM_UNNAMED(lit, num) - -enum mruby_presym { -#include <../build/presym.inc> -}; - -#undef MRB_PRESYM_NAMED -#undef MRB_PRESYM_UNNAMED /* - * For `MRB_OPSYM`, specify the names corresponding to operators (refer to - * `op_table` in `Rakefile` for the names that can be specified for it). - * Other than that, describe only word characters excluding leading and - * ending punctuations. + * Where `mrb_intern_lit` is allowed for symbol interning, it is directly + * replaced by the symbol ID if presym is enabled by using the following + * macros. + * + * MRB_OPSYM(xor) //=> ^ (Operator) + * MRB_CVSYM(xor) //=> @@xor (Class Variable) + * MRB_IVSYM(xor) //=> @xor (Instance Variable) + * MRB_SYM_B(xor) //=> xor! (Method with Bang) + * MRB_SYM_Q(xor) //=> xor? (Method with Question mark) + * MRB_SYM_E(xor) //=> xor= (Method with Equal) + * MRB_SYM(xor) //=> xor (Word characters) + * + * For `MRB_OPSYM`, specify the names corresponding to operators (see + * `MRuby::Presym::OPERATORS` in `lib/mruby/presym.rb for the names that can + * be specified for it). Other than that, describe only word characters + * excluding leading and ending punctuations. * - * Example: - * MRB_OPSYM(and) //=> & - * MRB_CVSYM(foo) //=> @@foo - * MRB_IVSYM(foo) //=> @foo - * MRB_SYM_B(foo) //=> foo! - * MRB_SYM_Q(foo) //=> foo? - * MRB_SYM_E(foo) //=> foo= - * MRB_SYM(foo) //=> foo + * These macros are expanded to `mrb_intern_lit` if presym is disabled, + * therefore the mruby state variable is required. The above macros can be + * used when the variable name is `mrb`. If you want to use other variable + * names, you need to use macros with `_2` suffix, such as `MRB_SYM_2`. */ -#define MRB_OPSYM(name) MRB_OPSYM__##name /* Operator */ -#define MRB_CVSYM(name) MRB_CVSYM__##name /* Class Variable */ -#define MRB_IVSYM(name) MRB_IVSYM__##name /* Instance Variable */ -#define MRB_SYM_B(name) MRB_SYM_B__##name /* Method with Bang */ -#define MRB_SYM_Q(name) MRB_SYM_Q__##name /* Method with Question mark */ -#define MRB_SYM_E(name) MRB_SYM_E__##name /* Method with Equal */ -#define MRB_SYM(name) MRB_SYM__##name /* Word characters */ #endif /* MRUBY_PRESYM_H */ diff --git a/include/mruby/presym/disable.h b/include/mruby/presym/disable.h new file mode 100644 index 000000000..477405225 --- /dev/null +++ b/include/mruby/presym/disable.h @@ -0,0 +1,68 @@ +/** +** @file mruby/presym/scanning.h - Disable Preallocated Symbols +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_PRESYM_DISABLE_H +#define MRUBY_PRESYM_DISABLE_H + +#include <string.h> + +#define MRB_PRESYM_MAX 0 + +#define MRB_OPSYM(name) MRB_OPSYM__##name(mrb) +#define MRB_CVSYM(name) mrb_intern_lit(mrb, "@@" #name) +#define MRB_IVSYM(name) mrb_intern_lit(mrb, "@" #name) +#define MRB_SYM_B(name) mrb_intern_lit(mrb, #name "!") +#define MRB_SYM_Q(name) mrb_intern_lit(mrb, #name "?") +#define MRB_SYM_E(name) mrb_intern_lit(mrb, #name "=") +#define MRB_SYM(name) mrb_intern_lit(mrb, #name) + +#define MRB_OPSYM_2(mrb, name) MRB_OPSYM__##name(mrb) +#define MRB_CVSYM_2(mrb, name) mrb_intern_lit(mrb, "@@" #name) +#define MRB_IVSYM_2(mrb, name) mrb_intern_lit(mrb, "@" #name) +#define MRB_SYM_B_2(mrb, name) mrb_intern_lit(mrb, #name "!") +#define MRB_SYM_Q_2(mrb, name) mrb_intern_lit(mrb, #name "?") +#define MRB_SYM_E_2(mrb, name) mrb_intern_lit(mrb, #name "=") +#define MRB_SYM_2(mrb, name) mrb_intern_lit(mrb, #name) + +#define MRB_OPSYM__not(mrb) mrb_intern_lit(mrb, "!") +#define MRB_OPSYM__mod(mrb) mrb_intern_lit(mrb, "%") +#define MRB_OPSYM__and(mrb) mrb_intern_lit(mrb, "&") +#define MRB_OPSYM__mul(mrb) mrb_intern_lit(mrb, "*") +#define MRB_OPSYM__add(mrb) mrb_intern_lit(mrb, "+") +#define MRB_OPSYM__sub(mrb) mrb_intern_lit(mrb, "-") +#define MRB_OPSYM__div(mrb) mrb_intern_lit(mrb, "/") +#define MRB_OPSYM__lt(mrb) mrb_intern_lit(mrb, "<") +#define MRB_OPSYM__gt(mrb) mrb_intern_lit(mrb, ">") +#define MRB_OPSYM__xor(mrb) mrb_intern_lit(mrb, "^") +#define MRB_OPSYM__tick(mrb) mrb_intern_lit(mrb, "`") +#define MRB_OPSYM__or(mrb) mrb_intern_lit(mrb, "|") +#define MRB_OPSYM__neg(mrb) mrb_intern_lit(mrb, "~") +#define MRB_OPSYM__neq(mrb) mrb_intern_lit(mrb, "!=") +#define MRB_OPSYM__nmatch(mrb) mrb_intern_lit(mrb, "!~") +#define MRB_OPSYM__andand(mrb) mrb_intern_lit(mrb, "&&") +#define MRB_OPSYM__pow(mrb) mrb_intern_lit(mrb, "**") +#define MRB_OPSYM__plus(mrb) mrb_intern_lit(mrb, "+@") +#define MRB_OPSYM__minus(mrb) mrb_intern_lit(mrb, "-@") +#define MRB_OPSYM__lshift(mrb) mrb_intern_lit(mrb, "<<") +#define MRB_OPSYM__le(mrb) mrb_intern_lit(mrb, "<=") +#define MRB_OPSYM__eq(mrb) mrb_intern_lit(mrb, "==") +#define MRB_OPSYM__match(mrb) mrb_intern_lit(mrb, "=~") +#define MRB_OPSYM__ge(mrb) mrb_intern_lit(mrb, ">=") +#define MRB_OPSYM__rshift(mrb) mrb_intern_lit(mrb, ">>") +#define MRB_OPSYM__aref(mrb) mrb_intern_lit(mrb, "[]") +#define MRB_OPSYM__oror(mrb) mrb_intern_lit(mrb, "||") +#define MRB_OPSYM__cmp(mrb) mrb_intern_lit(mrb, "<=>") +#define MRB_OPSYM__eqq(mrb) mrb_intern_lit(mrb, "===") +#define MRB_OPSYM__aset(mrb) mrb_intern_lit(mrb, "[]=") + +#define MRB_PRESYM_DEFINE_VAR_AND_INITER(name, size, ...) \ + static mrb_sym name[size]; \ + static void init_##name(mrb_state *mrb) { \ + mrb_sym name__[] = {__VA_ARGS__}; \ + memcpy(name, name__, sizeof(name)); \ + } + +#endif /* MRUBY_PRESYM_DISABLE_H */ diff --git a/include/mruby/presym/enable.h b/include/mruby/presym/enable.h new file mode 100644 index 000000000..0aec7274d --- /dev/null +++ b/include/mruby/presym/enable.h @@ -0,0 +1,45 @@ +/** +** @file mruby/presym/scanning.h - Enable Preallocated Symbols +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_PRESYM_ENABLE_H +#define MRUBY_PRESYM_ENABLE_H + +#undef MRB_PRESYM_MAX +#ifdef MRB_USE_ALL_SYMBOLS +# define MRB_PRESYM_NAMED(lit, num, type, name) MRB_##type##__##name = (num), +#else +# define MRB_PRESYM_NAMED(lit, num, type, name) MRB_##type##__##name = (num<<1), +#endif +#define MRB_PRESYM_UNNAMED(lit, num) + +enum mruby_presym { +# include <mruby/presym.inc> +}; + +#undef MRB_PRESYM_NAMED +#undef MRB_PRESYM_UNNAMED + +#define MRB_OPSYM(name) MRB_OPSYM__##name +#define MRB_CVSYM(name) MRB_CVSYM__##name +#define MRB_IVSYM(name) MRB_IVSYM__##name +#define MRB_SYM_B(name) MRB_SYM_B__##name +#define MRB_SYM_Q(name) MRB_SYM_Q__##name +#define MRB_SYM_E(name) MRB_SYM_E__##name +#define MRB_SYM(name) MRB_SYM__##name + +#define MRB_OPSYM_2(mrb, name) MRB_OPSYM__##name +#define MRB_CVSYM_2(mrb, name) MRB_CVSYM__##name +#define MRB_IVSYM_2(mrb, name) MRB_IVSYM__##name +#define MRB_SYM_B_2(mrb, name) MRB_SYM_B__##name +#define MRB_SYM_Q_2(mrb, name) MRB_SYM_Q__##name +#define MRB_SYM_E_2(mrb, name) MRB_SYM_E__##name +#define MRB_SYM_2(mrb, name) MRB_SYM__##name + +#define MRB_PRESYM_DEFINE_VAR_AND_INITER(name, size, ...) \ + static const mrb_sym name[] = {__VA_ARGS__}; \ + static void init_##name(mrb_state *mrb) {} + +#endif /* MRUBY_PRESYM_ENABLE_H */ diff --git a/include/mruby/presym/scanning.h b/include/mruby/presym/scanning.h new file mode 100644 index 000000000..11a3ba312 --- /dev/null +++ b/include/mruby/presym/scanning.h @@ -0,0 +1,69 @@ +/** +** @file mruby/presym/scanning.h - Scanning Preallocated Symbols +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_PRESYM_SCANNING_H +#define MRUBY_PRESYM_SCANNING_H + +#define MRB_PRESYM_SCANNING_TAGGED(arg) <@! arg !@> + +#undef mrb_intern_lit +#define mrb_intern_lit(mrb, name) MRB_PRESYM_SCANNING_TAGGED(name) +#define mrb_define_method(mrb, c, name, f, a) MRB_PRESYM_SCANNING_TAGGED(name) +#define mrb_define_class_method(mrb, c, name, f, a) MRB_PRESYM_SCANNING_TAGGED(name) +#define mrb_define_class(mrb, name, s) MRB_PRESYM_SCANNING_TAGGED(name) +#define mrb_define_module(mrb, name) MRB_PRESYM_SCANNING_TAGGED(name) +#define mrb_define_module_function(mrb, c, name, f, s) MRB_PRESYM_SCANNING_TAGGED(name) +#define mrb_define_const(mrb, c, name, v) MRB_PRESYM_SCANNING_TAGGED(name) +#define mrb_define_global_const(mrb, name, v) MRB_PRESYM_SCANNING_TAGGED(name) + +#define MRB_OPSYM(name) MRB_OPSYM__##name(mrb) +#define MRB_CVSYM(name) MRB_PRESYM_SCANNING_TAGGED("@@" #name) +#define MRB_IVSYM(name) MRB_PRESYM_SCANNING_TAGGED("@" #name) +#define MRB_SYM_B(name) MRB_PRESYM_SCANNING_TAGGED(#name "!") +#define MRB_SYM_Q(name) MRB_PRESYM_SCANNING_TAGGED(#name "?") +#define MRB_SYM_E(name) MRB_PRESYM_SCANNING_TAGGED(#name "=") +#define MRB_SYM(name) MRB_PRESYM_SCANNING_TAGGED(#name) + +#define MRB_OPSYM_2(mrb, name) MRB_OPSYM__##name(mrb) +#define MRB_CVSYM_2(mrb, name) MRB_PRESYM_SCANNING_TAGGED("@@" #name) +#define MRB_IVSYM_2(mrb, name) MRB_PRESYM_SCANNING_TAGGED("@" #name) +#define MRB_SYM_B_2(mrb, name) MRB_PRESYM_SCANNING_TAGGED(#name "!") +#define MRB_SYM_Q_2(mrb, name) MRB_PRESYM_SCANNING_TAGGED(#name "?") +#define MRB_SYM_E_2(mrb, name) MRB_PRESYM_SCANNING_TAGGED(#name "=") +#define MRB_SYM_2(mrb, name) MRB_PRESYM_SCANNING_TAGGED(#name) + +#define MRB_OPSYM__not(mrb) MRB_PRESYM_SCANNING_TAGGED("!") +#define MRB_OPSYM__mod(mrb) MRB_PRESYM_SCANNING_TAGGED("%") +#define MRB_OPSYM__and(mrb) MRB_PRESYM_SCANNING_TAGGED("&") +#define MRB_OPSYM__mul(mrb) MRB_PRESYM_SCANNING_TAGGED("*") +#define MRB_OPSYM__add(mrb) MRB_PRESYM_SCANNING_TAGGED("+") +#define MRB_OPSYM__sub(mrb) MRB_PRESYM_SCANNING_TAGGED("-") +#define MRB_OPSYM__div(mrb) MRB_PRESYM_SCANNING_TAGGED("/") +#define MRB_OPSYM__lt(mrb) MRB_PRESYM_SCANNING_TAGGED("<") +#define MRB_OPSYM__gt(mrb) MRB_PRESYM_SCANNING_TAGGED(">") +#define MRB_OPSYM__xor(mrb) MRB_PRESYM_SCANNING_TAGGED("^") +#define MRB_OPSYM__tick(mrb) MRB_PRESYM_SCANNING_TAGGED("`") +#define MRB_OPSYM__or(mrb) MRB_PRESYM_SCANNING_TAGGED("|") +#define MRB_OPSYM__neg(mrb) MRB_PRESYM_SCANNING_TAGGED("~") +#define MRB_OPSYM__neq(mrb) MRB_PRESYM_SCANNING_TAGGED("!=") +#define MRB_OPSYM__nmatch(mrb) MRB_PRESYM_SCANNING_TAGGED("!~") +#define MRB_OPSYM__andand(mrb) MRB_PRESYM_SCANNING_TAGGED("&&") +#define MRB_OPSYM__pow(mrb) MRB_PRESYM_SCANNING_TAGGED("**") +#define MRB_OPSYM__plus(mrb) MRB_PRESYM_SCANNING_TAGGED("+@") +#define MRB_OPSYM__minus(mrb) MRB_PRESYM_SCANNING_TAGGED("-@") +#define MRB_OPSYM__lshift(mrb) MRB_PRESYM_SCANNING_TAGGED("<<") +#define MRB_OPSYM__le(mrb) MRB_PRESYM_SCANNING_TAGGED("<=") +#define MRB_OPSYM__eq(mrb) MRB_PRESYM_SCANNING_TAGGED("==") +#define MRB_OPSYM__match(mrb) MRB_PRESYM_SCANNING_TAGGED("=~") +#define MRB_OPSYM__ge(mrb) MRB_PRESYM_SCANNING_TAGGED(">=") +#define MRB_OPSYM__rshift(mrb) MRB_PRESYM_SCANNING_TAGGED(">>") +#define MRB_OPSYM__aref(mrb) MRB_PRESYM_SCANNING_TAGGED("[]") +#define MRB_OPSYM__oror(mrb) MRB_PRESYM_SCANNING_TAGGED("||") +#define MRB_OPSYM__cmp(mrb) MRB_PRESYM_SCANNING_TAGGED("<=>") +#define MRB_OPSYM__eqq(mrb) MRB_PRESYM_SCANNING_TAGGED("===") +#define MRB_OPSYM__aset(mrb) MRB_PRESYM_SCANNING_TAGGED("[]=") + +#endif /* MRUBY_PRESYM_SCANNING_H */ diff --git a/lib/mruby/build.rb b/lib/mruby/build.rb index 8fe1da2de..2819ad594 100644 --- a/lib/mruby/build.rb +++ b/lib/mruby/build.rb @@ -5,6 +5,7 @@ require "mruby/build/command" module MRuby autoload :Gem, "mruby/gem" autoload :Lockfile, "mruby/lockfile" + autoload :Presym, "mruby/presym" class << self def targets @@ -51,6 +52,7 @@ module MRuby class Build class << self attr_accessor :current + def mruby_config_path path = ENV['MRUBY_CONFIG'] || ENV['CONFIG'] if path.nil? || path.empty? @@ -61,11 +63,16 @@ module MRuby end path end + + def install_dir + @install_dir ||= ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin" + end end + include Rake::DSL include LoadGems attr_accessor :name, :bins, :exts, :file_separator, :build_dir, :gem_clone_dir - attr_reader :libmruby_core_objs, :libmruby_objs, :gems, :toolchains, :gem_dir_to_repo_url + attr_reader :products, :libmruby_core_objs, :libmruby_objs, :gems, :toolchains, :presym, :mrbc_build, :gem_dir_to_repo_url alias libmruby libmruby_objs @@ -73,16 +80,16 @@ module MRuby COMMANDS = COMPILERS + %w(linker archiver yacc gperf git exts mrbc) attr_block MRuby::Build::COMMANDS - Exts = Struct.new(:object, :executable, :library) + Exts = Struct.new(:object, :executable, :library, :preprocessed) - def initialize(name='host', build_dir=nil, &block) + def initialize(name='host', build_dir=nil, internal: false, &block) @name = name.to_s unless current = MRuby.targets[@name] if ENV['OS'] == 'Windows_NT' - @exts = Exts.new('.o', '.exe', '.a') + @exts = Exts.new('.o', '.exe', '.a', '.i') else - @exts = Exts.new('.o', '', '.a') + @exts = Exts.new('.o', '', '.a', '.i') end build_dir = build_dir || ENV['MRUBY_BUILD_DIR'] || "#{MRUBY_ROOT}/build" @@ -101,6 +108,7 @@ module MRuby @git = Command::Git.new(self) @mrbc = Command::Mrbc.new(self) + @products = [] @bins = [] @gems = MRuby::Gem::List.new @libmruby_core_objs = [] @@ -113,6 +121,9 @@ module MRuby @enable_bintest = false @enable_test = false @enable_lock = true + @enable_presym = true + @mrbcfile_external = false + @internal = internal @toolchains = [] @gem_dir_to_repo_url = {} @@ -121,7 +132,14 @@ module MRuby MRuby::Build.current = current current.instance_eval(&block) - current.build_mrbc_exec if current.libmruby_enabled? && @name == "host" + if current.libmruby_enabled? && !current.mrbcfile_external? + if current.presym_enabled? + current.create_mrbc_build if current.host? || current.gems["mruby-bin-mrbc"] + elsif current.host? + current.build_mrbc_exec + end + end + current.presym = Presym.new(current) if current.presym_enabled? current.build_mrbtest if current.test_enabled? end @@ -149,6 +167,17 @@ module MRuby @enable_debug = true end + def presym_enabled? + @enable_presym + end + + def disable_presym + if @enable_presym + @enable_presym = false + compilers.each{|c| c.defines << "MRB_NO_PRESYM"} + end + end + def disable_lock @enable_lock = false end @@ -200,8 +229,29 @@ module MRuby @cxx_abi_enabled = true end - def compile_as_cxx src, cxx_src, obj = nil, includes = [] - obj = objfile(cxx_src) if obj.nil? + def compile_as_cxx(src, cxx_src = nil, obj = nil, includes = []) + # + # If `cxx_src` is specified, this method behaves the same as before as + # compatibility mode, but `.d` file is not read. + # + # If `cxx_src` is omitted, `.d` file is read by using mruby standard + # Rake rule (C++ source name is also changed). + # + if cxx_src + obj ||= cxx_src + @exts.object + dsts = [obj] + dsts << (cxx_src + @exts.preprocessed) if presym_enabled? + defines = [] + include_paths = ["#{MRUBY_ROOT}/src", *includes] + dsts.each do |dst| + file dst => cxx_src do |t| + cxx.run t.name, t.prerequisites.first, defines, include_paths + end + end + else + cxx_src = "#{build_dir}/#{src.relative_path})".ext << "-cxx.cxx" + obj = cxx_src.ext(@exts.object) + end file cxx_src => [src, __FILE__] do |t| mkdir_p File.dirname t.name @@ -219,10 +269,6 @@ extern "C" { EOS end - file obj => cxx_src do |t| - cxx.run t.name, t.prerequisites.first, [], ["#{MRUBY_ROOT}/src"] + includes - end - obj end @@ -263,11 +309,11 @@ EOS end def build_mrbtest - gem :core => 'mruby-test' + gem :core => 'mruby-test' unless @gems['mruby-test'] end def build_mrbc_exec - gem :core => 'mruby-bin-mrbc' + gem :core => 'mruby-bin-mrbc' unless @gems['mruby-bin-mrbc'] end def locks @@ -278,10 +324,23 @@ EOS return @mrbcfile if @mrbcfile gem_name = "mruby-bin-mrbc" - gem = gems[gem_name] || MRuby.targets["host"].gems[gem_name] + gem = @gems[gem_name] + gem ||= (host = MRuby.targets["host"]) && host.gems[gem_name] + unless gem + fail "external mrbc or mruby-bin-mrbc gem in current('#{@name}') or 'host' build is required" + end @mrbcfile = exefile("#{gem.build.build_dir}/bin/mrbc") end + def mrbcfile=(path) + @mrbcfile = path + @mrbcfile_external = true + end + + def mrbcfile_external? + @mrbcfile_external + end + def compilers COMPILERS.map do |c| instance_variable_get("@#{c}") @@ -289,7 +348,7 @@ EOS end def define_rules - use_mrdb = @gems.find{|g| g.name == "mruby-bin-debugger"} + use_mrdb = @gems["mruby-bin-debugger"] compilers.each do |compiler| if respond_to?(:enable_gems?) && enable_gems? compiler.defines -= %w(MRB_NO_GEMS) @@ -298,7 +357,10 @@ EOS end compiler.defines |= %w(MRB_USE_DEBUG_HOOK) if use_mrdb end - cc.define_rules(build_dir, MRUBY_ROOT) + [@cc, *(@cxx if cxx_exception_enabled?)].each do |compiler| + compiler.define_rules(@build_dir, MRUBY_ROOT, @exts.object) + compiler.define_rules(@build_dir, MRUBY_ROOT, @exts.preprocessed) if presym_enabled? + end end def filename(name) @@ -359,7 +421,8 @@ EOS puts ">>> Bintest #{name} <<<" targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir } targets << filename(".") if File.directory? "./bintest" - env = {"BUILD_DIR" => @build_dir} + mrbc = @gems["mruby-bin-mrbc"] ? exefile("#{@build_dir}/bin/mrbc") : mrbcfile + env = {"BUILD_DIR" => @build_dir, "MRBCFILE" => mrbc} sh env, "ruby test/bintest.rb#{verbose_flag} #{targets.join ' '}" end @@ -393,6 +456,41 @@ EOS def libraries [libmruby_static] end + + def host? + @name == "host" + end + + def internal? + @internal + end + + protected + + attr_writer :presym + + def create_mrbc_build + exclusions = %i[@name @build_dir @gems @enable_test @enable_bintest @internal] + name = "#{@name}/mrbc" + MRuby.targets.delete(name) + build = self.class.new(name, internal: true){} + instance_variables.each do |n| + next if exclusions.include?(n) + v = instance_variable_get(n) + v = case v + when nil, true, false, Numeric; v + when String, Command; v.clone + else Marshal.load(Marshal.dump(v)) # deep clone + end + build.instance_variable_set(n, v) + end + build.build_mrbc_exec + build.disable_libmruby + build.disable_presym + @mrbc_build = build + self.mrbcfile = build.mrbcfile + build + end end # Build class CrossBuild < Build @@ -405,7 +503,7 @@ EOS def initialize(name, build_dir=nil, &block) @test_runner = Command::CrossTestRunner.new(self) super - unless MRuby.targets['host'] + unless mrbcfile_external? || MRuby.targets['host'] # add minimal 'host' MRuby::Build.new('host') do |conf| if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] @@ -413,16 +511,13 @@ EOS else toolchain :gcc end - conf.gem :core => 'mruby-bin-mrbc' + conf.build_mrbc_exec conf.disable_libmruby + conf.disable_presym end end end - def mrbcfile - MRuby.targets['host'].mrbcfile - end - def run_test @test_runner.runner_options << verbose_flag mrbtest = exefile("#{build_dir}/bin/mrbtest") @@ -433,5 +528,9 @@ EOS @test_runner.run(mrbtest) end end + + protected + + def create_mrbc_build; end end # CrossBuild end # MRuby diff --git a/lib/mruby/build/command.rb b/lib/mruby/build/command.rb index 80657eadc..9362a9d95 100644 --- a/lib/mruby/build/command.rb +++ b/lib/mruby/build/command.rb @@ -42,6 +42,7 @@ module MRuby attr_accessor :label, :flags, :include_paths, :defines, :source_exts attr_accessor :compile_options, :option_define, :option_include_path, :out_ext attr_accessor :cxx_compile_flag, :cxx_exception_flag, :cxx_invalid_flags + attr_writer :preprocess_options def initialize(build, source_exts=[], label: "CC") super(build) @@ -55,9 +56,15 @@ module MRuby @option_define = %q[-D"%s"] @compile_options = %q[%{flags} -o "%{outfile}" -c "%{infile}"] @cxx_invalid_flags = [] + @out_ext = build.exts.object end alias header_search_paths include_paths + + def preprocess_options + @preprocess_options ||= @compile_options.sub(/(?:\A|\s)\K-c(?=\s)/, "-E -P") + end + def search_header_path(name) header_search_paths.find do |v| File.exist? build.filename("#{v}/#{name}").sub(/^"(.*)"$/, '\1') @@ -79,13 +86,20 @@ module MRuby def run(outfile, infile, _defines=[], _include_paths=[], _flags=[]) mkdir_p File.dirname(outfile) - _pp @label, infile.relative_path, outfile.relative_path - _run compile_options, { :flags => all_flags(_defines, _include_paths, _flags), - :infile => filename(infile), :outfile => filename(outfile) } + flags = all_flags(_defines, _include_paths, _flags) + if File.extname(outfile) == build.exts.object + label = @label + opts = compile_options + else + label = "CPP" + opts = preprocess_options + flags << " -DMRB_PRESYM_SCANNING" + end + _pp label, infile.relative_path, outfile.relative_path + _run opts, flags: flags, infile: filename(infile), outfile: filename(outfile) end - def define_rules(build_dir, source_dir='') - @out_ext = build.exts.object + def define_rules(build_dir, source_dir='', out_ext=build.exts.object) gemrake = File.join(source_dir, "mrbgem.rake") rakedep = File.exist?(gemrake) ? [ gemrake ] : [] @@ -143,10 +157,10 @@ module MRuby # /src/value_array.h: # def get_dependencies(file) - file = file.ext('d') unless File.extname(file) == '.d' - return [MRUBY_CONFIG] unless File.exist?(file) + dep_file = "#{file}.d" + return [MRUBY_CONFIG] unless File.exist?(dep_file) - deps = File.read(file).gsub("\\\n ", "").split("\n").map do |dep_line| + deps = File.read(dep_file).gsub("\\\n ", "").split("\n").map do |dep_line| # dep_line: # - "/build/host/src/array.o: /src/array.c /include/mruby/common.h ..." # - "" @@ -187,6 +201,10 @@ module MRuby [libraries, _libraries].flatten.map{ |d| option_library % d }.join(' ') end + def run_attrs + [@libraries, @library_paths, @flags, @flags_before_libraries, @flags_after_libraries] + end + def run(outfile, objfiles, _libraries=[], _library_paths=[], _flags=[], _flags_before_libraries=[], _flags_after_libraries=[]) mkdir_p File.dirname(outfile) library_flags = [libraries, _libraries].flatten.map { |d| option_library % d } diff --git a/lib/mruby/gem.rb b/lib/mruby/gem.rb index e3b758f4f..4e918745f 100644 --- a/lib/mruby/gem.rb +++ b/lib/mruby/gem.rb @@ -7,7 +7,6 @@ module MRuby class << self attr_accessor :current end - LinkerConfig = Struct.new(:libraries, :library_paths, :flags, :flags_before_libraries, :flags_after_libraries) class Specification include Rake::DSL @@ -50,13 +49,13 @@ module MRuby end def setup - return if defined?(@linker) # return if already set up + return if defined?(@bins) # return if already set up MRuby::Gem.current = self MRuby::Build::COMMANDS.each do |command| instance_variable_set("@#{command}", @build.send(command).clone) end - @linker = LinkerConfig.new([], [], [], [], []) + @linker.run_attrs.each(&:clear) @rbfiles = Dir.glob("#{@dir}/mrblib/**/*.rb").sort @objs = Dir.glob("#{@dir}/src/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f| @@ -72,6 +71,7 @@ module MRuby @test_args = {} @bins = [] + @cdump = true @requirements = [] @export_include_paths = [] @@ -81,7 +81,6 @@ module MRuby @generate_functions = !(@rbfiles.empty? && @objs.empty?) @objs << objfile("#{build_dir}/gem_init") if @generate_functions - @cdump = core? # by default core gems use cdump and others use mrb dump if !name || !licenses || !authors fail "#{name || dir} required to set name, license(s) and author(s)" @@ -96,10 +95,11 @@ module MRuby end def setup_compilers - (core? ? [cc] : compilers).each do |compiler| - compiler.define_rules build_dir, "#{dir}" + (core? ? [@cc, *(@cxx if build.cxx_exception_enabled?)] : compilers).each do |compiler| + compiler.define_rules build_dir, @dir, @build.exts.preprocessed if build.presym_enabled? + compiler.define_rules build_dir, @dir, @build.exts.object compiler.defines << %Q[MRBGEM_#{funcname.upcase}_VERSION=#{version}] - compiler.include_paths << "#{dir}/include" if File.directory? "#{dir}/include" + compiler.include_paths << "#{@dir}/include" if File.directory? "#{@dir}/include" end define_gem_init_builder if @generate_functions @@ -114,12 +114,12 @@ module MRuby return false end - def enable_cdump - @cdump = true + def disable_cdump + @cdump = false end def cdump? - @cdump + build.presym_enabled? && @cdump end def core? @@ -175,7 +175,6 @@ module MRuby end def define_gem_init_builder - file objfile("#{build_dir}/gem_init") => [ "#{build_dir}/gem_init.c", File.join(dir, "mrbgem.rake") ] file "#{build_dir}/gem_init.c" => [build.mrbcfile, __FILE__] + [rbfiles].flatten do |t| mkdir_p build_dir generate_gem_init("#{build_dir}/gem_init.c") @@ -187,7 +186,7 @@ module MRuby open(fname, 'w') do |f| print_gem_init_header f unless rbfiles.empty? - if @cdump + if cdump? build.mrbc.run f, rbfiles, "gem_mrblib_#{funcname}_proc" else build.mrbc.run f, rbfiles, "gem_mrblib_irep_#{funcname}", false @@ -198,10 +197,10 @@ module MRuby f.puts %Q[] f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_init(mrb_state *mrb) {] f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] - f.puts %Q[ struct REnv *e;] unless rbfiles.empty? + f.puts %Q[ gem_mrblib_#{funcname}_proc_init_syms(mrb);] if !rbfiles.empty? && cdump? f.puts %Q[ mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")] unless rbfiles.empty? - if @cdump + if cdump? f.puts %Q[ mrb_load_proc(mrb, gem_mrblib_#{funcname}_proc);] else f.puts %Q[ mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});] @@ -211,7 +210,7 @@ module MRuby f.puts %Q[ mrb_close(mrb);] f.puts %Q[ exit(EXIT_FAILURE);] f.puts %Q[ }] - f.puts %Q[ e = mrb->c->cibase->env;] + f.puts %Q[ struct REnv *e = mrb->c->cibase->env;] f.puts %Q[ mrb->c->cibase->env = NULL;] f.puts %Q[ mrb_env_unshare(mrb, e);] end @@ -241,8 +240,6 @@ module MRuby f.puts %Q[#include <mruby.h>] else f.puts %Q[#include <stdlib.h>] - f.puts %Q[#include <mruby.h>] - f.puts %Q[#include <mruby/proc.h>] end end @@ -251,7 +248,7 @@ module MRuby f.puts %Q[#include <stdio.h>] f.puts %Q[#include <stdlib.h>] f.puts %Q[#include <mruby.h>] - f.puts %Q[#include <mruby/proc.h>] + f.puts %Q[#include <mruby/irep.h>] f.puts %Q[#include <mruby/variable.h>] f.puts %Q[#include <mruby/hash.h>] unless test_args.empty? end diff --git a/lib/mruby/presym.rb b/lib/mruby/presym.rb new file mode 100644 index 000000000..75a903dba --- /dev/null +++ b/lib/mruby/presym.rb @@ -0,0 +1,113 @@ +module MRuby + class Presym + include Rake::DSL + + OPERATORS = { + "!" => "not", + "%" => "mod", + "&" => "and", + "*" => "mul", + "+" => "add", + "-" => "sub", + "/" => "div", + "<" => "lt", + ">" => "gt", + "^" => "xor", + "`" => "tick", + "|" => "or", + "~" => "neg", + "!=" => "neq", + "!~" => "nmatch", + "&&" => "andand", + "**" => "pow", + "+@" => "plus", + "-@" => "minus", + "<<" => "lshift", + "<=" => "le", + "==" => "eq", + "=~" => "match", + ">=" => "ge", + ">>" => "rshift", + "[]" => "aref", + "||" => "oror", + "<=>" => "cmp", + "===" => "eqq", + "[]=" => "aset", + }.freeze + + SYMBOL_TO_MACRO = { + # Symbol => Macro + # [prefix, suffix] => [prefix, suffix] + ["@@" , "" ] => ["CV" , "" ], + ["@" , "" ] => ["IV" , "" ], + ["" , "!" ] => ["" , "_B" ], + ["" , "?" ] => ["" , "_Q" ], + ["" , "=" ] => ["" , "_E" ], + ["" , "" ] => ["" , "" ], + }.freeze + + C_STR_LITERAL_RE = /"(?:[^\\\"]|\\.)*"/ + + def initialize(build) + @build = build + end + + def scan(paths) + presym_hash = {} + paths.each {|path| read_preprocessed(presym_hash, path)} + presym_hash.keys.sort_by!{|sym| [c_literal_size(sym), sym]} + end + + def read_list + File.readlines(list_path, mode: "r:binary").each(&:chomp!) + end + + def write_list(presyms) + _pp "GEN", list_path.relative_path + File.binwrite(list_path, presyms.join("\n") << "\n") + end + + def write_header(presyms) + prefix_re = Regexp.union(*SYMBOL_TO_MACRO.keys.map(&:first).uniq) + suffix_re = Regexp.union(*SYMBOL_TO_MACRO.keys.map(&:last).uniq) + sym_re = /\A(#{prefix_re})?([\w&&\D]\w*)(#{suffix_re})?\z/o + _pp "GEN", header_path.relative_path + mkdir_p(File.dirname(header_path)) + File.open(header_path, "w:binary") do |f| + f.puts "/* MRB_PRESYM_NAMED(lit, num, type, name) */" + f.puts "/* MRB_PRESYM_UNNAMED(lit, num) */" + presyms.each.with_index(1) do |sym, num| + if sym_re =~ sym && (affixes = SYMBOL_TO_MACRO[[$1, $3]]) + f.puts %|MRB_PRESYM_NAMED("#{sym}", #{num}, #{affixes * 'SYM'}, #{$2})| + elsif name = OPERATORS[sym] + f.puts %|MRB_PRESYM_NAMED("#{sym}", #{num}, OPSYM, #{name})| + elsif + f.puts %|MRB_PRESYM_UNNAMED("#{sym}", #{num})| + end + end + f.puts "#define MRB_PRESYM_MAX #{presyms.size}" + end + end + + def list_path + @list_pat ||= "#{@build.build_dir}/presym".freeze + end + + def header_path + @header_path ||= "#{@build.build_dir}/include/mruby/presym.inc".freeze + end + + private + + def read_preprocessed(presym_hash, path) + File.binread(path).scan(/<@! (.*?) !@>/) do |part,| + literals = part.scan(C_STR_LITERAL_RE) + presym_hash[literals.map{|l| l[1..-2]}.join] = true unless literals.empty? + end + end + + def c_literal_size(literal_without_quote) + literal_without_quote.size # TODO: consider escape sequence + end + end +end diff --git a/mrbgems/mruby-bin-mruby/mrbgem.rake b/mrbgems/mruby-bin-mruby/mrbgem.rake index 1415013e3..36bf2fa61 100644 --- a/mrbgems/mruby-bin-mruby/mrbgem.rake +++ b/mrbgems/mruby-bin-mruby/mrbgem.rake @@ -7,6 +7,6 @@ MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec| spec.add_test_dependency('mruby-print', :core => 'mruby-print') if build.cxx_exception_enabled? - build.compile_as_cxx("#{spec.dir}/tools/mruby/mruby.c", "#{spec.build_dir}/tools/mruby/mruby.cxx") + build.compile_as_cxx("#{spec.dir}/tools/mruby/mruby.c") end end diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 4ac092176..00a33021f 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -819,7 +819,7 @@ for_body(codegen_scope *s, node *tree) genop_2(s, OP_BLOCK, cursp(), s->irep->rlen-1); push();pop(); /* space for a block */ pop(); - idx = new_sym(s, MRB_SYM(each)); + idx = new_sym(s, MRB_SYM_2(s->mrb, each)); genop_3(s, OP_SENDB, cursp(), idx, 0); } @@ -1547,14 +1547,14 @@ codegen(codegen_scope *s, node *tree, int val) gen_move(s, cursp(), exc, 0); push_n(2); pop_n(2); /* space for one arg and a block */ pop(); - genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM(__case_eqq)), 1); + genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM_2(s->mrb, __case_eqq)), 1); } else { if (n4) { codegen(s, n4->car, VAL); } else { - genop_2(s, OP_GETCONST, cursp(), new_sym(s, MRB_SYM(StandardError))); + genop_2(s, OP_GETCONST, cursp(), new_sym(s, MRB_SYM_2(s->mrb, StandardError))); push(); } pop(); @@ -1668,7 +1668,7 @@ codegen(codegen_scope *s, node *tree, int val) { node *n = tree->car->cdr; mrb_sym mid = nsym(n->cdr->car); - mrb_sym mnil = MRB_SYM_Q(nil); + mrb_sym mnil = MRB_SYM_Q_2(s->mrb, nil); if (mid == mnil && n->cdr->cdr->car == NULL) { nil_p = TRUE; codegen(s, n->car, VAL); @@ -1804,10 +1804,10 @@ codegen(codegen_scope *s, node *tree, int val) gen_move(s, cursp(), head, 0); push(); push(); pop(); pop(); pop(); if (nint(n->car->car) == NODE_SPLAT) { - genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM(__case_eqq)), 1); + genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM_2(s->mrb, __case_eqq)), 1); } else { - genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_OPSYM(eqq)), 1); + genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_OPSYM_2(s->mrb, eqq)), 1); } } else { @@ -2333,7 +2333,7 @@ codegen(codegen_scope *s, node *tree, int val) pop_n(n+1); genop_2S(s, OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)); if (sendv) n = CALL_MAXARGS; - genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM(call)), n); + genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM_2(s->mrb, call)), n); if (val) push(); } break; @@ -2582,7 +2582,7 @@ codegen(codegen_scope *s, node *tree, int val) default: if (val) { - int sym = new_sym(s, MRB_OPSYM(minus)); + int sym = new_sym(s, MRB_OPSYM_2(s->mrb, minus)); codegen(s, tree, VAL); pop(); genop_3(s, OP_SEND, cursp(), sym, 0); @@ -2655,7 +2655,7 @@ codegen(codegen_scope *s, node *tree, int val) { node *n; int ai = mrb_gc_arena_save(s->mrb); - int sym = new_sym(s, MRB_SYM(Kernel)); + int sym = new_sym(s, MRB_SYM_2(s->mrb, Kernel)); genop_1(s, OP_LOADSELF, cursp()); push(); @@ -2674,7 +2674,7 @@ codegen(codegen_scope *s, node *tree, int val) } push(); /* for block */ pop_n(3); - sym = new_sym(s, MRB_OPSYM(tick)); /* ` */ + sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */ genop_3(s, OP_SEND, cursp(), sym, 1); if (val) push(); mrb_gc_arena_restore(s->mrb, ai); @@ -2694,7 +2694,7 @@ codegen(codegen_scope *s, node *tree, int val) genop_bs(s, OP_STRING, cursp(), off); push(); push(); pop_n(3); - sym = new_sym(s, MRB_OPSYM(tick)); /* ` */ + sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */ genop_3(s, OP_SEND, cursp(), sym, 1); if (val) push(); mrb_gc_arena_restore(s->mrb, ai); @@ -2735,7 +2735,7 @@ codegen(codegen_scope *s, node *tree, int val) } push(); /* space for a block */ pop_n(argc+2); - sym = new_sym(s, MRB_SYM(compile)); + sym = new_sym(s, MRB_SYM_2(s->mrb, compile)); genop_3(s, OP_SEND, cursp(), sym, argc); mrb_gc_arena_restore(s->mrb, ai); push(); @@ -2789,7 +2789,7 @@ codegen(codegen_scope *s, node *tree, int val) } push(); /* space for a block */ pop_n(argc+2); - sym = new_sym(s, MRB_SYM(compile)); + sym = new_sym(s, MRB_SYM_2(s->mrb, compile)); genop_3(s, OP_SEND, cursp(), sym, argc); mrb_gc_arena_restore(s->mrb, ai); push(); diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index a5f3f93de..0be251ef5 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -89,7 +89,7 @@ intern_gen(parser_state *p, const char *s, size_t len) } #define intern(s,len) intern_gen(p,(s),(len)) -#define intern_lit(s) mrb_intern_lit(p->mrb, s) +#define intern_op(op) MRB_OPSYM_2(p->mrb, op) static void cons_free_gen(parser_state *p, node *cons) @@ -315,14 +315,14 @@ static void local_add_blk(parser_state *p, mrb_sym blk) { /* allocate register for block */ - local_add_f(p, blk ? blk : MRB_OPSYM(and)); + local_add_f(p, blk ? blk : intern_op(and)); } static void local_add_kw(parser_state *p, mrb_sym kwd) { /* allocate register for keywords hash */ - local_add_f(p, kwd ? kwd : MRB_OPSYM(pow)); + local_add_f(p, kwd ? kwd : intern_op(pow)); } static node* @@ -960,13 +960,13 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b) static node* new_imaginary(parser_state *p, node *imaginary) { - return new_call(p, new_const(p, MRB_SYM(Kernel)), MRB_SYM(Complex), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1); } static node* new_rational(parser_state *p, node *rational) { - return new_call(p, new_const(p, MRB_SYM(Kernel)), MRB_SYM(Rational), list1(list1(rational)), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), list1(list1(rational)), 1); } /* (:int . i) */ @@ -1707,7 +1707,7 @@ command_asgn : lhs '=' command_rhs } | primary_value '[' opt_call_args ']' tOP_ASGN command_rhs { - $$ = new_op_asgn(p, new_call(p, $1, MRB_OPSYM(aref), $3, '.'), $5, $6); + $$ = new_op_asgn(p, new_call(p, $1, intern_op(aref), $3, '.'), $5, $6); } | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs { @@ -1963,7 +1963,7 @@ mlhs_node : variable } | primary_value '[' opt_call_args ']' { - $$ = new_call(p, $1, MRB_OPSYM(aref), $3, '.'); + $$ = new_call(p, $1, intern_op(aref), $3, '.'); } | primary_value call_op tIDENTIFIER { @@ -2002,7 +2002,7 @@ lhs : variable } | primary_value '[' opt_call_args ']' { - $$ = new_call(p, $1, MRB_OPSYM(aref), $3, '.'); + $$ = new_call(p, $1, intern_op(aref), $3, '.'); } | primary_value call_op tIDENTIFIER { @@ -2090,36 +2090,36 @@ undef_list : fsym } ; -op : '|' { $$ = MRB_OPSYM(or); } - | '^' { $$ = MRB_OPSYM(xor); } - | '&' { $$ = MRB_OPSYM(and); } - | tCMP { $$ = MRB_OPSYM(cmp); } - | tEQ { $$ = MRB_OPSYM(eq); } - | tEQQ { $$ = MRB_OPSYM(eqq); } - | tMATCH { $$ = MRB_OPSYM(match); } - | tNMATCH { $$ = MRB_OPSYM(nmatch); } - | '>' { $$ = MRB_OPSYM(gt); } - | tGEQ { $$ = MRB_OPSYM(ge); } - | '<' { $$ = MRB_OPSYM(lt); } - | tLEQ { $$ = MRB_OPSYM(le); } - | tNEQ { $$ = MRB_OPSYM(neq); } - | tLSHFT { $$ = MRB_OPSYM(lshift); } - | tRSHFT { $$ = MRB_OPSYM(rshift); } - | '+' { $$ = MRB_OPSYM(add); } - | '-' { $$ = MRB_OPSYM(sub); } - | '*' { $$ = MRB_OPSYM(mul); } - | tSTAR { $$ = MRB_OPSYM(mul); } - | '/' { $$ = MRB_OPSYM(div); } - | '%' { $$ = MRB_OPSYM(mod); } - | tPOW { $$ = MRB_OPSYM(pow); } - | tDSTAR { $$ = MRB_OPSYM(pow); } - | '!' { $$ = MRB_OPSYM(not); } - | '~' { $$ = MRB_OPSYM(neg); } - | tUPLUS { $$ = MRB_OPSYM(plus); } - | tUMINUS { $$ = MRB_OPSYM(minus); } - | tAREF { $$ = MRB_OPSYM(aref); } - | tASET { $$ = MRB_OPSYM(aset); } - | '`' { $$ = MRB_OPSYM(tick); } +op : '|' { $$ = intern_op(or); } + | '^' { $$ = intern_op(xor); } + | '&' { $$ = intern_op(and); } + | tCMP { $$ = intern_op(cmp); } + | tEQ { $$ = intern_op(eq); } + | tEQQ { $$ = intern_op(eqq); } + | tMATCH { $$ = intern_op(match); } + | tNMATCH { $$ = intern_op(nmatch); } + | '>' { $$ = intern_op(gt); } + | tGEQ { $$ = intern_op(ge); } + | '<' { $$ = intern_op(lt); } + | tLEQ { $$ = intern_op(le); } + | tNEQ { $$ = intern_op(neq); } + | tLSHFT { $$ = intern_op(lshift); } + | tRSHFT { $$ = intern_op(rshift); } + | '+' { $$ = intern_op(add); } + | '-' { $$ = intern_op(sub); } + | '*' { $$ = intern_op(mul); } + | tSTAR { $$ = intern_op(mul); } + | '/' { $$ = intern_op(div); } + | '%' { $$ = intern_op(mod); } + | tPOW { $$ = intern_op(pow); } + | tDSTAR { $$ = intern_op(pow); } + | '!' { $$ = intern_op(not); } + | '~' { $$ = intern_op(neg); } + | tUPLUS { $$ = intern_op(plus); } + | tUMINUS { $$ = intern_op(minus); } + | tAREF { $$ = intern_op(aref); } + | tASET { $$ = intern_op(aset); } + | '`' { $$ = intern_op(tick); } ; reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__ @@ -2146,7 +2146,7 @@ arg : lhs '=' arg_rhs } | primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs { - $$ = new_op_asgn(p, new_call(p, $1, MRB_OPSYM(aref), $3, '.'), $5, $6); + $$ = new_op_asgn(p, new_call(p, $1, intern_op(aref), $3, '.'), $5, $6); } | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs { @@ -2401,14 +2401,14 @@ paren_args : '(' opt_call_args ')' | '(' args comma tBDOT3 rparen { #if 1 - mrb_sym r = MRB_OPSYM(mul); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym b = intern_op(and); $$ = cons(push($2, new_splat(p, new_lvar(p, r))), new_block_arg(p, new_lvar(p, b))); #else - mrb_sym r = MRB_OPSYM(mul); - mrb_sym k = MRB_OPSYM(pow); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym k = intern_op(pow); + mrb_sym b = intern_op(and); $$ = cons(list2(push($2, new_splat(p, new_lvar(p, r))), new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))), new_block_arg(p, new_lvar(p, b))); @@ -2417,16 +2417,16 @@ paren_args : '(' opt_call_args ')' | '(' tBDOT3 rparen { #if 1 - mrb_sym r = MRB_OPSYM(mul); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym b = intern_op(and); if (local_var_p(p, r) && local_var_p(p, b)) { $$ = cons(list1(new_splat(p, new_lvar(p, r))), new_block_arg(p, new_lvar(p, b))); } #else - mrb_sym r = MRB_OPSYM(mul); - mrb_sym k = MRB_OPSYM(pow); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym k = intern_op(pow); + mrb_sym b = intern_op(and); if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) { $$ = cons(list2(new_splat(p, new_lvar(p, r)), new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))), @@ -3115,11 +3115,11 @@ method_call : operation paren_args } | primary_value call_op paren_args { - $$ = new_call(p, $1, MRB_SYM(call), $3, $2); + $$ = new_call(p, $1, MRB_SYM_2(p->mrb, call), $3, $2); } | primary_value tCOLON2 paren_args { - $$ = new_call(p, $1, MRB_SYM(call), $3, tCOLON2); + $$ = new_call(p, $1, MRB_SYM_2(p->mrb, call), $3, tCOLON2); } | keyword_super paren_args { @@ -3131,7 +3131,7 @@ method_call : operation paren_args } | primary_value '[' opt_call_args ']' { - $$ = new_call(p, $1, MRB_OPSYM(aref), $3, '.'); + $$ = new_call(p, $1, intern_op(aref), $3, '.'); } ; @@ -3514,15 +3514,15 @@ f_arglist_paren : '(' f_args rparen { #if 1 /* til real keyword args implemented */ - mrb_sym r = MRB_OPSYM(mul); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym b = intern_op(and); local_add_f(p, r); $$ = new_args(p, $2, 0, r, 0, new_args_tail(p, 0, 0, b)); #else - mrb_sym r = MRB_OPSYM(mul); - mrb_sym k = MRB_OPSYM(pow); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym k = intern_op(pow); + mrb_sym b = intern_op(and); local_add_f(p, r); local_add_f(p, k); $$ = new_args(p, $2, 0, r, 0, new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); @@ -3532,15 +3532,15 @@ f_arglist_paren : '(' f_args rparen { #if 1 /* til real keyword args implemented */ - mrb_sym r = MRB_OPSYM(mul); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym b = intern_op(and); local_add_f(p, r); $$ = new_args(p, 0, 0, r, 0, new_args_tail(p, 0, 0, b)); #else - mrb_sym r = MRB_OPSYM(mul); - mrb_sym k = MRB_OPSYM(pow); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym k = intern_op(pow); + mrb_sym b = intern_op(and); local_add_f(p, r); local_add_f(p, k); $$ = new_args(p, 0, 0, r, 0, new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); @@ -3706,7 +3706,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail } | /* none */ { - local_add_f(p, MRB_OPSYM(and)); + local_add_f(p, intern_op(and)); $$ = new_args(p, 0, 0, 0, 0, 0); } ; @@ -3830,7 +3830,7 @@ f_rest_arg : restarg_mark tIDENTIFIER } | restarg_mark { - local_add_f(p, MRB_OPSYM(mul)); + local_add_f(p, intern_op(mul)); $$ = -1; } ; @@ -5215,7 +5215,7 @@ parser_yylex(parser_state *p) case '*': if ((c = nextc(p)) == '*') { if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(pow); + pylval.id = intern_op(pow); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5233,7 +5233,7 @@ parser_yylex(parser_state *p) } else { if (c == '=') { - pylval.id = MRB_OPSYM(mul); + pylval.id = intern_op(mul); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5349,7 +5349,7 @@ parser_yylex(parser_state *p) } if (c == '<') { if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(lshift); + pylval.id = intern_op(lshift); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5371,7 +5371,7 @@ parser_yylex(parser_state *p) } if (c == '>') { if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(rshift); + pylval.id = intern_op(rshift); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5479,7 +5479,7 @@ parser_yylex(parser_state *p) if ((c = nextc(p)) == '&') { p->lstate = EXPR_BEG; if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(andand); + pylval.id = intern_op(andand); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5491,7 +5491,7 @@ parser_yylex(parser_state *p) return tANDDOT; } else if (c == '=') { - pylval.id = MRB_OPSYM(and); + pylval.id = intern_op(and); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5518,7 +5518,7 @@ parser_yylex(parser_state *p) if ((c = nextc(p)) == '|') { p->lstate = EXPR_BEG; if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(oror); + pylval.id = intern_op(oror); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5526,7 +5526,7 @@ parser_yylex(parser_state *p) return tOROP; } if (c == '=') { - pylval.id = MRB_OPSYM(or); + pylval.id = intern_op(or); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5550,7 +5550,7 @@ parser_yylex(parser_state *p) return '+'; } if (c == '=') { - pylval.id = MRB_OPSYM(add); + pylval.id = intern_op(add); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5578,7 +5578,7 @@ parser_yylex(parser_state *p) return '-'; } if (c == '=') { - pylval.id = MRB_OPSYM(sub); + pylval.id = intern_op(sub); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5901,7 +5901,7 @@ parser_yylex(parser_state *p) return tREGEXP_BEG; } if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(div); + pylval.id = intern_op(div); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -5920,7 +5920,7 @@ parser_yylex(parser_state *p) case '^': if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(xor); + pylval.id = intern_op(xor); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -6098,7 +6098,7 @@ parser_yylex(parser_state *p) } } if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(mod); + pylval.id = intern_op(mod); p->lstate = EXPR_BEG; return tOP_ASGN; } diff --git a/mrbgems/mruby-compiler/core/y.tab.c b/mrbgems/mruby-compiler/core/y.tab.c index a16038eb2..0709bfa74 100644 --- a/mrbgems/mruby-compiler/core/y.tab.c +++ b/mrbgems/mruby-compiler/core/y.tab.c @@ -152,7 +152,7 @@ intern_gen(parser_state *p, const char *s, size_t len) } #define intern(s,len) intern_gen(p,(s),(len)) -#define intern_lit(s) mrb_intern_lit(p->mrb, s) +#define intern_op(op) MRB_OPSYM_2(p->mrb, op) static void cons_free_gen(parser_state *p, node *cons) @@ -378,14 +378,14 @@ static void local_add_blk(parser_state *p, mrb_sym blk) { /* allocate register for block */ - local_add_f(p, blk ? blk : MRB_OPSYM(and)); + local_add_f(p, blk ? blk : intern_op(and)); } static void local_add_kw(parser_state *p, mrb_sym kwd) { /* allocate register for keywords hash */ - local_add_f(p, kwd ? kwd : MRB_OPSYM(pow)); + local_add_f(p, kwd ? kwd : intern_op(pow)); } static node* @@ -1023,13 +1023,13 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b) static node* new_imaginary(parser_state *p, node *imaginary) { - return new_call(p, new_const(p, MRB_SYM(Kernel)), MRB_SYM(Complex), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1); } static node* new_rational(parser_state *p, node *rational) { - return new_call(p, new_const(p, MRB_SYM(Kernel)), MRB_SYM(Rational), list1(list1(rational)), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), list1(list1(rational)), 1); } /* (:int . i) */ @@ -6148,7 +6148,7 @@ yyreduce: case 36: #line 1709 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), MRB_OPSYM(aref), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd)); + (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), intern_op(aref), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd)); } #line 6154 "mrbgems/mruby-compiler/core/y.tab.c" break; @@ -6551,7 +6551,7 @@ yyreduce: case 93: #line 1965 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_call(p, (yyvsp[-3].nd), MRB_OPSYM(aref), (yyvsp[-1].nd), '.'); + (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } #line 6557 "mrbgems/mruby-compiler/core/y.tab.c" break; @@ -6620,7 +6620,7 @@ yyreduce: case 101: #line 2004 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_call(p, (yyvsp[-3].nd), MRB_OPSYM(aref), (yyvsp[-1].nd), '.'); + (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } #line 6626 "mrbgems/mruby-compiler/core/y.tab.c" break; @@ -6761,181 +6761,181 @@ yyreduce: case 124: #line 2093 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(or); } + { (yyval.id) = intern_op(or); } #line 6766 "mrbgems/mruby-compiler/core/y.tab.c" break; case 125: #line 2094 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(xor); } + { (yyval.id) = intern_op(xor); } #line 6772 "mrbgems/mruby-compiler/core/y.tab.c" break; case 126: #line 2095 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(and); } + { (yyval.id) = intern_op(and); } #line 6778 "mrbgems/mruby-compiler/core/y.tab.c" break; case 127: #line 2096 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(cmp); } + { (yyval.id) = intern_op(cmp); } #line 6784 "mrbgems/mruby-compiler/core/y.tab.c" break; case 128: #line 2097 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(eq); } + { (yyval.id) = intern_op(eq); } #line 6790 "mrbgems/mruby-compiler/core/y.tab.c" break; case 129: #line 2098 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(eqq); } + { (yyval.id) = intern_op(eqq); } #line 6796 "mrbgems/mruby-compiler/core/y.tab.c" break; case 130: #line 2099 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(match); } + { (yyval.id) = intern_op(match); } #line 6802 "mrbgems/mruby-compiler/core/y.tab.c" break; case 131: #line 2100 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(nmatch); } + { (yyval.id) = intern_op(nmatch); } #line 6808 "mrbgems/mruby-compiler/core/y.tab.c" break; case 132: #line 2101 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(gt); } + { (yyval.id) = intern_op(gt); } #line 6814 "mrbgems/mruby-compiler/core/y.tab.c" break; case 133: #line 2102 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(ge); } + { (yyval.id) = intern_op(ge); } #line 6820 "mrbgems/mruby-compiler/core/y.tab.c" break; case 134: #line 2103 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(lt); } + { (yyval.id) = intern_op(lt); } #line 6826 "mrbgems/mruby-compiler/core/y.tab.c" break; case 135: #line 2104 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(le); } + { (yyval.id) = intern_op(le); } #line 6832 "mrbgems/mruby-compiler/core/y.tab.c" break; case 136: #line 2105 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(neq); } + { (yyval.id) = intern_op(neq); } #line 6838 "mrbgems/mruby-compiler/core/y.tab.c" break; case 137: #line 2106 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(lshift); } + { (yyval.id) = intern_op(lshift); } #line 6844 "mrbgems/mruby-compiler/core/y.tab.c" break; case 138: #line 2107 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(rshift); } + { (yyval.id) = intern_op(rshift); } #line 6850 "mrbgems/mruby-compiler/core/y.tab.c" break; case 139: #line 2108 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(add); } + { (yyval.id) = intern_op(add); } #line 6856 "mrbgems/mruby-compiler/core/y.tab.c" break; case 140: #line 2109 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(sub); } + { (yyval.id) = intern_op(sub); } #line 6862 "mrbgems/mruby-compiler/core/y.tab.c" break; case 141: #line 2110 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(mul); } + { (yyval.id) = intern_op(mul); } #line 6868 "mrbgems/mruby-compiler/core/y.tab.c" break; case 142: #line 2111 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(mul); } + { (yyval.id) = intern_op(mul); } #line 6874 "mrbgems/mruby-compiler/core/y.tab.c" break; case 143: #line 2112 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(div); } + { (yyval.id) = intern_op(div); } #line 6880 "mrbgems/mruby-compiler/core/y.tab.c" break; case 144: #line 2113 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(mod); } + { (yyval.id) = intern_op(mod); } #line 6886 "mrbgems/mruby-compiler/core/y.tab.c" break; case 145: #line 2114 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(pow); } + { (yyval.id) = intern_op(pow); } #line 6892 "mrbgems/mruby-compiler/core/y.tab.c" break; case 146: #line 2115 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(pow); } + { (yyval.id) = intern_op(pow); } #line 6898 "mrbgems/mruby-compiler/core/y.tab.c" break; case 147: #line 2116 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(not); } + { (yyval.id) = intern_op(not); } #line 6904 "mrbgems/mruby-compiler/core/y.tab.c" break; case 148: #line 2117 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(neg); } + { (yyval.id) = intern_op(neg); } #line 6910 "mrbgems/mruby-compiler/core/y.tab.c" break; case 149: #line 2118 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(plus); } + { (yyval.id) = intern_op(plus); } #line 6916 "mrbgems/mruby-compiler/core/y.tab.c" break; case 150: #line 2119 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(minus); } + { (yyval.id) = intern_op(minus); } #line 6922 "mrbgems/mruby-compiler/core/y.tab.c" break; case 151: #line 2120 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(aref); } + { (yyval.id) = intern_op(aref); } #line 6928 "mrbgems/mruby-compiler/core/y.tab.c" break; case 152: #line 2121 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(aset); } + { (yyval.id) = intern_op(aset); } #line 6934 "mrbgems/mruby-compiler/core/y.tab.c" break; case 153: #line 2122 "mrbgems/mruby-compiler/core/parse.y" - { (yyval.id) = MRB_OPSYM(tick); } + { (yyval.id) = intern_op(tick); } #line 6940 "mrbgems/mruby-compiler/core/y.tab.c" break; @@ -6958,7 +6958,7 @@ yyreduce: case 196: #line 2148 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), MRB_OPSYM(aref), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd)); + (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), intern_op(aref), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd)); } #line 6964 "mrbgems/mruby-compiler/core/y.tab.c" break; @@ -7426,14 +7426,14 @@ yyreduce: #line 2402 "mrbgems/mruby-compiler/core/parse.y" { #if 1 - mrb_sym r = MRB_OPSYM(mul); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym b = intern_op(and); (yyval.nd) = cons(push((yyvsp[-3].nd), new_splat(p, new_lvar(p, r))), new_block_arg(p, new_lvar(p, b))); #else - mrb_sym r = MRB_OPSYM(mul); - mrb_sym k = MRB_OPSYM(pow); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym k = intern_op(pow); + mrb_sym b = intern_op(and); (yyval.nd) = cons(list2(push((yyvsp[-3].nd), new_splat(p, new_lvar(p, r))), new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))), new_block_arg(p, new_lvar(p, b))); @@ -7446,16 +7446,16 @@ yyreduce: #line 2418 "mrbgems/mruby-compiler/core/parse.y" { #if 1 - mrb_sym r = MRB_OPSYM(mul); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym b = intern_op(and); if (local_var_p(p, r) && local_var_p(p, b)) { (yyval.nd) = cons(list1(new_splat(p, new_lvar(p, r))), new_block_arg(p, new_lvar(p, b))); } #else - mrb_sym r = MRB_OPSYM(mul); - mrb_sym k = MRB_OPSYM(pow); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym k = intern_op(pow); + mrb_sym b = intern_op(and); if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) { (yyval.nd) = cons(list2(new_splat(p, new_lvar(p, r)), new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))), @@ -8555,7 +8555,7 @@ yyreduce: case 406: #line 3117 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_call(p, (yyvsp[-2].nd), MRB_SYM(call), (yyvsp[0].nd), (yyvsp[-1].num)); + (yyval.nd) = new_call(p, (yyvsp[-2].nd), MRB_SYM_2(p->mrb, call), (yyvsp[0].nd), (yyvsp[-1].num)); } #line 8561 "mrbgems/mruby-compiler/core/y.tab.c" break; @@ -8563,7 +8563,7 @@ yyreduce: case 407: #line 3121 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_call(p, (yyvsp[-2].nd), MRB_SYM(call), (yyvsp[0].nd), tCOLON2); + (yyval.nd) = new_call(p, (yyvsp[-2].nd), MRB_SYM_2(p->mrb, call), (yyvsp[0].nd), tCOLON2); } #line 8569 "mrbgems/mruby-compiler/core/y.tab.c" break; @@ -8587,7 +8587,7 @@ yyreduce: case 410: #line 3133 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_call(p, (yyvsp[-3].nd), MRB_OPSYM(aref), (yyvsp[-1].nd), '.'); + (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } #line 8593 "mrbgems/mruby-compiler/core/y.tab.c" break; @@ -9103,15 +9103,15 @@ yyreduce: { #if 1 /* til real keyword args implemented */ - mrb_sym r = MRB_OPSYM(mul); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym b = intern_op(and); local_add_f(p, r); (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, r, 0, new_args_tail(p, 0, 0, b)); #else - mrb_sym r = MRB_OPSYM(mul); - mrb_sym k = MRB_OPSYM(pow); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym k = intern_op(pow); + mrb_sym b = intern_op(and); local_add_f(p, r); local_add_f(p, k); (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, r, 0, new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); @@ -9125,15 +9125,15 @@ yyreduce: { #if 1 /* til real keyword args implemented */ - mrb_sym r = MRB_OPSYM(mul); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym b = intern_op(and); local_add_f(p, r); (yyval.nd) = new_args(p, 0, 0, r, 0, new_args_tail(p, 0, 0, b)); #else - mrb_sym r = MRB_OPSYM(mul); - mrb_sym k = MRB_OPSYM(pow); - mrb_sym b = MRB_OPSYM(and); + mrb_sym r = intern_op(mul); + mrb_sym k = intern_op(pow); + mrb_sym b = intern_op(and); local_add_f(p, r); local_add_f(p, k); (yyval.nd) = new_args(p, 0, 0, r, 0, new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); @@ -9406,7 +9406,7 @@ yyreduce: case 533: #line 3708 "mrbgems/mruby-compiler/core/parse.y" { - local_add_f(p, MRB_OPSYM(and)); + local_add_f(p, intern_op(and)); (yyval.nd) = new_args(p, 0, 0, 0, 0, 0); } #line 9413 "mrbgems/mruby-compiler/core/y.tab.c" @@ -9590,7 +9590,7 @@ yyreduce: case 556: #line 3832 "mrbgems/mruby-compiler/core/parse.y" { - local_add_f(p, MRB_OPSYM(mul)); + local_add_f(p, intern_op(mul)); (yyval.id) = -1; } #line 9597 "mrbgems/mruby-compiler/core/y.tab.c" @@ -11216,7 +11216,7 @@ parser_yylex(parser_state *p) case '*': if ((c = nextc(p)) == '*') { if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(pow); + pylval.id = intern_op(pow); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11234,7 +11234,7 @@ parser_yylex(parser_state *p) } else { if (c == '=') { - pylval.id = MRB_OPSYM(mul); + pylval.id = intern_op(mul); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11350,7 +11350,7 @@ parser_yylex(parser_state *p) } if (c == '<') { if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(lshift); + pylval.id = intern_op(lshift); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11372,7 +11372,7 @@ parser_yylex(parser_state *p) } if (c == '>') { if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(rshift); + pylval.id = intern_op(rshift); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11480,7 +11480,7 @@ parser_yylex(parser_state *p) if ((c = nextc(p)) == '&') { p->lstate = EXPR_BEG; if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(andand); + pylval.id = intern_op(andand); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11492,7 +11492,7 @@ parser_yylex(parser_state *p) return tANDDOT; } else if (c == '=') { - pylval.id = MRB_OPSYM(and); + pylval.id = intern_op(and); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11519,7 +11519,7 @@ parser_yylex(parser_state *p) if ((c = nextc(p)) == '|') { p->lstate = EXPR_BEG; if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(oror); + pylval.id = intern_op(oror); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11527,7 +11527,7 @@ parser_yylex(parser_state *p) return tOROP; } if (c == '=') { - pylval.id = MRB_OPSYM(or); + pylval.id = intern_op(or); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11551,7 +11551,7 @@ parser_yylex(parser_state *p) return '+'; } if (c == '=') { - pylval.id = MRB_OPSYM(add); + pylval.id = intern_op(add); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11579,7 +11579,7 @@ parser_yylex(parser_state *p) return '-'; } if (c == '=') { - pylval.id = MRB_OPSYM(sub); + pylval.id = intern_op(sub); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11902,7 +11902,7 @@ parser_yylex(parser_state *p) return tREGEXP_BEG; } if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(div); + pylval.id = intern_op(div); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -11921,7 +11921,7 @@ parser_yylex(parser_state *p) case '^': if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(xor); + pylval.id = intern_op(xor); p->lstate = EXPR_BEG; return tOP_ASGN; } @@ -12099,7 +12099,7 @@ parser_yylex(parser_state *p) } } if ((c = nextc(p)) == '=') { - pylval.id = MRB_OPSYM(mod); + pylval.id = intern_op(mod); p->lstate = EXPR_BEG; return tOP_ASGN; } diff --git a/mrbgems/mruby-compiler/mrbgem.rake b/mrbgems/mruby-compiler/mrbgem.rake index 70f9e19d8..da910537a 100644 --- a/mrbgems/mruby-compiler/mrbgem.rake +++ b/mrbgems/mruby-compiler/mrbgem.rake @@ -5,13 +5,13 @@ MRuby::Gem::Specification.new 'mruby-compiler' do |spec| as_cxx_srcs = %w[codegen y.tab].map{|name| "#{dir}/core/#{name}.c"} objs = Dir.glob("#{dir}/core/*.c").map do |src| - dst = src.pathmap("#{build_dir}/core/%n") if build.cxx_exception_enabled? && as_cxx_srcs.include?(src) - build.compile_as_cxx(src, "#{dst}.cxx") + build.compile_as_cxx(src) else - objfile(dst) + objfile(src.pathmap("#{build_dir}/core/%n")) end end + objs << objfile("#{build_dir}/core/y.tab") build.libmruby_core_objs << objs lex_def = "#{dir}/core/lex.def" diff --git a/mrbgems/mruby-error/mrbgem.rake b/mrbgems/mruby-error/mrbgem.rake index 30a4259a8..ff7334744 100644 --- a/mrbgems/mruby-error/mrbgem.rake +++ b/mrbgems/mruby-error/mrbgem.rake @@ -4,7 +4,7 @@ MRuby::Gem::Specification.new('mruby-error') do |spec| spec.summary = 'extensional error handling' if build.cxx_exception_enabled? - @objs << build.compile_as_cxx("#{spec.dir}/src/exception.c", "#{spec.build_dir}/src/exception.cxx") - @objs.delete_if { |v| v == objfile("#{spec.build_dir}/src/exception") } + objs << build.compile_as_cxx("#{spec.dir}/src/exception.c") + objs.delete_if { |v| v == objfile("#{spec.build_dir}/src/exception") } end end diff --git a/src/class.c b/src/class.c index 270d8885f..85a26d343 100644 --- a/src/class.c +++ b/src/class.c @@ -2792,7 +2792,8 @@ static const mrb_code new_iseq[] = { OP_RETURN, 0x0 /* OP_RETURN R0 */ }; -const mrb_sym new_syms[] = { MRB_SYM(allocate), MRB_SYM(initialize) }; +MRB_PRESYM_DEFINE_VAR_AND_INITER(new_syms, 2, MRB_SYM(allocate), MRB_SYM(initialize)) + static const mrb_irep new_irep = { 3, 6, 0, MRB_IREP_STATIC, new_iseq, NULL, new_syms, NULL, NULL, NULL, @@ -2805,6 +2806,7 @@ init_class_new(mrb_state *mrb, struct RClass *cls) struct RProc *p; mrb_method_t m; + init_new_syms(mrb); p = mrb_proc_new(mrb, &new_irep); MRB_METHOD_FROM_PROC(m, p); mrb_define_method_raw(mrb, cls, MRB_SYM(new), m); diff --git a/src/debug.c b/src/debug.c index c03c91cf5..2f9320ac9 100644 --- a/src/debug.c +++ b/src/debug.c @@ -66,7 +66,7 @@ mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) { - if (irep && pc < irep->ilen) { + if (irep && pc >= 0 && pc < irep->ilen) { mrb_irep_debug_info_file* f = NULL; if (!irep->debug_info) { return -1; diff --git a/src/dump.c b/src/dump.c index 40f149f5d..3464f08b9 100644 --- a/src/dump.c +++ b/src/dump.c @@ -10,7 +10,6 @@ #include <mruby/dump.h> #include <mruby/string.h> #include <mruby/irep.h> -#include <mruby/numeric.h> #include <mruby/debug.h> #ifndef MRB_NO_FLOAT @@ -24,6 +23,45 @@ static size_t get_irep_record_size_1(mrb_state *mrb, const mrb_irep *irep); # error This code cannot be built on your environment. #endif +#define OPERATOR_SYMBOL(sym_name, name) {name, sym_name, sizeof(sym_name)-1} +struct operator_symbol { + const char *name; + const char *sym_name; + uint16_t sym_name_len; +}; +static const struct operator_symbol operator_table[] = { + OPERATOR_SYMBOL("!", "not"), + OPERATOR_SYMBOL("%", "mod"), + OPERATOR_SYMBOL("&", "and"), + OPERATOR_SYMBOL("*", "mul"), + OPERATOR_SYMBOL("+", "add"), + OPERATOR_SYMBOL("-", "sub"), + OPERATOR_SYMBOL("/", "div"), + OPERATOR_SYMBOL("<", "lt"), + OPERATOR_SYMBOL(">", "gt"), + OPERATOR_SYMBOL("^", "xor"), + OPERATOR_SYMBOL("`", "tick"), + OPERATOR_SYMBOL("|", "or"), + OPERATOR_SYMBOL("~", "neg"), + OPERATOR_SYMBOL("!=", "neq"), + OPERATOR_SYMBOL("!~", "nmatch"), + OPERATOR_SYMBOL("&&", "andand"), + OPERATOR_SYMBOL("**", "pow"), + OPERATOR_SYMBOL("+@", "plus"), + OPERATOR_SYMBOL("-@", "minus"), + OPERATOR_SYMBOL("<<", "lshift"), + OPERATOR_SYMBOL("<=", "le"), + OPERATOR_SYMBOL("==", "eq"), + OPERATOR_SYMBOL("=~", "match"), + OPERATOR_SYMBOL(">=", "ge"), + OPERATOR_SYMBOL(">>", "rshift"), + OPERATOR_SYMBOL("[]", "aref"), + OPERATOR_SYMBOL("||", "oror"), + OPERATOR_SYMBOL("<=>", "cmp"), + OPERATOR_SYMBOL("===", "eqq"), + OPERATOR_SYMBOL("[]=", "aset"), +}; + static size_t get_irep_header_size(mrb_state *mrb) { @@ -888,6 +926,8 @@ mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *f return MRB_DUMP_WRITE_FAULT; } if (fprintf(fp, + "#include <mruby.h>\n" + "#include <mruby/proc.h>\n" "#ifdef __cplusplus\n" "extern const uint8_t %s[];\n" "#endif\n" @@ -960,26 +1000,132 @@ dump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp) return MRB_DUMP_OK; } -mrb_bool mrb_sym_static_p(mrb_state *mrb, mrb_sym sym); +static mrb_bool +sym_name_word_p(const char *name, mrb_int len) +{ + if (len == 0) return FALSE; + if (name[0] != '_' && !ISALPHA(name[0])) return FALSE; + for (int i = 1; i < len; i++) { + if (name[i] != '_' && !ISALNUM(name[i])) return FALSE; + } + return TRUE; +} + +static mrb_bool +sym_name_with_equal_p(const char *name, mrb_int len) +{ + return len >= 2 && name[len-1] == '=' && sym_name_word_p(name, len-1); +} + +static mrb_bool +sym_name_with_question_mark_p(const char *name, mrb_int len) +{ + return len >= 2 && name[len-1] == '?' && sym_name_word_p(name, len-1); +} + +static mrb_bool +sym_name_with_bang_p(const char *name, mrb_int len) +{ + return len >= 2 && name[len-1] == '!' && sym_name_word_p(name, len-1); +} + +static mrb_bool +sym_name_ivar_p(const char *name, mrb_int len) +{ + return len >= 2 && name[0] == '@' && sym_name_word_p(name+1, len-1); +} + +static mrb_bool +sym_name_cvar_p(const char *name, mrb_int len) +{ + return len >= 3 && name[0] == '@' && sym_name_ivar_p(name+1, len-1); +} + +const char * +sym_operator_p(const char *name, mrb_int len) +{ + mrb_sym start, idx; + mrb_sym table_size = sizeof(operator_table)/sizeof(struct operator_symbol); + int cmp; + const struct operator_symbol *op_sym; + for (start = 0; table_size != 0; table_size/=2) { + idx = start+table_size/2; + op_sym = &operator_table[idx]; + cmp = len-op_sym->sym_name_len; + if (cmp == 0) { + cmp = memcmp(name, op_sym->sym_name, len); + if (cmp == 0) return op_sym->name; + } + if (0 < cmp) { + start = ++idx; + --table_size; + } + } + return NULL; +} static int -dump_sym(mrb_state *mrb, mrb_sym sym, FILE *fp) +dump_sym(mrb_state *mrb, mrb_sym sym, const char *var_name, int idx, mrb_value init_syms_code, FILE *fp, mrb_bool *presymp) { - const char *name; if (sym == 0) return MRB_DUMP_INVALID_ARGUMENT; - name = mrb_sym_name(mrb, sym); - if (!name) { - fprintf(stderr, "undefined symbol (%d) - define presym\n", sym); + + mrb_int len; + const char *name = mrb_sym_name_len(mrb, sym, &len), *op_name; + if (!name) return MRB_DUMP_INVALID_ARGUMENT; + if (presymp) *presymp = TRUE; + if (sym_name_word_p(name, len)) { + fprintf(fp, "MRB_SYM(%s)", name); + } + else if (sym_name_with_equal_p(name, len)) { + fprintf(fp, "MRB_SYM_E(%.*s)", (int)(len-1), name); + } + else if (sym_name_with_question_mark_p(name, len)) { + fprintf(fp, "MRB_SYM_Q(%.*s)", (int)(len-1), name); + } + else if (sym_name_with_bang_p(name, len)) { + fprintf(fp, "MRB_SYM_B(%.*s)", (int)(len-1), name); } - if (!mrb_sym_static_p(mrb, sym)) { - fprintf(stderr, "no static symbol (%s) - define presym\n", name); + else if (sym_name_ivar_p(name, len)) { + fprintf(fp, "MRB_IVSYM(%s)", name+1); } - fprintf(fp, "%d /* %s */,", sym, name); + else if (sym_name_cvar_p(name, len)) { + fprintf(fp, "MRB_CVSYM(%s)", name+2); + } + else if ((op_name = sym_operator_p(name, len))) { + fprintf(fp, "MRB_OPSYM(%s)", op_name); + } + else { + mrb_assert(var_name); + char buf[32]; + mrb_str_cat_lit(mrb, init_syms_code, " "); + mrb_str_cat_cstr(mrb, init_syms_code, var_name); + snprintf(buf, sizeof(buf), "[%d] = ", idx); + mrb_str_cat_cstr(mrb, init_syms_code, buf); + mrb_str_cat_lit(mrb, init_syms_code, "mrb_intern_lit(mrb, \""); + mrb_str_cat_cstr(mrb, init_syms_code, mrb_sym_dump(mrb, sym)); + mrb_str_cat_lit(mrb, init_syms_code, "\");\n"); + *presymp = FALSE; + fputs("0", fp); + } + fputs(", ", fp); return MRB_DUMP_OK; } +static const char* +sym_var_name(mrb_state *mrb, const char *initname, const char *key, int n) +{ + char buf[32]; + mrb_value s = mrb_str_new_cstr(mrb, initname); + mrb_str_cat_lit(mrb, s, "_"); + mrb_str_cat_cstr(mrb, s, key); + mrb_str_cat_lit(mrb, s, "_"); + snprintf(buf, sizeof(buf), "%d", n); + mrb_str_cat_cstr(mrb, s, buf); + return RSTRING_PTR(s); +} + static int -dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *name, int n, int *mp) +dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *name, int n, mrb_value init_syms_code, int *mp) { int i, len; int max = *mp; @@ -988,7 +1134,7 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, if (irep->reps) { for (i=0,len=irep->rlen; i<len; i++) { *mp += len; - if (dump_irep_struct(mrb, irep->reps[i], flags, fp, name, max+i, mp) != MRB_DUMP_OK) + if (dump_irep_struct(mrb, irep->reps[i], flags, fp, name, max+i, init_syms_code, mp) != MRB_DUMP_OK) return MRB_DUMP_INVALID_ARGUMENT; } fprintf(fp, "static const mrb_irep *%s_reps_%d[%d] = {\n", name, n, len); @@ -1009,12 +1155,19 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, } /* dump syms */ if (irep->syms) { + int ai = mrb_gc_arena_save(mrb); + const char *var_name = sym_var_name(mrb, name, "syms", n); + mrb_bool all_presym = TRUE, presym; len=irep->slen; - fprintf(fp, "static const mrb_sym %s_syms_%d[%d] = {", name, n, len); + fprintf(fp, "mrb_DEFINE_SYMS_VAR(%s, %d, (", var_name, len); for (i=0; i<len; i++) { - dump_sym(mrb, irep->syms[i], fp); + dump_sym(mrb, irep->syms[i], var_name, i, init_syms_code, fp, &presym); + all_presym &= presym; } - fputs("};\n", fp); + fputs("), ", fp); + if (all_presym) fputs("const", fp); + fputs(");\n", fp); + mrb_gc_arena_restore(mrb, ai); } /* dump iseq */ len=irep->ilen+sizeof(struct mrb_irep_catch_handler)*irep->clen; @@ -1029,7 +1182,7 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, len=irep->nlocals; fprintf(fp, "static const mrb_sym %s_lv_%d[%d] = {", name, n, len-1); for (i=0; i+1<len; i++) { - fprintf(fp, "%uU, ", irep->lv[i]); + dump_sym(mrb, irep->lv[i], NULL, 0, mrb_nil_value(), fp, NULL); } fputs("};\n", fp); } @@ -1070,20 +1223,28 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname) { - int max = 1; - int n; - if (fp == NULL || initname == NULL || initname[0] == '\0') { return MRB_DUMP_INVALID_ARGUMENT; } if (fprintf(fp, "#include <mruby.h>\n" "#include <mruby/proc.h>\n\n") < 0) { return MRB_DUMP_WRITE_FAULT; } - n = dump_irep_struct(mrb, irep, flags, fp, initname, 0, &max); + fputs("#define mrb_BRACED(...) {__VA_ARGS__}\n", fp); + fputs("#define mrb_DEFINE_SYMS_VAR(name, len, syms, qualifier) \\\n", fp); + fputs(" static qualifier mrb_sym name[len] = mrb_BRACED syms\n", fp); + fputs("\n", fp); + mrb_value init_syms_code = mrb_str_new_capa(mrb, 0); + int max = 1; + int n = dump_irep_struct(mrb, irep, flags, fp, initname, 0, init_syms_code, &max); if (n != MRB_DUMP_OK) return n; fprintf(fp, "#ifdef __cplusplus\nextern const struct RProc %s[];\n#endif\n", initname); fprintf(fp, "const struct RProc %s[] = {{\n", initname); fprintf(fp, "NULL,NULL,MRB_TT_PROC,7,0,{&%s_irep_0},NULL,{NULL},\n}};\n", initname); + fputs("static void\n", fp); + fprintf(fp, "%s_init_syms(mrb_state *mrb)\n", initname); + fputs("{\n", fp); + fputs(RSTRING_PTR(init_syms_code), fp); + fputs("}\n", fp); return MRB_DUMP_OK; } diff --git a/src/symbol.c b/src/symbol.c index c78f41f63..58decc1f1 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -12,15 +12,19 @@ #include <mruby/dump.h> #include <mruby/class.h> -#undef MRB_PRESYM_MAX -#define MRB_PRESYM_NAMED(lit, num, type, name) {lit, sizeof(lit)-1}, -#define MRB_PRESYM_UNNAMED(lit, num) {lit, sizeof(lit)-1}, +#ifndef MRB_NO_PRESYM + +# undef MRB_PRESYM_MAX +# define MRB_PRESYM_NAMED(lit, num, type, name) {lit, sizeof(lit)-1}, +# define MRB_PRESYM_UNNAMED(lit, num) {lit, sizeof(lit)-1}, static const struct { const char *name; uint16_t len; } presym_table[] = { -#include <../build/presym.inc> +#ifndef MRB_PRESYM_SCANNING +# include <mruby/presym.inc> +#endif }; static mrb_sym @@ -51,6 +55,8 @@ presym_sym2name(mrb_sym sym, mrb_int *lenp) return presym_table[sym-1].name; } +#endif /* MRB_NO_PRESYM */ + /* ------------------------------------------------------ */ typedef struct symbol_name { mrb_bool lit : 1; @@ -147,9 +153,11 @@ find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp) symbol_name *sname; uint8_t hash; +#ifndef MRB_NO_PRESYM /* presym */ i = presym_find(name, len); if (i > 0) return i<<SYMBOL_SHIFT; +#endif /* inline symbol */ i = sym_inline_pack(name, len); @@ -306,10 +314,12 @@ sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp) if (SYMBOL_INLINE_P(sym)) return sym_inline_unpack(sym, buf, lenp); sym >>= SYMBOL_SHIFT; +#ifndef MRB_NO_PRESYM { const char *name = presym_sym2name(sym, lenp); if (name) return name; } +#endif sym -= MRB_PRESYM_MAX; if (sym == 0 || mrb->symidx < sym) { diff --git a/tasks/benchmark.rake b/tasks/benchmark.rake index 6f0b0ef6a..12e0d4602 100644 --- a/tasks/benchmark.rake +++ b/tasks/benchmark.rake @@ -50,7 +50,7 @@ end MRuby.each_target do |target| - next if target.name == 'host' + next if target.name == 'host' || target.internal? mruby_bin = "#{target.build_dir}/bin/mruby" bm_files.each do |bm_file| diff --git a/tasks/bin.rake b/tasks/bin.rake new file mode 100644 index 000000000..afef065a1 --- /dev/null +++ b/tasks/bin.rake @@ -0,0 +1,35 @@ +install_task = ->(src) do + dst = "#{MRuby::Build.install_dir}/#{File.basename(src)}" + file dst => src do + install_D src, dst + end + dst +end + +MRuby.each_target do |build| + if build.host? && build.mrbc_build && !build.gems["mruby-bin-mrbc"] + exe = build.exefile("#{build.mrbc_build.build_dir}/bin/mrbc") + build.products << install_task.(exe) + end + + build.bins.each do |bin| + exe = build.exefile("#{build.build_dir}/bin/#{bin}") + build.products << (build.host? ? install_task.(exe) : exe) + end + + linker_attrs = build.gems.map{|gem| gem.linker.run_attrs}.transpose + build.gems.each do |gem| + gem.bins.each do |bin| + exe = build.exefile("#{build.build_dir}/bin/#{bin}") + objs = Dir["#{gem.dir}/tools/#{bin}/*.{c,cpp,cxx,cc}"].map do |f| + build.objfile(f.pathmap("#{gem.build_dir}/tools/#{bin}/%n")) + end + + file exe => objs.concat(build.libraries) do |t| + build.linker.run t.name, t.prerequisites, *linker_attrs + end + + build.products << (build.host? ? install_task.(exe) : exe) + end + end +end diff --git a/tasks/core.rake b/tasks/core.rake index aca5faed8..a47722e8b 100644 --- a/tasks/core.rake +++ b/tasks/core.rake @@ -2,11 +2,10 @@ as_cxx_srcs = %w[vm error gc].map{|name| "#{MRUBY_ROOT}/src/#{name}.c"} MRuby.each_target do objs = Dir.glob("#{MRUBY_ROOT}/src/*.c").map do |src| - dst = src.pathmap("#{build_dir}/src/%n") if cxx_exception_enabled? && as_cxx_srcs.include?(src) - compile_as_cxx(src, "#{dst}.cxx") + compile_as_cxx(src) else - objfile(dst) + objfile(src.pathmap("#{build_dir}/src/%n")) end end self.libmruby_core_objs << objs diff --git a/tasks/libmruby.rake b/tasks/libmruby.rake index c73b25d3b..23cd992ff 100644 --- a/tasks/libmruby.rake +++ b/tasks/libmruby.rake @@ -3,6 +3,8 @@ MRuby.each_target do archiver.run t.name, t.prerequisites end + products << libmruby_core_static + next unless libmruby_enabled? file libmruby_static => libmruby_objs.flatten do |t| @@ -27,4 +29,6 @@ MRuby.each_target do f.puts "MRUBY_LIBMRUBY_PATH = #{libmruby_static}" end end + + products << libmruby_static end diff --git a/tasks/mrblib.rake b/tasks/mrblib.rake index a7f592593..5567515d6 100644 --- a/tasks/mrblib.rake +++ b/tasks/mrblib.rake @@ -2,13 +2,18 @@ MRuby.each_target do next unless libmruby_enabled? src = "#{build_dir}/mrblib/mrblib.c" - obj = objfile(src.ext) rbfiles = Dir["#{MRUBY_ROOT}/mrblib/*.rb"].sort! - self.libmruby_objs << obj + self.libmruby_objs << objfile(src.ext) - file obj => src file src => [mrbcfile, __FILE__, *rbfiles] do |t| + if presym_enabled? + cdump = true + suffix = "proc" + else + cdump = false + suffix = "irep" + end mkdir_p File.dirname(t.name) File.open(t.name, 'w') do |f| _pp "GEN", "mrblib/*.rb", "#{t.name.relative_path}" @@ -19,14 +24,17 @@ MRuby.each_target do f.puts %Q[ * This file was generated!] f.puts %Q[ * All manual changes will get lost.] f.puts %Q[ */] - mrbc.run f, rbfiles, 'mrblib_proc' - f.puts <<INIT_END -void -mrb_init_mrblib(mrb_state *mrb) -{ - mrb_load_proc(mrb, mrblib_proc); -} -INIT_END + unless presym_enabled? + f.puts %Q[#include <mruby.h>] + f.puts %Q[#include <mruby/irep.h>] + end + mrbc.run f, rbfiles, "mrblib_#{suffix}", cdump + f.puts %Q[void] + f.puts %Q[mrb_init_mrblib(mrb_state *mrb)] + f.puts %Q[{] + f.puts %Q[ mrblib_#{suffix}_init_syms(mrb);] if cdump + f.puts %Q[ mrb_load_#{suffix}(mrb, mrblib_#{suffix});] + f.puts %Q[}] end end end diff --git a/tasks/presym.rake b/tasks/presym.rake new file mode 100644 index 000000000..f3a076ac6 --- /dev/null +++ b/tasks/presym.rake @@ -0,0 +1,41 @@ +all_prerequisites = ->(task_name, prereqs) do + Rake::Task[task_name].prerequisites.each do |prereq_name| + next if prereqs[prereq_name] + prereqs[prereq_name] = true + all_prerequisites.(Rake::Task[prereq_name].name, prereqs) + end +end + +MRuby.each_target do |build| + gensym_task = task(:gensym) + next unless build.presym_enabled? + + presym = build.presym + + include_dir = "#{build.build_dir}/include" + build.compilers.each{|c| c.include_paths << include_dir} + build.gems.each{|gem| gem.compilers.each{|c| c.include_paths << include_dir}} + + prereqs = {} + pps = [] + mrbtest = "#{build.class.install_dir}/mrbtest" + mrbc_build_dir = "#{build.mrbc_build.build_dir}/" if build.mrbc_build + build.products.each do |product| + all_prerequisites.(product, prereqs) unless product == mrbtest + end + prereqs.each_key do |prereq| + next unless File.extname(prereq) == build.exts.object + next if mrbc_build_dir && prereq.start_with?(mrbc_build_dir) + pps << prereq.ext(build.exts.preprocessed) + end + + file presym.list_path => pps do + presyms = presym.scan(pps) + current_presyms = presym.read_list if File.exist?(presym.list_path) + update = presyms != current_presyms + presym.write_list(presyms) if update + presym.write_header(presyms) if update || !File.exist?(presym.header_path) + end + + gensym_task.enhance([presym.list_path]) +end diff --git a/tasks/toolchains/gcc.rake b/tasks/toolchains/gcc.rake index 316d2d9a1..8714e1854 100644 --- a/tasks/toolchains/gcc.rake +++ b/tasks/toolchains/gcc.rake @@ -3,6 +3,7 @@ MRuby::Toolchain.new(:gcc) do |conf, params| compiler_flags = %w(-g -O3 -Wall -Wundef) c_mandatory_flags = %w(-std=gnu99) cxx_invalid_flags = %w(-Werror-implicit-function-declaration) + compile_opt = '%{flags} -MMD -MF "%{outfile}.d" -o "%{outfile}" "%{infile}"' [conf.cc, conf.objc, conf.asm, conf.cxx].each do |compiler| if compiler == conf.cxx @@ -14,7 +15,8 @@ MRuby::Toolchain.new(:gcc) do |conf, params| end compiler.option_include_path = %q[-I"%s"] compiler.option_define = '-D%s' - compiler.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"] + compiler.compile_options = "-c #{compile_opt}" + compiler.preprocess_options = "-E -P #{compile_opt}" compiler.cxx_compile_flag = '-x c++ -std=gnu++03' compiler.cxx_exception_flag = '-fexceptions' compiler.cxx_invalid_flags = c_mandatory_flags + cxx_invalid_flags diff --git a/tasks/toolchains/openwrt.rake b/tasks/toolchains/openwrt.rake index c376d96ec..d5763d8de 100644 --- a/tasks/toolchains/openwrt.rake +++ b/tasks/toolchains/openwrt.rake @@ -1,24 +1,19 @@ # usage of environmental variables to set the # cross compiling toolchain proper MRuby::Toolchain.new(:openwrt) do |conf| - [conf.cc, conf.objc, conf.asm].each do |cc| - cc.command = ENV['TARGET_CC'] - cc.flags = ENV['TARGET_CFLAGS'] - cc.include_paths = ["#{MRUBY_ROOT}/include"] + [conf.cc, conf.cxx, conf.objc, conf.asm].each do |cc| + if cc == conf.cxx + cc.command = ENV['TARGET_CXX'] + cc.flags = ENV['TARGET_CXXFLAGS'] + else + cc.command = ENV['TARGET_CC'] + cc.flags = ENV['TARGET_CFLAGS'] + end cc.option_include_path = %q[-I"%s"] cc.option_define = '-D%s' - cc.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"] + cc.compile_options = %q[%{flags} -MMD -MF "%{outfile}.d" -o "%{outfile}" -c "%{infile}"] end - [conf.cxx].each do |cxx| - cxx.command = ENV['TARGET_CXX'] - cxx.flags = ENV['TARGET_CXXFLAGS'] - cxx.include_paths = ["#{MRUBY_ROOT}/include"] - cxx.option_include_path = %q[-I"%s"] - cxx.option_define = '-D%s' - cxx.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"] - end - conf.linker do |linker| linker.command = ENV['TARGET_CC'] linker.flags = ENV['TARGET_LDFLAGS'] diff --git a/tasks/toolchains/visualcpp.rake b/tasks/toolchains/visualcpp.rake index 5094495e3..00e364082 100644 --- a/tasks/toolchains/visualcpp.rake +++ b/tasks/toolchains/visualcpp.rake @@ -1,25 +1,21 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params| - conf.cc do |cc| - cc.command = ENV['CC'] || 'cl.exe' - # C4013: implicit function declaration - cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /MD /O2 /D_CRT_SECURE_NO_WARNINGS)] - cc.defines = %w(MRB_STACK_EXTEND_DOUBLING) - cc.option_include_path = %q[/I"%s"] - cc.option_define = '/D%s' - cc.compile_options = %Q[%{flags} /Fo"%{outfile}" "%{infile}"] - cc.cxx_compile_flag = '/TP' - cc.cxx_exception_flag = '/EHs' - end - - conf.cxx do |cxx| - cxx.command = ENV['CXX'] || 'cl.exe' - cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /W3 /Zi /MD /O2 /EHs /D_CRT_SECURE_NO_WARNINGS)] - cxx.defines = %w(MRB_STACK_EXTEND_DOUBLING) - cxx.option_include_path = %q[/I"%s"] - cxx.option_define = '/D%s' - cxx.compile_options = %Q[%{flags} /Fo"%{outfile}" "%{infile}"] - cxx.cxx_compile_flag = '/TP' - cxx.cxx_exception_flag = '/EHs' + compiler_flags = %w(/nologo /W3 /MD /O2 /D_CRT_SECURE_NO_WARNINGS) + [conf.cc, conf.cxx].each do |compiler| + if compiler == conf.cc + compiler.command = ENV['CC'] || 'cl.exe' + # C4013: implicit function declaration + compiler.flags = [*(ENV['CFLAGS'] || compiler_flags + %w(/we4013))] + else + compiler.command = ENV['CXX'] || 'cl.exe' + compiler.flags = [*(ENV['CXXFLAGS'] || ENV['CFLAGS'] || compiler_flags + %w(/EHs))] + end + compiler.defines = %w(MRB_STACK_EXTEND_DOUBLING) + compiler.option_include_path = %q[/I"%s"] + compiler.option_define = '/D%s' + compiler.compile_options = %Q[/Zi /c /Fo"%{outfile}" %{flags} "%{infile}"] + compiler.preprocess_options = %Q[/EP %{flags} "%{infile}" > "%{outfile}"] + compiler.cxx_compile_flag = '/TP' + compiler.cxx_exception_flag = '/EHs' end conf.linker do |linker| diff --git a/test/bintest.rb b/test/bintest.rb index 4a3f161ba..a6888c9fb 100644 --- a/test/bintest.rb +++ b/test/bintest.rb @@ -4,7 +4,8 @@ require 'test/assert.rb' GEMNAME = "" def cmd(s) - path = "#{ENV['BUILD_DIR']}/bin/#{s}" + path = s == "mrbc" ? ENV['MRBCFILE'] : "#{ENV['BUILD_DIR']}/bin/#{s}" + path = path.sub(/\.exe\z/, "") if /mswin(?!ce)|mingw|bccwin/ =~ RbConfig::CONFIG['host_os'] path = "#{path}.exe".tr("/", "\\") end |
