about summary refs log tree commit diff stats
path: root/rebuild_wrappers.py
diff options
context:
space:
mode:
Diffstat (limited to 'rebuild_wrappers.py')
-rwxr-xr-xrebuild_wrappers.py199
1 files changed, 158 insertions, 41 deletions
diff --git a/rebuild_wrappers.py b/rebuild_wrappers.py
index ab6cb1da..ab354013 100755
--- a/rebuild_wrappers.py
+++ b/rebuild_wrappers.py
@@ -150,14 +150,18 @@ class FunctionConvention(object):
 		self.ident = ident
 		self.name = convname
 		self.values = valid_chars
-# Free letters:  B   FG  J      QR T    YZa   e gh jk mno qrst    z
+# Free letters:  B   FG  JK     QR T    YZa   e gh jk mno qrst   yz
 conventions = {
-	'F': FunctionConvention('F', "System V", ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X', 'Y', 'y', 'b']),
-	'W': FunctionConvention('W', "Windows",  ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd',      'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M',      'P', 'A'])
+	'F': FunctionConvention('F', "System V", ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X', 'Y', 'b']),
+	'W': FunctionConvention('W', "Windows",  ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd',      'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M',      'P', 'A'])
 }
-sortedvalues = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X', 'Y', 'y', 'b', '0', '1']
+sortedvalues = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X', 'Y', 'b', '0', '1']
 assert(all(all(c not in conv.values[:i] and c in sortedvalues for i, c in enumerate(conv.values)) for conv in conventions.values()))
 
+# Some type depend on HAVE_LD80BITS; define this here so we can use it in readFiles and main
+depends_on_ld: str = "DY"
+assert(all(c in sortedvalues for c in depends_on_ld))
+
 class FunctionType(str):
 	@staticmethod
 	def validate(s: str, post: str) -> bool:
@@ -369,7 +373,7 @@ def readFiles(files: Iterable[Filename]) -> Tuple[JumbledGlobals, JumbledRedirec
 		
 		# typedefs is a list of all "*FE*" types for the current file
 		# mystructs  is a map  of all char -> (structure C name, replacement) for structures
-		typedefs  : JumbledTypedefs   = {}
+		typedefs    : JumbledTypedefs   = {}
 		mystructs   : JumbledStructures = {}
 		mystructuses: JumbledStructUses = {}
 		filespec[filename[:-10]] = (typedefs, mystructs, mystructuses)
@@ -531,6 +535,19 @@ def readFiles(files: Iterable[Filename]) -> Tuple[JumbledGlobals, JumbledRedirec
 					if ln not in gbl[str(dependants)]:
 						gbl[str(dependants)].append(FunctionType(ln))
 					
+					if any(c in origLine for c in depends_on_ld):
+						if (gotype != "GOM") and (gotype != "GOWM") and (gotype != "GOD") and (gotype != "GODW"):
+							print("\033[91mError:\033[m type depends on HAVE_LD80BITS but the GO type doesn't support that ({0}:{1})"
+			 					.format(filename, line[:-1]))
+							halt_required = True
+					if (gotype == "GO2") or (gotype == "GOW2") or (gotype == "GOD") or (gotype == "GODW"):
+						altfun = line.split(',')[2].split(')')[0].strip()
+						if altfun == "":
+							print("\033[91mError:\033[m empty alt function ({0}:{1})".format(filename, line[:-1]))
+							halt_required = True
+						elif altfun == funname:
+							print("\033[91mError:\033[m alt function is the original function ({0}:{1})".format(filename, line[:-1]))
+							halt_required = True
 					if origLine[2] == "E":
 						if (gotype != "GOM") and (gotype != "GOWM"):
 							if (gotype != "GO2") or not (line.split(',')[2].split(')')[0].strip().startswith('my_')):
@@ -829,10 +846,10 @@ def main(root: str, files: Iterable[Filename], ver: str):
 	
 	# Detect functions which return in an x87 register
 	retx87_wraps: Dict[ClausesStr, List[FunctionType]] = {}
-	return_x87: str = "DK"
+	return_x87: str = "D"
 	
 	# Sanity checks
-	forbidden_simple: Dict[str, str] = {"ARM64": "EDKVOSNMHPAxXYyb", "RV64": "EcwiDKVOSNMHPAxXYyb"}
+	forbidden_simple: Dict[str, str] = {"ARM64": "EDVOSNMHPAxXYb", "RV64": "EcwiDVOSNMHPAxXYb"}
 	assert(all(k in allowed_simply for k in forbidden_simple))
 	assert(all(k in allowed_regs for k in forbidden_simple))
 	assert(all(k in allowed_fpr for k in forbidden_simple))
@@ -843,6 +860,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
 		assert(all(c not in allowed_simply[k1] + allowed_regs[k1] + allowed_fpr[k1] for c in forbidden_simple[k1]))
 		assert(all(c in allowed_simply[k1] + allowed_regs[k1] + allowed_fpr[k1] + forbidden_simple[k1] for c in allowed_conv.values))
 	assert(all(c in allowed_conv.values for c in return_x87))
+	assert(all(c in forbidden_simple[k] for c in depends_on_ld for k in forbidden_simple))
 	
 	simple_wraps: Dict[str, Dict[ClausesStr, List[Tuple[FunctionType, int]]]] = {
 		k1: {} for k1 in forbidden_simple
@@ -852,7 +870,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
 		regs_count: int = 0
 		fpr_count : int = 0
 		
-		ret = {}
+		ret: Dict[str, int] = {}
 		for k in forbidden_simple:
 			if v.get_convention() is not allowed_conv:
 				continue
@@ -1034,20 +1052,53 @@ def main(root: str, files: Iterable[Filename], ver: str):
 	# Rewrite the wrapper.c file:
 	# i and u should only be 32 bits
 	td_types = {
-		#      E            v       c         w          i          I          C          W           u           U           f        d         D              K         l           L            p        V        O          S        N      M      H                    P        A			x				X           Y              y         b
-		'F': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "...", "unsigned __int128", "void*", "void*", "complexf_t", "complex_t", "complexl_t", "complex_t", "void*"],
-		#      E            v       c         w          i          I          C          W           u           U           f        d         K         l           L            p        V        O          S        N      M      P        A
-		'W': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "...", "void*", "void*"]
+		#      E            v       c         w          i          I          C          W           u           U           f        d         D              l           L            p        V        O          S        N      M      H                    P        A        x             X            Y             b
+		'F': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "...", "unsigned __int128", "void*", "void*", "complexf_t", "complex_t", "complexl_t", "void*"],
+		#      E            v       c         w          i          I          C          W           u           U           f        d                        l           L            p        V        O          S        N      M                           P        A
+		'W': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double",                "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "...",                      "void*", "void*"]
+	}
+	td_types_nold = {
+		'F': {'D': "double", 'Y': "complex_t"},
+		'W': {}
+	}
+	td_types_ld = {
+		k: {t: td_types[k][conventions[k].values.index(t)] for t in td_types_nold[k]} for k in td_types_nold
 	}
 	assert(all(k in conventions for k in td_types))
+	assert(all(k in conventions for k in td_types_nold))
+	assert(all(t in depends_on_ld for k in td_types_nold for t in td_types_nold[k]))
 	for k in conventions:
 		if len(conventions[k].values) != len(td_types[k]):
 			raise NotImplementedError("len(values) = {lenval} != len(td_types) = {lentypes}".format(lenval=len(conventions[k].values), lentypes=len(td_types[k])))
 	
 	def generate_typedefs(arr: Iterable[FunctionType], file) -> None:
+		any_depends_on_ld = False
 		for v in arr:
+			if any(c in v for c in depends_on_ld):
+				any_depends_on_ld = True
+				continue
 			file.write("typedef " + td_types[v.get_convention().ident][v.get_convention().values.index(v[0])] + " (*" + v + "_t)"
 				+ "(" + ', '.join(td_types[v.get_convention().ident][v.get_convention().values.index(t)] for t in v[2:]) + ");\n")
+		if any_depends_on_ld:
+			file.write("\n#ifdef HAVE_LD80BITS\n")
+			for v in arr:
+				if all(c not in v for c in depends_on_ld):
+					continue
+				file.write("typedef " + td_types[v.get_convention().ident][v.get_convention().values.index(v[0])] + " (*" + v + "_t)"
+					+ "(" + ', '.join(td_types[v.get_convention().ident][v.get_convention().values.index(t)] for t in v[2:]) + ");\n")
+			file.write("#else // HAVE_LD80BITS\n")
+			for k in td_types_nold:
+				for t in td_types_nold[k]:
+					td_types[k][conventions[k].values.index(t)] = td_types_nold[k][t]
+			for v in arr:
+				if all(c not in v for c in depends_on_ld):
+					continue
+				file.write("typedef " + td_types[v.get_convention().ident][v.get_convention().values.index(v[0])] + " (*" + v + "_t)"
+					+ "(" + ', '.join(td_types[v.get_convention().ident][v.get_convention().values.index(t)] for t in v[2:]) + ");\n")
+			for k in td_types_nold:
+				for t in td_types_ld[k]:
+					td_types[k][conventions[k].values.index(t)] = td_types_ld[k][t]
+			file.write("#endif\n")
 	
 	with open(os.path.join(root, "src", "wrapped", "generated", "wrapper.c"), 'w') as file:
 		file.write(files_header["wrapper.c"].format(lbr="{", rbr="}", version=ver))
@@ -1081,7 +1132,6 @@ def main(root: str, files: Iterable[Filename], ver: str):
 				"emu->xmm[0].f[0]=fn({0});",                               # f
 				"emu->xmm[0].d[0]=fn({0});",                               # d
 				"long double ld=fn({0}); fpu_do_push(emu); ST0val = ld;",  # D
-				"double db=fn({0}); fpu_do_push(emu); ST0val = db;",       # K
 				"R_RAX=(intptr_t)fn({0});",                                # l
 				"R_RAX=(uintptr_t)fn({0});",                               # L
 				"R_RAX=(uintptr_t)fn({0});",                               # p
@@ -1093,10 +1143,9 @@ def main(root: str, files: Iterable[Filename], ver: str):
 				"unsigned __int128 u128 = fn({0}); R_RAX=(u128&0xFFFFFFFFFFFFFFFFL); R_RDX=(u128>>64)&0xFFFFFFFFFFFFFFFFL;", # H
 				"\n#error Invalid return type: pointer in the stack\n",    # P
 				"\n#error Invalid return type: va_list\n",                 # A
-				'from_complexf(emu, fn({0}));', 	                       # x
-				'from_complex(emu, fn({0}));',                             # X
-				'from_complexl(emu, fn({0}));', 	                       # Y
-				'from_complexk(emu, fn({0}));',                            # y
+				"from_complexf(emu, fn({0}));",                            # x
+				"from_complex(emu, fn({0}));",                             # X
+				"from_complexl(emu, fn({0}));",                            # Y
 				"\n#error Invalid return type: xcb_connection_t*\n",       # b
 			],
 			conventions['W']: [
@@ -1112,7 +1161,6 @@ def main(root: str, files: Iterable[Filename], ver: str):
 				"R_RAX=fn({0});",                                          # U
 				"emu->xmm[0].f[0]=fn({0});",                               # f
 				"emu->xmm[0].d[0]=fn({0});",                               # d
-				"double db=fn({0}); fpu_do_push(emu); ST0val = db;",       # K
 				"R_RAX=(intptr_t)fn({0});",                                # l
 				"R_RAX=(uintptr_t)fn({0});",                               # L
 				"R_RAX=(uintptr_t)fn({0});",                               # p
@@ -1125,19 +1173,29 @@ def main(root: str, files: Iterable[Filename], ver: str):
 				"\n#error Invalid return type: va_list\n",                 # A
 			]
 		}
+		vals_nold = {
+			conventions['F']: {
+				'D': "double db=fn({0}); fpu_do_push(emu); ST0val = db;",
+				'Y': "from_complexk(emu, fn({0}));",
+			},
+			conventions['W']: {}
+		}
+		vals_ld = {
+			k: {t: vals[k][k.values.index(t)] for t in vals_nold[k]} for k in vals_nold
+		}
 		
 		# vreg: value is in a general register
-		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X  Y  y  b
-		vreg   = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 2, 2, 0, 1, 0, 0, 0, 0, 1]
+		#         E  v  c  w  i  I  C  W  u  U  f  d  D  l  L  p  V  O  S  N  M  H  P  A  x  X  Y  b
+		vreg   = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 2, 2, 0, 1, 0, 0, 0, 1]
 		# vxmm: value is in a XMM register
-		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X  Y  y  b
-		vxmm   = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0]
+		#         E  v  c  w  i  I  C  W  u  U  f  d  D  l  L  p  V  O  S  N  M  H  P  A  x  X  Y  b
+		vxmm   = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]
 		# vother: value is elsewere
-		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X  Y  y  b
-		vother = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+		#         E  v  c  w  i  I  C  W  u  U  f  d  D  l  L  p  V  O  S  N  M  H  P  A  x  X  Y  b
+		vother = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
 		# vstack: value is on the stack (or out of register)
-		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X  Y  y  b
-		vstack = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 2, 4, 4, 1]
+		#         E  v  c  w  i  I  C  W  u  U  f  d  D  l  L  p  V  O  S  N  M  H  P  A  x  X  Y  b
+		vstack = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 2, 4, 1]
 		arg_r = [
 			"",                            # E
 			"",                            # v
@@ -1152,7 +1210,6 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"",                            # f
 			"",                            # d
 			"",                            # D
-			"",                            # K
 			"(intptr_t){p}, ",             # l
 			"(uintptr_t){p}, ",            # L
 			"(void*){p}, ",                # p
@@ -1164,10 +1221,9 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"\n#error Use pp instead\n",   # H
 			"",                            # P
 			"(void*){p}, ",                # A
-			"",	                           # x
+			"",                            # x
 			"",                            # X
-			"",							   # Y
-			"",							   # y
+			"",                            # Y
 			"aligned_xcb, ",               # b
 		]
 		arg_x = [
@@ -1184,7 +1240,6 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"emu->xmm[{p}].f[0], ",   # f
 			"emu->xmm[{p}].d[0], ",   # d
 			"",                       # D
-			"",                       # K
 			"",                       # l
 			"",                       # L
 			"",                       # p
@@ -1198,8 +1253,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"",                       # A
 			"to_complexf(emu, {p}), ", # x
 			"to_complex(emu, {p}), ",  # X
-			"", 				      # Y
-			"", 				      # y
+			"",                       # Y
 			"",                       # b
 		]
 		arg_o = [
@@ -1216,7 +1270,6 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"",                       # f
 			"",                       # d
 			"",                       # D
-			"",                       # K
 			"",                       # l
 			"",                       # L
 			"",                       # p
@@ -1230,8 +1283,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"",                       # A
 			"",                       # x
 			"",                       # X
-			"",						  # Y
-			"",						  # y
+			"",                       # Y
 			"",                       # b
 		]
 		arg_s = [
@@ -1248,7 +1300,6 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"*(float*)(R_RSP + {p}), ",                 # f
 			"*(double*)(R_RSP + {p}), ",                # d
 			"LD2localLD((void*)(R_RSP + {p})), ",       # D
-			"FromLD((void*)(R_RSP + {p})), ",           # K
 			"*(intptr_t*)(R_RSP + {p}), ",              # l
 			"*(uintptr_t*)(R_RSP + {p}), ",             # L
 			"*(void**)(R_RSP + {p}), ",                 # p
@@ -1262,10 +1313,16 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"*(void**)(R_RSP + {p}), ",                 # A
 			"*(complexf_t*)(R_RSP + {p}), ",            # x
 			"*(complex_t*)(R_RSP + {p}), ",             # X
-			"to_complexl(emu, R_RSP + {p}), ",		    # Y
-			"to_complexk(emu, R_RSP + {p}), ",		    # y
+			"to_complexl(emu, R_RSP + {p}), ",          # Y
 			"aligned_xcb, ",                            # b
 		]
+		arg_s_nold = {
+			'D': "FromLD((void*)(R_RSP + {p})), ",      # K
+			'Y': "to_complexk(emu, R_RSP + {p}), ",     # y
+		}
+		arg_s_ld = {
+			t: arg_s[conventions['F'].values.index(t)] for t in arg_s_nold
+		}
 		
 		# Asserts
 		for k in conventions:
@@ -1446,22 +1503,82 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			f.write(" }\n")
 		
 		for k in gbls:
+			any_depends_on_ld = False
 			if k != str(Clauses()):
 				file.write("\n#if " + k + "\n")
 			for v in gbls[k]:
+				if any(c in v for c in depends_on_ld):
+					any_depends_on_ld = True
+					continue
 				if v == FunctionType("vFv"):
 					# Suppress all warnings...
 					file.write("void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); (void)emu; }\n")
 				else:
 					function_writer(file, v, v + "_t")
+			if any_depends_on_ld:
+				file.write("\n#ifdef HAVE_LD80BITS\n")
+				for v in gbls[k]:
+					if all(c not in v for c in depends_on_ld):
+						continue
+					if v == FunctionType("vFv"):
+						# Suppress all warnings...
+						file.write("void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); (void)emu; }\n")
+					else:
+						function_writer(file, v, v + "_t")
+				file.write("#else // HAVE_LD80BITS\n")
+				for c in vals_nold:
+					for t in vals_nold[c]:
+						vals[c][c.values.index(t)] = vals_nold[c][t]
+				for t in arg_s_nold:
+					arg_s[conventions['F'].values.index(t)] = arg_s_nold[t]
+				for v in gbls[k]:
+					if all(c not in v for c in depends_on_ld):
+						continue
+					if v == FunctionType("vFv"):
+						# Suppress all warnings...
+						file.write("void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); (void)emu; }\n")
+					else:
+						function_writer(file, v, v + "_t")
+				for c in vals_nold:
+					for t in vals_ld[c]:
+						vals[c][c.values.index(t)] = vals_ld[c][t]
+				for t in arg_s_nold:
+					arg_s[conventions['F'].values.index(t)] = arg_s_nold[t]
+				file.write("#endif\n")
 			if k != str(Clauses()):
 				file.write("#endif\n")
 		file.write("\n")
 		for k in redirects:
+			any_depends_on_ld = False
 			if k != str(Clauses()):
 				file.write("\n#if " + k + "\n")
 			for vr, vf in redirects[k]:
+				if any(c in vr for c in depends_on_ld):
+					any_depends_on_ld = True
+					continue
 				function_writer(file, vr, vf + "_t")
+			if any_depends_on_ld:
+				file.write("\n#ifdef HAVE_LD80BITS\n")
+				for vr, vf in redirects[k]:
+					if all(c not in vr for c in depends_on_ld):
+						continue
+					function_writer(file, vr, vf + "_t")
+				file.write("#else // HAVE_LD80BITS\n")
+				for c in vals_nold:
+					for t in vals_nold[c]:
+						vals[c][c.values.index(t)] = vals_nold[c][t]
+				for t in arg_s_nold:
+					arg_s[conventions['F'].values.index(t)] = arg_s_nold[t]
+				for vr, vf in redirects[k]:
+					if all(c not in vr for c in depends_on_ld):
+						continue
+					function_writer(file, vr, vf + "_t")
+				for c in vals_nold:
+					for t in vals_ld[c]:
+						vals[c][c.values.index(t)] = vals_ld[c][t]
+				for t in arg_s_nold:
+					arg_s[conventions['F'].values.index(t)] = arg_s_nold[t]
+				file.write("#endif\n")
 			if k != str(Clauses()):
 				file.write("#endif\n")
 		
@@ -1561,11 +1678,11 @@ def main(root: str, files: Iterable[Filename], ver: str):
 	return 0
 
 if __name__ == '__main__':
-	limit = []
+	limit: List[int] = []
 	for i, v in enumerate(sys.argv):
 		if v == "--":
 			limit.append(i)
 	Define.defines = list(map(DefineType, sys.argv[2:limit[0]]))
-	if main(sys.argv[1], sys.argv[limit[0]+1:], "2.4.0.23") != 0:
+	if main(sys.argv[1], sys.argv[limit[0]+1:], "2.5.0.24") != 0:
 		exit(2)
 	exit(0)