2023-04-12 14:21:03 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
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:
|
2023-07-19 23:35:07 +00:00
|
|
|
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:
|
2023-07-19 23:35:07 +00:00
|
|
|
m3_Sig += c
|
2023-04-12 14:21:03 +00:00
|
|
|
|
2023-07-19 23:35:07 +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
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
for line in inFile:
|
|
|
|
if line.isspace():
|
|
|
|
continue
|
|
|
|
desc = line.split()
|
2023-04-12 14:21:03 +00:00
|
|
|
|
2023-07-19 23:35:07 +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
|
|
|
|
2023-07-19 23:35:07 +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
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
for link in links:
|
|
|
|
linkProc += link
|
2023-04-14 09:48:36 +00:00
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
linkProc += '\treturn(0);\n'
|
|
|
|
linkProc += '}\n'
|
2023-04-12 14:21:03 +00:00
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
for stub in stubs:
|
|
|
|
outFile.write(stub)
|
2023-04-12 14:21:03 +00:00
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
outFile.write('\n')
|
|
|
|
outFile.write(linkProc)
|
2023-04-12 14:21:03 +00:00
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
inFile.close()
|
|
|
|
outFile.close()
|
2023-04-12 14:21:03 +00:00
|
|
|
|
2023-07-19 23:35:07 +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
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
apiName = sys.argv[1]
|
|
|
|
cdir = ''
|
2023-04-12 14:21:03 +00:00
|
|
|
|
2023-07-19 23:35:07 +00:00
|
|
|
if len(sys.argv) > 2:
|
|
|
|
cdir = sys.argv[2]
|
|
|
|
|
|
|
|
bindgen(apiName, cdir)
|