diff --git a/Rakefile b/Rakefile index a5c49e1..d746f67 100644 --- a/Rakefile +++ b/Rakefile @@ -10,6 +10,8 @@ require 'rake/testtask' require 'bundler' +require File.expand_path("../lib/rltk/version", __FILE__) + begin require 'rdoc/task' @@ -45,3 +47,96 @@ Rake::TestTask.new do |t| end Bundler::GemHelper.install_tasks + +task :check_bindings, :verbose do |t, args| + (args = args.to_hash)[:verbose] = (args[:verbose] == 'true') + + require 'lib/rltk/cg/bindings' + + # Check for objdump. + if not (bin = `which objdump`.chomp)[0,1] == '/' + warn 'objdump binary not found.' + return + end + + # Locate the LLVM shared library. + lib_path = nil + + paths = ENV['LD_LIBRARY_PATH'].split(/:/).uniq + paths << '/usr/lib/' + paths << '/usr/lib64/' + + paths.each do |path| + test_path = File.join(path, "libLLVM-#{RLTK::LLVM_TARGET_VERSION}.so") + if File.exists?(test_path) + lib_path = test_path + end + end + + if not lib_path + puts "libLLVM-#{RLTK::LLVM_TARGET_VERSION}.so not found." + return + end + + # Grab libLLVM symbols. + lines = `#{bin} -t #{lib_path}` + + lsyms = lines.map do |l| + md = l.match(/\s(LLVM\w+)/) + if md then md[1] else nil end + end.compact.uniq + + # Grab libLLVM-EB symbols. + lib_path = "ext/libLLVM-ECB-#{RLTK::LLVM_TARGET_VERSION}.so" + + if not File.exists?(lib_path) + puts 'Extending Bindings shared library not present.' + return + end + + lines = `#{bin} -t #{lib_path}` + + lsyms |= lsyms = lines.map do |l| + md = l.match(/\s(LLVM\w+)/) + if md then md[1] else nil end + end.compact.uniq + + # Defined symbols. + dsyms = Symbol.all_symbols.map do |sym| + sym = sym.to_s + if sym.match(/^LLVM[a-zA-Z]+/) then sym else nil end + end.compact + + # Sort the symbols. + bound = Array.new + unbound = Array.new + unbinds = Array.new + + lsyms.each do |sym| + if dsyms.include?(sym) then bound else unbound end << sym + end + + dsyms.each do |sym| + if not lsyms.include?(sym) then unbinds << sym end + end + + puts "Bound Functions: #{bound.length}" + puts "Unbound Functions: #{unbound.length}" + puts "Bad Bindings: #{unbinds.length}" + puts "Completeness: #{((bound.length / lsyms.length.to_f) * 100).to_i}%" + + if args[:verbose] + puts() if unbound.length > 0 and unbinds.length > 0 + + if unbound.length > 0 + puts 'Unbound Functions:' + unbound.sort.each {|sym| puts sym} + puts + end + + if unbinds.length > 0 + puts 'Bad Bindings:' + unbinds.sort.each {|sym| puts sym} + end + end +end diff --git a/lib/rltk/cg.rb b/lib/rltk/cg.rb new file mode 100644 index 0000000..93faa78 --- /dev/null +++ b/lib/rltk/cg.rb @@ -0,0 +1,9 @@ +# Author: Chris Wailes +# Project: Ruby Language Toolkit +# Date: 2012/03/08 +# Description: This file adds some autoload features for the RLTK code +# generation. + +module RLTK::CG + autoload :Bindings, 'rltk/cg/bindings' +end diff --git a/lib/rltk/cg/bindings.rb b/lib/rltk/cg/bindings.rb new file mode 100644 index 0000000..36fcfe0 --- /dev/null +++ b/lib/rltk/cg/bindings.rb @@ -0,0 +1,10 @@ +# Author: Chris Wailes +# Project: Ruby Language Toolkit +# Date: 2012/03/08 +# Description: This file holds bindings to LLVM. + +require 'ffi' + +module RLTK::CG::Bindings + +end diff --git a/lib/rltk/version.rb b/lib/rltk/version.rb index ad3c90e..661dffa 100644 --- a/lib/rltk/version.rb +++ b/lib/rltk/version.rb @@ -4,5 +4,6 @@ # Description: This file specifies the version number of RLTK. module RLTK - VERSION = "1.2.0" + LLVM_TARGET_VERSION = '3.0' + VERSION = '1.2.0' end