port: advance VC6 typeobject frontier and preserve regression coverage
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Guard VC6-compatible default allocator copies, fields, and call order."""
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
source = Path(sys.argv[1]).read_text()
|
||||
# Preserve ctx/malloc/calloc/realloc/free and WITH_PYMALLOC selection.
|
||||
macros = source[source.index("#define MALLOC_ALLOC"):source.index("typedef struct {", source.index("#define MALLOC_ALLOC"))]
|
||||
expected_macros = """
|
||||
#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree}
|
||||
#ifdef WITH_PYMALLOC
|
||||
# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free}
|
||||
#endif
|
||||
#define PYRAW_ALLOC MALLOC_ALLOC
|
||||
#ifdef WITH_PYMALLOC
|
||||
# define PYOBJ_ALLOC PYMALLOC_ALLOC
|
||||
#else
|
||||
# define PYOBJ_ALLOC MALLOC_ALLOC
|
||||
#endif
|
||||
#define PYMEM_ALLOC PYOBJ_ALLOC
|
||||
"""
|
||||
assert macros.split() == expected_macros.split(), (
|
||||
"default allocator fields or WITH_PYMALLOC selection changed"
|
||||
)
|
||||
|
||||
match = re.search(
|
||||
r"\npymem_set_default_allocator\([^)]*\)\s*\{(.*?)\n\}", source, re.S
|
||||
)
|
||||
assert match, "pymem_set_default_allocator definition not found"
|
||||
body = re.sub(r"/\*.*?\*/", "", match.group(1), flags=re.S)
|
||||
declaration = "PyMemAllocatorEx new_alloc;"
|
||||
if body.count(declaration) != 1 or not body.lstrip().startswith(declaration):
|
||||
sys.exit("new_alloc must be declared once without initializer at function entry")
|
||||
|
||||
expected = """
|
||||
if (old_alloc != NULL) {
|
||||
PyMem_GetAllocator(domain, old_alloc);
|
||||
}
|
||||
switch(domain)
|
||||
{
|
||||
case PYMEM_DOMAIN_RAW:
|
||||
{
|
||||
PyMemAllocatorEx alloc = PYRAW_ALLOC;
|
||||
new_alloc = alloc;
|
||||
break;
|
||||
}
|
||||
case PYMEM_DOMAIN_MEM:
|
||||
{
|
||||
PyMemAllocatorEx alloc = PYMEM_ALLOC;
|
||||
new_alloc = alloc;
|
||||
break;
|
||||
}
|
||||
case PYMEM_DOMAIN_OBJ:
|
||||
{
|
||||
PyMemAllocatorEx alloc = PYOBJ_ALLOC;
|
||||
new_alloc = alloc;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
PyMem_SetAllocator(domain, &new_alloc);
|
||||
if (debug) {
|
||||
_PyMem_SetupDebugHooksDomain(domain);
|
||||
}
|
||||
return 0;
|
||||
"""
|
||||
if body.replace(declaration, "").split() != expected.split():
|
||||
sys.exit("default allocator switch, assignments, or call order changed")
|
||||
print("obmalloc default allocator C89 assignments, allocator semantics, and execution order: PASS")
|
||||
Reference in New Issue
Block a user