Skip to content

Commit 01c506d

Browse files
committed
use static libtcc
1 parent 4834086 commit 01c506d

File tree

7 files changed

+304
-151
lines changed

7 files changed

+304
-151
lines changed

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.idea/
2+
build/
3+
coverage/
4+
linux/
5+
node-tinycc.iml
6+
node_modules/
7+
tinycc/
8+
lib_build/
9+
posix/

binding.gyp

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
'targets': [
3+
{
4+
'target_name': 'tcc',
5+
'include_dirs': ['<!(node -e "require(\'nan\')")', 'posix/include/'],
6+
'sources': [
7+
'src/tcc.cpp',
8+
],
9+
'libraries': [
10+
'-ltcc',
11+
'-L../posix/lib/'
12+
],
13+
#'cflags!': [ '-fno-exceptions' ],
14+
#'cflags_cc!': [ '-fno-exceptions' ],
15+
'conditions': [
16+
['OS=="mac"', {
17+
'xcode_settings': {
18+
'OTHER_LDFLAGS': [
19+
'-ltcc'
20+
]
21+
},
22+
}],
23+
]
24+
},
25+
]
26+
}

index.js

+36-110
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,33 @@
11
/*
22
TODO:
3-
- replace ffi shared lib version of Tcc with native version (needed for OSX)
43
- use EventEmitter for compile steps
54
- use ref.coerceType where appropriate
65
- enhance InlineGenerator with struct and array functionality
76
*/
7+
'use strict';
88

9-
var ffi = require('ffi');
10-
var ref = require('ref');
9+
const ffi = require('ffi');
10+
const ref = require('ref');
1111

12-
var void_p = ref.refType(ref.types.void);
13-
var TCCState_p = void_p;
14-
15-
function Tcc(tcclib, tccpath) {
16-
if (!(this instanceof Tcc))
17-
return new Tcc(tcclib, tccpath);
18-
this.lib = ffi.Library(tcclib || './linux/lib/libtcc.so', {
19-
// missing: tcc_enable_debug, tcc_set_error_func, tcc_set_warning, tcc_add_sysinclude_path, tcc_output_file
20-
'tcc_new': [TCCState_p, []],
21-
'tcc_delete': ['void', [TCCState_p]], // TODO: explicit destructor
22-
'tcc_set_lib_path': ['void', [TCCState_p, 'string']],
23-
'tcc_set_output_type': ['int', [TCCState_p, 'int']],
24-
'tcc_set_options': ['void', [TCCState_p, 'string']],
25-
'tcc_define_symbol': ['void', [TCCState_p, 'string', 'string']],
26-
'tcc_undefine_symbol': ['void', [TCCState_p, 'string']],
27-
'tcc_add_include_path': ['int', [TCCState_p, 'string']],
28-
'tcc_add_library': ['int', [TCCState_p, 'string']],
29-
'tcc_add_library_path': ['int', [TCCState_p, 'string']],
30-
'tcc_add_file': ['int', [TCCState_p, 'string']], // TODO: check unicode compat
31-
'tcc_compile_string': ['int', [TCCState_p, 'string']],
32-
'tcc_relocate': ['int', [TCCState_p, 'int']],
33-
'tcc_add_symbol': ['int', [TCCState_p, 'string', 'string']],
34-
'tcc_get_symbol': [void_p, [TCCState_p, 'string']],
35-
'tcc_run': ['int', [TCCState_p, 'int', void_p]]
36-
});
37-
this.ctx = this.lib.tcc_new();
38-
this.lib.tcc_set_lib_path(this.ctx, tccpath || './linux/lib/tcc');
39-
this.lib.tcc_set_output_type(this.ctx, 0); // memory build only
40-
this._obj_refs = {};
41-
}
42-
Tcc.prototype.set_option = function(option) {
43-
this.lib.tcc_set_option(this.ctx, option);
44-
}
45-
Tcc.prototype.define = function(symbol, value) {
46-
this.lib.tcc_define_symbol(this.ctx, symbol, value);
47-
}
48-
Tcc.prototype.undefine = function(symbol) {
49-
this.lib.tcc_undefine_symbol(this.ctx, symbol);
50-
}
51-
Tcc.prototype.add_include_path = function(path) {
52-
if (this.lib.tcc_add_include_path(this.ctx, path) == -1)
53-
throw new Error('error add_include_path: ' + path);
54-
}
55-
Tcc.prototype.add_library = function(library) {
56-
if (this.lib.tcc_add_library(this.ctx, library) == -1)
57-
throw new Error('error add_library: ' + library);
58-
}
59-
Tcc.prototype.add_link_path = function(path) {
60-
if (this.lib.tcc_add_library_path(this.ctx, path) == -1)
61-
throw new Error('error add_link_path: ' + path);
62-
}
63-
Tcc.prototype.add_file = function(path) {
64-
if (this.lib.tcc_add_file(this.ctx, path) == -1)
65-
throw new Error('error add_file: ' + path);
66-
}
67-
Tcc.prototype.compile = function(code) {
68-
if (this.lib.tcc_compile_string(this.ctx, code) == -1)
69-
throw new Error('error compile');
70-
}
71-
Tcc.prototype.relocate = function() {
72-
if (this.lib.tcc_relocate(this.ctx, 1) == -1)
73-
throw new Error('compile relocate');
74-
}
75-
Tcc.prototype.run = function(argc, argv) {
76-
// TODO: handle string array
77-
return this.lib.tcc_run(this.ctx, argc, argv);
78-
}
79-
Tcc.prototype.add_symbol = function(symbol, value) { // TODO: hold ref for value
80-
if (this.lib.tcc_add_symbol(this.ctx, symbol, value) == -1)
81-
throw new Error('error add_symbol: ' + symbol);
82-
}
83-
Tcc.prototype.get_symbol = function(symbol) {
84-
return this.lib.tcc_get_symbol(this.ctx, symbol);
85-
}
86-
Tcc.prototype.resolve_symbol = function(symbol, type) {
12+
const Tcc = require('./build/Release/tcc').TCC;
13+
Tcc.prototype.resolveSymbol = function(symbol, type) {
8714
// TODO: support array and struct
88-
if (typeof type === "function")
89-
return type(this.get_symbol(symbol));
15+
if (typeof type === "function") {
16+
return type(this.getSymbol(symbol));
17+
}
9018
type = ref.coerceType(type);
91-
var res = this.get_symbol(symbol).reinterpret(type.size);
19+
let res = this.getSymbol(symbol).reinterpret(type.size);
9220
res.type = type;
9321
return res;
94-
}
95-
Tcc.prototype.set_symbol = function(symbol, value) { // TODO: hold ref for value
96-
var buf = this.get_symbol(symbol).reinterpret(value.type.size);
22+
};
23+
Tcc.prototype.setSymbol = function(symbol, value) {
24+
let buf = this.getSymbol(symbol).reinterpret(value.type.size);
9725
buf.type = value.type;
9826
ref.set(buf, 0, value.deref());
99-
}
100-
Tcc.prototype.set_function = function(symbol, cb) { // TODO: hold ref for value
101-
ref.set(this.resolve_symbol(symbol, 'void *'), 0, cb);
102-
}
103-
27+
};
28+
Tcc.prototype.set_function = function(symbol, cb) {
29+
ref.set(this.resolveSymbol(symbol, 'void *'), 0, cb);
30+
};
10431

10532
/**
10633
* C function type.
@@ -132,26 +59,24 @@ function Declaration(code, forward, symbols) {
13259
function InlineGenerator() {
13360
if (!(this instanceof InlineGenerator))
13461
return new InlineGenerator();
135-
var that = this;
13662
this.headerparts = [];
13763
this.parts = [];
13864
this.symbols = null;
139-
this.callables = [];
14065
}
14166

14267
/**
14368
* Get C code of added declarations.
14469
*/
14570
InlineGenerator.prototype.code = function() {
146-
var top = this.headerparts.join('\n');
147-
var forward = this.parts.map(function(el){return el.forward;}).join('\n');
148-
var code = this.parts.map(function(el){return el.code;}).join('\n');
71+
let top = this.headerparts.join('\n');
72+
let forward = this.parts.map(function(el){return el.forward;}).join('\n');
73+
let code = this.parts.map(function(el){return el.code;}).join('\n');
14974
return [
15075
'/* top */', top, '',
15176
'/* forward */', forward, '',
15277
'/* code */', code, ''
15378
].join('\n');
154-
}
79+
};
15580

15681
/**
15782
* Add a declaration to the generator.
@@ -162,14 +87,14 @@ InlineGenerator.prototype.add_declaration = function(decl) {
16287
if (!(decl instanceof Declaration))
16388
throw new Error('cannot add declaration');
16489
this.parts.push(decl);
165-
}
90+
};
16691

16792
/**
16893
* Add a topdeclaration to the generator.
16994
*/
17095
InlineGenerator.prototype.add_topdeclaration = function(decl) {
17196
this.headerparts.push(decl.code);
172-
}
97+
};
17398

17499
/**
175100
* Bind a tcc state to this generator.
@@ -179,27 +104,28 @@ InlineGenerator.prototype.add_topdeclaration = function(decl) {
179104
InlineGenerator.prototype.bind_state = function(state) {
180105
if (this.symbols)
181106
return this.symbols;
182-
var all_symbols = {};
183-
for (var i=0; i<this.parts.length; ++i) {
107+
let all_symbols = {};
108+
for (let i=0; i<this.parts.length; ++i) {
184109
if (this.parts[i].symbols.length)
185-
for (var j=0; j<this.parts[i].symbols.length; ++j) {
186-
var sym = this.parts[i].symbols[j];
110+
for (let j=0; j<this.parts[i].symbols.length; ++j) {
111+
let sym = this.parts[i].symbols[j];
187112
if (sym[0] instanceof FuncSymbol) {
188-
ref.set(state.resolve_symbol(sym[1], 'void *'), 0, sym[0].cb);
113+
ref.set(state.resolveSymbol(sym[1], 'void *'), 0, sym[0].cb);
189114
} else {
190-
var resolved = state.resolve_symbol(sym[1], sym[0]);
115+
let resolved = state.resolveSymbol(sym[1], sym[0]);
191116
this.parts[i].symbols_resolved[sym[1]] = resolved;
192117
all_symbols[sym[1]] = resolved;
193118
}
194119
}
195120
}
196121
this.symbols = all_symbols;
197122
return all_symbols;
198-
}
123+
};
199124

200125
/**
201126
* FuncSymbol - thin wrapper of ffi.Callback
202-
* needed to distingish type in `InlineGenerator.bind_state` for reverse symbol resolution of JS functions
127+
* needed to distingish type in `InlineGenerator.bind_state` for reverse symbol resolution
128+
* of JS functions
203129
*/
204130
function FuncSymbol(restype, args, f) {
205131
if (!(this instanceof FuncSymbol))
@@ -221,21 +147,21 @@ function c_callable(restype, name, args, f) {
221147
/**
222148
* Convenient function to create a C function in C useable from JS
223149
*/
224-
var c_function = function(restype, name, args, code) {
225-
var header = restype + ' ' + name + '(' + args.map(function(el){return el.join(' ')}).join(', ') + ')';
226-
var declaration = new Declaration(
150+
const c_function = function(restype, name, args, code) {
151+
let header = restype + ' ' + name + '(' + args.map(function(el){return el.join(' ')}).join(', ') + ')';
152+
let declaration = new Declaration(
227153
header + '\n{' + code + '}\n',
228154
header + ';',
229155
[[CFuncType(restype, args.map(function(el){return el[0];})), name]]
230156
);
231-
var func = function() {
157+
let func = function() {
232158
if (func.declaration.symbols_resolved[name])
233159
return func.declaration.symbols_resolved[name].apply(this, arguments);
234160
throw new Error('c_function "'+name+'" must be compiled and bound before usage');
235161
};
236162
func.declaration = declaration;
237163
return func;
238-
}
164+
};
239165

240166
module.exports.Tcc = Tcc;
241167
module.exports.CFuncType = CFuncType;

install_tcc.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#!/bin/sh
22
echo $(pwd)
33
rm -rf ./tinycc
4-
rm -rf ./build
4+
rm -rf ./lib_build
55
git clone git://repo.or.cz/tinycc.git
6-
mkdir build
7-
cd build
8-
../tinycc/configure --prefix=../linux --with-libgcc --disable-static
6+
mkdir lib_build
7+
cd lib_build
8+
../tinycc/configure --prefix=../posix --with-libgcc --extra-cflags="-fPIC"
99
make all
1010
make install

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "index.js",
66
"scripts": {
77
"test": "node_modules/istanbul/lib/cli.js cover node_modules/mocha/bin/_mocha -- -R spec",
8-
"postinstall": "./install_tcc.sh"
8+
"preinstall": "./install_tcc.sh"
99
},
1010
"author": "",
1111
"license": "MIT",

0 commit comments

Comments
 (0)