@@ -146,6 +146,13 @@ function CFuncType(restype, args) {
146
146
return ( pointer ) => ffi . ForeignFunction ( pointer , restype , args ) ;
147
147
}
148
148
149
+ /**
150
+ * Wrapper of ffi.Callback to distingish a function type in `bind_state`.
151
+ */
152
+ function FuncSymbol ( restype , args , f ) {
153
+ this . cb = ffi . Callback ( restype , args , f ) ;
154
+ }
155
+
149
156
/**
150
157
* Create a C code object to be used with InlineGenerator.
151
158
*/
@@ -229,44 +236,29 @@ InlineGenerator.prototype.bind_state = function(state) {
229
236
} ;
230
237
231
238
/**
232
- * Wrapper of ffi.Callback to distingish a function type in `bind_state` .
239
+ * Helper function to create c declarations .
233
240
*/
234
- function FuncSymbol ( restype , args , f ) {
235
- this . cb = ffi . Callback ( restype , args , f ) ;
236
- }
237
-
238
- /**
239
- * Convenvient function to import a function symbol from JS to C code.
240
- */
241
- function c_callable ( restype , name , args , f ) {
242
- return new Declaration (
243
- '' ,
244
- `${ restype } (*${ name } )(${ args . join ( ', ' ) } ) = 0;` ,
245
- [ [ new FuncSymbol ( restype , args , f ) , name ] ]
246
- ) ;
247
- }
248
-
241
+ // build postfix token list
249
242
function _postfix ( res , type ) {
250
- type = ref . coerceType ( type ) ;
251
- let typename = type . name ;
252
- while ( typename . endsWith ( '*' ) ) {
253
- res . push ( '*' ) ;
254
- typename = typename . slice ( 0 , - 1 ) ;
255
- }
256
- if ( typename === 'StructType' ) {
257
- if ( ! type . prototype . _name )
258
- throw new Error ( 'unkown C name for type ' + typename ) ;
259
- res . push ( `struct ${ type . prototype . _name } ` ) ;
260
- } else if ( typename === 'ArrayType' ) {
261
- res . push ( `${ '[' + ( type . fixedLength || '' ) + ']' } ` ) ;
262
- _postfix ( res , type . type ) ;
263
- } else
264
- res . push ( typename ) ;
265
- return res ;
243
+ type = ref . coerceType ( type ) ;
244
+ let typename = type . name ;
245
+ while ( typename . endsWith ( '*' ) ) {
246
+ res . push ( '*' ) ;
247
+ typename = typename . slice ( 0 , - 1 ) ;
248
+ }
249
+ if ( typename === 'StructType' ) {
250
+ if ( ! type . prototype . _name )
251
+ throw new Error ( 'unkown C name for type ' + typename ) ;
252
+ res . push ( `struct ${ type . prototype . _name } ` ) ;
253
+ } else if ( typename === 'ArrayType' ) {
254
+ res . push ( `${ '[' + ( type . fixedLength || '' ) + ']' } ` ) ;
255
+ _postfix ( res , type . type ) ;
256
+ } else
257
+ res . push ( typename ) ;
258
+ return res ;
266
259
}
267
-
268
- // create full c declaration for parameters and struct members
269
- function _cdecl ( varname , type ) {
260
+ // create c declarations for parameters and struct members
261
+ function _var_decl ( varname , type ) {
270
262
let pf = _postfix ( [ varname ] , type ) ;
271
263
let s = pf . shift ( ) ;
272
264
while ( pf . length > 1 ) {
@@ -279,29 +271,47 @@ function _cdecl(varname, type) {
279
271
}
280
272
return `${ pf . shift ( ) } ${ s } ` ;
281
273
}
282
-
283
- // helper to resolve C names for restype
274
+ // construct function declarations
275
+ function _func_decl ( restype , name , args , pointer = false ) {
276
+ let vars = '' ;
277
+ if ( args . length )
278
+ vars = ( args [ 0 ] instanceof Array )
279
+ ? args . map ( ( [ type , varname ] ) => _var_decl ( varname , type ) ) . join ( ', ' )
280
+ : args . map ( ( type ) => _var_decl ( '' , type ) ) . join ( ', ' ) ;
281
+ return `${ _restype ( restype ) } ` + ( ( pointer ) ? `(*${ name } )` : name ) + `(${ vars } )` ;
282
+ }
283
+ // resolve C names for restype
284
284
function _restype ( type ) {
285
- type = ref . coerceType ( type ) ;
286
- let typename = type . name ;
287
- if ( typename . startsWith ( 'StructType' ) ) {
288
- if ( ! type . prototype . _name )
289
- throw new Error ( 'unkown C name for type ' + type ) ;
290
- typename = `struct ${ typename . replace ( 'StructType' , type . prototype . _name ) } ` ;
291
- } else if ( typename . startsWith ( 'ArrayType' ) ) {
292
- throw new Error ( 'ArrayType not allowed as restype' ) ;
293
- }
294
- return typename ;
285
+ type = ref . coerceType ( type ) ;
286
+ let typename = type . name ;
287
+ if ( typename . startsWith ( 'StructType' ) ) {
288
+ if ( ! type . prototype . _name )
289
+ throw new Error ( 'unkown C name for type ' + type ) ;
290
+ typename = `struct ${ typename . replace ( 'StructType' , type . prototype . _name ) } ` ;
291
+ } else if ( typename . startsWith ( 'ArrayType' ) ) {
292
+ throw new Error ( 'ArrayType not allowed as restype' ) ;
293
+ }
294
+ return typename ;
295
+ }
296
+
297
+ /**
298
+ * Convenvient function to import a function symbol from JS to C code.
299
+ */
300
+ function c_callable ( restype , name , args , f ) {
301
+ return new Declaration (
302
+ '' ,
303
+ _func_decl ( restype , name , args , true ) + ' = 0;' ,
304
+ [ [ new FuncSymbol ( restype , args , f ) , name ] ]
305
+ ) ;
295
306
}
296
307
297
308
/**
298
309
* Convenient function to create a C function useable from JS.
299
310
*/
300
311
function c_function ( restype , name , args , code ) {
301
- let header = `${ _restype ( restype ) } ${ name } ` ;
302
- header += `(${ args . map ( ( [ type , varname ] ) => _cdecl ( varname , type ) ) . join ( ', ' ) } )` ;
312
+ let header = _func_decl ( restype , name , args ) ;
303
313
let declaration = new Declaration (
304
- header + ` \n{\n${ code } \n}\n`,
314
+ ` ${ header } \n{\n${ code } \n}\n`,
305
315
header + ';' ,
306
316
[ [ CFuncType ( restype , args . map ( ( [ type , _ ] ) => type ) ) , name ] ]
307
317
) ;
@@ -329,7 +339,7 @@ function c_struct(name, structType) {
329
339
} ) ;
330
340
let members = fields . map (
331
341
// FIXME: need to declare member alignment?
332
- ( el ) => ` ${ _cdecl ( el , structType . fields [ el ] . type ) } ;`
342
+ ( el ) => ` ${ _var_decl ( el , structType . fields [ el ] . type ) } ;`
333
343
) . join ( '\n' ) ;
334
344
return `struct __attribute__((aligned(${ structType . alignment } ))) ${ name } {\n${ members } \n};` ;
335
345
} ,
@@ -347,4 +357,5 @@ module.exports.Declaration = Declaration;
347
357
module . exports . c_function = c_function ;
348
358
module . exports . c_callable = c_callable ;
349
359
module . exports . c_struct = c_struct ;
350
- module . exports . _cdecl = _cdecl ;
360
+ module . exports . _var_decl = _var_decl ;
361
+ module . exports . _func_decl = _func_decl ;
0 commit comments