ffi 1.9.10 → 1.9.11
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Rakefile +30 -8
- data/ext/ffi_c/AbstractMemory.c +1 -1
- data/ext/ffi_c/Buffer.c +1 -1
- data/ext/ffi_c/Call.c +12 -25
- data/ext/ffi_c/Call.h +17 -0
- data/ext/ffi_c/Function.c +24 -26
- data/ext/ffi_c/MethodHandle.c +3 -5
- data/ext/ffi_c/Pointer.c +3 -3
- data/ext/ffi_c/Variadic.c +24 -0
- data/ext/ffi_c/compat.h +0 -5
- data/ext/ffi_c/libffi/src/mips/ffi.c +4 -2
- data/ext/ffi_c/rbffi_endian.h +1 -1
- data/ffi.gemspec +1 -1
- data/lib/ffi/autopointer.rb +36 -27
- data/lib/ffi/enum.rb +1 -3
- data/lib/ffi/library.rb +14 -1
- data/lib/ffi/pointer.rb +1 -1
- data/lib/ffi/struct.rb +1 -1
- data/lib/ffi/tools/types_generator.rb +6 -7
- data/lib/ffi/types.rb +8 -4
- data/lib/ffi/version.rb +1 -1
- data/libtest/FunctionTest.c +1 -1
- data/libtest/VariadicTest.c +37 -0
- data/spec/ffi/fixtures/ClosureTest.c +15 -0
- data/spec/ffi/fixtures/FunctionTest.c +88 -4
- data/spec/ffi/fixtures/PipeHelper.h +21 -0
- data/spec/ffi/fixtures/PipeHelperPosix.c +41 -0
- data/spec/ffi/fixtures/PipeHelperWindows.c +72 -0
- data/spec/ffi/function_spec.rb +15 -10
- data/spec/ffi/rbx/attach_function_spec.rb +22 -21
- data/spec/ffi/struct_spec.rb +4 -4
- data/spec/ffi/variadic_spec.rb +19 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd5a2a6512c110a9b389f35fc72dc8cdaa750726
|
4
|
+
data.tar.gz: e245890dfe6d77d2c7377a0e7e397fd6603b1dde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 628b2b63ee4f4ddc196dbb169d68613e72b7710b00219f3c4001aa9b62c997f0540d92b6649aae09cb2d6937d5d3b2a2fc746c1ca3c571c8771602405ed143dc
|
7
|
+
data.tar.gz: f459df3bd97f90de497d6acf4c5e631e02a6e88287c09328873def76ea3f91f9aa87adf6271265626a6567169e16855954288b91058b84b36a40f7bdbfc83852
|
data/Rakefile
CHANGED
@@ -93,13 +93,13 @@ task :package => 'gem:package'
|
|
93
93
|
|
94
94
|
CLOBBER.include 'lib/ffi/types.conf'
|
95
95
|
CLOBBER.include 'pkg'
|
96
|
+
CLOBBER.include 'log'
|
96
97
|
|
97
98
|
CLEAN.include 'build'
|
98
99
|
CLEAN.include 'conftest.dSYM'
|
99
100
|
CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}'
|
100
101
|
CLEAN.include 'spec/ffi/fixtures/*.o'
|
101
|
-
CLEAN.include "pkg/ffi
|
102
|
-
CLEAN.include "pkg/ffi-#{FFI::VERSION}-java"
|
102
|
+
CLEAN.include "pkg/ffi-*-{mingw32,java}"
|
103
103
|
CLEAN.include 'lib/1.*'
|
104
104
|
CLEAN.include 'lib/2.*'
|
105
105
|
CLEAN.include 'bin'
|
@@ -138,7 +138,7 @@ end
|
|
138
138
|
task 'spec:run' => TEST_DEPS
|
139
139
|
task 'spec:specdoc' => TEST_DEPS
|
140
140
|
|
141
|
-
task :default => :
|
141
|
+
task :default => :spec
|
142
142
|
|
143
143
|
namespace 'java' do
|
144
144
|
|
@@ -175,15 +175,16 @@ if USE_RAKE_COMPILER
|
|
175
175
|
ext.cross_platform = %w[i386-mingw32 x64-mingw32] # forces the Windows platform instead of the default one
|
176
176
|
end
|
177
177
|
|
178
|
-
ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.3:2.0.0:2.1.
|
178
|
+
ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.3:2.0.0:2.1.6:2.2.2:2.3.0'
|
179
179
|
|
180
|
+
# To reduce the gem file size strip mingw32 dlls before packaging
|
180
181
|
ENV['RUBY_CC_VERSION'].to_s.split(':').each do |ruby_version|
|
181
|
-
task "
|
182
|
-
sh "i686-w64-mingw32-strip -S
|
182
|
+
task "build/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so" do |t|
|
183
|
+
sh "i686-w64-mingw32-strip -S build/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
|
183
184
|
end
|
184
185
|
|
185
|
-
task "
|
186
|
-
sh "x86_64-w64-mingw32-strip -S
|
186
|
+
task "build/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so" do |t|
|
187
|
+
sh "x86_64-w64-mingw32-strip -S build/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
|
187
188
|
end
|
188
189
|
end
|
189
190
|
|
@@ -194,6 +195,27 @@ if USE_RAKE_COMPILER
|
|
194
195
|
end
|
195
196
|
end
|
196
197
|
|
198
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
|
199
|
+
require 'ffi/platform'
|
200
|
+
types_conf = File.expand_path(File.join(FFI::Platform::CONF_DIR, 'types.conf'))
|
201
|
+
logfile = File.join(File.dirname(__FILE__), 'types_log')
|
202
|
+
|
203
|
+
file types_conf => File.join("lib", "ffi", "version.rb") do |task|
|
204
|
+
require 'fileutils'
|
205
|
+
require 'ffi/tools/types_generator'
|
206
|
+
options = {}
|
207
|
+
FileUtils.mkdir_p(File.dirname(task.name), { :mode => 0755 })
|
208
|
+
File.open(task.name, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f|
|
209
|
+
f.puts FFI::TypesGenerator.generate(options)
|
210
|
+
end
|
211
|
+
File.open(logfile, 'w') do |log|
|
212
|
+
log.puts(types_conf)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
task :types_conf => types_conf do
|
217
|
+
end
|
218
|
+
|
197
219
|
Gem::Tasks.new do |t|
|
198
220
|
t.scm.tag.format = '%s'
|
199
221
|
end
|
data/ext/ffi_c/AbstractMemory.c
CHANGED
@@ -497,7 +497,7 @@ memory_put_bytes(int argc, VALUE* argv, VALUE self)
|
|
497
497
|
off = NUM2LONG(offset);
|
498
498
|
idx = nargs > 2 ? NUM2LONG(rbIndex) : 0;
|
499
499
|
if (idx < 0) {
|
500
|
-
rb_raise(rb_eRangeError, "index
|
500
|
+
rb_raise(rb_eRangeError, "index cannot be less than zero");
|
501
501
|
return Qnil;
|
502
502
|
}
|
503
503
|
len = nargs > 3 ? NUM2LONG(rbLength) : (RSTRING_LEN(str) - idx);
|
data/ext/ffi_c/Buffer.c
CHANGED
@@ -253,7 +253,7 @@ buffer_inspect(VALUE self)
|
|
253
253
|
* @overload order(order)
|
254
254
|
* @param [:big, :little, :network] order
|
255
255
|
* @return [self]
|
256
|
-
* Set
|
256
|
+
* Set endianness of Buffer (+:network+ is an alias for +:big+).
|
257
257
|
*/
|
258
258
|
static VALUE
|
259
259
|
buffer_order(int argc, VALUE* argv, VALUE self)
|
data/ext/ffi_c/Call.c
CHANGED
@@ -338,40 +338,27 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
|
|
338
338
|
}
|
339
339
|
}
|
340
340
|
|
341
|
-
|
342
|
-
typedef struct BlockingCall_ {
|
343
|
-
rbffi_frame_t* frame;
|
344
|
-
void* function;
|
345
|
-
FunctionType* info;
|
346
|
-
void **ffiValues;
|
347
|
-
void* retval;
|
348
|
-
void* params;
|
349
|
-
#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
|
350
|
-
void* stkretval;
|
351
|
-
#endif
|
352
|
-
} BlockingCall;
|
353
|
-
|
354
341
|
static VALUE
|
355
342
|
call_blocking_function(void* data)
|
356
343
|
{
|
357
|
-
|
344
|
+
rbffi_blocking_call_t* b = (rbffi_blocking_call_t *) data;
|
358
345
|
b->frame->has_gvl = false;
|
359
|
-
ffi_call(&b->
|
346
|
+
ffi_call(&b->cif, FFI_FN(b->function), b->retval, b->ffiValues);
|
360
347
|
b->frame->has_gvl = true;
|
361
348
|
|
362
349
|
return Qnil;
|
363
350
|
}
|
364
351
|
|
365
|
-
|
366
|
-
|
352
|
+
VALUE
|
353
|
+
rbffi_do_blocking_call(void *data)
|
367
354
|
{
|
368
355
|
rbffi_thread_blocking_region(call_blocking_function, data, (void *) -1, NULL);
|
369
356
|
|
370
357
|
return Qnil;
|
371
358
|
}
|
372
359
|
|
373
|
-
|
374
|
-
|
360
|
+
VALUE
|
361
|
+
rbffi_save_frame_exception(void *data, VALUE exc)
|
375
362
|
{
|
376
363
|
rbffi_frame_t* frame = (rbffi_frame_t *) data;
|
377
364
|
frame->exc = exc;
|
@@ -390,7 +377,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
390
377
|
retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
|
391
378
|
|
392
379
|
if (unlikely(fnInfo->blocking)) {
|
393
|
-
|
380
|
+
rbffi_blocking_call_t* bc;
|
394
381
|
|
395
382
|
/*
|
396
383
|
* due to the way thread switching works on older ruby variants, we
|
@@ -399,16 +386,16 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
399
386
|
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
400
387
|
ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
|
401
388
|
params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
|
402
|
-
bc = ALLOCA_N(
|
389
|
+
bc = ALLOCA_N(rbffi_blocking_call_t, 1);
|
403
390
|
bc->retval = retval;
|
404
391
|
#else
|
405
392
|
ffiValues = ALLOC_N(void *, fnInfo->parameterCount);
|
406
393
|
params = ALLOC_N(FFIStorage, fnInfo->parameterCount);
|
407
|
-
bc = ALLOC_N(
|
394
|
+
bc = ALLOC_N(rbffi_blocking_call_t, 1);
|
408
395
|
bc->retval = xmalloc(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
|
409
396
|
bc->stkretval = retval;
|
410
397
|
#endif
|
411
|
-
bc->
|
398
|
+
bc->cif = fnInfo->ffi_cif;
|
412
399
|
bc->function = function;
|
413
400
|
bc->ffiValues = ffiValues;
|
414
401
|
bc->params = params;
|
@@ -419,11 +406,11 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
419
406
|
fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
|
420
407
|
|
421
408
|
rbffi_frame_push(&frame);
|
422
|
-
rb_rescue2(
|
409
|
+
rb_rescue2(rbffi_do_blocking_call, (VALUE) bc, rbffi_save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
|
423
410
|
rbffi_frame_pop(&frame);
|
424
411
|
|
425
412
|
#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
|
426
|
-
memcpy(bc->stkretval, bc->retval, MAX(bc->
|
413
|
+
memcpy(bc->stkretval, bc->retval, MAX(bc->cif.rtype->size, FFI_SIZEOF_ARG));
|
427
414
|
xfree(bc->params);
|
428
415
|
xfree(bc->ffiValues);
|
429
416
|
xfree(bc->retval);
|
data/ext/ffi_c/Call.h
CHANGED
@@ -33,6 +33,8 @@
|
|
33
33
|
#ifndef RBFFI_CALL_H
|
34
34
|
#define RBFFI_CALL_H
|
35
35
|
|
36
|
+
#include "Thread.h"
|
37
|
+
|
36
38
|
#ifdef __cplusplus
|
37
39
|
extern "C" {
|
38
40
|
#endif
|
@@ -85,6 +87,21 @@ Invoker rbffi_GetInvoker(struct FunctionType_* fnInfo);
|
|
85
87
|
extern VALUE rbffi_GetEnumValue(VALUE enums, VALUE value);
|
86
88
|
extern int rbffi_GetSignedIntValue(VALUE value, int type, int minValue, int maxValue, const char* typeName, VALUE enums);
|
87
89
|
|
90
|
+
typedef struct rbffi_blocking_call {
|
91
|
+
rbffi_frame_t* frame;
|
92
|
+
void* function;
|
93
|
+
ffi_cif cif;
|
94
|
+
void **ffiValues;
|
95
|
+
void* retval;
|
96
|
+
void* params;
|
97
|
+
#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
|
98
|
+
void* stkretval;
|
99
|
+
#endif
|
100
|
+
} rbffi_blocking_call_t;
|
101
|
+
|
102
|
+
VALUE rbffi_do_blocking_call(void* data);
|
103
|
+
VALUE rbffi_save_frame_exception(void *data, VALUE exc);
|
104
|
+
|
88
105
|
#ifdef __cplusplus
|
89
106
|
}
|
90
107
|
#endif
|
data/ext/ffi_c/Function.c
CHANGED
@@ -202,7 +202,7 @@ function_free(Function *fn)
|
|
202
202
|
static VALUE
|
203
203
|
function_initialize(int argc, VALUE* argv, VALUE self)
|
204
204
|
{
|
205
|
-
|
205
|
+
|
206
206
|
VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil;
|
207
207
|
VALUE rbFunctionInfo = Qnil;
|
208
208
|
VALUE infoArgv[3];
|
@@ -229,14 +229,14 @@ function_initialize(int argc, VALUE* argv, VALUE self)
|
|
229
229
|
* Function.new(:int, [ :int ], addr, { :convention => :stdcall })
|
230
230
|
*/
|
231
231
|
}
|
232
|
-
|
232
|
+
|
233
233
|
infoArgv[0] = rbReturnType;
|
234
234
|
infoArgv[1] = rbParamTypes;
|
235
235
|
infoArgv[2] = rbOptions;
|
236
236
|
rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass);
|
237
237
|
|
238
238
|
function_init(self, rbFunctionInfo, rbProc);
|
239
|
-
|
239
|
+
|
240
240
|
return self;
|
241
241
|
}
|
242
242
|
|
@@ -272,12 +272,12 @@ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
|
|
272
272
|
return cbref;
|
273
273
|
}
|
274
274
|
}
|
275
|
-
|
275
|
+
|
276
276
|
cbTable = RTEST(rb_ivar_defined(proc, id_cbtable)) ? rb_ivar_get(proc, id_cbtable) : Qnil;
|
277
277
|
if (cbTable != Qnil && (callback = rb_hash_aref(cbTable, rbFunctionInfo)) != Qnil) {
|
278
278
|
return callback;
|
279
279
|
}
|
280
|
-
|
280
|
+
|
281
281
|
/* No existing function for the proc with that signature, create a new one and cache it */
|
282
282
|
callback = rbffi_Function_NewInstance(rbFunctionInfo, proc);
|
283
283
|
if (cbref == Qnil) {
|
@@ -297,7 +297,7 @@ static VALUE
|
|
297
297
|
function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
298
298
|
{
|
299
299
|
Function* fn = NULL;
|
300
|
-
|
300
|
+
|
301
301
|
Data_Get_Struct(self, Function, fn);
|
302
302
|
|
303
303
|
fn->rbFunctionInfo = rbFunctionInfo;
|
@@ -342,7 +342,7 @@ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
|
|
342
342
|
rb_raise(rb_eTypeError, "wrong argument type %s, expected pointer or proc",
|
343
343
|
rb_obj_classname(rbProc));
|
344
344
|
}
|
345
|
-
|
345
|
+
|
346
346
|
fn->rbProc = rbProc;
|
347
347
|
|
348
348
|
return self;
|
@@ -402,7 +402,7 @@ function_attach(VALUE self, VALUE module, VALUE name)
|
|
402
402
|
rb_define_singleton_method(module, StringValueCStr(name),
|
403
403
|
rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
|
404
404
|
|
405
|
-
|
405
|
+
|
406
406
|
rb_define_method(module, StringValueCStr(name),
|
407
407
|
rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
|
408
408
|
|
@@ -452,10 +452,10 @@ function_release(VALUE self)
|
|
452
452
|
if (fn->closure == NULL) {
|
453
453
|
rb_raise(rb_eRuntimeError, "cannot free function which was not allocated");
|
454
454
|
}
|
455
|
-
|
455
|
+
|
456
456
|
rbffi_Closure_Free(fn->closure);
|
457
457
|
fn->closure = NULL;
|
458
|
-
|
458
|
+
|
459
459
|
return self;
|
460
460
|
}
|
461
461
|
|
@@ -463,13 +463,13 @@ static void
|
|
463
463
|
callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
|
464
464
|
{
|
465
465
|
struct gvl_callback cb = { 0 };
|
466
|
-
|
466
|
+
|
467
467
|
cb.closure = (Closure *) user_data;
|
468
468
|
cb.retval = retval;
|
469
469
|
cb.parameters = parameters;
|
470
470
|
cb.done = false;
|
471
471
|
cb.frame = rbffi_frame_current();
|
472
|
-
|
472
|
+
|
473
473
|
if (cb.frame != NULL) cb.frame->exc = Qnil;
|
474
474
|
if (cb.frame != NULL && cb.frame->has_gvl) {
|
475
475
|
callback_with_gvl(&cb);
|
@@ -651,14 +651,14 @@ async_cb_wait(void *data)
|
|
651
651
|
WaitForSingleObject(async_cb_cond, INFINITE);
|
652
652
|
EnterCriticalSection(&async_cb_lock);
|
653
653
|
}
|
654
|
-
|
654
|
+
|
655
655
|
if (async_cb_list != NULL) {
|
656
656
|
w->cb = async_cb_list;
|
657
657
|
async_cb_list = async_cb_list->next;
|
658
658
|
}
|
659
659
|
|
660
660
|
LeaveCriticalSection(&async_cb_lock);
|
661
|
-
|
661
|
+
|
662
662
|
return Qnil;
|
663
663
|
}
|
664
664
|
|
@@ -686,14 +686,14 @@ async_cb_wait(void *data)
|
|
686
686
|
while (!w->stop && async_cb_list == NULL) {
|
687
687
|
pthread_cond_wait(&async_cb_cond, &async_cb_mutex);
|
688
688
|
}
|
689
|
-
|
689
|
+
|
690
690
|
if (async_cb_list != NULL) {
|
691
691
|
w->cb = async_cb_list;
|
692
692
|
async_cb_list = async_cb_list->next;
|
693
693
|
}
|
694
694
|
|
695
695
|
pthread_mutex_unlock(&async_cb_mutex);
|
696
|
-
|
696
|
+
|
697
697
|
return Qnil;
|
698
698
|
}
|
699
699
|
|
@@ -713,9 +713,9 @@ static VALUE
|
|
713
713
|
async_cb_call(void *data)
|
714
714
|
{
|
715
715
|
struct gvl_callback* cb = (struct gvl_callback *) data;
|
716
|
-
|
716
|
+
|
717
717
|
callback_with_gvl(data);
|
718
|
-
|
718
|
+
|
719
719
|
/* Signal the original native thread that the ruby code has completed */
|
720
720
|
#ifdef _WIN32
|
721
721
|
SetEvent(cb->async_event);
|
@@ -835,8 +835,7 @@ invoke_callback(void* data)
|
|
835
835
|
}
|
836
836
|
|
837
837
|
rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
|
838
|
-
|
839
|
-
|
838
|
+
|
840
839
|
if (unlikely(returnType->nativeType == NATIVE_MAPPED)) {
|
841
840
|
VALUE values[] = { rbReturnValue, Qnil };
|
842
841
|
rbReturnValue = rb_funcall2(((MappedType *) returnType)->rbConverter, id_to_native, 2, values);
|
@@ -915,7 +914,7 @@ invoke_callback(void* data)
|
|
915
914
|
} else {
|
916
915
|
memset(retval, 0, returnType->ffiType->size);
|
917
916
|
}
|
918
|
-
|
917
|
+
|
919
918
|
} else {
|
920
919
|
memset(retval, 0, returnType->ffiType->size);
|
921
920
|
}
|
@@ -929,14 +928,14 @@ invoke_callback(void* data)
|
|
929
928
|
return Qnil;
|
930
929
|
}
|
931
930
|
|
932
|
-
static VALUE
|
931
|
+
static VALUE
|
933
932
|
save_callback_exception(void* data, VALUE exc)
|
934
933
|
{
|
935
934
|
struct gvl_callback* cb = (struct gvl_callback *) data;
|
936
|
-
|
935
|
+
|
937
936
|
memset(cb->retval, 0, ((Function *) cb->closure->info)->info->returnType->ffiType->size);
|
938
937
|
if (cb->frame != NULL) cb->frame->exc = exc;
|
939
|
-
|
938
|
+
|
940
939
|
return Qnil;
|
941
940
|
}
|
942
941
|
|
@@ -963,7 +962,7 @@ rbffi_Function_Init(VALUE moduleFFI)
|
|
963
962
|
* Document-class: FFI::Function < FFI::Pointer
|
964
963
|
*/
|
965
964
|
rbffi_FunctionClass = rb_define_class_under(moduleFFI, "Function", rbffi_PointerClass);
|
966
|
-
|
965
|
+
|
967
966
|
rb_global_variable(&rbffi_FunctionClass);
|
968
967
|
rb_define_alloc_func(rbffi_FunctionClass, function_allocate);
|
969
968
|
|
@@ -997,4 +996,3 @@ rbffi_Function_Init(VALUE moduleFFI)
|
|
997
996
|
async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
|
998
997
|
#endif
|
999
998
|
}
|
1000
|
-
|
data/ext/ffi_c/MethodHandle.c
CHANGED
@@ -228,9 +228,8 @@ custom_trampoline(int argc, VALUE* argv, VALUE self, Closure* handle)
|
|
228
228
|
{
|
229
229
|
FunctionType* fnInfo = (FunctionType *) handle->info;
|
230
230
|
VALUE rbReturnValue;
|
231
|
-
|
231
|
+
|
232
232
|
RB_GC_GUARD(rbReturnValue) = (*fnInfo->invoke)(argc, argv, handle->function, fnInfo);
|
233
|
-
RB_GC_GUARD_PTR(argv);
|
234
233
|
RB_GC_GUARD(self);
|
235
234
|
|
236
235
|
return rbReturnValue;
|
@@ -243,10 +242,10 @@ static VALUE custom_trampoline(caddr_t args, Closure*);
|
|
243
242
|
#define TRAMPOLINE_FUN_MAGIC (0xbeefcafe)
|
244
243
|
|
245
244
|
/*
|
246
|
-
* This is a hand-coded trampoline to
|
245
|
+
* This is a hand-coded trampoline to speed-up entry from ruby to the FFI translation
|
247
246
|
* layer for i386 arches.
|
248
247
|
*
|
249
|
-
* This does not make a
|
248
|
+
* This does not make a discernible difference vs a raw closure, so for now,
|
250
249
|
* it is not enabled.
|
251
250
|
*/
|
252
251
|
__asm__(
|
@@ -357,4 +356,3 @@ rbffi_MethodHandle_Init(VALUE module)
|
|
357
356
|
|
358
357
|
#endif
|
359
358
|
}
|
360
|
-
|
data/ext/ffi_c/Pointer.c
CHANGED
@@ -89,7 +89,7 @@ ptr_allocate(VALUE klass)
|
|
89
89
|
* @overload initialize(type, address)
|
90
90
|
* @param [Type] type type for pointer
|
91
91
|
* @param [Integer] address base address for pointer
|
92
|
-
* Create a new pointer from a {Type} and a base
|
92
|
+
* Create a new pointer from a {Type} and a base address
|
93
93
|
* @return [self]
|
94
94
|
* A new instance of Pointer.
|
95
95
|
*/
|
@@ -146,11 +146,11 @@ ptr_initialize(int argc, VALUE* argv, VALUE self)
|
|
146
146
|
* call-seq: ptr.initialize_copy(other)
|
147
147
|
* @param [Pointer] other source for cloning or dupping
|
148
148
|
* @return [self]
|
149
|
-
* @raise {RuntimeError} if +other+ is an unbounded memory area, or is
|
149
|
+
* @raise {RuntimeError} if +other+ is an unbounded memory area, or is unreadable/unwritable
|
150
150
|
* @raise {NoMemError} if failed to allocate memory for new object
|
151
151
|
* DO NOT CALL THIS METHOD.
|
152
152
|
*
|
153
|
-
* This method is internally used by #dup and #clone. Memory
|
153
|
+
* This method is internally used by #dup and #clone. Memory content is copied from +other+.
|
154
154
|
*/
|
155
155
|
static VALUE
|
156
156
|
ptr_initialize_copy(VALUE self, VALUE other)
|