Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 import argparse
6 import re
8 STUB_TEMPLATE = '''
9 typedef %(returnType)s (*%(functionName)s_t)(%(paramTypes)s);
10 static %(functionName)s_t f_%(functionName)s;
11 extern "C" NS_EXPORT %(returnType)s JNICALL
12 %(functionName)s(%(parameterList)s) {
13 if (!f_%(functionName)s) {
14 arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
15 "JNI Function called before it was loaded");
16 return %(returnValue)s;
17 }
18 %(returnKeyword)s f_%(functionName)s(%(arguments)s);
19 }
20 '''
21 BINDING_TEMPLATE = ' xul_dlsym("%(functionName)s", &f_%(functionName)s);\n'
24 class Generator:
25 """
26 Class to convert a javah-produced JNI stub file into stubs/bindings files
27 for inclusion into mozglue.
28 """
29 def __init__(self, outputfile):
30 self.outputfile = outputfile
32 def write(self, guard, stuff):
33 self.outputfile.write('#ifdef %s\n' % guard)
34 self.outputfile.write(stuff)
35 self.outputfile.write('#endif\n\n')
37 def process(self, inputfile):
38 self.outputfile.write('/* WARNING - This file is autogenerated by '
39 + 'mobile/android/base/jni-generator.py. '
40 + 'Do not edit manually! */\n')
42 # this matches lines such as:
43 # JNIEXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onResume
44 # and extracts the return type and the function name
45 nameRegex = re.compile('''JNIEXPORT \s+
46 (?P<returnType>\S+) \s+
47 JNICALL \s+
48 (?P<functionName>\S+)''', re.VERBOSE)
50 # this matches lines such as:
51 # (JNIEnv *, jclass);
52 # and extracts everything within the parens; this will be split
53 # on commas to get the argument types.
54 paramsRegex = re.compile('\((.*)\);')
56 for line in inputfile:
57 line = line.strip()
59 match = re.match(nameRegex, line)
60 if match:
61 returnType = match.group('returnType')
62 functionName = match.group('functionName')
64 match = re.match(paramsRegex, line)
65 if match:
66 paramTypes = re.split('\s*,\s*', match.group(1))
67 paramNames = ['arg%d' % i for i in range(0, len(paramTypes))]
68 if returnType == 'void':
69 returnValue = ''
70 elif returnType in ('jobject', 'jstring'):
71 returnValue = 'nullptr'
72 elif returnType in ('jint', 'jfloat', 'jdouble', 'jlong'):
73 returnValue = '0'
74 elif returnType == 'jboolean':
75 returnValue = 'false'
76 else:
77 raise Exception(('Unsupported JNI return type %s found; '
78 + 'please update mobile/android/base/'
79 + 'jni-generator.py to handle this case!')
80 % returnType)
82 self.write('JNI_STUBS', STUB_TEMPLATE % {
83 'returnType': returnType,
84 'functionName': functionName,
85 'paramTypes': ', '.join(paramTypes),
86 'parameterList': ', '.join('%s %s' % param
87 for param in zip(paramTypes, paramNames)),
88 'arguments': ', '.join(paramNames),
89 'returnValue': returnValue,
90 'returnKeyword': 'return' if returnType != 'void' else ''})
91 self.write('JNI_BINDINGS', BINDING_TEMPLATE % {
92 'functionName': functionName})
95 def main():
96 parser = argparse.ArgumentParser(
97 description='Generate mozglue bindings for JNI functions.')
98 parser.add_argument('inputfile', type=argparse.FileType('r'))
99 parser.add_argument('outputfile', type=argparse.FileType('w'))
100 args = parser.parse_args()
101 gen = Generator(args.outputfile)
102 try:
103 gen.process(args.inputfile)
104 finally:
105 args.outputfile.close()
106 args.inputfile.close()
108 if __name__ == '__main__':
109 main()