class Myco::CodeLoader::AbstractLoader

Attributes

ast[RW]
block_environment[RW]
compiled_code[RW]
constant_scope[RW]
filename[RW]
generator[RW]
line[RW]
receiver[RW]
string[RW]
variable_scope[RW]

Public Class Methods

new(filename, line = 1) click to toggle source
# File lib/myco/code_loader.rb, line 113
def initialize filename, line = 1
  @filename = filename
  @line     = line
end

Public Instance Methods

bind_to(kwargs={}) click to toggle source

TODO: fix rubinius JIT issue and use “cscope:nil, vscope:nil, receiver:nil, call_depth:1” here

# File lib/myco/code_loader.rb, line 119
def bind_to kwargs={}
  loc = Rubinius::VM.backtrace(kwargs.fetch(:call_depth, 1), true).first
  @constant_scope = kwargs[:cscope] || loc.constant_scope
  @variable_scope = kwargs[:vscope] || loc.variables
  @receiver =     kwargs[:receiver] || loc.instance_variable_get(:@receiver)
  
  self
end
compile() click to toggle source
# File lib/myco/code_loader.rb, line 185
def compile
  @block_environment || make_block_environment
end
emit_rb!(filename=nil) click to toggle source
# File lib/myco/code_loader.rb, line 194
def emit_rb! filename=nil
  @ast || make_ast
  
  filename = emit_filename('.rb', filename)
  return nil unless filename
  
  File.open(filename, "w+") { |file| file.write(@ast.to_ruby_code) }
end
emit_rbc!(filename=nil) click to toggle source
# File lib/myco/code_loader.rb, line 203
def emit_rbc! filename=nil
  @compiled_code || make_compiled_code
  
  filename = emit_filename('.rbc', filename)
  return nil unless filename
  
  compiled_file_type.dump(
    @compiled_code, filename, Rubinius::Signature, Rubinius::RUBY_LIB_VERSION
  )
end
is_rb?() click to toggle source
# File lib/myco/code_loader.rb, line 214
def is_rb?;  false end
is_rbc?() click to toggle source
# File lib/myco/code_loader.rb, line 215
def is_rbc?; false end
load() click to toggle source
# File lib/myco/code_loader.rb, line 189
def load
  compile
  @block_environment.call_on_instance(@receiver)
end
make_ast() click to toggle source
# File lib/myco/code_loader.rb, line 132
def make_ast
  @string || make_string
  
  parser = new_parser
  begin
    ast = parser.parse_string(@string)
  rescue Exception => e
    full_message = "Error while parsing #{filename}:\n" + e.message
    raise e.class, full_message, e.backtrace
  end
  
  ast = ast_root_for(ast)
  ast.file = filename.to_sym
  ast.variable_scope = @variable_scope
  
  @ast = ast
end
make_block_environment() click to toggle source
# File lib/myco/code_loader.rb, line 170
def make_block_environment
  @compiled_code || make_compiled_code
  code = @compiled_code
  
  code.scope = @constant_scope
  script = Rubinius::CompiledCode::Script.new(code, @filename, true)
  script.eval_source = @string
  code.scope.script = script
  
  be = Rubinius::BlockEnvironment.new
  be.under_context(@variable_scope, code)
  
  @block_environment = be
end
make_compiled_code() click to toggle source
# File lib/myco/code_loader.rb, line 162
def make_compiled_code
  @generator || make_generator
  
  code = @generator.package(Rubinius::CompiledCode)
  
  @compiled_code = code
end
make_generator() click to toggle source
# File lib/myco/code_loader.rb, line 150
def make_generator
  @ast || make_ast
  
  g = new_generator
  @ast.bytecode(g)
  
  g.close
  g.encode
  
  @generator = g
end
make_string() click to toggle source
# File lib/myco/code_loader.rb, line 128
def make_string
  @string = File.read(filename)
end

Private Instance Methods

emit_filename(file_ext, override=nil) click to toggle source

Return the filename to emit, or nil if the file is already current relative to modification time of the file at the myco_filename.

# File lib/myco/code_loader.rb, line 232
def emit_filename file_ext, override=nil
  if override
    filename = override
  else
    orig_filename = myco_filename
    filename ||= orig_filename + file_ext
    
    if File.file?(myco_filename)
      ref_mtime = File.mtime(myco_filename)
      if File.file?(filename) && (File.mtime(filename) >= ref_mtime)
        return nil
      end
    end
  end
  
  mkdir_p(File.dirname(filename))
  return filename
end
mkdir_p(dir) click to toggle source
# File lib/myco/code_loader.rb, line 224
def mkdir_p dir
  # TODO: do manually, without depending on FileUtils
  require 'fileutils'
  FileUtils.mkdir_p(dir)
end
myco_filename() click to toggle source

Return @filename, stripped of any .rbc or .rb file extension

# File lib/myco/code_loader.rb, line 220
def myco_filename
  @filename.sub(/\.rbc?$/, '')
end