#!/usr/bin/env ruby require 'rubygems' require 'optparse' require 'cast_off' this = File.expand_path("#{Gem.bindir()}/#{File.basename(__FILE__)}") step = nil verbose = false clear = false threshold = 100 name = nil opt = OptionParser.new(<<-EOS, 32, ' ') CastOff is a compiler for Ruby1.9.3. Usage: cast_off [options] [programfile] [arguments] EOS opt.separator("\n Options:") opt.on('--run', <<-EOS.strip) {|v| step = 'run' } Execute [programfile] with compiled codes. EOS opt.on('--threshold=COUNT', <<-EOS.strip, Integer) {|v| threshold = v } Compile method which is executed more than COUNT. Default value is 100. EOS opt.on('--name=NAME', <<-EOS.strip, String) {|v| name = v } Name compiled codes NAME. This name is used for search of compiled codes. If you don't use this option, CastOff uses File.basename([programfile]) as name. EOS opt.on('--clear', <<-EOS.strip) {|v| clear = true } Clear profile information and delete compiled codes. If you want to clear profile information and compiled codes of target name "foo", you should execute following command. $cast_off --clear --name=foo EOS opt.on('--step-1') {|v| step = '1' } opt.on('--step-2') {|v| step = '2' } opt.on('--verbose', <<-EOS.strip) {|v| verbose = true } Show compilation progress and internal information. EOS opt.on_tail('-h', "--help", "Show this help.") do message = opt.to_s.gsub(/\n[ ]*--step-[0-9]+[ ]*/, '') message.concat(<<-EOS) Example: ------------------------------------------ # fib.rb def fib n (n < 3) ? 1 : (fib(n-1) + fib(n-2)) end fib(ARGV.shift.to_i) ------------------------------------------ 1 Profile and compile fib.rb: $cast_off fib.rb 30 # 30 is a argument of fib.rb 2 Run fib.rb with compiled codes: $cast_off --run fib.rb 30 # 30 is a argument of fib.rb Report bugs to . EOS puts message exit end opt.on_tail("--version", "Show version number.") do puts Gem.loaded_specs['cast_off'].version.to_s exit end opt.order!(ARGV) args = ARGV.join(" ") script = ARGV.shift || '' name = File.basename(script) unless name if clear if name.empty? STDERR.puts(<<-EOS) Invalid arguments. You should pass target name to CastOff. If you want to clear profile information and compiled codes of target name "foo", you should execute following command. $cast_off --clear --name=foo EOS exit(1) end CastOff.program_name = name CastOff.clear() exit(0) end unless File.exist?(script) if script.empty? STDERR.puts("Invalid arguments. You should pass [programname] to CastOff.") else STDERR.puts("#{script} is not exist.") end exit(1) end configuration = <<-EOS CastOff.program_name = #{name.inspect} CastOff.skip_configuration_check(true) CastOff.use_default_configuration() EOS eval(configuration, binding) CastOff.compilation_threshold = threshold CastOff.program_name = name CastOff.verbose(verbose) case step when nil STDERR.puts("-------------------------------- compilation start: threshold = #{threshold}, name = #{name}, profiling = ruby #{args} --------------------------------") 2.times do |i| system("#{this} --step-#{i + 1} --threshold=#{threshold} --name=#{name} #{verbose ? '--verbose' : ''} #{args}") unless $? == 0 STDERR.puts("Failed to execute 'ruby #{args}'") exit end end when '1' STDERR.puts("-------------------------------- step 1 --------------------------------") if verbose CastOff.development(true) CastOff.use_base_configuration(false) CastOff.autocompile() when '2' STDERR.puts("-------------------------------- step 2 --------------------------------") if verbose CastOff.development(true) CastOff.use_base_configuration(false) CastOff.autoload() at_exit{ CastOff.development(false) CastOff.use_base_configuration(true) # step 3 CastOff.load(true) } fin = Object.new ObjectSpace.define_finalizer(fin){ =begin msg = <<-EOS ---------------------------------------------------------------------------------------- Compilation finished successfully. Please add following lines to top of #{script}. require 'cast_off' #{configuration.chomp} CastOff.autoload() ---------------------------------------------------------------------------------------- EOS =end msg = <<-EOS ---------------------------------------------------------------------------------------- Compilation finished successfully. You can execute #{script} with compiled codes by use of following command. $cast_off --run --name=#{name} #{args} ---------------------------------------------------------------------------------------- EOS STDERR.puts(msg) } when 'run' CastOff.autoload() else raise("should not be reached") end $0 = script load script if step