'use strict'; /** * Module dependencies. */ const ref = require('ref-napi'); const assert = require('assert'); const debug = require('debug')('ffi:ffi'); const Struct = require('ref-struct-di')(ref); const bindings = require('./bindings'); /** * Export some of the properties from the "bindings" file. */ ['FFI_TYPES', 'FFI_OK', 'FFI_BAD_TYPEDEF', 'FFI_BAD_ABI', 'FFI_DEFAULT_ABI', 'FFI_FIRST_ABI', 'FFI_LAST_ABI', 'FFI_SYSV', 'FFI_UNIX64', 'FFI_WIN64', 'FFI_VFP', 'FFI_STDCALL', 'FFI_THISCALL', 'FFI_FASTCALL', 'RTLD_LAZY', 'RTLD_NOW', 'RTLD_LOCAL', 'RTLD_GLOBAL', 'RTLD_NOLOAD', 'RTLD_NODELETE', 'RTLD_FIRST', 'RTLD_NEXT', 'RTLD_DEFAULT', 'RTLD_SELF', 'RTLD_MAIN_ONLY', 'FFI_MS_CDECL'].forEach(prop => { if (!bindings.hasOwnProperty(prop)) { return debug('skipping exporting of non-existant property', prop); } const desc = Object.getOwnPropertyDescriptor(bindings, prop); Object.defineProperty(exports, prop, desc); }); /** * Set the `ffi_type` property on the built-in types. */ Object.keys(bindings.FFI_TYPES).forEach(name => { const type = bindings.FFI_TYPES[name]; type.name = name; if (name === 'pointer') return; // there is no "pointer" type... ref.types[name].ffi_type = type; }); // make `size_t` use the "ffi_type_pointer" ref.types.size_t.ffi_type = bindings.FFI_TYPES.pointer; // make `Utf8String` use "ffi_type_pointer" const CString = ref.types.CString || ref.types.Utf8String; CString.ffi_type = bindings.FFI_TYPES.pointer; // make `Object` use the "ffi_type_pointer" ref.types.Object.ffi_type = bindings.FFI_TYPES.pointer; // libffi is weird when it comes to long data types (defaults to 64-bit), // so we emulate here, since some platforms have 32-bit longs and some // platforms have 64-bit longs. switch (ref.sizeof.long) { case 4: ref.types.ulong.ffi_type = bindings.FFI_TYPES.uint32; ref.types.long.ffi_type = bindings.FFI_TYPES.int32; break; case 8: ref.types.ulong.ffi_type = bindings.FFI_TYPES.uint64; ref.types.long.ffi_type = bindings.FFI_TYPES.int64; break; default: throw new Error('unsupported "long" size: ' + ref.sizeof.long); } /** * Alias the "ref" types onto ffi's exports, for convenience... */ exports.types = ref.types; // Include our other modules exports.version = bindings.version; exports.CIF = require('./cif'); exports.CIF_var = require('./cif_var'); exports.Function = require('./function'); exports.ForeignFunction = require('./foreign_function'); exports.VariadicForeignFunction = require('./foreign_function_var'); exports.DynamicLibrary = require('./dynamic_library'); exports.Library = require('./library'); exports.Callback = require('./callback'); exports.errno = require('./errno'); exports.ffiType = require('./type'); // the shared library extension for this platform exports.LIB_EXT = exports.Library.EXT; // the FFI_TYPE struct definition exports.FFI_TYPE = exports.ffiType.FFI_TYPE;