@@ -72,8 +72,9 @@ let wchar_t = null;
72
72
try {
73
73
wchar_t = require ( 'ref-wchar' ) ;
74
74
const Iconv = require ( 'iconv' ) . Iconv ;
75
- const wchar_set = new Iconv ( 'UTF-8' , 'UTF-16' + ref . endianness ) . convert ;
76
- const wchar_get = new Iconv ( 'UTF-16' + ref . endianness , 'UTF-8' ) . convert ;
75
+ let encoding = ( ( process . platform === 'win32' ) ? 'UTF-16' : 'UTF-32' ) + ref . endianness ;
76
+ const wchar_set = new Iconv ( 'UTF-8' , encoding ) . convert ;
77
+ const wchar_get = new Iconv ( encoding , 'UTF-8' ) . convert ;
77
78
78
79
// monkey patch broken wchar_t.toString
79
80
wchar_t . toString = ( buffer ) => {
@@ -373,24 +374,27 @@ function DefaultTcc() {
373
374
}
374
375
375
376
/**
376
- * Wrapper for lazy evaluation of a ffi.ForeignFunction.
377
- * This is needed to postpone the creation of a ffi.ForeignFunction
377
+ * Wrapper for lazy evaluation of a ffi.ForeignFunction or ffi.VariadicForeignFunction .
378
+ * This is needed to postpone the creation of the ffi function
378
379
* until we got the real C symbol pointer.
379
380
* @param {string|object } restype - known type of `ref.types`
380
- * @param {array } args - array of parameter types
381
+ * @param {Array } args - array of parameter types
382
+ * @param {boolean= } variadic - indicate a variadic function
381
383
* @return {function(ref.ref) : ffi.ForeignFunction }
382
384
* @function module:node-tinycc.CFuncType
383
385
*/
384
- function CFuncType ( restype , args ) {
385
- return ( pointer ) => ffi . ForeignFunction ( pointer , restype , args ) ;
386
+ function CFuncType ( restype , args , variadic ) {
387
+ return ( pointer ) => ( variadic )
388
+ ? ffi . VariadicForeignFunction ( pointer , restype , args )
389
+ : ffi . ForeignFunction ( pointer , restype , args ) ;
386
390
}
387
391
388
392
/**
389
393
* Internal wrapper for ffi.Callback to distingish a function type in
390
394
* `CodeGenerator.bindState`. It also holds a reference of
391
395
* the callback to avoid early garbage collection.
392
396
* @param {string|object } restype - known type of `ref.types`
393
- * @param {array } args - array of parameter types
397
+ * @param {Array } args - array of parameter types
394
398
* @param {function } f - callback function
395
399
* @constructor module:node-tinycc.FuncSymbol
396
400
*/
@@ -427,7 +431,7 @@ function FuncSymbol(restype, args, f) {
427
431
* @param {string|function } code - C source as string or a function
428
432
* returning the source code string
429
433
* @param {string= } forward - optional forward declaration
430
- * @param {array = } symbols - optional array of [type, symbol name]
434
+ * @param {Array = } symbols - optional array of [type, symbol name]
431
435
* to be autoresolved by the generator
432
436
* @return {Declaration }
433
437
* @constructor module:node-tinycc.Declaration
@@ -469,7 +473,7 @@ function Declaration(code, forward, symbols) {
469
473
* );
470
474
* gen.addDeclaration(
471
475
* tcc.Declaration(
472
- * 'void func() { printf("Hello World!\n"); }',
476
+ * 'void func() { printf("Hello World!\\ n"); }',
473
477
* 'void func();',
474
478
* [[tcc.CFuncType('void', []), 'func']]
475
479
* )
@@ -633,7 +637,7 @@ CodeGenerator.prototype.addTopDeclaration = function(decl) {
633
637
* corresponding type.
634
638
*
635
639
* @param {Tcc } state - state to bind to symbols
636
- * @return {object }
640
+ * @return {Object }
637
641
* @method module:node-tinycc.CodeGenerator#bindState
638
642
*/
639
643
CodeGenerator . prototype . bindState = function ( state ) {
@@ -725,19 +729,22 @@ function _restype(type) {
725
729
726
730
/**
727
731
* Helper to create full C function declarations.
728
- * @param restype
729
- * @param name
730
- * @param args
731
- * @param pointer
732
+ * @param {string|Object } restype
733
+ * @param {string } name
734
+ * @param {Array } args
735
+ * @param {boolean= } varargs
736
+ * @param {boolean= } pointer
732
737
* @return {string }
733
738
* @private
734
739
*/
735
- function _func_decl ( restype , name , args , pointer ) {
740
+ function _func_decl ( restype , name , args , varargs , pointer ) {
736
741
let vars = '' ;
737
742
if ( args . length )
738
743
vars = ( args [ 0 ] instanceof Array )
739
744
? args . map ( ( [ type , varname ] ) => _var_decl ( varname , type ) ) . join ( ', ' )
740
745
: args . map ( ( type ) => _var_decl ( '' , type ) ) . join ( ', ' ) ;
746
+ if ( varargs )
747
+ vars += ', ...' ;
741
748
return `${ _restype ( restype ) } ` + ( ( pointer ) ? `(*${ name } )` : name ) + `(${ vars } )` ;
742
749
}
743
750
@@ -755,17 +762,17 @@ function _func_decl(restype, name, args, pointer) {
755
762
* gen.addDeclaration(decl);
756
763
* ...
757
764
* ```
758
- * @param {string|object } restype - known type of `ref.types`
765
+ * @param {string|Object } restype - known type of `ref.types`
759
766
* @param {string } name - function pointer name
760
- * @param {array } args - array of parameter types
767
+ * @param {Array } args - array of parameter types
761
768
* @param {function } f - Javascript function
762
769
* @return {Declaration }
763
770
* @function module:node-tinycc.c_callable
764
771
*/
765
772
function c_callable ( restype , name , args , f ) {
766
773
return new Declaration (
767
774
'' ,
768
- _func_decl ( restype , name , args , true ) + ' = 0;' ,
775
+ _func_decl ( restype , name , args , false , true ) + ' = 0;' ,
769
776
[ [ new FuncSymbol ( restype , args , f ) , name ] ]
770
777
) ;
771
778
}
@@ -798,19 +805,25 @@ function c_callable(restype, name, args, f) {
798
805
* gen.bindState(state);
799
806
* console.log(add(23, 42)); // use it
800
807
* ```
801
- * @param {string|object } restype - known type of `ref.types`
808
+ * @param {string|Object } restype - known type of `ref.types`
802
809
* @param {string } name - function pointer name
803
- * @param {array } args - array of [type, parameter name]
810
+ * @param {Array } args - array of [type, parameter name]
804
811
* @param {string } code - C function body
805
812
* @return {func } proxy function
806
813
* @function module:node-tinycc.c_function
807
814
*/
808
815
function c_function ( restype , name , args , code ) {
809
- let header = _func_decl ( restype , name , args ) ;
816
+ let last_arg = args . pop ( ) ;
817
+ let varargs = (
818
+ last_arg && last_arg === '...'
819
+ || ( last_arg instanceof Array && last_arg . length === 1 && last_arg [ 0 ] === '...' ) ) ;
820
+ if ( last_arg && ! varargs )
821
+ args . push ( last_arg ) ;
822
+ let header = _func_decl ( restype , name , args , varargs ) ;
810
823
let declaration = new Declaration (
811
824
`${ header } \n{\n${ code || '' } \n}\n` ,
812
825
header + ';' ,
813
- [ [ CFuncType ( restype , args . map ( ( [ type , _ ] ) => type ) ) , name ] ]
826
+ [ [ CFuncType ( restype , args . map ( ( [ type , _ ] ) => type ) , varargs ) , name ] ]
814
827
) ;
815
828
let func = function ( ) {
816
829
if ( func . declaration . symbols_resolved [ name ] )
0 commit comments