Class: Ruby2CExtension::Plugins::InlineMethods

Inherits:
Ruby2CExtension::Plugin show all
Defined in:
lib/ruby2cext/plugins/inline_methods.rb

Constant Summary collapse

METHODS =
{
  [:nil?, 0] => proc { |cfun, recv, args|
    "(Qnil == (#{recv}) ? Qtrue : Qfalse)"
  },
  [:equal?, 1] => proc { |cfun, recv, args|
    cfun.instance_eval {
      c_scope_res {
        l "VALUE recv = #{recv};"
        "(recv == (#{comp(args[0])}) ? Qtrue : Qfalse)"
      }
    }
  },
  :__send__ => proc { |cfun, recv, args|
    unless args
      raise Ruby2CExtension::Ruby2CExtError, "inlining #__send__ without arguments is not allowed"
    end
    cfun.instance_eval {
      add_helper "        static void inline_method_send_no_method_name() {\n          rb_raise(rb_eArgError, \"no method name given\");\n        }\n      EOC\n      c_scope_res {\n        l \"VALUE recv = \#{recv};\"\n        build_args(args)\n        l \"if (argc == 0) inline_method_send_no_method_name();\"\n        \"rb_funcall2(recv, rb_to_id(argv[0]), argc - 1, (&(argv[0])) + 1)\"\n      }\n    }\n  },\n}\n"

Instance Attribute Summary

Attributes inherited from Ruby2CExtension::Plugin

#compiler

Instance Method Summary collapse

Methods inherited from Ruby2CExtension::Plugin

#global_c_code, #init_c_code

Constructor Details

#initialize(compiler) ⇒ InlineMethods



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/ruby2cext/plugins/inline_methods.rb', line 40

def initialize(compiler)
  super
  self_node = [:self, {}]
  compiler.add_preprocessor(:vcall) { |cfun, node|
    handle(cfun, node.last[:mid], self_node, false) || node
  }
  compiler.add_preprocessor(:fcall) { |cfun, node|
    handle(cfun, node.last[:mid], self_node, node.last[:args]) || node
  }
  compiler.add_preprocessor(:call) { |cfun, node|
    handle(cfun, node.last[:mid], node.last[:recv], node.last[:args]) || node
  }
end

Instance Method Details

#handle(cfun, method, recv, args) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ruby2cext/plugins/inline_methods.rb', line 54

def handle(cfun, method, recv, args)
  if (pr = METHODS[method])
    pr.call(cfun, cfun.comp(recv), args)
  else
    args ||= [:array, []]
    if args.first == :array && (pr = METHODS[[method, args.last.size]])
      pr.call(cfun, cfun.comp(recv), args.last)
    else
      nil
    end
  end
end