rb-threadframe 0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +23 -0
 - data/NEWS +2 -0
 - data/README.md +9 -0
 - data/Rakefile +162 -0
 - data/ext/extconf.rb +12 -0
 - data/ext/iseq_extra.c +404 -0
 - data/ext/iseq_extra.h +8 -0
 - data/ext/iseq_mini.h +41 -0
 - data/ext/node.h +483 -0
 - data/ext/proc_extra.c +108 -0
 - data/ext/proc_extra.h +3 -0
 - data/ext/thread_extra.c +84 -0
 - data/ext/thread_extra.h +5 -0
 - data/ext/thread_frame.c +1022 -0
 - data/ext/thread_frame.h +4 -0
 - data/ext/thread_pthread.h +24 -0
 - data/include/method_mini.h +90 -0
 - data/include/node.h +483 -0
 - data/include/ruby19_externs.h +36 -0
 - data/include/thread_pthread.h +24 -0
 - data/include/vm_core_mini.h +357 -0
 - data/lib/iseq_extra.rb +89 -0
 - data/lib/thread_frame.rb +3 -0
 - data/test/unit/cfunc-use.rb +11 -0
 - data/test/unit/test-argc.rb +45 -0
 - data/test/unit/test-binding.rb +44 -0
 - data/test/unit/test-invalid.rb +40 -0
 - data/test/unit/test-iseq-brkpt.rb +61 -0
 - data/test/unit/test-iseq.rb +121 -0
 - data/test/unit/test-lib-iseq-extra.rb +57 -0
 - data/test/unit/test-prev.rb +54 -0
 - data/test/unit/test-proc.rb +23 -0
 - data/test/unit/test-return-stop.rb +64 -0
 - data/test/unit/test-settracefunc.rb +315 -0
 - data/test/unit/test-source.rb +104 -0
 - data/test/unit/test-sp-size.rb +45 -0
 - data/test/unit/test-thread-trace-masks.rb +90 -0
 - data/test/unit/test-thread.rb +168 -0
 - data/test/unit/test-trace.rb +55 -0
 - data/threadframe.rd +163 -0
 - metadata +110 -0
 
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (C) 2010  Rocky Bernstein <rockyb@rubyforge.org>
         
     | 
| 
      
 2 
     | 
    
         
            +
            All rights reserved.
         
     | 
| 
      
 3 
     | 
    
         
            +
             *
         
     | 
| 
      
 4 
     | 
    
         
            +
            Redistribution and use in source and binary forms, with or without
         
     | 
| 
      
 5 
     | 
    
         
            +
            modification, are permitted provided that the following conditions
         
     | 
| 
      
 6 
     | 
    
         
            +
            are met:
         
     | 
| 
      
 7 
     | 
    
         
            +
            1. Redistributions of source code must retain the above copyright
         
     | 
| 
      
 8 
     | 
    
         
            +
               notice, this list of conditions and the following disclaimer.
         
     | 
| 
      
 9 
     | 
    
         
            +
            2. Redistributions in binary form must reproduce the above copyright
         
     | 
| 
      
 10 
     | 
    
         
            +
               notice, this list of conditions and the following disclaimer in the
         
     | 
| 
      
 11 
     | 
    
         
            +
               documentation and/or other materials provided with the distribution.
         
     | 
| 
      
 12 
     | 
    
         
            +
             *
         
     | 
| 
      
 13 
     | 
    
         
            +
            THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
         
     | 
| 
      
 14 
     | 
    
         
            +
            ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
         
     | 
| 
      
 15 
     | 
    
         
            +
            IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
         
     | 
| 
      
 16 
     | 
    
         
            +
            ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
         
     | 
| 
      
 17 
     | 
    
         
            +
            FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
         
     | 
| 
      
 18 
     | 
    
         
            +
            DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
         
     | 
| 
      
 19 
     | 
    
         
            +
            OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
         
     | 
| 
      
 20 
     | 
    
         
            +
            HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
         
     | 
| 
      
 21 
     | 
    
         
            +
            LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
         
     | 
| 
      
 22 
     | 
    
         
            +
            OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
         
     | 
| 
      
 23 
     | 
    
         
            +
            SUCH DAMAGE.
         
     | 
    
        data/README.md
    ADDED
    
    
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,162 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rake
         
     | 
| 
      
 2 
     | 
    
         
            +
            # -*- Ruby -*-
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rake'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rake/gempackagetask'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'rake/rdoctask'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'rake/testtask'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            rake_dir = File.dirname(__FILE__)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            require 'rbconfig'
         
     | 
| 
      
 12 
     | 
    
         
            +
            RUBY_PATH = File.join(RbConfig::CONFIG['bindir'],  
         
     | 
| 
      
 13 
     | 
    
         
            +
                                  RbConfig::CONFIG['RUBY_INSTALL_NAME'])
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            SO_NAME = 'thread_frame.so'
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            PACKAGE_VERSION = open("ext/thread_frame.c") do |f| 
         
     | 
| 
      
 18 
     | 
    
         
            +
              f.grep(/^#define THREADFRAME_VERSION/).first[/"(.+)"/,1]
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            EXT_FILES     = FileList[%w(ext/*.c ext/*.h)]
         
     | 
| 
      
 22 
     | 
    
         
            +
            INCLUDE_FILES = FileList['include/*.h']
         
     | 
| 
      
 23 
     | 
    
         
            +
            LIB_FILES     = FileList['lib/*.rb']
         
     | 
| 
      
 24 
     | 
    
         
            +
            TEST_FILES    = FileList['test/**/*.rb']
         
     | 
| 
      
 25 
     | 
    
         
            +
            COMMON_FILES  = FileList[%w(README.md Rakefile LICENSE NEWS)]
         
     | 
| 
      
 26 
     | 
    
         
            +
            ALL_FILES     = COMMON_FILES + INCLUDE_FILES + LIB_FILES + EXT_FILES + 
         
     | 
| 
      
 27 
     | 
    
         
            +
              TEST_FILES
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            desc 'Create the core thread-frame shared library extension'
         
     | 
| 
      
 30 
     | 
    
         
            +
            task :ext do
         
     | 
| 
      
 31 
     | 
    
         
            +
              Dir.chdir('ext') do
         
     | 
| 
      
 32 
     | 
    
         
            +
                system("#{Gem.ruby} extconf.rb && make")
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            desc 'Remove built files'
         
     | 
| 
      
 37 
     | 
    
         
            +
            task :clean do
         
     | 
| 
      
 38 
     | 
    
         
            +
              cd 'ext' do
         
     | 
| 
      
 39 
     | 
    
         
            +
                if File.exist?('Makefile')
         
     | 
| 
      
 40 
     | 
    
         
            +
                  sh 'make clean'
         
     | 
| 
      
 41 
     | 
    
         
            +
                  rm 'Makefile'
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
                derived_files = Dir.glob('.o') + Dir.glob('*.so')
         
     | 
| 
      
 44 
     | 
    
         
            +
                rm derived_files unless derived_files.empty?
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            def run_standalone_ruby_file(directory)
         
     | 
| 
      
 49 
     | 
    
         
            +
              puts ('*' * 10) + ' ' + directory + ' ' + ('*' * 10)
         
     | 
| 
      
 50 
     | 
    
         
            +
              Dir.chdir(directory) do
         
     | 
| 
      
 51 
     | 
    
         
            +
                Dir.glob('*.rb').each do |ruby_file|
         
     | 
| 
      
 52 
     | 
    
         
            +
                  puts ('-' * 20) + ' ' + ruby_file + ' ' + ('-' * 20)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  system(RUBY_PATH, ruby_file)
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            desc "Create a GNU-style ChangeLog via git2cl"
         
     | 
| 
      
 59 
     | 
    
         
            +
            task :ChangeLog do
         
     | 
| 
      
 60 
     | 
    
         
            +
              system("git log --pretty --numstat --summary | git2cl > ChangeLog")
         
     | 
| 
      
 61 
     | 
    
         
            +
            end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            task :default => [:test]
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            desc 'Test units - the smaller tests'
         
     | 
| 
      
 66 
     | 
    
         
            +
            task :'test:unit' => [:ext] do |t|
         
     | 
| 
      
 67 
     | 
    
         
            +
              Rake::TestTask.new(:'test:unit') do |t|
         
     | 
| 
      
 68 
     | 
    
         
            +
                t.libs << './ext'
         
     | 
| 
      
 69 
     | 
    
         
            +
                t.test_files = FileList['test/unit/**/*.rb']
         
     | 
| 
      
 70 
     | 
    
         
            +
                # t.pattern = 'test/**/*test-*.rb' # instead of above
         
     | 
| 
      
 71 
     | 
    
         
            +
                t.verbose = true
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
            end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            desc 'Test everything - unit tests for now.'
         
     | 
| 
      
 76 
     | 
    
         
            +
            task :test do
         
     | 
| 
      
 77 
     | 
    
         
            +
              exceptions = ['test:unit'].collect do |task|
         
     | 
| 
      
 78 
     | 
    
         
            +
                begin
         
     | 
| 
      
 79 
     | 
    
         
            +
                  Rake::Task[task].invoke
         
     | 
| 
      
 80 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 81 
     | 
    
         
            +
                rescue => e
         
     | 
| 
      
 82 
     | 
    
         
            +
                  e
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
              end.compact
         
     | 
| 
      
 85 
     | 
    
         
            +
              
         
     | 
| 
      
 86 
     | 
    
         
            +
              exceptions.each {|e| puts e;puts e.backtrace }
         
     | 
| 
      
 87 
     | 
    
         
            +
              raise "Test failures" unless exceptions.empty?
         
     | 
| 
      
 88 
     | 
    
         
            +
            end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            desc "Test everything - same as test."
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            task :'check' do
         
     | 
| 
      
 93 
     | 
    
         
            +
              run_standalone_ruby_file(File.join(%W(#{rake_dir} test unit)))
         
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            # ---------  RDoc Documentation ------
         
     | 
| 
      
 97 
     | 
    
         
            +
            desc 'Generate rdoc documentation'
         
     | 
| 
      
 98 
     | 
    
         
            +
            Rake::RDocTask.new('rdoc') do |rdoc|
         
     | 
| 
      
 99 
     | 
    
         
            +
              rdoc.rdoc_dir = 'doc/rdoc'
         
     | 
| 
      
 100 
     | 
    
         
            +
              rdoc.title    = 'rb-threadframe'
         
     | 
| 
      
 101 
     | 
    
         
            +
              # Show source inline with line numbers
         
     | 
| 
      
 102 
     | 
    
         
            +
              rdoc.options << '--inline-source' << '--line-numbers'
         
     | 
| 
      
 103 
     | 
    
         
            +
              # Make the readme file the start page for the generated html
         
     | 
| 
      
 104 
     | 
    
         
            +
              rdoc.options << '--main' << 'README.md'
         
     | 
| 
      
 105 
     | 
    
         
            +
              rdoc.rdoc_files.include('ext/**/*.c',
         
     | 
| 
      
 106 
     | 
    
         
            +
                                      'README.md')
         
     | 
| 
      
 107 
     | 
    
         
            +
            end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            # Base GEM Specification
         
     | 
| 
      
 110 
     | 
    
         
            +
            spec = Gem::Specification.new do |spec|
         
     | 
| 
      
 111 
     | 
    
         
            +
              spec.name = "rb-threadframe"
         
     | 
| 
      
 112 
     | 
    
         
            +
              
         
     | 
| 
      
 113 
     | 
    
         
            +
              spec.homepage = "http://github.com/rocky/rb-threadframe/tree/master"
         
     | 
| 
      
 114 
     | 
    
         
            +
              spec.summary = "Frame introspection"
         
     | 
| 
      
 115 
     | 
    
         
            +
              spec.description = <<-EOF
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            rb-threadframe gives introspection access for frames of a thread.
         
     | 
| 
      
 118 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
              spec.version = PACKAGE_VERSION
         
     | 
| 
      
 121 
     | 
    
         
            +
              spec.require_path = 'lib'
         
     | 
| 
      
 122 
     | 
    
         
            +
              spec.extensions = ["ext/extconf.rb"]
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
              spec.author = "R. Bernstein"
         
     | 
| 
      
 125 
     | 
    
         
            +
              spec.email = "rocky@gnu.org"
         
     | 
| 
      
 126 
     | 
    
         
            +
              spec.platform = Gem::Platform::RUBY
         
     | 
| 
      
 127 
     | 
    
         
            +
              spec.files = ALL_FILES.to_a  
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
              spec.required_ruby_version = '>= 1.9.2'
         
     | 
| 
      
 130 
     | 
    
         
            +
              spec.date = Time.now
         
     | 
| 
      
 131 
     | 
    
         
            +
              # spec.rubyforge_project = 'rocky-hacks'
         
     | 
| 
      
 132 
     | 
    
         
            +
              
         
     | 
| 
      
 133 
     | 
    
         
            +
              # rdoc
         
     | 
| 
      
 134 
     | 
    
         
            +
              spec.has_rdoc = true
         
     | 
| 
      
 135 
     | 
    
         
            +
              spec.extra_rdoc_files = ['README.md', 'threadframe.rd'] + 
         
     | 
| 
      
 136 
     | 
    
         
            +
                                       FileList['ext/*.c']
         
     | 
| 
      
 137 
     | 
    
         
            +
            end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            # Rake task to build the default package
         
     | 
| 
      
 140 
     | 
    
         
            +
            Rake::GemPackageTask.new(spec) do |pkg|
         
     | 
| 
      
 141 
     | 
    
         
            +
              pkg.need_tar = true
         
     | 
| 
      
 142 
     | 
    
         
            +
            end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
            def install(spec, *opts)
         
     | 
| 
      
 145 
     | 
    
         
            +
              args = ['gem', 'install', "pkg/#{spec.name}-#{spec.version}.gem"] + opts
         
     | 
| 
      
 146 
     | 
    
         
            +
              system(*args)
         
     | 
| 
      
 147 
     | 
    
         
            +
            end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
            desc 'Install locally'
         
     | 
| 
      
 150 
     | 
    
         
            +
            task :install => :package do
         
     | 
| 
      
 151 
     | 
    
         
            +
              Dir.chdir(File::dirname(__FILE__)) do
         
     | 
| 
      
 152 
     | 
    
         
            +
                # ri and rdoc take lots of time
         
     | 
| 
      
 153 
     | 
    
         
            +
                install(spec, '--no-ri', '--no-rdoc')
         
     | 
| 
      
 154 
     | 
    
         
            +
              end
         
     | 
| 
      
 155 
     | 
    
         
            +
            end    
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            task :install_full => :package do
         
     | 
| 
      
 158 
     | 
    
         
            +
              Dir.chdir(File::dirname(__FILE__)) do
         
     | 
| 
      
 159 
     | 
    
         
            +
                install(spec)
         
     | 
| 
      
 160 
     | 
    
         
            +
              end
         
     | 
| 
      
 161 
     | 
    
         
            +
            end    
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
    
        data/ext/extconf.rb
    ADDED
    
    | 
         @@ -0,0 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "mkmf"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            fail "You need to install a threadframe-patched Ruby.
         
     | 
| 
      
 4 
     | 
    
         
            +
            See http://github.com/rocky/rb-threadframe/wiki/How-to-Install" unless 
         
     | 
| 
      
 5 
     | 
    
         
            +
              RbConfig::CONFIG.member?('rb-threadframe')
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            config_file = File.join(File.dirname(__FILE__), 'config_options')
         
     | 
| 
      
 8 
     | 
    
         
            +
            load config_file if File.exist?(config_file)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            # Temporary: to turn off optimization
         
     | 
| 
      
 11 
     | 
    
         
            +
            # $CFLAGS='-fno-strict-aliasing -g -fPIC'
         
     | 
| 
      
 12 
     | 
    
         
            +
            create_makefile("thread_frame")
         
     | 
    
        data/ext/iseq_extra.c
    ADDED
    
    | 
         @@ -0,0 +1,404 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 2 
     | 
    
         
            +
             * Copyright (C) 2010 Rocky Bernstein
         
     | 
| 
      
 3 
     | 
    
         
            +
             */
         
     | 
| 
      
 4 
     | 
    
         
            +
            #if 0  /* The following is to fake out rdoc, until I find a better fix. */
         
     | 
| 
      
 5 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 6 
     | 
    
         
            +
             *  Additions to the RubyVM::InstructionSequence class
         
     | 
| 
      
 7 
     | 
    
         
            +
             */
         
     | 
| 
      
 8 
     | 
    
         
            +
            VALUE rb_cIseq = rb_define_class_under(rb_cRubyVM, "InstructionSequence", ...)
         
     | 
| 
      
 9 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            #include "../include/vm_core_mini.h"   /* Pulls in ruby.h and node.h */
         
     | 
| 
      
 12 
     | 
    
         
            +
            #ifdef HAVE_COMPILE_OPTIONS
         
     | 
| 
      
 13 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 14 
     | 
    
         
            +
            #include "iseq_mini.h"  /* Pulls in ruby.h */
         
     | 
| 
      
 15 
     | 
    
         
            +
            #include "../include/ruby19_externs.h"
         
     | 
| 
      
 16 
     | 
    
         
            +
            #include <string.h>       /* For strlen() */
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            struct iseq_insn_info_entry {
         
     | 
| 
      
 19 
     | 
    
         
            +
                unsigned short position;
         
     | 
| 
      
 20 
     | 
    
         
            +
                unsigned short line_no;
         
     | 
| 
      
 21 
     | 
    
         
            +
                unsigned short sp;
         
     | 
| 
      
 22 
     | 
    
         
            +
            };
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            #ifdef HAVE_COMPILE_OPTIONS
         
     | 
| 
      
 25 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 26 
     | 
    
         
            +
             *  Document-method: RubyVM::InstructionSequence::compile_options
         
     | 
| 
      
 27 
     | 
    
         
            +
             *
         
     | 
| 
      
 28 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 29 
     | 
    
         
            +
             *     RubyVM::InstructionSequence#compile_options -> Hash
         
     | 
| 
      
 30 
     | 
    
         
            +
             *
         
     | 
| 
      
 31 
     | 
    
         
            +
             *  Returns a hash of the compiler options used to create the 
         
     | 
| 
      
 32 
     | 
    
         
            +
             *  instruction sequence.
         
     | 
| 
      
 33 
     | 
    
         
            +
             */
         
     | 
| 
      
 34 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 35 
     | 
    
         
            +
            iseq_compile_options(VALUE iseqval)
         
     | 
| 
      
 36 
     | 
    
         
            +
            {
         
     | 
| 
      
 37 
     | 
    
         
            +
                rb_iseq_t *iseq;
         
     | 
| 
      
 38 
     | 
    
         
            +
                if (Qnil == iseqval) return Qnil;
         
     | 
| 
      
 39 
     | 
    
         
            +
                else {
         
     | 
| 
      
 40 
     | 
    
         
            +
            	VALUE hash_opts = rb_hash_new();
         
     | 
| 
      
 41 
     | 
    
         
            +
            	rb_compile_option_t *compile_opts;
         
     | 
| 
      
 42 
     | 
    
         
            +
            	GetISeqPtr(iseqval, iseq);
         
     | 
| 
      
 43 
     | 
    
         
            +
            	if (!iseq->compile_data) return Qnil;
         
     | 
| 
      
 44 
     | 
    
         
            +
            	compile_opts = iseq->compile_data->option;
         
     | 
| 
      
 45 
     | 
    
         
            +
            	rb_hash_aset(hash_opts, rb_str_new2("inline_const_cache"), 
         
     | 
| 
      
 46 
     | 
    
         
            +
            		     (compile_opts->inline_const_cache) ? Qtrue : Qfalse);
         
     | 
| 
      
 47 
     | 
    
         
            +
            	return hash_opts;
         
     | 
| 
      
 48 
     | 
    
         
            +
                }
         
     | 
| 
      
 49 
     | 
    
         
            +
                
         
     | 
| 
      
 50 
     | 
    
         
            +
            }
         
     | 
| 
      
 51 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 54 
     | 
    
         
            +
             *  Document-method: RubyVM::InstructionSequence::encoded
         
     | 
| 
      
 55 
     | 
    
         
            +
             * 
         
     | 
| 
      
 56 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 57 
     | 
    
         
            +
             *     RubyVM::InstructionSequence#iseq_encoded -> String
         
     | 
| 
      
 58 
     | 
    
         
            +
             *
         
     | 
| 
      
 59 
     | 
    
         
            +
             *  Returns a string of the encoded bytes of the instruction
         
     | 
| 
      
 60 
     | 
    
         
            +
             *  sequence. Note that this is probably not usable as is, may be useful in
         
     | 
| 
      
 61 
     | 
    
         
            +
             *  decoding instructions (using other info) or for getting a sha1
         
     | 
| 
      
 62 
     | 
    
         
            +
             *  checksum.
         
     | 
| 
      
 63 
     | 
    
         
            +
             */
         
     | 
| 
      
 64 
     | 
    
         
            +
            VALUE 
         
     | 
| 
      
 65 
     | 
    
         
            +
            iseq_iseq_encoded(VALUE iseqval)
         
     | 
| 
      
 66 
     | 
    
         
            +
            {
         
     | 
| 
      
 67 
     | 
    
         
            +
                rb_iseq_t *iseq;
         
     | 
| 
      
 68 
     | 
    
         
            +
                GetISeqPtr(iseqval, iseq);
         
     | 
| 
      
 69 
     | 
    
         
            +
                return rb_str_new((char *) iseq->iseq_encoded, iseq->iseq_size);
         
     | 
| 
      
 70 
     | 
    
         
            +
            }
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 74 
     | 
    
         
            +
             *  Document-method: RubyVM::InstructionSequence::equal?
         
     | 
| 
      
 75 
     | 
    
         
            +
             * 
         
     | 
| 
      
 76 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 77 
     | 
    
         
            +
             *     RubyVM::InstructionSequence#equal?(iseq2) -> bool
         
     | 
| 
      
 78 
     | 
    
         
            +
             *
         
     | 
| 
      
 79 
     | 
    
         
            +
             *  Returns true if the instruction sequences are equal.
         
     | 
| 
      
 80 
     | 
    
         
            +
             */
         
     | 
| 
      
 81 
     | 
    
         
            +
            VALUE 
         
     | 
| 
      
 82 
     | 
    
         
            +
            iseq_equal(VALUE iseqval1, VALUE iseqval2)
         
     | 
| 
      
 83 
     | 
    
         
            +
            {
         
     | 
| 
      
 84 
     | 
    
         
            +
                rb_iseq_t *iseq1, *iseq2;
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                if (Qnil == iseqval2) return Qfalse;
         
     | 
| 
      
 87 
     | 
    
         
            +
                if (!rb_obj_is_kind_of(iseqval2, rb_cISeq)) {
         
     | 
| 
      
 88 
     | 
    
         
            +
            	rb_raise(rb_eTypeError, 
         
     | 
| 
      
 89 
     | 
    
         
            +
            		 "comparison argument must be an instance of %s or nil (is %s)",
         
     | 
| 
      
 90 
     | 
    
         
            +
            		 rb_obj_classname(iseqval1), rb_obj_classname(iseqval2));
         
     | 
| 
      
 91 
     | 
    
         
            +
                }
         
     | 
| 
      
 92 
     | 
    
         
            +
                
         
     | 
| 
      
 93 
     | 
    
         
            +
                if (iseqval1 == iseqval2) return Qtrue;
         
     | 
| 
      
 94 
     | 
    
         
            +
                GetISeqPtr(iseqval1, iseq1);
         
     | 
| 
      
 95 
     | 
    
         
            +
                GetISeqPtr(iseqval2, iseq2);
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                /* FIXME: the count 28 below  is bogus. I think this should be the fields
         
     | 
| 
      
 98 
     | 
    
         
            +
                   from "type" to  "mark_ary". Should also include iseq->encoded.
         
     | 
| 
      
 99 
     | 
    
         
            +
                 */
         
     | 
| 
      
 100 
     | 
    
         
            +
                if (0 == memcmp(iseq1, iseq2, 28))
         
     | 
| 
      
 101 
     | 
    
         
            +
            	return Qtrue;
         
     | 
| 
      
 102 
     | 
    
         
            +
                else
         
     | 
| 
      
 103 
     | 
    
         
            +
            	return Qfalse;
         
     | 
| 
      
 104 
     | 
    
         
            +
            }
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 108 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 109 
     | 
    
         
            +
             *     RubyVM::InstructionSequence#local_name(i) - String
         
     | 
| 
      
 110 
     | 
    
         
            +
             * 
         
     | 
| 
      
 111 
     | 
    
         
            +
             *  Returns the string name of local variable in i'th position
         
     | 
| 
      
 112 
     | 
    
         
            +
             *  of the instruction sequence local table, or nil if i is
         
     | 
| 
      
 113 
     | 
    
         
            +
             * out of range.
         
     | 
| 
      
 114 
     | 
    
         
            +
             */
         
     | 
| 
      
 115 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 116 
     | 
    
         
            +
            iseq_local_name(VALUE iseqval, VALUE val)
         
     | 
| 
      
 117 
     | 
    
         
            +
            {
         
     | 
| 
      
 118 
     | 
    
         
            +
                rb_iseq_t *iseq;
         
     | 
| 
      
 119 
     | 
    
         
            +
                if (FIXNUM_P(val)) {
         
     | 
| 
      
 120 
     | 
    
         
            +
                  long int i = FIX2INT(val);
         
     | 
| 
      
 121 
     | 
    
         
            +
                  long int size;
         
     | 
| 
      
 122 
     | 
    
         
            +
                  
         
     | 
| 
      
 123 
     | 
    
         
            +
                  GetISeqPtr(iseqval, iseq);
         
     | 
| 
      
 124 
     | 
    
         
            +
                  
         
     | 
| 
      
 125 
     | 
    
         
            +
                  size = iseq->local_table_size;
         
     | 
| 
      
 126 
     | 
    
         
            +
                  
         
     | 
| 
      
 127 
     | 
    
         
            +
                  if (i < 0) i = size + i;
         
     | 
| 
      
 128 
     | 
    
         
            +
                  
         
     | 
| 
      
 129 
     | 
    
         
            +
                  if (i >= size)
         
     | 
| 
      
 130 
     | 
    
         
            +
            	rb_raise(rb_eIndexError, 
         
     | 
| 
      
 131 
     | 
    
         
            +
            		 "local table index %ld should be in the range -%ld .. %ld",
         
     | 
| 
      
 132 
     | 
    
         
            +
            		 i, size, size-1);
         
     | 
| 
      
 133 
     | 
    
         
            +
                  
         
     | 
| 
      
 134 
     | 
    
         
            +
                  return rb_str_new2(rb_id2name(iseq->local_table[i]));
         
     | 
| 
      
 135 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 136 
     | 
    
         
            +
                  rb_raise(rb_eTypeError, "type mismatch: %s given, Fixnum expected", 
         
     | 
| 
      
 137 
     | 
    
         
            +
            	       rb_class2name(CLASS_OF(val)));
         
     | 
| 
      
 138 
     | 
    
         
            +
                }
         
     | 
| 
      
 139 
     | 
    
         
            +
                /* not reached. */
         
     | 
| 
      
 140 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 141 
     | 
    
         
            +
            }
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 144 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 145 
     | 
    
         
            +
             *     RubyVM::InstructionSequence#name -> String
         
     | 
| 
      
 146 
     | 
    
         
            +
             * 
         
     | 
| 
      
 147 
     | 
    
         
            +
             *  Returns the name if the instruction sequence.
         
     | 
| 
      
 148 
     | 
    
         
            +
             */
         
     | 
| 
      
 149 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 150 
     | 
    
         
            +
            iseq_name(VALUE iseqval)
         
     | 
| 
      
 151 
     | 
    
         
            +
            {
         
     | 
| 
      
 152 
     | 
    
         
            +
                rb_iseq_t *iseq;
         
     | 
| 
      
 153 
     | 
    
         
            +
                GetISeqPtr(iseqval, iseq);
         
     | 
| 
      
 154 
     | 
    
         
            +
                return(iseq->name);
         
     | 
| 
      
 155 
     | 
    
         
            +
            }
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 158 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 159 
     | 
    
         
            +
             *     RubyVM::InstructionSequence#offsetlines -> Hash[Fixnum] -> [Fixnum]
         
     | 
| 
      
 160 
     | 
    
         
            +
             * 
         
     | 
| 
      
 161 
     | 
    
         
            +
             * Returns an hash. The keys in the hash form the VM offsets of the
         
     | 
| 
      
 162 
     | 
    
         
            +
             * instructions.  The value of the hash for a given offset is a list
         
     | 
| 
      
 163 
     | 
    
         
            +
             * of line numbers associated with that offset.
         
     | 
| 
      
 164 
     | 
    
         
            +
             */
         
     | 
| 
      
 165 
     | 
    
         
            +
            VALUE iseq_offsetlines(VALUE iseqval)
         
     | 
| 
      
 166 
     | 
    
         
            +
            {
         
     | 
| 
      
 167 
     | 
    
         
            +
                rb_iseq_t *iseq;
         
     | 
| 
      
 168 
     | 
    
         
            +
                VALUE offsetlines = rb_hash_new();
         
     | 
| 
      
 169 
     | 
    
         
            +
                unsigned long i, size;
         
     | 
| 
      
 170 
     | 
    
         
            +
                struct iseq_insn_info_entry *table;
         
     | 
| 
      
 171 
     | 
    
         
            +
               
         
     | 
| 
      
 172 
     | 
    
         
            +
                GetISeqPtr(iseqval, iseq);
         
     | 
| 
      
 173 
     | 
    
         
            +
                
         
     | 
| 
      
 174 
     | 
    
         
            +
                size = iseq->insn_info_size;
         
     | 
| 
      
 175 
     | 
    
         
            +
                table = iseq->insn_info_table;
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                for (i = 0; i < size; i++) {
         
     | 
| 
      
 178 
     | 
    
         
            +
            	VALUE ary = rb_ary_new2(1);
         
     | 
| 
      
 179 
     | 
    
         
            +
            	rb_ary_push(ary, INT2FIX(table[i].line_no));
         
     | 
| 
      
 180 
     | 
    
         
            +
            	rb_hash_aset(offsetlines, INT2FIX(table[i].position), ary);
         
     | 
| 
      
 181 
     | 
    
         
            +
                }
         
     | 
| 
      
 182 
     | 
    
         
            +
                return offsetlines;
         
     | 
| 
      
 183 
     | 
    
         
            +
            }
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            /* 
         
     | 
| 
      
 186 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 187 
     | 
    
         
            +
             *     RubyVM::InstructionSequence#offset2lines(offset) -> [Fixnum]
         
     | 
| 
      
 188 
     | 
    
         
            +
             * 
         
     | 
| 
      
 189 
     | 
    
         
            +
             * Returns an Array or nil. If offset is found then return the list of
         
     | 
| 
      
 190 
     | 
    
         
            +
             * lines associated with that offset. If the offset isn't found return nil.
         
     | 
| 
      
 191 
     | 
    
         
            +
             */
         
     | 
| 
      
 192 
     | 
    
         
            +
            VALUE iseq_offset2lines(VALUE iseqval, VALUE offsetval)
         
     | 
| 
      
 193 
     | 
    
         
            +
            {
         
     | 
| 
      
 194 
     | 
    
         
            +
                rb_iseq_t *iseq;
         
     | 
| 
      
 195 
     | 
    
         
            +
               
         
     | 
| 
      
 196 
     | 
    
         
            +
                GetISeqPtr(iseqval, iseq);
         
     | 
| 
      
 197 
     | 
    
         
            +
                
         
     | 
| 
      
 198 
     | 
    
         
            +
                if (FIXNUM_P(offsetval)) {
         
     | 
| 
      
 199 
     | 
    
         
            +
            	unsigned long i, size;
         
     | 
| 
      
 200 
     | 
    
         
            +
            	int offset = FIX2INT(offsetval);
         
     | 
| 
      
 201 
     | 
    
         
            +
            	struct iseq_insn_info_entry *table;
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
            	size = iseq->insn_info_size;
         
     | 
| 
      
 204 
     | 
    
         
            +
            	table = iseq->insn_info_table;
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
            	for (i = 0; i < size; i++) {
         
     | 
| 
      
 207 
     | 
    
         
            +
            	    if (table[i].position == offset) {
         
     | 
| 
      
 208 
     | 
    
         
            +
            		VALUE ary = rb_ary_new2(1);
         
     | 
| 
      
 209 
     | 
    
         
            +
            		rb_ary_push(ary, INT2FIX(table[i].line_no));
         
     | 
| 
      
 210 
     | 
    
         
            +
            		return ary;
         
     | 
| 
      
 211 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 212 
     | 
    
         
            +
            	}
         
     | 
| 
      
 213 
     | 
    
         
            +
                }
         
     | 
| 
      
 214 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 215 
     | 
    
         
            +
            }
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
            /* FIXME: should return array of destroyed entries */
         
     | 
| 
      
 218 
     | 
    
         
            +
            VALUE iseq_killcache(VALUE iseqval)
         
     | 
| 
      
 219 
     | 
    
         
            +
            {
         
     | 
| 
      
 220 
     | 
    
         
            +
                rb_iseq_t *iseqdat;
         
     | 
| 
      
 221 
     | 
    
         
            +
                VALUE *iseq ;
         
     | 
| 
      
 222 
     | 
    
         
            +
                unsigned long i, size, count = 0;
         
     | 
| 
      
 223 
     | 
    
         
            +
                struct iseq_insn_info_entry *table;
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                GetISeqPtr(iseqval, iseqdat);
         
     | 
| 
      
 226 
     | 
    
         
            +
                iseq = iseqdat->iseq;
         
     | 
| 
      
 227 
     | 
    
         
            +
                size = iseqdat->insn_info_size;
         
     | 
| 
      
 228 
     | 
    
         
            +
                table = iseqdat->insn_info_table;
         
     | 
| 
      
 229 
     | 
    
         
            +
                for (i = 0; i < size; i++) {
         
     | 
| 
      
 230 
     | 
    
         
            +
                  const unsigned long pos = table[i].position;
         
     | 
| 
      
 231 
     | 
    
         
            +
                  const VALUE insn = iseq[pos];
         
     | 
| 
      
 232 
     | 
    
         
            +
                  if (0 == strncmp(insn_name(insn), "getinlinecache", 
         
     | 
| 
      
 233 
     | 
    
         
            +
            		       sizeof("getinlinecache")))
         
     | 
| 
      
 234 
     | 
    
         
            +
                  {
         
     | 
| 
      
 235 
     | 
    
         
            +
            	/* printf("pos: %lu\n", pos); */
         
     | 
| 
      
 236 
     | 
    
         
            +
            	count ++;
         
     | 
| 
      
 237 
     | 
    
         
            +
            	iseq[pos] = 0;
         
     | 
| 
      
 238 
     | 
    
         
            +
            	iseq[pos+1] = 0;
         
     | 
| 
      
 239 
     | 
    
         
            +
            	iseq[pos+2] = 0;
         
     | 
| 
      
 240 
     | 
    
         
            +
                  }
         
     | 
| 
      
 241 
     | 
    
         
            +
                }
         
     | 
| 
      
 242 
     | 
    
         
            +
                return INT2FIX(count);
         
     | 
| 
      
 243 
     | 
    
         
            +
            }
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
            const char *
         
     | 
| 
      
 246 
     | 
    
         
            +
            source_container_type(VALUE fileval) 
         
     | 
| 
      
 247 
     | 
    
         
            +
            {
         
     | 
| 
      
 248 
     | 
    
         
            +
                const char *filename = RSTRING_PTR(fileval);
         
     | 
| 
      
 249 
     | 
    
         
            +
                size_t len = strlen(filename);
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
                /* FIXME: Looking for (...) is a hack that I would love to know how
         
     | 
| 
      
 252 
     | 
    
         
            +
                   to remove. Probably Ruby has to be changed to record this kind
         
     | 
| 
      
 253 
     | 
    
         
            +
                   of information.
         
     | 
| 
      
 254 
     | 
    
         
            +
                 */
         
     | 
| 
      
 255 
     | 
    
         
            +
                if (len > 0 && 
         
     | 
| 
      
 256 
     | 
    
         
            +
            	((filename[0] == '(' && filename[len-1] == ')')
         
     | 
| 
      
 257 
     | 
    
         
            +
            	 || 0 == strncmp(filename, "<compiled>", 
         
     | 
| 
      
 258 
     | 
    
         
            +
            			 sizeof("<compiled>"))))
         
     | 
| 
      
 259 
     | 
    
         
            +
            	return "string";
         
     | 
| 
      
 260 
     | 
    
         
            +
                else
         
     | 
| 
      
 261 
     | 
    
         
            +
            	return "file";
         
     | 
| 
      
 262 
     | 
    
         
            +
            }
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
            VALUE
         
     | 
| 
      
 266 
     | 
    
         
            +
            iseq_source_container_internal(rb_iseq_t *iseq)
         
     | 
| 
      
 267 
     | 
    
         
            +
            {
         
     | 
| 
      
 268 
     | 
    
         
            +
                VALUE fileval = iseq->filename;
         
     | 
| 
      
 269 
     | 
    
         
            +
                const char *contain_type = source_container_type(fileval);
         
     | 
| 
      
 270 
     | 
    
         
            +
                
         
     | 
| 
      
 271 
     | 
    
         
            +
                return rb_ary_new3(2, rb_str_new2(contain_type), fileval);
         
     | 
| 
      
 272 
     | 
    
         
            +
            }
         
     | 
| 
      
 273 
     | 
    
         
            +
             
     | 
| 
      
 274 
     | 
    
         
            +
            /*
         
     | 
| 
      
 275 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 276 
     | 
    
         
            +
             *    RubyVM::InstructionSequence#source_container() -> [Type, String]
         
     | 
| 
      
 277 
     | 
    
         
            +
             *
         
     | 
| 
      
 278 
     | 
    
         
            +
             * Returns a tuple representing kind of container, e.g. file
         
     | 
| 
      
 279 
     | 
    
         
            +
             * eval'd string object, and the name of the container. If file,
         
     | 
| 
      
 280 
     | 
    
         
            +
             * it would be a file name. If an eval'd string it might be the string.
         
     | 
| 
      
 281 
     | 
    
         
            +
             */
         
     | 
| 
      
 282 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 283 
     | 
    
         
            +
            iseq_source_container(VALUE iseqval)
         
     | 
| 
      
 284 
     | 
    
         
            +
            {
         
     | 
| 
      
 285 
     | 
    
         
            +
                rb_iseq_t *iseq;
         
     | 
| 
      
 286 
     | 
    
         
            +
               
         
     | 
| 
      
 287 
     | 
    
         
            +
                if (Qnil == iseqval) return Qnil;
         
     | 
| 
      
 288 
     | 
    
         
            +
                GetISeqPtr(iseqval, iseq);
         
     | 
| 
      
 289 
     | 
    
         
            +
                return iseq_source_container_internal(iseq);
         
     | 
| 
      
 290 
     | 
    
         
            +
            }
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
            #if 0
         
     | 
| 
      
 294 
     | 
    
         
            +
            /*
         
     | 
| 
      
 295 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 296 
     | 
    
         
            +
             *    RubyVM::InstructionSequence#type() -> Fixnum
         
     | 
| 
      
 297 
     | 
    
         
            +
             *
         
     | 
| 
      
 298 
     | 
    
         
            +
             * Returns instruction-sequence type.
         
     | 
| 
      
 299 
     | 
    
         
            +
             */
         
     | 
| 
      
 300 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 301 
     | 
    
         
            +
            iseq_type(VALUE iseqval)
         
     | 
| 
      
 302 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 303 
     | 
    
         
            +
             
     | 
| 
      
 304 
     | 
    
         
            +
            #define ISEQ_FIELD_METHOD(FIELD)		\
         
     | 
| 
      
 305 
     | 
    
         
            +
            static VALUE					\
         
     | 
| 
      
 306 
     | 
    
         
            +
            iseq_##FIELD(VALUE iseqval)			\
         
     | 
| 
      
 307 
     | 
    
         
            +
            {						\
         
     | 
| 
      
 308 
     | 
    
         
            +
              rb_iseq_t *iseq;				\
         
     | 
| 
      
 309 
     | 
    
         
            +
              if (Qnil == iseqval) return Qnil;		\
         
     | 
| 
      
 310 
     | 
    
         
            +
              GetISeqPtr(iseqval, iseq);			\
         
     | 
| 
      
 311 
     | 
    
         
            +
              return iseq->FIELD;				\
         
     | 
| 
      
 312 
     | 
    
         
            +
            }
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
      
 314 
     | 
    
         
            +
            ISEQ_FIELD_METHOD(orig) ;
         
     | 
| 
      
 315 
     | 
    
         
            +
            ISEQ_FIELD_METHOD(self) ;
         
     | 
| 
      
 316 
     | 
    
         
            +
            ISEQ_FIELD_METHOD(type) ;
         
     | 
| 
      
 317 
     | 
    
         
            +
             
     | 
| 
      
 318 
     | 
    
         
            +
            #define ISEQ_INT_FIELD_METHOD(FIELD)		\
         
     | 
| 
      
 319 
     | 
    
         
            +
            extern VALUE					\
         
     | 
| 
      
 320 
     | 
    
         
            +
            iseq_##FIELD(VALUE iseqval)			\
         
     | 
| 
      
 321 
     | 
    
         
            +
            {						\
         
     | 
| 
      
 322 
     | 
    
         
            +
              rb_iseq_t *iseq;				\
         
     | 
| 
      
 323 
     | 
    
         
            +
              GetISeqPtr(iseqval, iseq);			\
         
     | 
| 
      
 324 
     | 
    
         
            +
              return INT2FIX(iseq->FIELD);			\
         
     | 
| 
      
 325 
     | 
    
         
            +
            }
         
     | 
| 
      
 326 
     | 
    
         
            +
             
     | 
| 
      
 327 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(arg_block) ;
         
     | 
| 
      
 328 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(arg_opts) ;
         
     | 
| 
      
 329 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(arg_post_len) ;
         
     | 
| 
      
 330 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(arg_rest) ;
         
     | 
| 
      
 331 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(arg_simple) ;
         
     | 
| 
      
 332 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(argc) ;
         
     | 
| 
      
 333 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(iseq_size) ;
         
     | 
| 
      
 334 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(klass) ;
         
     | 
| 
      
 335 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(line_no) ;
         
     | 
| 
      
 336 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(local_size) ;
         
     | 
| 
      
 337 
     | 
    
         
            +
            ISEQ_INT_FIELD_METHOD(local_table_size) ;
         
     | 
| 
      
 338 
     | 
    
         
            +
             
     | 
| 
      
 339 
     | 
    
         
            +
            /*
         
     | 
| 
      
 340 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 341 
     | 
    
         
            +
             *    RubyVM::InstructionSequence#line_range() -> Range
         
     | 
| 
      
 342 
     | 
    
         
            +
             *
         
     | 
| 
      
 343 
     | 
    
         
            +
             * Returns a range containing the starting line number and the
         
     | 
| 
      
 344 
     | 
    
         
            +
             * ending line of the source code for the instruction-sequence.
         
     | 
| 
      
 345 
     | 
    
         
            +
             */
         
     | 
| 
      
 346 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 347 
     | 
    
         
            +
            iseq_line_range(VALUE iseqval) 
         
     | 
| 
      
 348 
     | 
    
         
            +
            {
         
     | 
| 
      
 349 
     | 
    
         
            +
                rb_iseq_t *iseq;
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
                GetISeqPtr(iseqval, iseq);
         
     | 
| 
      
 352 
     | 
    
         
            +
                if (Qnil == iseqval) return Qnil;
         
     | 
| 
      
 353 
     | 
    
         
            +
                else {
         
     | 
| 
      
 354 
     | 
    
         
            +
            	unsigned long i, size = iseq->insn_info_size;
         
     | 
| 
      
 355 
     | 
    
         
            +
            	struct iseq_insn_info_entry *table = iseq->insn_info_table;
         
     | 
| 
      
 356 
     | 
    
         
            +
            	unsigned short min_line = table[0].line_no;
         
     | 
| 
      
 357 
     | 
    
         
            +
            	unsigned short max_line = table[0].line_no;
         
     | 
| 
      
 358 
     | 
    
         
            +
            	
         
     | 
| 
      
 359 
     | 
    
         
            +
            	for (i = 0; i < size; i++) {
         
     | 
| 
      
 360 
     | 
    
         
            +
            	    if (table[i].line_no < min_line) 
         
     | 
| 
      
 361 
     | 
    
         
            +
            		min_line = table[i].line_no;
         
     | 
| 
      
 362 
     | 
    
         
            +
            	    else if (table[i].line_no > max_line)
         
     | 
| 
      
 363 
     | 
    
         
            +
            		max_line = table[i].line_no;
         
     | 
| 
      
 364 
     | 
    
         
            +
            	}
         
     | 
| 
      
 365 
     | 
    
         
            +
            	return rb_range_new(INT2FIX(min_line), INT2FIX(max_line), 0);
         
     | 
| 
      
 366 
     | 
    
         
            +
                }
         
     | 
| 
      
 367 
     | 
    
         
            +
            }
         
     | 
| 
      
 368 
     | 
    
         
            +
             
     | 
| 
      
 369 
     | 
    
         
            +
             
     | 
| 
      
 370 
     | 
    
         
            +
            /* RDoc can't find methods when we use a definition like this: */
         
     | 
| 
      
 371 
     | 
    
         
            +
            #define RB_DEFINE_ISEQ_METHOD(FIELD, ARGC) \
         
     | 
| 
      
 372 
     | 
    
         
            +
                rb_define_method(rb_cISeq, #FIELD, iseq_##FIELD, ARGC);
         
     | 
| 
      
 373 
     | 
    
         
            +
             
     | 
| 
      
 374 
     | 
    
         
            +
            void
         
     | 
| 
      
 375 
     | 
    
         
            +
            Init_iseq_extra(void)
         
     | 
| 
      
 376 
     | 
    
         
            +
            {
         
     | 
| 
      
 377 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "arg_block",        iseq_arg_block, 0) ;
         
     | 
| 
      
 378 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "arg_opts",         iseq_arg_opts, 0) ;
         
     | 
| 
      
 379 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "arg_post_len",     iseq_arg_post_len, 0) ;
         
     | 
| 
      
 380 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "arg_rest",         iseq_arg_rest, 0) ;
         
     | 
| 
      
 381 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "arg_simple",       iseq_arg_simple, 0) ;
         
     | 
| 
      
 382 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "argc",             iseq_argc, 0) ;
         
     | 
| 
      
 383 
     | 
    
         
            +
            #ifdef HAVE_COMPILE_OPTIONS
         
     | 
| 
      
 384 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "compile_options",  iseq_compile_options, 0) ;
         
     | 
| 
      
 385 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 386 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "equal?",           iseq_equal, 1) ;
         
     | 
| 
      
 387 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "encoded",          iseq_iseq_encoded, 0) ;
         
     | 
| 
      
 388 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "iseq_size",        iseq_iseq_size, 0) ;
         
     | 
| 
      
 389 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "killcache",        iseq_killcache, 0) ;
         
     | 
| 
      
 390 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "klass",            iseq_klass, 0) ;
         
     | 
| 
      
 391 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "lineno",           iseq_line_no, 0) ;
         
     | 
| 
      
 392 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "line_range",       iseq_line_range, 0) ;
         
     | 
| 
      
 393 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "local_name",       iseq_local_name, 1) ;
         
     | 
| 
      
 394 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "local_size",       iseq_local_size, 0) ;
         
     | 
| 
      
 395 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "local_table_size", iseq_local_table_size, 0) ;
         
     | 
| 
      
 396 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "offset2lines",     iseq_offset2lines, 1) ;
         
     | 
| 
      
 397 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "offsetlines",      iseq_offsetlines, 0) ;
         
     | 
| 
      
 398 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "orig",             iseq_orig, 0) ;
         
     | 
| 
      
 399 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "name",             iseq_name, 0) ;
         
     | 
| 
      
 400 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "self",             iseq_self, 0) ;
         
     | 
| 
      
 401 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "source_container", iseq_source_container, 0) ;
         
     | 
| 
      
 402 
     | 
    
         
            +
                rb_define_method(rb_cISeq, "type",             iseq_type, 0) ;
         
     | 
| 
      
 403 
     | 
    
         
            +
             
     | 
| 
      
 404 
     | 
    
         
            +
            }
         
     |