Skip to content

Commit 85f3dd3

Browse files
committed
fix and test declaration creation
1 parent 9463c60 commit 85f3dd3

File tree

5 files changed

+187
-80
lines changed

5 files changed

+187
-80
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Run inline C code on the fly.
22

33
Tested on:
44

5-
- Linux with nodejs 6.11 64 bit, gcc 4.8
5+
- Linux with nodejs 6.11 64 bit, (gcc 4.8 on x86, gcc 6.3 on ARM)
66
- Windows 10 with nodejs 6.11 32 and 64 bit
77
- OSX 10.10 with nodejs 6.10, llvm 3.5 (Cave! TCC is not fully
88
ported to OSX, support is experimental!)

index.js

+63-52
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ function CFuncType(restype, args) {
146146
return (pointer) => ffi.ForeignFunction(pointer, restype, args);
147147
}
148148

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+
149156
/**
150157
* Create a C code object to be used with InlineGenerator.
151158
*/
@@ -229,44 +236,29 @@ InlineGenerator.prototype.bind_state = function(state) {
229236
};
230237

231238
/**
232-
* Wrapper of ffi.Callback to distingish a function type in `bind_state`.
239+
* Helper function to create c declarations.
233240
*/
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
249242
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;
266259
}
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) {
270262
let pf = _postfix([varname], type);
271263
let s = pf.shift();
272264
while (pf.length > 1) {
@@ -279,29 +271,47 @@ function _cdecl(varname, type) {
279271
}
280272
return `${pf.shift()} ${s}`;
281273
}
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
284284
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+
);
295306
}
296307

297308
/**
298309
* Convenient function to create a C function useable from JS.
299310
*/
300311
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);
303313
let declaration = new Declaration(
304-
header + `\n{\n${code}\n}\n`,
314+
`${header}\n{\n${code}\n}\n`,
305315
header + ';',
306316
[[CFuncType(restype, args.map(([type, _]) => type)), name]]
307317
);
@@ -329,7 +339,7 @@ function c_struct(name, structType) {
329339
});
330340
let members = fields.map(
331341
// FIXME: need to declare member alignment?
332-
(el) => ` ${_cdecl(el, structType.fields[el].type)};`
342+
(el) => ` ${_var_decl(el, structType.fields[el].type)};`
333343
).join('\n');
334344
return `struct __attribute__((aligned(${structType.alignment}))) ${name} {\n${members}\n};`;
335345
},
@@ -347,4 +357,5 @@ module.exports.Declaration = Declaration;
347357
module.exports.c_function = c_function;
348358
module.exports.c_callable = c_callable;
349359
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;

install_tcc.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ mkdir lib_build
77
cd lib_build
88
../tinycc/configure --prefix=../posix --extra-cflags="-fPIC"
99
make all
10-
make test
10+
#make test
1111
make install

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "node-tinycc",
3-
"version": "0.0.5",
3+
"version": "0.0.6",
44
"description": "Inline C in Javascript with Tiny C Compiler.",
55
"main": "index.js",
66
"scripts": {
@@ -13,7 +13,7 @@
1313
"dependencies": {
1414
"ffi": "^2.2.0",
1515
"ref": "^1.3.4",
16-
"ref-array": "^1.2.0",
16+
"ref-array": "https://github.com/jerch/ref-array",
1717
"ref-struct": "^1.1.0"
1818
},
1919
"devDependencies": {

0 commit comments

Comments
 (0)