Skip to content

Commit 57453ad

Browse files
committed
[js] Support returning simple values from native calls
1 parent 08c9653 commit 57453ad

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

src/vm/js/nqp-runtime/nativecall.js

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
var op = {};
33
var ffi = require('ffi');
44
var ref = require('ref');
5+
const bignum = require('bignum-browserify');
6+
57
const Null = require('./null.js');
8+
const null_s = require('./null_s.js');
69
exports.op = op;
710

811
const ctypes = {
@@ -11,7 +14,10 @@ const ctypes = {
1114
utf8str: ref.types.CString,
1215
};
1316

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))) {
1521
ctypes[type] = ref.types[type];
1622
}
1723

@@ -30,6 +36,7 @@ op.buildnativecall = function(ctx, target, libname, symbol, convention, args, re
3036
symbols[symbol] = [mapType(returns), args.array.map(mapType)];
3137
target.$$lib = ffi.Library(libname === '' ? null : libname, symbols); // eslint-disable-line new-cap
3238
target.$$symbol = symbol;
39+
target.$$ret = returns.content.get('type').$$getStr();
3340
target.$$args = args.array.map(arg => arg.content.get('type').$$getStr());
3441
} catch (e) {
3542
throw new NQPException("native call exception:" + e);
@@ -42,30 +49,55 @@ op.nativecall = function(returns, callObject, args) {
4249
const type = callObject.$$args[i];
4350
// HACK for cpointers not being done properly yet
4451
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) {
4653
mangled[i] = arg.$$getInt();
47-
} else if (type === 'longlong' || type == 'uint') {
54+
} else if (type in longInts) {
4855
if (arg.$$getBignum) {
4956
mangled[i] = arg.$$getBignum().toString();
5057
} else {
5158
mangled[i] = arg.$$getInt();
5259
}
53-
} else if (type === 'float' || type === 'double') {
60+
} else if (type in floats) {
5461
mangled[i] = args.array[i].$$decont(null).$$getNum();
5562
} else if (type === 'utf8str') {
5663
mangled[i] = args.array[i].$$decont(null).$$getStr();
5764
} else if (type === 'cpointer') {
58-
// TODO - do this properly
59-
mangled[i] = args.array[i];
65+
mangled[i] = args.array[i].$$decont(null).$$getPointer();
6066
} else {
6167
throw "can't mangle: " + callObject.$$args[i];
6268
}
6369
}
6470
const ret = callObject.$$lib[callObject.$$symbol].apply(callObject.$$lib, mangled);
65-
if (ret === null) {
71+
72+
if (callObject.$$ret === 'void') {
6673
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;
6798
} else {
68-
return ret;
99+
console.log('returning ', typeof callObject.$$ret, callObject.$$ret, shortInts, callObject.$$ret in shortInts);
100+
return ret === null ? Null : ret;
69101
}
70102
};
71103

src/vm/js/nqp-runtime/reprs.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,19 @@ class NativeCall extends REPR {
14741474
};
14751475
reprs.NativeCall = NativeCall;
14761476

1477-
class CPointer extends REPR {};
1477+
class CPointer extends REPR {
1478+
setupSTable(STable) {
1479+
STable.addInternalMethods(class {
1480+
$$setPointer(value) {
1481+
this.$$pointer = value;
1482+
}
1483+
1484+
$$getPointer() {
1485+
return this.$$pointer;
1486+
}
1487+
});
1488+
}
1489+
};
14781490
reprs.CPointer = CPointer;
14791491

14801492
class AsyncTask extends REPR {};

0 commit comments

Comments
 (0)