-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathjscpptypes.js
109 lines (100 loc) · 2.83 KB
/
jscpptypes.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
const { Cu, Cc, Ci } = require("chrome");
const { OS } = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let mangler = OS == "WINNT" ? require("winnt-mangler")
: require("gcc-mangler");
// For some reason (ctype.uintptr_t.ptr has wrong size??),
// we can't use ptr for class type and use uint64_t instead.
// But we expect all class intances to be pointer and have isNull method...
if (OS == "WINNT") {
ctypes.uint64_t.prototype.isNull = function () {
parseInt(this);
}
}
function CppClass(name) {
if (!name)
throw new Error("CppClass `name` argument is mandatory");
return {
isClassObject: true,
name: name,
ctype: OS == "WINNT" ? ctypes.uint64_t : ctypes.uintptr_t.ptr,
create: function () {
//if (this.ctype == ctypes.uintptr_t)
// throw new Error("CppClass.create only works for class pointers");
return this.ctype(0);
},
get ptr() {
// Create ptr dynamically and keep a cache in
// order to return the same object each time
// we access ptr attribute
delete this.ptr;
let ptr = CppClass(this.name);
ptr.ctype = this.ctype.ptr;
ptr.targetType = this;
this.ptr = ptr;
return ptr;
},
// Returns a pointer to type object at given address
// the address should be an hexadecimal string, like 0x0a3927ff...
fromAddress: function (addr) {
return ctypes.cast(ctypes.uintptr_t(addr), this.ctype);
}
};
}
exports.CppClass = CppClass;
function Const(type, ptr) {
return {
isConst: true,
ptr: ptr,
ctype: ptr ? type.ptr : type
};
}
exports.Const = Const;
function Enum(name) {
return {
isEnum: true,
ctype: ctypes.int,
name: name
};
}
exports.Enum = Enum;
function convertToCtypes(arg) {
if (arg.isClassObject || arg.isConst || arg.isEnum) {
return arg.ctype;
}
return arg;
}
function declare(lib, name, returnType) {
let args = Array.slice(arguments, 3);
let ctypesArgs = args.map(convertToCtypes);
let symbol = mangler.mangleFunction(name, returnType, args);
let f;
try {
f = lib.declare.apply(
lib,
[symbol,
ctypes.default_abi,
convertToCtypes(returnType)].concat(ctypesArgs)
);
} catch(e) {
// Just in case, try the unmangled version
try {
f = lib.declare.apply(
lib,
[name,
ctypes.default_abi,
convertToCtypes(returnType)].concat(ctypesArgs)
);
} catch(e) {
throw new Error("Unable to find function '" + name +
"', mangled symbol (" + symbol + ")");
}
}
return function () {
//console.log(">> "+name);
//console.log(Array.slice(arguments).join(', '));
return f.apply(this, arguments);
}
}
exports.declare = declare;