From 8932d9b02114aea0ce914fd5dc402190d376cd8d Mon Sep 17 00:00:00 2001 From: Satoshi Shiba Date: Tue, 29 Nov 2011 03:47:47 +0900 Subject: [PATCH] v0.3.4 => v0.3.5 --- cast_off.gemspec | 6 +- ext/cast_off/cast_off.c.rb | 19 ++- ext/cast_off/depend | 4 +- ext/cast_off/extconf.rb | 4 +- ext/cast_off/generated_c_include/inline_api.h | 109 ------------------ .../generated_c_include/unbox_api.h.rb | 70 ++++++++--- lib/cast_off/compile.rb | 45 ++++---- lib/cast_off/compile/code_manager.rb | 45 ++++++-- lib/cast_off/compile/configuration.rb | 6 +- lib/cast_off/compile/ir/call_ir.rb | 16 +-- lib/cast_off/compile/ir/guard_ir.rb | 11 +- lib/cast_off/compile/ir/simple_ir.rb | 2 +- 12 files changed, 165 insertions(+), 172 deletions(-) diff --git a/cast_off.gemspec b/cast_off.gemspec index 287609e..dc8a766 100644 --- a/cast_off.gemspec +++ b/cast_off.gemspec @@ -1,10 +1,12 @@ Gem::Specification.new do |spec| spec.name = "cast_off" - spec.version = "0.3.3" + spec.version = "0.3.5" spec.platform = Gem::Platform::RUBY spec.summary = "Compiler for Ruby1.9.3" spec.description = <<-EOS -CastOff is a compiler for Ruby1.9.3 +CastOff is a compiler for Ruby1.9.3. +Command line tool cast_off is available after installation. +See 'cast_off --help' for more information. EOS spec.files = Dir['{lib/**/*,ext/**/*}'] + %w[ cast_off.gemspec diff --git a/ext/cast_off/cast_off.c.rb b/ext/cast_off/cast_off.c.rb index 41f7bd5..a18512a 100644 --- a/ext/cast_off/cast_off.c.rb +++ b/ext/cast_off/cast_off.c.rb @@ -734,6 +734,12 @@ def = me->def; } } +static VALUE cast_off_class_wrapper_method_defined_p(VALUE self, VALUE mid) +{ + VALUE klass = cast_off_class_wrapper_get_class(self); + return search_method(klass, SYM2ID(mid)) ? Qtrue : Qfalse; +} + static VALUE cast_off_class_wrapper_get_method_type(VALUE self, VALUE mid) { VALUE klass = cast_off_class_wrapper_get_class(self); @@ -948,14 +954,22 @@ module = wrapper->module; VALUE module = cast_off_module_wrapper_get_module(self); VALUE name = rb_mod_name(module); - /* TODO error handling */ + if (TYPE(name) != T_STRING) { + rb_raise(rb_eTypeError, "failed to get module name"); + } + return name; } static VALUE cast_off_module_wrapper_marshal_load(VALUE self, VALUE name) { - VALUE module = rb_path_to_class(name); + VALUE module; + + if (NIL_P(name)) { + rb_raise(rb_eArgError, "invalid marshal"); + } + module = rb_path_to_class(name); if (rb_obj_class(module) != rb_cModule) { rb_raise(rb_eCastOffCompileError, "failed to load module"); } @@ -1495,6 +1509,7 @@ module = wrapper->module; rb_define_method(rb_cCastOffClassWrapper, "singleton?", cast_off_class_wrapper_singleton_p, 0); rb_define_method(rb_cCastOffClassWrapper, "get_cfunc_argc", cast_off_class_wrapper_get_cfunc_argc, 1); rb_define_method(rb_cCastOffClassWrapper, "get_method_type", cast_off_class_wrapper_get_method_type, 1); + rb_define_method(rb_cCastOffClassWrapper, "method_defined?", cast_off_class_wrapper_method_defined_p, 1); rb_define_method(rb_cCastOffClassWrapper, "get_attr_id", cast_off_class_wrapper_get_attr_id, 1); rb_define_method(rb_cCastOffClassWrapper, "instance_method_exist?", cast_off_class_wrapper_instance_method_exist_p, 1); rb_define_method(rb_cCastOffClassWrapper, "contain_class", cast_off_class_wrapper_contain_class, 0); diff --git a/ext/cast_off/depend b/ext/cast_off/depend index b176876..b248c45 100644 --- a/ext/cast_off/depend +++ b/ext/cast_off/depend @@ -3,7 +3,7 @@ $(srcdir)/generated_c_include/unbox_api.h: \ $(RUBY) -- $(srcdir)/generated_c_include/unbox_api.h.rb > $@ -cast_off.c: \ +$(srcdir)/cast_off.c: \ $(srcdir)/ruby_source/1.9.3/debug.h \ $(srcdir)/ruby_source/1.9.3/gc.h \ $(srcdir)/ruby_source/1.9.3/id.h \ @@ -51,7 +51,7 @@ cast_off.c: \ $(RUBY) -- $(srcdir)/cast_off.c.rb $(srcdir)/ruby_source $(srcdir)/generated_c_include > $@ -cast_off.o: \ +$(srcdir)/cast_off.o: \ $(arch_hdrdir)/ruby/config.h \ $(hdrdir)/ruby/defines.h \ $(hdrdir)/ruby/intern.h \ diff --git a/ext/cast_off/extconf.rb b/ext/cast_off/extconf.rb index 219e7ff..60b9dac 100644 --- a/ext/cast_off/extconf.rb +++ b/ext/cast_off/extconf.rb @@ -12,8 +12,8 @@ $defs.push '-DCABI_PASS_CFP' if enable_config 'cabi-pass-cfp', true $INCFLAGS << ' -I$(srcdir)/ruby_source' -$objs = %w'cast_off.o' -$srcs = %w'cast_off.c.rb' +$objs = %w'$(srcdir)/cast_off.o' +$srcs = %w'$(srcdir)/cast_off.c.rb' create_header create_makefile 'cast_off' diff --git a/ext/cast_off/generated_c_include/inline_api.h b/ext/cast_off/generated_c_include/inline_api.h index b372157..66ee72f 100644 --- a/ext/cast_off/generated_c_include/inline_api.h +++ b/ext/cast_off/generated_c_include/inline_api.h @@ -1,114 +1,5 @@ #define TYPE_ERROR_MESSAGE() "type mismatch" -static inline VALUE -cast_off_inline_fixnum_fixnum_plus(VALUE recv, VALUE obj) -{ -#if 0 -#ifdef INJECT_GUARD - if (UNLIKELY(!FIXNUM_2_P(recv, obj))) { - rb_raise(rb_eCastOffExecutionError, TYPE_ERROR_MESSAGE()); - } -#endif -#endif - -#ifndef LONG_LONG_VALUE - { - VALUE val = (recv + (obj & (~1))); -#ifdef INJECT_GUARD - if ((~(recv ^ obj) & (recv ^ val)) & ((VALUE)0x01 << ((sizeof(VALUE) * CHAR_BIT) - 1))) { - rb_raise(rb_eCastOffExecutionError, TYPE_ERROR_MESSAGE()); - } -#endif /* INJECT_GUARD */ - return val; - } -#else /* LONG_LONG_VALUE */ - { - long a, b, c; - a = FIX2LONG(recv); - b = FIX2LONG(obj); - c = a + b; -#ifdef INJECT_GUARD - if (UNLIKELY(!FIXABLE(c))) { - rb_raise(rb_eCastOffExecutionError, TYPE_ERROR_MESSAGE()); - } -#endif /* INJECT_GUARD */ - return LONG2FIX(c); - } -#endif /* LONG_LONG_VALUE */ -} - -static inline VALUE -cast_off_inline_fixnum_float_plus(VALUE recv, VALUE obj) -{ - return DBL2NUM((double)FIX2LONG(recv) + RFLOAT_VALUE(obj)); -} - -static inline VALUE -cast_off_inline_fixnum_fixnum_minus(VALUE recv, VALUE obj) -{ - long a, b, c; - -#if 0 -#ifdef INJECT_GUARD - if (UNLIKELY(!FIXNUM_2_P(recv, obj))) { - rb_raise(rb_eCastOffExecutionError, TYPE_ERROR_MESSAGE()); - } -#endif -#endif - - a = FIX2LONG(recv); - b = FIX2LONG(obj); - c = a - b; -#ifdef INJECT_GUARD - if (LIKELY(FIXABLE(c))) { -#endif - return LONG2FIX(c); -#ifdef INJECT_GUARD - } else { - rb_raise(rb_eCastOffExecutionError, TYPE_ERROR_MESSAGE()); - } -#endif -} - -static inline VALUE -cast_off_inline_fixnum_float_minus(VALUE recv, VALUE obj) -{ - return DBL2NUM((double)FIX2LONG(recv) - RFLOAT_VALUE(obj)); -} - -static inline VALUE -cast_off_inline_fixnum_fixnum_mult(VALUE recv, VALUE obj) -{ - long a, b, c; - -#if 0 -#ifdef INJECT_GUARD - if (UNLIKELY(!FIXNUM_2_P(recv, obj))) { - rb_raise(rb_eCastOffExecutionError, TYPE_ERROR_MESSAGE()); - } -#endif -#endif - - a = FIX2LONG(recv); - b = FIX2LONG(obj); - c = a * b; -#ifdef INJECT_GUARD - if (LIKELY(FIXABLE(c))) { -#endif - return LONG2FIX(c); -#ifdef INJECT_GUARD - } else { - rb_raise(rb_eCastOffExecutionError, TYPE_ERROR_MESSAGE()); - } -#endif -} - -static inline VALUE -cast_off_inline_fixnum_float_mult(VALUE recv, VALUE obj) -{ - return DBL2NUM((double)FIX2LONG(recv) * RFLOAT_VALUE(obj)); -} - static inline VALUE cast_off_inline_fixnum_le(VALUE recv, VALUE obj) { diff --git a/ext/cast_off/generated_c_include/unbox_api.h.rb b/ext/cast_off/generated_c_include/unbox_api.h.rb index d788eec..fd96618 100644 --- a/ext/cast_off/generated_c_include/unbox_api.h.rb +++ b/ext/cast_off/generated_c_include/unbox_api.h.rb @@ -9,91 +9,129 @@ #endif __END__ #define CBOOL2RBOOL(b) ((b) ? Qtrue : Qfalse) -#ifdef INJECT_GUARD -#define CFIX2RFIX(b) (FIXABLE?((b)) ? LONG2FIX((b)) : rb_raise(rb_eCastOffExecutionError, TYPE_ERROR_MESSAGE())) -#else -#define CFIX2RFIX(b) LONG2FIX((b)) -#endif static inline VALUE CDOUBLE2RINT(double f) { if (f > 0.0) f = floor(f); if (f < 0.0) f = ceil(f); return FIXABLE(f) ? LONG2FIX((double)f) : rb_dbl2big(f); } +static inline VALUE PLUS(long a, long b) +{ + long c = a + b; + if (FIXABLE(c)) { + return LONG2FIX(c); + } else { + return rb_big_plus(rb_int2big(a), rb_int2big(b)); + } +} +static inline VALUE MINUS(long a, long b) +{ + long c = a - b; + if (FIXABLE(c)) { + return LONG2FIX(c); + } else { + return rb_big_minus(rb_int2big(a), rb_int2big(b)); + } +} +static inline VALUE MULT(long a, long b) +{ + if (a == 0) { + return LONG2FIX(0); + } else { + volatile long c = a * b; + if (FIXABLE(c) && c / a == b) { + return LONG2FIX(c); + } else { + return rb_big_mul(rb_int2big(a), rb_int2big(b)); + } + } +} %# arg size, [type0, type1, ...] %[['float', % {'-' => 'uminus'}, % 0, +% :unary_operator, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {}, % {'VALUE' => 'DBL2NUM', 'double' => ''}], % ['float', % {'' => 'to_f'}, % 0, +% :unary_operator, % {'VALUE' => ''}, % {}, % {'VALUE' => '', 'double' => 'RFLOAT_VALUE'}], % ['float', % {'' => 'to_i'}, % 0, +% :unary_operator, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {}, % {'VALUE' => 'CDOUBLE2RINT'}], % ['fixnum', % {'-' => 'uminus'}, % 0, +% :unary_operator, % {'VALUE' => 'FIX2LONG', 'long' => ''}, % {}, -% {'VALUE' => 'CFIX2RFIX', 'long' => ''}], +% {'VALUE' => 'LONG2NUM'}], % ['fixnum', % {'(double)' => 'to_f'}, % 0, +% :unary_operator, % {'VALUE' => 'FIX2LONG', 'long' => ''}, % {}, % {'VALUE' => 'DBL2NUM', 'double' => ''}], % ['float_float', % {'+' => 'plus', '-' => 'minus', '*' => 'mult', '/' => 'div'}, % 1, +% :binary_operator, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {'VALUE' => 'DBL2NUM', 'double' => ''}], % ['float_float', % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq'}, % 1, +% :binary_operator, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {'VALUE' => 'CBOOL2RBOOL'}], % ['fixnum_fixnum', -% {'+' => 'plus', '-' => 'minus', '*' => 'mult', '/' => 'div'}, +% {'PLUS' => 'plus', 'MINUS' => 'minus', 'MULT' => 'mult'}, % 1, +% :function, % {'VALUE' => 'FIX2LONG', 'long' => ''}, % {'VALUE' => 'FIX2LONG', 'long' => ''}, -% {'VALUE' => 'CFIX2RFIX', 'long' => ''}], +% {'VALUE' => ''}], % ['fixnum_float', -% {'+' => 'plus', '-' => 'minus', '*' => 'mult', '/' => 'div'}, +% {'+' => 'plus', '-' => 'minus', '*' => 'mult'}, % 1, +% :binary_operator, % {'VALUE' => '(double)FIX2LONG', 'long' => ''}, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {'VALUE' => 'DBL2NUM', 'double' => ''}], % ['fixnum_float', % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq'}, % 1, +% :binary_operator, % {'VALUE' => '(double)FIX2LONG', 'long' => ''}, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {'VALUE' => 'CBOOL2RBOOL'}], % ['float_fixnum', % {'+' => 'plus', '-' => 'minus', '*' => 'mult', '/' => 'div'}, % 1, +% :binary_operator, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {'VALUE' => '(double)FIX2LONG', 'long' => ''}, % {'VALUE' => 'DBL2NUM', 'double' => ''}], % ['float_fixnum', % {'>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le', '==' => 'eq', '==' => 'eqq'}, % 1, +% :binary_operator, % {'VALUE' => 'RFLOAT_VALUE', 'double' => ''}, % {'VALUE' => '(double)FIX2LONG', 'long' => ''}, -% {'VALUE' => 'CBOOL2RBOOL'}]].each do |(function_name, h, argc, reciever_converter, arguments_converter, return_value_converter)| +% {'VALUE' => 'CBOOL2RBOOL'}]].each do |(function_name, h, argc, operation, reciever_converter, arguments_converter, return_value_converter)| % arguments_decls = arguments_converter.keys % reciever_decls = reciever_converter.keys % return_value_decls = return_value_converter.keys @@ -117,11 +155,17 @@ static inline <%= return_value %> cast_off_inline_<%= function_name %>_<%= name %>_<%= suffix %>(<%= parameter.join(', ') %>) { -% if argc > 0 +% case operation +% when :unary_operator +% raise unless argc == 0 && statement.size == 1 + return <%= return_value_converter[return_value] %>(<%= operator %>(<%= statement.first %>)); +% when :binary_operator +% raise unless argc == 1 && statement.size == 2 return <%= return_value_converter[return_value] %>(<%= statement.join(" #{operator} ") %>); +% when :function + return <%= return_value_converter[return_value] %>(<%= operator %>(<%= statement.join(", ") %>)); % else -% raise unless statement.size == 1 - return <%= return_value_converter[return_value] %>(<%= operator %>(<%= statement.first %>)); +% raise % end } % end diff --git a/lib/cast_off/compile.rb b/lib/cast_off/compile.rb index 776c4e8..6030f75 100644 --- a/lib/cast_off/compile.rb +++ b/lib/cast_off/compile.rb @@ -95,7 +95,11 @@ def autocompile() #count = @@compilation_threshold if contain_loop?(klass, mid) bug() unless bind.instance_of?(Binding) || bind.nil? bind_table[[klass, mid]] = bind - location_table[[klass, mid]] = (file =~ /\(/) ? nil : [File.expand_path(file), line] + begin + location_table[[klass, mid]] = (file =~ /\(/) ? nil : [File.expand_path(file), line] + rescue Errno::ENOENT + location_table[[klass, mid]] = nil + end end #if cinfo #table = (cinfo_table[[klass, mid]] ||= {}) @@ -153,7 +157,7 @@ def delete_original_instance_method_iseq(target, mid) @@original_instance_method_iseq.delete([t, mid]) end - def compile(target, mid, bind_or_typemap = nil, typemap = nil) + def compile(target, mid, bind_or_typemap = nil, typemap = nil, force_compilation = false) execute_no_hook() do case target when Class, Module @@ -164,7 +168,7 @@ def compile(target, mid, bind_or_typemap = nil, typemap = nil) mid, bind, typemap = parse_arguments(mid, bind_or_typemap, typemap) t = override_target(target, mid) iseq = @@original_instance_method_iseq[[t, mid]] || get_iseq(target, mid, false) - manager, configuration, suggestion = compile_iseq(iseq, mid, typemap, false, bind) + manager, configuration, suggestion = compile_iseq(iseq, mid, typemap, false, bind, force_compilation) manager.compilation_target_is_a(t, mid, false) set_direct_call(target, mid, target.instance_of?(Class) ? :class : :module, manager, configuration) load_binary(manager, configuration, suggestion, iseq) @@ -182,11 +186,11 @@ def delete_original_singleton_method_iseq(obj, mid) @@original_singleton_method_iseq.delete([obj, mid]) end - def compile_singleton_method(obj, mid, bind_or_typemap = nil, typemap = nil) + def compile_singleton_method(obj, mid, bind_or_typemap = nil, typemap = nil, force_compilation = false) execute_no_hook() do mid, bind, typemap = parse_arguments(mid, bind_or_typemap, typemap) iseq = @@original_singleton_method_iseq[[obj, mid]] || get_iseq(obj, mid, true) - manager, configuration, suggestion = compile_iseq(iseq, mid, typemap, false, bind) + manager, configuration, suggestion = compile_iseq(iseq, mid, typemap, false, bind, force_compilation) manager.compilation_target_is_a(obj, mid, true) set_direct_call(obj, mid, :singleton, manager, configuration) load_binary(manager, configuration, suggestion, iseq) @@ -205,7 +209,7 @@ def execute(typemap = nil, &block) if !@@loaded_binary[key] execute_no_hook() do bind = block.binding - manager, configuration, suggestion = compile_iseq(iseq, nil, typemap, false, bind) + manager, configuration, suggestion = compile_iseq(iseq, nil, typemap, false, bind, false) load_binary(manager, configuration, suggestion, iseq) @@loaded_binary[key] = manager.signiture end @@ -257,7 +261,7 @@ def execute_no_hook() end end - def compile_iseq(iseq, mid, typemap, is_proc, bind) + def compile_iseq(iseq, mid, typemap, is_proc, bind, force_compilation) filepath, line_no = *iseq.to_a.slice(7, 2) raise(UnsupportedError.new(<<-EOS)) unless filepath && File.exist?(filepath) @@ -268,7 +272,7 @@ def compile_iseq(iseq, mid, typemap, is_proc, bind) suggestion = Suggestion.new(iseq, @@suggestion_io) configuration = nil manager.do_atomically() do - configuration = __compile(iseq, manager, typemap || {}, mid, is_proc, bind, suggestion) + configuration = __compile(iseq, manager, typemap || {}, mid, is_proc, bind, suggestion, force_compilation) end bug() unless configuration.instance_of?(Configuration) [manager, configuration, suggestion] @@ -328,9 +332,8 @@ def re_compile(signiture, sampling_table) return false unless update_p ann = manager.load_annotation() || {} bug() unless ann.instance_of?(Hash) - manager.version_up() begin - __send__(singleton ? 'compile_singleton_method' : 'compile', target, mid, ann) + __send__(singleton ? 'compile_singleton_method' : 'compile', target, mid, ann, nil, true) vlog("re-compilation success: #{target}#{singleton ? '.' : '#'}#{mid}") rescue => e vlog("re-compilation failed: #{target}#{singleton ? '.' : '#'}#{mid} => #{e}") @@ -340,8 +343,8 @@ def re_compile(signiture, sampling_table) class ReCompilation < StandardError; end - def __compile(iseq, manager, annotation, mid, is_proc, bind, suggestion) - if reuse_compiled_code? && !manager.target_file_updated? + def __compile(iseq, manager, annotation, mid, is_proc, bind, suggestion, force_compilation) + if !force_compilation && reuse_compiled_code? && !manager.target_file_updated? # already compiled if CastOff.development? || !CastOff.skip_configuration_check? || manager.last_configuration_enabled_development? conf = Configuration.new(annotation, bind) @@ -361,6 +364,7 @@ def __compile(iseq, manager, annotation, mid, is_proc, bind, suggestion) union_base_configuration(conf, manager) end else + manager.clear_base_configuration() if manager.target_file_updated? conf = Configuration.new(annotation, bind) union_base_configuration(conf, manager) end @@ -384,6 +388,7 @@ def __compile(iseq, manager, annotation, mid, is_proc, bind, suggestion) require 'cast_off/compile/stack' require 'cast_off/compile/information' conf.validate() + manager.version_up() bug() unless conf dep = Dependency.new() block_inlining = true @@ -418,17 +423,17 @@ def __load(compiled) end bind = bind.bind if bind skip = false - if singleton - iseq = @@original_singleton_method_iseq[[klass, mid]] || get_iseq(klass, mid, true) - else - begin + begin + if singleton + iseq = @@original_singleton_method_iseq[[klass, mid]] || get_iseq(klass, mid, true) + else t = override_target(klass, mid) iseq = @@original_instance_method_iseq[[t, mid]] || get_iseq(klass, mid, false) - rescue CompileError, UnsupportedError - @@skipped |= [entry] - dlog("skip: entry = #{entry}") - skip = true end + rescue CompileError, UnsupportedError + @@skipped |= [entry] + dlog("skip: entry = #{entry}") + skip = true end f, l = *iseq.to_a.slice(7, 2) unless skip if !skip && f == file && l == line diff --git a/lib/cast_off/compile/code_manager.rb b/lib/cast_off/compile/code_manager.rb index 71ab03d..c0c71ad 100644 --- a/lib/cast_off/compile/code_manager.rb +++ b/lib/cast_off/compile/code_manager.rb @@ -12,12 +12,21 @@ class CodeManager attr_reader :signiture, :compilation_target + def self.generate_signiture(unique_string) + unique_string.gsub(/\.|\/|-|:/, "_") + end + + def self.base_directory_name() + p = generate_signiture(File.expand_path(__FILE__)) + p.gsub(/_lib_ruby_gems_1_9_1_gems_/, '.').gsub(/_lib_cast_off_compile_code_manager_rb$/, '') + end + CastOffDir = "#{ENV["HOME"]}/.CastOff" FileUtils.mkdir(CastOffDir) unless File.exist?(CastOffDir) - BaseDir = "#{CastOffDir}/#{File.expand_path(__FILE__).gsub(/\.|\/|-|:/, "_")}" + BaseDir = "#{CastOffDir}/#{base_directory_name()}" FileUtils.mkdir(BaseDir) unless File.exist?(BaseDir) - @@program_name = File.expand_path($PROGRAM_NAME) + @@program_name = File.basename($PROGRAM_NAME) CastOff::Compiler.class_eval do def program_name=(dir) CastOff::Compiler::CodeManager.class_variable_set(:@@program_name, dir) @@ -25,7 +34,7 @@ def program_name=(dir) end def self.program_dir() - dir = "#{BaseDir}/#{@@program_name.gsub(/\.|\/|-|:/, "_")}" + dir = "#{BaseDir}/#{generate_signiture(@@program_name)}" FileUtils.mkdir(dir) unless File.exist?(dir) dir end @@ -92,12 +101,12 @@ def create_dstdir() end def version_up() - bug() unless File.exist?(@versionpath) - v = File.read(@versionpath).to_i + v = File.exist?(@versionpath) ? File.read(@versionpath).to_i : @version bug() if v < 0 v = [@version, v].max + 1 - vlog("version: #{@version} => #{v}") + dlog("version: #{@version} => #{v}") File.open(@versionpath, 'w'){|f| f.write(v)} + set_path() end def fetch_version() @@ -110,11 +119,28 @@ def fetch_version() version.to_i end + FILEPATH_LIMITED = CONFIG["host_os"].match(/mswin/) + FILEPATH_LIMIT = 255 + def check_length() + return unless FILEPATH_LIMITED + raise(UnsupportedError.new(<<-EOS)) if @longpath.length > FILEPATH_LIMIT + +Failed to generate signiture for #{@filepath}:#{@line_no}. +Signiture is generated from filepath and line_no. +Max length of signiture is #{FILEPATH_LIMIT} in this environment. + EOS + end + def initialize(filepath, line_no) @filepath = filepath @line_no = line_no - base_sign = "#{@filepath}_#{@line_no}".gsub(/\.|\/|-|:/, "_") - dir = self.class.program_dir() + @compilation_target = nil + set_path() + end + + def set_path() + base_sign = CodeManager.generate_signiture("#{@filepath}_#{@line_no}") + dir = CodeManager.program_dir() @dstdir = "#{dir}/#{base_sign}" @lockpath = "#{@dstdir}/lock" @versionfile = "version" @@ -131,7 +157,8 @@ def initialize(filepath, line_no) @development_mark_file = "development" @development_mark_path = "#{@dstdir}/#{@development_mark_file}" @dstbin = "#{@dstdir}/#{@signiture}.so" - @compilation_target = nil + @longpath = @base_configuration_path # FIXME + check_length() end class CompilationTarget diff --git a/lib/cast_off/compile/configuration.rb b/lib/cast_off/compile/configuration.rb index b852c8d..55656cc 100644 --- a/lib/cast_off/compile/configuration.rb +++ b/lib/cast_off/compile/configuration.rb @@ -445,7 +445,11 @@ def dump(io = nil) end def self.load(io) - conf = Marshal.load(io) + begin + conf = Marshal.load(io) + rescue NameError + return nil + end bug() unless conf.instance_of?(Configuration) return nil unless conf.check_method_information_usage() conf diff --git a/lib/cast_off/compile/ir/call_ir.rb b/lib/cast_off/compile/ir/call_ir.rb index f61bc05..26a11f9 100644 --- a/lib/cast_off/compile/ir/call_ir.rb +++ b/lib/cast_off/compile/ir/call_ir.rb @@ -1088,7 +1088,7 @@ def to_c(params) EOS when DEFINED_FUNC ret << <<-EOS - if (rb_method_boundp(rb_class_of(#{val}), #{@id}), 0) { + if (rb_method_boundp(rb_class_of(#{val}), #{@id}, 0)) { #{@return_value} = #{@needstr ? 'rb_str_new2("method")' : 'Qtrue'}; } else { #{@return_value} = Qnil; @@ -1714,9 +1714,9 @@ def funcall_code(klass, id, recv, param, argc) [MethodWrapper.new(ArrayWrapper, :empty?), 1] => [['empty_p', [], nil, [TrueClass, FalseClass], false, false]], [MethodWrapper.new(ArrayWrapper, :last), 1] => [['last', [], nil, nil, false, false]], [MethodWrapper.new(ArrayWrapper, :first), 1] => [['first', [], nil, nil, false, false]], - [MethodWrapper.new(FixnumWrapper, :+), 2] => [['fixnum_plus', [Fixnum], Fixnum, nil, true, true], ['float_plus', [Float], nil, Float, true, true]], # FIXME - [MethodWrapper.new(FixnumWrapper, :-), 2] => [['fixnum_minus', [Fixnum], Fixnum, nil, true, true], ['float_minus', [Float], nil, Float, true, true]], # FIXME - [MethodWrapper.new(FixnumWrapper, :*), 2] => [['fixnum_mult', [Fixnum], Fixnum, nil, true, true], ['float_mult', [Float], nil, Float, true, true]], # FIXME + [MethodWrapper.new(FixnumWrapper, :+), 2] => [['fixnum_plus', [Fixnum], nil, [Fixnum, Bignum], false, true], ['float_plus', [Float], nil, Float, true, true]], # FIXME + [MethodWrapper.new(FixnumWrapper, :-), 2] => [['fixnum_minus', [Fixnum], nil, [Fixnum, Bignum], false, true], ['float_minus', [Float], nil, Float, true, true]], # FIXME + [MethodWrapper.new(FixnumWrapper, :*), 2] => [['fixnum_mult', [Fixnum], nil, [Fixnum, Bignum], false, true], ['float_mult', [Float], nil, Float, true, true]], # FIXME [MethodWrapper.new(FixnumWrapper, :<=), 2] => [['le', [Fixnum], nil, [TrueClass, FalseClass], false, false]], [MethodWrapper.new(FixnumWrapper, :<), 2] => [['lt', [Fixnum], nil, [TrueClass, FalseClass], false, false]], [MethodWrapper.new(FixnumWrapper, :>=), 2] => [['ge', [Fixnum], nil, [TrueClass, FalseClass], false, false]], @@ -1741,7 +1741,7 @@ def funcall_code(klass, id, recv, param, argc) ['fixnum_eq', [Fixnum], nil, [TrueClass, FalseClass], false, true]], [MethodWrapper.new(FloatWrapper, :===), 2] => [['float_eqq', [Float], nil, [TrueClass, FalseClass], false, true], ['fixnum_eqq', [Fixnum], nil, [TrueClass, FalseClass], false, true]], - [MethodWrapper.new(FixnumWrapper, :-@), 1] => [['uminus', [], Fixnum, nil, true, true]], + [MethodWrapper.new(FixnumWrapper, :-@), 1] => [['uminus', [], nil, [Fixnum, Bignum], false, true]], [MethodWrapper.new(FloatWrapper, :-@), 1] => [['uminus', [], nil, Float, true, true]], [MethodWrapper.new(FixnumWrapper, :to_f), 1] => [['to_f', [], nil, Float, true, true]], [MethodWrapper.new(FloatWrapper, :to_f), 1] => [['to_f', [], nil, Float, true, false]], @@ -2076,7 +2076,7 @@ def to_c(params) id = @translator.allocate_id(@method_id) bug() if recv.undefined? if @configuration.development? && sampling_return_value? - ret << " sampling_tmp = #{recv};" + ret << " sampling_tmp = #{recv.boxed_form};" end if blockarg? ret << funcall_code(nil, id, recv, param, @argc) @@ -2117,7 +2117,7 @@ def to_c(params) else_class = types[else_index] else_code = not_funcall_code(else_class, @method_id, recv, param, @argc) if !else_code - @dependency.add(else_class, @method_id, false) + @dependency.add(else_class, @method_id, false) if else_class.method_defined? else_code = funcall_code(else_class, id, recv, param, @argc) end if nil_code == else_code @@ -2151,7 +2151,7 @@ def to_c(params) end end if @configuration.development? && sampling_return_value? - ret << " sampling_poscall(#{@return_value}, sampling_tmp, ID2SYM(rb_intern(#{@method_id.to_s.inspect})));" + ret << " sampling_poscall(#{@return_value.boxed_form}, sampling_tmp, ID2SYM(rb_intern(#{@method_id.to_s.inspect})));" end ret.join("\n") end diff --git a/lib/cast_off/compile/ir/guard_ir.rb b/lib/cast_off/compile/ir/guard_ir.rb index 2961f8a..c61bc38 100644 --- a/lib/cast_off/compile/ir/guard_ir.rb +++ b/lib/cast_off/compile/ir/guard_ir.rb @@ -254,12 +254,14 @@ def initialize(val, vars, insn, cfg) @variables << @guard_value @variables_without_result << @guard_value @result_variable = nil - @dependent_local_variables = get_dependent_local_variables(vars) - @dependent_stack_variables = get_dependent_stack_variables(vars) - @dependent_variables = @dependent_local_variables.values.flatten + @dependent_stack_variables.values.flatten @source = @insn.source @source = @source.empty? ? nil : @source @source_line = @insn.line.to_s + if @configuration.deoptimize? + @dependent_local_variables = get_dependent_local_variables(vars) + @dependent_stack_variables = get_dependent_stack_variables(vars) + @dependent_variables = @dependent_local_variables.values.flatten + @dependent_stack_variables.values.flatten + end end ### unboxing begin ### @@ -277,6 +279,7 @@ def propergate_boxed_value(defs) if @guard_value.boxed? change |= defs.propergate_boxed_value_backward(@guard_value) if @configuration.deoptimize? + bug() unless @dependent_variables @dependent_variables.each do |var| if var.is_a?(DynamicVariable) bug() unless var.boxed? @@ -318,6 +321,7 @@ def mark(defs) @alive = true defs.mark(@guard_value) if @configuration.deoptimize? + bug() unless @dependent_variables @dependent_variables.each{|v| defs.mark(v)} end true @@ -418,6 +422,7 @@ def type_propergation(defs) def reset() super() if @configuration.deoptimize? + bug() unless @dependent_variables @dependent_variables.map! do |v| bug() unless v.is_a?(Variable) @cfg.find_variable(v) diff --git a/lib/cast_off/compile/ir/simple_ir.rb b/lib/cast_off/compile/ir/simple_ir.rb index c8b10f1..06d86c3 100644 --- a/lib/cast_off/compile/ir/simple_ir.rb +++ b/lib/cast_off/compile/ir/simple_ir.rb @@ -616,7 +616,7 @@ def sampling_variable() if @configuration.development? @sampling_variable.each do |var| next if var.is_a?(Literal) - s << " sampling_variable(#{var}, ID2SYM(rb_intern(#{var.source.inspect})));" + s << " sampling_variable(#{var.boxed_form}, ID2SYM(rb_intern(#{var.source.inspect})));" end end s.empty? ? nil : s.join("\n")