mobile/android/base/jni-generator.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial