orca/scripts/bindgen.py

136 lines
3.1 KiB
Python
Raw Normal View History

2023-04-12 14:21:03 +00:00
#!/usr/bin/env python3
import sys
def bindgen(apiName, cdir):
inPath = cdir + '/bindgen_' + apiName + '_api.txt'
outPath = cdir + '/bindgen_' + apiName + '_api.c'
inFile = open(inPath, 'r')
outFile = open(outPath, 'w')
stubs = []
links = []
def gen_stub(name, sig, native_name):
if native_name == None:
native_name = name
src = 'const void* ' + name + '_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem)\n'
src += '{\n'
spIndex = 0
parsingRet = True
retCount = 0
argCount = 0
retString = ''
argString = ''
for index, c in enumerate(sig):
if parsingRet:
if retCount > 1:
print('unsupported multiple return types\n')
break
if c == '(':
parsingRet = False
continue
elif c == ')':
print('unexpected ) while parsing return type\n')
break;
elif c == 'v':
continue
elif c == 'i':
retString = '*((i32*)&_sp[0]) = '
elif c == 'I':
retString = '*((i64*)&_sp[0]) = '
elif c == 'f':
retString = '*((f32*)&_sp[0]) = '
elif c == 'F':
retString = '*((f64*)&_sp[0]) = '
elif c == 'p':
print('returning pointers is not supported yet\n')
break
else:
print('unrecognized type ' + c + ' in procedure return\n')
break
retCount += 1
2023-04-12 14:21:03 +00:00
else:
argIndex = argCount + retCount
if c == ')':
break
elif c == 'v':
break
elif c == 'i':
argString += '*(i32*)&_sp[' + str(argIndex) + ']'
elif c == 'I':
argString += '*(i64*)&_sp[' + str(argIndex) + ']'
elif c == 'f':
argString += '*(f32*)&_sp[' + str(argIndex) + ']'
elif c == 'F':
argString += '*(f64*)&_sp[' + str(argIndex) + ']'
elif c == 'p':
argString += '(void*)((char*)_mem + *(i32*)&_sp[' + str(argIndex) + '])'
else:
print('unrecognized type ' + c + ' in procedure signature\n')
break
if index+2 < len(sig):
argString += ', '
argCount += 1
src += '\t' + retString + native_name + '(' + argString + ');\n'
src += '\treturn(0);\n'
src += '}\n'
stubs.append(src)
def gen_link(name, sig):
m3_Sig = ''
for c in sig:
if c == 'p':
m3_Sig += 'i'
2023-04-12 14:21:03 +00:00
else:
m3_Sig += c
2023-04-12 14:21:03 +00:00
src = '\tres = m3_LinkRawFunction(module, "*", "' + name + '", "' + m3_Sig + '", ' + name + '_stub);\n'
src += '\tif(res != m3Err_none && res != m3Err_functionLookupFailed) { log_error("error: %s\\n", res); return(-1); }\n\n'
links.append(src)
2023-04-12 14:21:03 +00:00
for line in inFile:
if line.isspace():
continue
desc = line.split()
2023-04-12 14:21:03 +00:00
gen_stub(desc[0], desc[1], desc[2] if len(desc) > 2 else None)
gen_link(desc[0], desc[1])
2023-04-12 14:21:03 +00:00
linkProc = 'int bindgen_link_' + apiName + '_api(IM3Module module)\n'
linkProc += '{\n'
linkProc += '\tM3Result res;\n'
2023-04-12 14:21:03 +00:00
for link in links:
linkProc += link
2023-04-14 09:48:36 +00:00
linkProc += '\treturn(0);\n'
linkProc += '}\n'
2023-04-12 14:21:03 +00:00
for stub in stubs:
outFile.write(stub)
2023-04-12 14:21:03 +00:00
outFile.write('\n')
outFile.write(linkProc)
2023-04-12 14:21:03 +00:00
inFile.close()
outFile.close()
2023-04-12 14:21:03 +00:00
if __name__ == "__main__":
if len(sys.argv) < 2:
print("bindgen require an api name\n")
exit(-1)
2023-04-12 14:21:03 +00:00
apiName = sys.argv[1]
cdir = ''
2023-04-12 14:21:03 +00:00
if len(sys.argv) > 2:
cdir = sys.argv[2]
bindgen(apiName, cdir)