Module: Ruby2CExtension::Plugins::Util

Included in:
CacheCall, DirectSelfCall, IVarCache, InlineBuiltin, InlineBuiltin
Defined in:
lib/ruby2cext/plugins/util.rb

Instance Method Summary collapse

Instance Method Details

#args_arity(args) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/ruby2cext/plugins/util.rb', line 132

def args_arity(args)
    data = args.last
    case args.first
    when :array
        data.size
    when :splat
        -1
    when :argscat
        arity = args_arity(data[:head])
        (arity<0) ? arity : -arity - 1
    when :argspush
        arity = args_arity(data[:head])
        (arity<0) ? arity : arity + 1
    else
        -1
    end
end

#deduce_type(node) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ruby2cext/plugins/util.rb', line 6

def deduce_type(node)
    while true
        Array === node or return
        case node.first
        when :lit
            return Kernel.const_get(node.last[:lit].class.name)
        when :nil
            return NilClass
        when :false
            return FalseClass
        when :true
            return TrueClass
        when :str, :dstr
            return String
        when :dsym
            return Symbol
        when :array, :zarray, :masgn
            return Array
        when :hash
            return Hash
        when :dregx, :dregx_once
            return Regexp
        when :dasn_curr, :iasgn, :cvdecl, :gasgn, :cdecl
            node = node.last[:value]
        when :attrasgn
            args = node.last[:args]
            Array === args or return
            case args.first
            when :array
                node = args.last.last
            when :argspush
                node = args.last[:body]
            else
                return
            end
        else
            return
        end
    end
end

#split_args(arity, args, extra_allowed = nil) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/ruby2cext/plugins/util.rb', line 88

def split_args(arity, args, extra_allowed=nil)
    if arity<0
        extra_allowed = true
        arity = -arity -1
    end
    data = args.last
    required = []
    remaining = nil
    case args.first
    when :array
        if data.size>arity
            required = data[0, arity]
            remaining = [:array, data[arity, data.size-arity]]
        else
            required = data
        end
    when :splat
        remaining = args
    when :argscat
        required = split_args(arity, data[:head], true) or return nil
        remaining = [:argscat, {:head => required.pop, :body => data[:body]}]
    when :argspush
        if extra_allowed
            required = split_args(arity, data[:head], true) or return nil
            remaining = [:argspush, {:head => required.pop, :body => data[:body]}]
        else
            required = split_args(arity-1, data[:head], false) or return nil
            required << data[:body]
        end
    else
        return nil
    end
    if required.size<arity
        nil
    elsif extra_allowed
        remaining ||= [:array, []]
        required << remaining
    elsif remaining
        nil
    else
        required
    end
end

#values(cfun, nreused, *rvalues) ⇒ Object

:yield: *vals



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ruby2cext/plugins/util.rb', line 47

def values(cfun, nreused, *rvalues) # :yield: *vals
    header = "{"
    cfun.l(header)
    res = 0
    reuse = 0
    vals = []
    res_assign = ""
    res_val = ""
    direct = /\A\s*(\w+(\s*\[\s*\d+\s*\])?|\d+)\s*\Z/
    rvalues.each { |rvalue|
        nreused -= 1
        val = rvalue && cfun.comp(rvalue)
        if val == "res"
            if res_assign
                header.concat("VALUE res#{res};")
                res += 1
            end
            var = "res#{res}"
            cfun.l(res_assign = "#{var} = #{val};")
            res_val = val = var
        elsif nreused >= 0 and val and val !~ direct
            var = "reuse#{reuse}"
            header.concat("VALUE #{var};")
            cfun.l("#{var} = #{val};")
            val = var
        end
        vals << val
    }
    res_assign.replace("")
    res_val.replace("res")
    if header.size == 1
        header.replace("")
        yield(*vals)
    else
        res_rvalue = yield(*vals)
        cfun.assign_res(res_rvalue)
        cfun.l "}"
        "res"
    end
end