2
2
var op = { } ;
3
3
var ffi = require ( 'ffi' ) ;
4
4
var ref = require ( 'ref' ) ;
5
+ const bignum = require ( 'bignum-browserify' ) ;
6
+
5
7
const Null = require ( './null.js' ) ;
8
+ const null_s = require ( './null_s.js' ) ;
6
9
exports . op = op ;
7
10
8
11
const ctypes = {
@@ -11,7 +14,10 @@ const ctypes = {
11
14
utf8str : ref . types . CString ,
12
15
} ;
13
16
14
- for ( let type of [ 'int' , 'short' , 'char' , 'uint' , 'ushort' , 'uchar' , 'double' , 'float' , 'longlong' ] ) {
17
+ const shortInts = { int : true , short : true , char : true , ushort : true , uchar : true } ;
18
+ const longInts = { uint : true , longlong : true } ;
19
+ const floats = { double : true , float : true } ;
20
+ for ( let type of Object . keys ( floats ) . concat ( Object . keys ( shortInts ) , Object . keys ( longInts ) ) ) {
15
21
ctypes [ type ] = ref . types [ type ] ;
16
22
}
17
23
@@ -30,6 +36,7 @@ op.buildnativecall = function(ctx, target, libname, symbol, convention, args, re
30
36
symbols [ symbol ] = [ mapType ( returns ) , args . array . map ( mapType ) ] ;
31
37
target . $$lib = ffi . Library ( libname === '' ? null : libname , symbols ) ; // eslint-disable-line new-cap
32
38
target . $$symbol = symbol ;
39
+ target . $$ret = returns . content . get ( 'type' ) . $$getStr ( ) ;
33
40
target . $$args = args . array . map ( arg => arg . content . get ( 'type' ) . $$getStr ( ) ) ;
34
41
} catch ( e ) {
35
42
throw new NQPException ( "native call exception:" + e ) ;
@@ -42,30 +49,55 @@ op.nativecall = function(returns, callObject, args) {
42
49
const type = callObject . $$args [ i ] ;
43
50
// HACK for cpointers not being done properly yet
44
51
const arg = type === 'cpointer' ? args . array [ i ] : args . array [ i ] . $$decont ( null ) ;
45
- if ( type === 'int' || type === 'short' || type === 'char' || type == 'ushort' || type == 'uchar' ) {
52
+ if ( type in shortInts ) {
46
53
mangled [ i ] = arg . $$getInt ( ) ;
47
- } else if ( type === 'longlong' || type == 'uint' ) {
54
+ } else if ( type in longInts ) {
48
55
if ( arg . $$getBignum ) {
49
56
mangled [ i ] = arg . $$getBignum ( ) . toString ( ) ;
50
57
} else {
51
58
mangled [ i ] = arg . $$getInt ( ) ;
52
59
}
53
- } else if ( type === 'float' || type === 'double' ) {
60
+ } else if ( type in floats ) {
54
61
mangled [ i ] = args . array [ i ] . $$decont ( null ) . $$getNum ( ) ;
55
62
} else if ( type === 'utf8str' ) {
56
63
mangled [ i ] = args . array [ i ] . $$decont ( null ) . $$getStr ( ) ;
57
64
} else if ( type === 'cpointer' ) {
58
- // TODO - do this properly
59
- mangled [ i ] = args . array [ i ] ;
65
+ mangled [ i ] = args . array [ i ] . $$decont ( null ) . $$getPointer ( ) ;
60
66
} else {
61
67
throw "can't mangle: " + callObject . $$args [ i ] ;
62
68
}
63
69
}
64
70
const ret = callObject . $$lib [ callObject . $$symbol ] . apply ( callObject . $$lib , mangled ) ;
65
- if ( ret === null ) {
71
+
72
+ if ( callObject . $$ret === 'void' ) {
66
73
return Null ;
74
+ } else if ( callObject . $$ret === 'utf8str' ) {
75
+ if ( ret === null ) {
76
+ return returns ;
77
+ } else {
78
+ const boxed = returns . _STable . REPR . allocate ( returns . _STable ) ;
79
+ boxed . $$setStr ( ret ) ;
80
+ return boxed ;
81
+ }
82
+ } else if ( callObject . $$ret === 'cpointer' ) {
83
+ const boxed = returns . _STable . REPR . allocate ( returns . _STable ) ;
84
+ boxed . $$setPointer ( ret ) ;
85
+ return boxed ;
86
+ } else if ( callObject . $$ret in shortInts ) {
87
+ const boxed = returns . _STable . REPR . allocate ( returns . _STable ) ;
88
+ boxed . $$setInt ( ret ) ;
89
+ return boxed ;
90
+ } else if ( callObject . $$ret in longInts ) {
91
+ const boxed = returns . _STable . REPR . allocate ( returns . _STable ) ;
92
+ boxed . $$setBignum ( bignum ( ret ) ) ;
93
+ return boxed ;
94
+ } else if ( callObject . $$ret in floats ) {
95
+ const boxed = returns . _STable . REPR . allocate ( returns . _STable ) ;
96
+ boxed . $$setNum ( ret ) ;
97
+ return boxed ;
67
98
} else {
68
- return ret ;
99
+ console . log ( 'returning ' , typeof callObject . $$ret , callObject . $$ret , shortInts , callObject . $$ret in shortInts ) ;
100
+ return ret === null ? Null : ret ;
69
101
}
70
102
} ;
71
103
0 commit comments