-
Notifications
You must be signed in to change notification settings - Fork 20
/
runtime.js
66 lines (53 loc) · 2.41 KB
/
runtime.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* eslint-disable camelcase, key-spacing, no-multi-spaces, array-bracket-spacing */
const ffi = require('ffi-napi');
const ref = require('ref-napi');
const dlfcn = new ffi.Library(null, {
dlopen: ['pointer', ['string', 'int']]
});
const libobjc = new ffi.Library('libobjc', {
// Selectors
sel_getUid : ['pointer', ['string' ]],
sel_getName: ['string', ['pointer']],
// Classes
objc_getClass : ['pointer', ['string' ]],
object_getClass : ['pointer', ['pointer']],
object_isClass : ['bool', ['pointer']],
class_getName : ['string', ['pointer']],
class_getClassMethod : ['pointer', ['pointer', 'pointer']],
class_getInstanceMethod: ['pointer', ['pointer', 'pointer']],
class_addMethod : ['bool', ['pointer', 'pointer', 'pointer', 'string']],
class_replaceMethod : ['pointer', ['pointer', 'pointer', 'pointer', 'string']],
objc_allocateClassPair : ['pointer', ['pointer', 'string', 'int']],
objc_registerClassPair : ['void', ['pointer']],
// Methods
method_getImplementation : ['pointer', ['pointer']],
method_getTypeEncoding : ['string', ['pointer']],
method_copyReturnType : ['string', ['pointer']],
method_copyArgumentType : ['string', ['pointer', 'int']],
method_getNumberOfArguments : ['int', ['pointer']],
method_exchangeImplementations: ['void', ['pointer', 'pointer']],
method_setImplementation : ['pointer', ['pointer', 'pointer']],
// IMP
imp_implementationWithBlock: ['pointer', ['pointer']]
});
libobjc.objc_msgSend = ffi.DynamicLibrary().get('objc_msgSend'); // eslint-disable-line new-cap
const msgSend = (returnType, argumentTypes) => {
return ffi.ForeignFunction(libobjc.objc_msgSend, returnType, argumentTypes); // eslint-disable-line new-cap
};
const classExists = classname => !libobjc.objc_getClass(classname).isNull();
const getSymbol = name => new ffi.DynamicLibrary().get(name);
const getSymbolAsId = name => {
try {
const symbol = getSymbol(name);
symbol.type = ref.refType(ref.refType(ref.types.void));
return symbol.deref();
} catch (err) {
return null;
}
};
dlfcn.dlopen('/System/Library/Frameworks/Foundation.framework/Foundation', ffi.DynamicLibrary.FLAGS.RTLD_LAZY);
module.exports = libobjc;
module.exports.msgSend = msgSend;
module.exports.classExists = classExists;
module.exports.getSymbol = getSymbol;
module.exports.getSymbolAsId = getSymbolAsId;