Skip to content

Commit

Permalink
lib: removed circular module references
Browse files Browse the repository at this point in the history
Closes #63.

Squashed commit of the following:

commit 58ffa8c
Author: Justin Freitag <justin.freitag@gmail.com>
Date:   Wed Jun 27 15:38:35 2012 +1000

    re-added comments

commit ca43c9d
Author: Justin Freitag <justin.freitag@gmail.com>
Date:   Wed Jun 27 15:34:25 2012 +1000

    removed vim swap file

commit acd10dd
Author: Justin Freitag <justin.freitag@gmail.com>
Date:   Wed Jun 27 15:31:49 2012 +1000

    removed duplicate LIB_EXT definition

commit 21094ff
Author: Justin Freitag <justin.freitag@gmail.com>
Date:   Wed Jun 27 15:08:57 2012 +1000

    changes

commit 078008a
Author: Justin Freitag <justin.freitag@gmail.com>
Date:   Wed Jun 27 15:07:44 2012 +1000

    restored public api

commit 765a7ac
Author: Justin Freitag <justin.freitag@gmail.com>
Date:   Wed Jun 27 14:47:21 2012 +1000

    changes

commit bb43242
Author: Justin Freitag <justin.freitag@gmail.com>
Date:   Wed Jun 27 14:45:57 2012 +1000

    changes

commit 466c543
Author: Justin Freitag <justin.freitag@gmail.com>
Date:   Wed Jun 27 13:01:13 2012 +1000

    removed circular module references
  • Loading branch information
justinfreitag authored and TooTallNate committed Jun 28, 2012
1 parent 90f033e commit 0a556e9
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 128 deletions.
3 changes: 1 addition & 2 deletions lib/_foreign_function.js
@@ -1,6 +1,5 @@

var ffi = require('./ffi')
, assert = require('assert')
var assert = require('assert')
, debug = require('debug')('ffi:_ForeignFunction')
, ref = require('ref')
, bindings = require('./bindings')
Expand Down
4 changes: 2 additions & 2 deletions lib/callback.js
@@ -1,5 +1,5 @@

var ffi = require('./ffi')
var CIF = require('./cif')
, assert = require('assert')
, ref = require('ref')
, debug = require('debug')('ffi:Callback')
Expand Down Expand Up @@ -31,7 +31,7 @@ function Callback (retType, types, abi, func) {
types = types.map(ref.coerceType)

// create the `ffi_cif *` instance
var cif = ffi.CIF(retType, types, abi)
var cif = CIF(retType, types, abi)
var argc = types.length

return _Callback(cif, retType.size, argc, function (retval, params) {
Expand Down
6 changes: 3 additions & 3 deletions lib/cif.js
@@ -1,5 +1,5 @@

var ffi = require('./ffi')
var Type = require('./type').Type
, assert = require('assert')
, debug = require('debug')('ffi:cif')
, ref = require('ref')
Expand Down Expand Up @@ -30,11 +30,11 @@ function CIF (rtype, types, abi) {

var numArgs = types.length
var _argtypesptr = new Buffer(numArgs * POINTER_SIZE)
var _rtypeptr = ffi.ffiType(rtype)
var _rtypeptr = Type(rtype)

for (var i = 0; i < numArgs; i++) {
var type = types[i]
var ffiType = ffi.ffiType(type)
var ffiType = Type(type)

_argtypesptr.writePointer(ffiType, i * POINTER_SIZE)
}
Expand Down
6 changes: 3 additions & 3 deletions lib/cif_var.js
@@ -1,5 +1,5 @@

var ffi = require('./ffi')
var Type = require('./type').Type
, assert = require('assert')
, debug = require('debug')('ffi:cif_var')
, ref = require('ref')
Expand Down Expand Up @@ -31,10 +31,10 @@ function CIF_var (rtype, types, numFixedArgs, abi) {

var numTotalArgs = types.length
var _argtypesptr = new Buffer(numTotalArgs * POINTER_SIZE)
var _rtypeptr = ffi.ffiType(rtype)
var _rtypeptr = Type(rtype)

for (var i = 0; i < numTotalArgs; i++) {
var ffiType = ffi.ffiType(types[i])
var ffiType = Type(types[i])
_argtypesptr.writePointer(ffiType, i * POINTER_SIZE)
}

Expand Down
10 changes: 5 additions & 5 deletions lib/dynamic_library.js
@@ -1,4 +1,4 @@
var ffi = require('./ffi')
var ForeignFunction = require('./foreign_function')
, assert = require('assert')
, debug = require('debug')('ffi:DynamicLibrary')
, bindings = require('./bindings')
Expand All @@ -9,10 +9,10 @@ var int = ref.types.int
, charPtr = ref.refType(ref.types.char)
, voidPtr = ref.refType(ref.types.void)

var dlopen = ffi.ForeignFunction(bindings.StaticFunctions.dlopen, voidPtr, [ charPtr, int ])
, dlclose = ffi.ForeignFunction(bindings.StaticFunctions.dlclose, int, [ voidPtr ])
, dlsym = ffi.ForeignFunction(bindings.StaticFunctions.dlsym, voidPtr, [ voidPtr, charPtr ])
, dlerror = ffi.ForeignFunction(bindings.StaticFunctions.dlerror, charPtr, [ ])
var dlopen = ForeignFunction(bindings.StaticFunctions.dlopen, voidPtr, [ charPtr, int ])
, dlclose = ForeignFunction(bindings.StaticFunctions.dlclose, int, [ voidPtr ])
, dlsym = ForeignFunction(bindings.StaticFunctions.dlsym, voidPtr, [ voidPtr, charPtr ])
, dlerror = ForeignFunction(bindings.StaticFunctions.dlerror, charPtr, [ ])

/**
* `DynamicLibrary` loads and fetches function pointers for dynamic libraries
Expand Down
13 changes: 7 additions & 6 deletions lib/errno.js
Expand Up @@ -6,20 +6,21 @@
* On Windows it's a method execution called `_errno`.
*/

var ffi = require('./ffi')
var DynamicLibrary = require('./dynamic_library')
, ForeignFunction = require('./foreign_function')
, ref = require('ref')
, errnoPtr = null
, int = ref.types.int
, intPtr = ref.refType(int)

if (process.platform == 'darwin' || process.platform == 'mac') {
var __error = ffi.DynamicLibrary().get('__error')
errnoPtr = ffi.ForeignFunction(__error, intPtr, [])
var __error = DynamicLibrary().get('__error')
errnoPtr = ForeignFunction(__error, intPtr, [])
} else if (process.platform == 'win32') {
var _errno = ffi.DynamicLibrary('msvcrt.dll').get('_errno')
errnoPtr = ffi.ForeignFunction(_errno, intPtr, [])
var _errno = DynamicLibrary('msvcrt.dll').get('_errno')
errnoPtr = ForeignFunction(_errno, intPtr, [])
} else { // linux, sunos, etc.
var errnoGlobal = ffi.DynamicLibrary().get('errno').reinterpret(int.size)
var errnoGlobal = DynamicLibrary().get('errno').reinterpret(int.size)
errnoPtr = function () { return errnoGlobal }
// set the errno type
errnoGlobal.type = int
Expand Down
102 changes: 13 additions & 89 deletions lib/ffi.js
@@ -1,30 +1,8 @@

var ref = require('ref')
var assert = require('assert')
var debug = require('debug')('ffi:ffi')
var Struct = require('ref-struct')
var bindings = require('./bindings')
var ffi = exports

/**
* The extension to use on libraries.
* i.e. libm -> libm.so on linux
*/

Object.defineProperty(ffi, 'LIB_EXT', {
configurable: true
, enumerable: true
, writable: false
, value: {
'linux': '.so'
, 'linux2': '.so'
, 'sunos': '.so'
, 'solaris':'.so'
, 'darwin': '.dylib'
, 'mac': '.dylib'
, 'win32': '.dll'
}[process.platform]
})

/**
* Export some of the properties from the "bindings" file.
Expand All @@ -38,7 +16,7 @@ Object.defineProperty(ffi, 'LIB_EXT', {
return debug('skipping exporting of non-existant property: %s', prop)
}
var desc = Object.getOwnPropertyDescriptor(bindings, prop)
Object.defineProperty(ffi, prop, desc)
Object.defineProperty(exports, prop, desc)
})

/**
Expand Down Expand Up @@ -82,72 +60,18 @@ switch (ref.sizeof.long) {
* Alias the "ref" types onto ffi's exports, for convenience...
*/

ffi.types = ref.types


/**
* Returns a `ffi_type *` Buffer appropriate for the given "type".
*/

ffi.ffiType = function ffiType (type) {
debug('ffiType()', type.name || type)
type = ref.coerceType(type)
assert(type.indirection >= 1, 'invalid "type" given: ' + (type.name || type))
var rtn
if (type.indirection === 1) {
rtn = type.ffi_type
} else {
rtn = bindings.FFI_TYPES.pointer
}

if (!rtn && type.fields) {
// got a "ref-struct" type
// need to create the `ffi_type` instance manually
debug('creating an `ffi_type` for given "ref-struct" type')
var props = type.fields
, propNames = Object.keys(props)
, numProps = propNames.length
var t = new ffi.FFI_TYPE
t.size = 0
t.alignment = 0
t.type = 13 // FFI_TYPE_STRUCT
var elementsSize = ref.sizeof.pointer * (numProps + 1) // +1 because of the NULL terminator
var elements = t.elements = new Buffer(elementsSize)
for (var i = 0; i < numProps; i++) {
var prop = props[propNames[i]]
elements.writePointer(ffi.ffiType(prop.type), i * ref.sizeof.pointer)
}
// final NULL pointer to terminate the Array
elements.writePointer(ref.NULL, i * ref.sizeof.pointer)
// also set the `ffi_type` property to that it's cached for next time
rtn = type.ffi_type = t.ref()
}
assert(rtn, 'Could not determine the `ffi_type` instance for type: ' + (type.name || type))
debug('returning `ffi_type`', rtn.name)
return rtn
}

exports.types = ref.types

// Include our other modules
ffi.CIF = require('./cif')
ffi.CIF_var = require('./cif_var')
ffi.ForeignFunction = require('./foreign_function')
ffi.VariadicForeignFunction = require('./foreign_function_var')
ffi.DynamicLibrary = require('./dynamic_library')
ffi.Library = require('./library')
ffi.Callback = require('./callback')
ffi.errno = require('./errno')

/**
* Define the `ffi_type` struct (see deps/libffi/include/ffi.h) for use in JS.
* This struct type is used internally to define custom struct rtn/arg types.
*/
exports.CIF = require('./cif')
exports.CIF_var = require('./cif_var')
exports.ForeignFunction = require('./foreign_function')
exports.VariadicForeignFunction = require('./foreign_function_var')
exports.DynamicLibrary = require('./dynamic_library')
exports.Library = require('./library').Library
exports.LIB_EXT = require('./library').LIB_EXT
exports.Callback = require('./callback')
exports.errno = require('./errno')
exports.ffiType = require('./type').Type
exports.FFI_TYPE = require('./type').FFI_TYPE

ffi.FFI_TYPE = Struct()
ffi.FFI_TYPE.defineProperty('size', ref.types.size_t)
ffi.FFI_TYPE.defineProperty('alignment', ref.types.ushort)
ffi.FFI_TYPE.defineProperty('type', ref.types.ushort)
// this last prop is a C Array of `ffi_type *` elements, so this is `ffi_type **`
var ffi_type_ptr_array = ref.refType(ref.refType(ffi.FFI_TYPE))
ffi.FFI_TYPE.defineProperty('elements', ffi_type_ptr_array)
assert.equal(bindings.FFI_TYPE_SIZE, ffi.FFI_TYPE.size)
4 changes: 2 additions & 2 deletions lib/foreign_function.js
@@ -1,5 +1,5 @@

var ffi = require('./ffi')
var CIF = require('./cif')
, _ForeignFunction = require('./_foreign_function')
, debug = require('debug')('ffi:ForeignFunction')
, assert = require('assert')
Expand All @@ -26,7 +26,7 @@ function ForeignFunction (funcPtr, returnType, argTypes, abi) {
argTypes = argTypes.map(ref.coerceType)

// create the `ffi_cif *` instance
var cif = ffi.CIF(returnType, argTypes, abi)
var cif = CIF(returnType, argTypes, abi)

// create and return the JS proxy function
return _ForeignFunction(cif, funcPtr, returnType, argTypes)
Expand Down
11 changes: 6 additions & 5 deletions lib/foreign_function_var.js
@@ -1,5 +1,6 @@

var ffi = require('./ffi')
var CIF_var = require('./cif_var')
, Type = require('./type').Type
, _ForeignFunction = require('./_foreign_function')
, assert = require('assert')
, debug = require('debug')('ffi:VariadicForeignFunction')
Expand Down Expand Up @@ -36,7 +37,7 @@ function VariadicForeignFunction (funcPtr, returnType, fixedArgTypes, abi) {

// get the names of the fixed arg types
var fixedKey = fixedArgTypes.map(function (type) {
var ffi_type = ffi.ffiType(type)
var ffi_type = Type(type)
assert(ffi_type.name)
return ffi_type.name
})
Expand All @@ -55,14 +56,14 @@ function VariadicForeignFunction (funcPtr, returnType, fixedArgTypes, abi) {
var type = ref.coerceType(arguments[i])
argTypes.push(type)

var ffi_type = ffi.ffiType(type)
var ffi_type = Type(type)
assert(ffi_type.name)
key.push(ffi_type.name)
}

// now figure out the return type
var rtnType = ref.coerceType(variadic_function_generator.returnType)
var rtnName = ffi.ffiType(rtnType).name
var rtnName = Type(rtnType).name
assert(rtnName)

// first let's generate the key and see if we got a cache-hit
Expand All @@ -74,7 +75,7 @@ function VariadicForeignFunction (funcPtr, returnType, fixedArgTypes, abi) {
} else {
// create the `ffi_cif *` instance
debug('creating the variadic ffi_cif instance for key:', key)
var cif = ffi.CIF_var(returnType, argTypes, numFixedArgs, abi)
var cif = CIF_var(returnType, argTypes, numFixedArgs, abi)
func = cache[key] = _ForeignFunction(cif, funcPtr, rtnType, argTypes)
}
return func
Expand Down
46 changes: 35 additions & 11 deletions lib/library.js
@@ -1,24 +1,49 @@
/**
* The extension to use on libraries.
* i.e. libm -> libm.so on linux
*/

var ffi = require('./ffi')
var DynamicLibrary = require('./dynamic_library')
, ForeignFunction = require('./foreign_function')
, VariadicForeignFunction = require('./foreign_function_var')
, debug = require('debug')('ffi:Library')
, EXT = ffi.LIB_EXT
, RTLD_NOW = ffi.DynamicLibrary.FLAGS.RTLD_NOW
, RTLD_NOW = DynamicLibrary.FLAGS.RTLD_NOW

/**
* The extension to use on libraries.
* i.e. libm -> libm.so on linux
*/

Object.defineProperty(exports, 'LIB_EXT', {
configurable: true
, enumerable: true
, writable: false
, value: {
'linux': '.so'
, 'linux2': '.so'
, 'sunos': '.so'
, 'solaris':'.so'
, 'darwin': '.dylib'
, 'mac': '.dylib'
, 'win32': '.dll'
}[process.platform]
})

/**
* Provides a friendly abstraction/API on-top of DynamicLibrary and
* ForeignFunction.
*/

function Library (libfile, funcs) {
exports.Library = function Library (libfile, funcs) {
debug('creating Library object for', libfile)

if (libfile && libfile.indexOf(EXT) === -1) {
debug('appending library extension to library name', EXT)
libfile += EXT
if (libfile && libfile.indexOf(exports.LIB_EXT) === -1) {
debug('appending library extension to library name', exports.LIB_EXT)
libfile += exports.LIB_EXT
}

var lib = {}
var dl = new ffi.DynamicLibrary(libfile || null, RTLD_NOW)
var dl = new DynamicLibrary(libfile || null, RTLD_NOW)

Object.keys(funcs || {}).forEach(function (func) {
debug('defining function', func)
Expand All @@ -39,13 +64,12 @@ function Library (libfile, funcs) {
, varargs = fopts && fopts.varargs

if (varargs) {
lib[func] = ffi.VariadicForeignFunction(fptr, resultType, paramTypes, abi)
lib[func] = VariadicForeignFunction(fptr, resultType, paramTypes, abi)
} else {
var ff = ffi.ForeignFunction(fptr, resultType, paramTypes, abi)
var ff = ForeignFunction(fptr, resultType, paramTypes, abi)
lib[func] = async ? ff.async : ff
}
})

return lib
}
module.exports = Library

0 comments on commit 0a556e9

Please sign in to comment.