function.js
2.5 KB
1
2
3
4
5
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
46
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* Module dependencies.
*/
var ref = require('ref')
, assert = require('assert')
, bindings = require('./bindings')
, Callback = require('./callback')
, ForeignFunction = require('./foreign_function')
, debug = require('debug')('ffi:FunctionType')
/**
* Module exports.
*/
module.exports = Function
/**
* Creates and returns a "type" object for a C "function pointer".
*
* @api public
*/
function Function (retType, argTypes, abi) {
if (!(this instanceof Function)) {
return new Function(retType, argTypes, abi)
}
debug('creating new FunctionType')
// check args
assert(!!retType, 'expected a return "type" object as the first argument')
assert(Array.isArray(argTypes), 'expected Array of arg "type" objects as the second argument')
// normalize the "types" (they could be strings, so turn into real type
// instances)
this.retType = ref.coerceType(retType)
this.argTypes = argTypes.map(ref.coerceType)
this.abi = null == abi ? bindings.FFI_DEFAULT_ABI : abi
}
/**
* The "ffi_type" is set for node-ffi functions.
*/
Function.prototype.ffi_type = bindings.FFI_TYPES.pointer
/**
* The "size" is always pointer-sized.
*/
Function.prototype.size = ref.sizeof.pointer
/**
* The "alignment" is always pointer-aligned.
*/
Function.prototype.alignment = ref.alignof.pointer
/**
* The "indirection" is always 1 to ensure that our get()/set() get called.
*/
Function.prototype.indirection = 1
/**
* Returns a ffi.Callback pointer (Buffer) of this function type for the
* given `fn` Function.
*/
Function.prototype.toPointer = function toPointer (fn) {
return Callback(this.retType, this.argTypes, this.abi, fn)
}
/**
* Returns a ffi.ForeignFunction (Function) of this function type for the
* given `buf` Buffer.
*/
Function.prototype.toFunction = function toFunction (buf) {
return ForeignFunction(buf, this.retType, this.argTypes, this.abi)
}
/**
* get function; return a ForeignFunction instance.
*/
Function.prototype.get = function get (buffer, offset) {
debug('ffi FunctionType "get" function')
var ptr = buffer.readPointer(offset)
return this.toFunction(ptr)
}
/**
* set function; return a Callback buffer.
*/
Function.prototype.set = function set (buffer, offset, value) {
debug('ffi FunctionType "set" function')
var ptr
if ('function' == typeof value) {
ptr = this.toPointer(value)
} else if (Buffer.isBuffer(value)) {
ptr = value
} else {
throw new Error('don\'t know how to set callback function for: ' + value)
}
buffer.writePointer(ptr, offset)
}