Class: Ruby2CExtension::Concretize
- Defined in:
- lib/ruby2cext/concretize.rb
Constant Summary collapse
- @@count =
0- @@mutex =
Mutex.new
- @@r2r =
Ruby2Ruby.new
- @@pt =
ParseTree.new
- @@cache_hits =
0- @@log =
Logger.new (STDOUT)
- @@already_cified =
{}
Class Method Summary collapse
-
.c_ify!(klass, method_name, want_rb_afterward = false, want_just_c = false) ⇒ Object
returns rb code, or c code, or true on successfull load returns nil if want_rb_afterward && had to compile which is ok.
-
.c_ify_class!(klass, add_to_string = nil, skip_ancestors = false) ⇒ Object
pass in a class name instnace like c_ify_class! ClassName currently only cifys the singleton methods…
- .cache_hits ⇒ Object
-
.concretize_all!(classes_to_do = nil, all_together = true) ⇒ Object
turn all classes’ ruby methods into their C equivalents deemed unstable as of yet :(.
- .crystalize_after_first_time_through ⇒ Object
- .good_codes ⇒ Object
- .source_for(klass, method_name) ⇒ Object
Class Method Details
.c_ify!(klass, method_name, want_rb_afterward = false, want_just_c = false) ⇒ Object
returns rb code, or c code, or true on successfull load returns nil if want_rb_afterward && had to compile which is ok
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/ruby2cext/concretize.rb', line 53 def Concretize.c_ify! klass, method_name, want_rb_afterward = false, want_just_c = false count = @@mutex.synchronize { @@count += 1 } rb = "temp_#{count}.rb" ruby_code = source_for klass, method_name # TODO it probably catches railsy class style poorly [re-use my other desc_method?] return nil unless ruby_code assert klass.class.in?( [Class, Module]) # sanity check comment = "# concretize temp file: autogenerated: #{ Time.now }\n" if klass.class == Module klass_string = "module #{klass}" # modules don't descend else nearest_ancestor = klass.ancestors[1..-1].find{|ancestor| ancestor.class == Class} if nearest_ancestor klass_string = "class #{klass} < #{nearest_ancestor}" else # Object, I suppose klass_string = "class #{klass}" end end ruby_code_wrapped = comment + klass_string + "\npublic\n" + ruby_code + "\nend\n" @@log.debug ruby_code_wrapped if @@good_codes[ruby_code] && want_rb_afterward @@log.debug 'cache hit' @@cache_hits+= 1 return ruby_code_wrapped else @@log.debug 'cache miss' + @@good_codes.length.to_s end # sometimes ruby2ruby unpacks them wrong, so test for that File.open(rb, 'w') do |file| file.write ruby_code_wrapped end output = `ruby -c #{rb} 2>&1` if($?.exitstatus != 0) # unparsable ruby was generated...hmm... @@log.warn "got bad code generation", klass, method_name, ruby_code File.delete rb return nil # LTODO re-parse it [other parser?] make sure reparsing matches... else # see if it passes, below, too end if want_just_c return Concretize.compile_string(ruby_code_wrapped, want_just_c) else success = Concretize.compile_string(ruby_code_wrapped) rescue nil # can fail, like ...ensure; return nil if success @@good_codes[ruby_code] = true if want_rb_afterward return ruby_code_wrapped # no new [helpful] ruby code here, but pass it out anyway.. end end success end end |
.c_ify_class!(klass, add_to_string = nil, skip_ancestors = false) ⇒ Object
pass in a class name instnace like c_ify_class! ClassName currently only cifys the singleton methods… add_to_string is either nil or a string. returns whether that class and all ancestors had something ruby-y that it successfully converted to C
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/ruby2cext/concretize.rb', line 153 def Concretize.c_ify_class! klass, add_to_string = nil, skip_ancestors = false local_add_to_string = '' Ruby2CExtension::Plugins::DirectSelfCall.allow_public_methods # we're concretizing, so public methods are ok # TODO test that this actually does something to the C code :) success = false # LTODO class methods, singleton methods...sure! :) ancestors = [klass] if(!skip_ancestors) ancestors = klass.ancestors end for klass in ancestors # ltodo reverse... if @@already_cified[klass] # for now we keep all classes as real classes [not really concretize anything...we just c-ify everything aggressively] # when that is fixed be careful to get the inheritance wrong if two ancestors define the same method next end # TODO optionally take out all private checks :) for method_name in klass.instance_methods(false) string = Concretize.c_ify!(klass, method_name, true) if(string) local_add_to_string << " " << string success = true end end if add_to_string add_to_string << local_add_to_string else Concretize.compile_string(local_add_to_string) end @@already_cified[klass] = true print klass.to_s + " has " if(!success) print "no " end puts "ruby methods" end return success end |
.cache_hits ⇒ Object
117 118 119 |
# File 'lib/ruby2cext/concretize.rb', line 117 def self.cache_hits @@cache_hits #ltodo attr_reader? end |
.concretize_all!(classes_to_do = nil, all_together = true) ⇒ Object
turn all classes’ ruby methods into their C equivalents deemed unstable as of yet :(
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/ruby2cext/concretize.rb', line 203 def Concretize.concretize_all! classes_to_do = nil, all_together = true @@already_cified = {} # in case things have changed...maybe? if !classes_to_do classes_to_do = [] ObjectSpace.each_object(Class){|c| classes_to_do << c} end all_successful = [] if all_together all_ruby_codes = '' else all_ruby_codes = nil end classes_to_do.each{|klass| all_successful << klass if Concretize.c_ify_class!(klass, all_ruby_codes) } # puts 'none found' if all_ruby_codes == '' this is expected currently anytime after the first run... Concretize.compile_string(all_ruby_codes) all_successful end |
.crystalize_after_first_time_through ⇒ Object
244 245 246 247 248 249 250 251 252 |
# File 'lib/ruby2cext/concretize.rb', line 244 def Concretize.crystalize_after_first_time_through raise unless block_given? Tracer.start yield Tracer.stop_hook raise unless Tracer.all_classes.length > 0 puts 'crystalizing', Tracer.all_classes.inspect Concretize.concretize_all! Tracer.all_classes end |
.good_codes ⇒ Object
120 121 122 |
# File 'lib/ruby2cext/concretize.rb', line 120 def self.good_codes @@good_codes end |
.source_for(klass, method_name) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/ruby2cext/concretize.rb', line 12 def Concretize.source_for klass, method_name raw = @@pt.parse_tree_for_method(klass, method_name) begin processed = @@pt.process(raw) rescue return nil end code = @@r2r.process( processed ) if code.include?('&block') || code.include?('binding') # eval? # for now, try to avoid the tripsy case of ruby2cext not yielding arrays right yet... # TODO add some test cases for it in 'broken.rb' or something # LTODO fix it :) # TODO test it with rdoc...yeah. A real test sniff # compare with 1.9... nil else code end end |