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 <<-EOC
				static void inline_method_send_no_method_name() {
					rb_raise(rb_eArgError, "no method name given");
				}
			EOC
			c_scope_res {
				l "VALUE recv = #{recv};"
				build_args(args)
				l "if (argc == 0) inline_method_send_no_method_name();"
				"rb_funcall2(recv, rb_to_id(argv[0]), argc - 1, (&(argv[0])) + 1)"
			}
		}
	},
}

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

Returns a new instance of InlineMethods.



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

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



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

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