Top Level Namespace

Defined Under Namespace

Modules: DL

Constant Summary collapse

CDECL =
"cdecl"
STDCALL =
"stdcall"
CALLTYPES =
[CDECL, STDCALL]
DLTYPE =
{
  VOID => {
    :name => 'void',
    :type => 'void',
    :conv => nil,
  },
  CHAR => {
    :name => 'char',
    :type => 'char',
    :conv => 'NUM2CHR(%s)'
  },
  SHORT => {
    :name => 'short',
    :type => 'short',
    :conv => 'NUM2INT(%s)',
  },
  INT => {
    :name => 'int',
    :type => 'int',
    :conv => 'NUM2INT(%s)',
  },
  LONG  => {
    :name => 'long',
    :type => 'long',
    :conv => 'NUM2LONG(%s)',
  },
  LONG_LONG => {
    :name => 'long_long',
    :type => 'LONG_LONG',
    :conv => 'NUM2LL(%s)',
  },
  FLOAT => {
    :name => 'float',
    :type => 'float',
    :conv => '(float)RFLOAT_VALUE(%s)',
  },
  DOUBLE => {
    :name => 'double',
    :type => 'double',
    :conv => 'RFLOAT_VALUE(%s)',
  },
  VOIDP => {
    :name => 'ptr',
    :type => 'void *',
    :conv => 'NUM2PTR(%s)',
  },
}

Instance Method Summary collapse

Instance Method Details

#foreach_proc_entryObject



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'callback/mkcallback.rb', line 109

def foreach_proc_entry
  for calltype in CALLTYPES
    case calltype
    when CDECL
      proc_entry = "rb_DLCdeclCallbackProcs"
    when STDCALL
      proc_entry = "rb_DLStdcallCallbackProcs"
    else
      raise "unknown calltype: #{calltype}"
    end
    yield calltype, proc_entry
  end
end

#func_name(ty, argc, n, calltype) ⇒ Object



91
92
93
# File 'callback/mkcallback.rb', line 91

def func_name(ty, argc, n, calltype)
  "rb_dl_callback_#{DLTYPE[ty][:name]}_#{argc}_#{n}_#{calltype}"
end

#gen_callback_file(ty) {|body| ... } ⇒ Object

Yields:

  • (body)


165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'callback/mkcallback.rb', line 165

def gen_callback_file(ty)
  filename = "#{$output}-#{ty}.c"
  initname = "rb_dl_init_callbacks_#{ty}"
  body = "#include \"dl.h\"\n\nextern VALUE rb_DLCdeclCallbackAddrs, rb_DLCdeclCallbackProcs;\n#ifdef FUNC_STDCALL\nextern VALUE rb_DLStdcallCallbackAddrs, rb_DLStdcallCallbackProcs;\n#endif\nextern ID   rb_dl_cb_call;\n"
  yield body
  body << "void\n\#{initname}()\n{\n\#{gen_push_proc_ary(ty, \"rb_DLCdeclCallbackProcs\")}\n\#{gen_push_addr_ary(ty, \"rb_DLCdeclCallbackAddrs\", CDECL)}\n#ifdef FUNC_STDCALL\n\#{gen_push_proc_ary(ty, \"rb_DLStdcallCallbackProcs\")}\n\#{gen_push_addr_ary(ty, \"rb_DLStdcallCallbackAddrs\", STDCALL)}\n#endif\n}\n"
  [filename, initname, body]
end

#gen_push_addr_ary(ty, aryname, calltype) ⇒ Object



155
156
157
158
159
160
161
162
163
# File 'callback/mkcallback.rb', line 155

def gen_push_addr_ary(ty, aryname, calltype)
  sprintf("    rb_ary_push(#{aryname}, rb_ary_new3(%d,%s));",
          MAX_CALLBACK * DLSTACK_SIZE,
          (0...MAX_CALLBACK).collect{|i|
            (0...DLSTACK_SIZE).collect{|argc|
              "PTR2NUM(%s)" % func_name(ty,argc,i,calltype)
            }.join(",")
          }.join(","))
end

#gen_push_proc_ary(ty, aryname) ⇒ Object



147
148
149
150
151
152
153
# File 'callback/mkcallback.rb', line 147

def gen_push_proc_ary(ty, aryname)
  sprintf("    rb_ary_push(#{aryname}, rb_ary_new3(%d,%s));",
          MAX_CALLBACK * DLSTACK_SIZE,
          (0...MAX_CALLBACK).collect{
            (0...DLSTACK_SIZE).collect{ "Qnil" }.join(",")
          }.join(","))
end

#gencallback(ty, calltype, proc_entry, argc, n) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'callback/mkcallback.rb', line 123

def gencallback(ty, calltype, proc_entry, argc, n)
  dltype = DLTYPE[ty]
  ret = dltype[:conv]
  src = "\#{calltype == STDCALL ? \"\\n#ifdef FUNC_STDCALL\" : \"\"}\nstatic \#{dltype[:type]}\nFUNC_\#{calltype.upcase}(\#{func_name(ty,argc,n,calltype)})(\#{(0...argc).collect{|i| \"DLSTACK_TYPE stack\#{i}\"}.join(\", \")})\n{\nVALUE \#{ret ? \"ret, \" : \"\"}cb\#{argc > 0 ? \", args[\#{argc}]\" : \"\"};\n\#{\n(0...argc).collect{|i|\n\"\\n    args[\#{i}] = PTR2NUM(stack\#{i});\"\n}.join(\"\")\n}\ncb = rb_ary_entry(rb_ary_entry(\#{proc_entry}, \#{ty}), \#{(n * DLSTACK_SIZE) + argc});\n\#{ret ? \"ret = \" : \"\"}rb_funcall2(cb, rb_dl_cb_call, \#{argc}, \#{argc > 0 ? 'args' : 'NULL'});\n"
  src << "    return #{ret % "ret"};\n" if ret
  src << "}\n\#{calltype == STDCALL ? \"#endif\\n\" : \"\"}\n"
end