forked from ochameau/jscpptypes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
winnt-mangler.js
164 lines (148 loc) · 4.51 KB
/
winnt-mangler.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
const { Cu } = require("chrome");
Cu.import("resource://gre/modules/ctypes.jsm");
// Documentation about visual studio mangling
// http://en.wikipedia.org/wiki/Visual_C%2B%2B_name_mangling
// http://www.kegel.com/mangle.html
// Return symbol for a given primary type
function mangleBuiltinType(arg) {
if (arg == ctypes.size_t) {
if (ctypes.size_t.size == 8)
arg = ctypes.unsigned_long;
else
arg = ctypes.unsigned_int;
}
switch (arg) {
// XXX: signed char
case ctypes.char:
return 'D';
// XXX: unsigned char
case ctypes.short:
return 'F';
case ctypes.unsigned_short:
return 'G';
case ctypes.int:
return 'H';
case ctypes.bool:
return 'H';
case ctypes.unsigned_int:
return 'I';
case ctypes.long:
return 'J';
case ctypes.unsigned_long:
return 'K';
case ctypes.float:
return 'M';
case ctypes.double:
return 'N';
// XXX: long double
case ctypes.void_t:
return 'X';
case ctypes.jschar:
return '_W';
// XXX: elipsis
}
throw new Error("Unsupported type: " + arg);
}
// Returns symbol for each argument of a function: FunctionTypeCode
function mangleArgument(substitutes, arg, doNotSubstitute) {
let symbol = "";
let saveSubstitute = false;
if (!doNotSubstitute && (arg instanceof ctypes.PointerType ||
arg instanceof ctypes.FunctionType ||
arg.isClassObject ||
arg.isConst)) {
// Search for previous argument with same type
let sameArgIndex = substitutes.types.indexOf(arg);
// if a previous argument used the same struct or class name,
// just use argument index, beginning from 0
if (sameArgIndex != -1) {
return sameArgIndex;
} else {
saveSubstitute = true;
substitutes.types.push(arg);
}
}
if (arg.isConst) {
arg = arg.ctype;
if (arg.ptr) {
symbol += "PB";
symbol += mangleArgument(substitutes, arg.targetType);
} else {
//XXX: need to verify the non-pointer scenario:
symbol += "B";
symbol += mangleArgument(substitutes, arg);
}
} else if (arg.isEnum) {
symbol += "?AW4" + mangleName(substitutes, arg.name) + "@";
} else if (arg instanceof ctypes.PointerType ||
(arg.isClassObject && arg.targetType)) {
//XXX: Pointer can have a different CV-class modifier different than
// none = 'A'
symbol += "PA";
symbol += mangleArgument(substitutes, arg.targetType, (arg.isClassObject && arg.targetType));
} else if (arg.isClassObject || arg instanceof ctypes.StructType) {
let name = mangleName(substitutes, arg.name);
if (arg.isClassObject) {
// Handle C++ definitions
symbol += "V" + name + "@";
} else if (arg instanceof ctypes.StructType) {
symbol += "U" + name + "@";
}
} else {
symbol += mangleBuiltinType(arg);
}
if (saveSubstitute)
;//substitutes.push(arg);
return symbol;
}
// Returns symbol for a given name: BasicName Qualification '@'
// XXX: missing operator case
function mangleName(substitutes, name) {
// We put each name in reserve order seperated by '@' and with an extra
// '@' at the end.
let l = name.split("::");
l.reverse();
l = l.map(function (part) {
// Search for previous argument with same type
let sameArgIndex = substitutes.names.indexOf(part);
// if a previous argument used the same struct or class name,
// just use argument index, beginning from 0
if (sameArgIndex != -1) {
return sameArgIndex;
} else {
// We ignore the last part of function names
substitutes.names.push(part);
}
return part;
})
//XXX: not sure about this rule:
l = l.map(function (part) {
let i = parseInt(part);
if (i >= 0 && i<=9)
return part;
return part + "@";
});
return l.join("");
}
// Returns symbol for a given function: MangledName
function mangleFunction(funName, returnType, args) {
// XXX: It looks like function are always:
// UnqualifiedTypeCode -> 'Y',
// StorageClass: (Normal Storage) -> 'A',
let substitutes = {names:[], types:[]};
let symbol = "?" + mangleName(substitutes, funName) + "@" + "Y" + "A";
let allTypes = [returnType].concat(args);
for (let i = 0; i < allTypes.length; i++) {
symbol += mangleArgument(substitutes, allTypes[i]);
}
return symbol + "@Z";
}
exports.mangleFunction = mangleFunction;
function mangleConst(symbol) {
return symbol;
}
exports.mangleConst = mangleConst;
function manglePointer(symbol) {
return "PA" + symbol;
}
exports.manglePointer = manglePointer;