Skip to content

Commit 39284db

Browse files
committed
Formula to calculate padding for memory alignment
1 parent 1673081 commit 39284db

File tree

1 file changed

+113
-87
lines changed

1 file changed

+113
-87
lines changed

Source/PythonEngine.pas

+113-87
Original file line numberDiff line numberDiff line change
@@ -9995,11 +9995,16 @@ constructor PyConfig.Create(const AMinVersion: integer;
99959995

99969996
procedure PyConfig.Patch(const AMinVersion: integer;
99979997
const APyGILEnabled, APyStatEnabled, APyDebugEnabled: boolean);
9998-
type
9999-
TDataType = (dtChar = 0, dtShort = 2, dtInt = 4, dtLong = 8, dtPointer = 8);
100009998

10001-
function MakeSlot(var ASlot: pointer; const ASize: byte; ADataType: TDataType): pointer;
9999+
function MakeAddr(var AAddr: pointer; const AMemberSize: byte): pointer; overload;
10000+
{$IFDEF CPU64BITS}
10001+
var
10002+
LAlign: NativeUInt;
10003+
LOffset: NativeUInt;
10004+
LPadding: byte;
10005+
{$ENDIF CPU64BITS}
1000210006
begin
10007+
{$IFDEF CPU64BITS}
1000310008
{
1000410009
Data Type | Size in Bytes | Self-Alignment
1000510010
char 1 None (any address is fine)
@@ -10009,159 +10014,180 @@ procedure PyConfig.Patch(const AMinVersion: integer;
1000910014
Pointer 8 The address has to be a multiple of 8
1001010015
}
1001110016

10012-
{$IFDEF CPU64BITS}
10013-
while (NativeUInt(ASlot) mod Byte(ADataType)) <> 0 do
10014-
Inc(PByte(ASlot));
10017+
// Formula: padding = align - (current offset mod align) mod align
10018+
10019+
Assert(AMemberSize <= 8, 'Structure members must be handled individually.');
10020+
10021+
LAlign := AMemberSize;
10022+
LOffset := NativeUInt(AAddr) - NativeUInt(@_container[0]);
10023+
LPadding := (LAlign - (LOffset mod LAlign)) mod LAlign;
10024+
10025+
PNativeUInt(AAddr) := Pointer(NativeUInt(AAddr) + LPadding);
1001510026
{$ENDIF CPU64BITS}
1001610027

10017-
Result := ASlot;
10018-
PNativeUInt(ASlot) := Pointer(NativeUInt(ASlot) + ASize);
10028+
Result := AAddr;
10029+
PNativeUInt(AAddr) := Pointer(NativeUInt(AAddr) + AMemberSize);
1001910030
end;
1002010031

10032+
function MakeAddr(var AAddr: pointer; const AStructMembersSizes: TArray<byte>): pointer; overload;
10033+
begin
10034+
Assert(Length(AStructMembersSizes) > 0, 'Invalid argument "AStructMembersSizes".');
10035+
10036+
Result := MakeAddr(AAddr, AStructMembersSizes[Low(AStructMembersSizes)]);
10037+
for var I := Low(AStructMembersSizes) + 1 to High(AStructMembersSizes) do
10038+
MakeAddr(AAddr, AStructMembersSizes[I]);
10039+
end;
10040+
10041+
var
10042+
LAddr: pointer;
10043+
const
10044+
PyWideStringListMembersSizes: TArray<byte> = [
10045+
SizeOf(Py_ssize_t),
10046+
SizeOf(PPWCharT)];
1002110047
begin
10022-
var LSlot: pointer := @_container[0];
10048+
LAddr := @_container[Low(_container)];
1002310049
FillChar(_container, SizeOf(_container), 0);
1002410050

10025-
_config_init := MakeSlot(LSlot, SizeOf(integer), dtInt);
10026-
isolated := MakeSlot(LSlot, SizeOf(integer), dtInt);
10027-
use_environment := MakeSlot(LSlot, SizeOf(integer), dtInt);
10028-
dev_mode := MakeSlot(LSlot, SizeOf(integer), dtInt);
10029-
install_signal_handlers := MakeSlot(LSlot, SizeOf(integer), dtInt);
10030-
use_hash_seed := MakeSlot(LSlot, SizeOf(integer), dtInt);
10031-
hash_seed := MakeSlot(LSlot, SizeOf(C_LONG), dtInt);
10032-
faulthandler := MakeSlot(LSlot, SizeOf(integer), dtInt);
10051+
_config_init := MakeAddr(LAddr, SizeOf(integer));
10052+
isolated := MakeAddr(LAddr, SizeOf(integer));
10053+
use_environment := MakeAddr(LAddr, SizeOf(integer));
10054+
dev_mode := MakeAddr(LAddr, SizeOf(integer));
10055+
install_signal_handlers := MakeAddr(LAddr, SizeOf(integer));
10056+
use_hash_seed := MakeAddr(LAddr, SizeOf(integer));
10057+
hash_seed := MakeAddr(LAddr, SizeOf(C_LONG));
10058+
faulthandler := MakeAddr(LAddr, SizeOf(integer));
1003310059

1003410060
if (AMinVersion = 9) then
10035-
_use_peg_parser := MakeSlot(LSlot, SizeOf(integer), dtInt);
10061+
_use_peg_parser := MakeAddr(LAddr, SizeOf(integer));
1003610062

10037-
tracemalloc := MakeSlot(LSlot, SizeOf(integer), dtInt);
10063+
tracemalloc := MakeAddr(LAddr, SizeOf(integer));
1003810064

1003910065
if (AMinVersion >= 12) then
10040-
perf_profiling := MakeSlot(LSlot, SizeOf(integer), dtInt);
10066+
perf_profiling := MakeAddr(LAddr, SizeOf(integer));
1004110067

10042-
import_time := MakeSlot(LSlot, SizeOf(integer), dtInt);
10068+
import_time := MakeAddr(LAddr, SizeOf(integer));
1004310069

1004410070
if (AMinVersion >= 11) then
10045-
code_debug_ranges := MakeSlot(LSlot, SizeOf(integer), dtInt);
10071+
code_debug_ranges := MakeAddr(LAddr, SizeOf(integer));
1004610072

10047-
show_ref_count := MakeSlot(LSlot, SizeOf(integer), dtInt);
10073+
show_ref_count := MakeAddr(LAddr, SizeOf(integer));
1004810074

1004910075
if (AMinVersion = 8) then
10050-
show_alloc_count := MakeSlot(LSlot, SizeOf(integer), dtInt);
10076+
show_alloc_count := MakeAddr(LAddr, SizeOf(integer));
1005110077

10052-
dump_refs := MakeSlot(LSlot, SizeOf(integer), dtInt);
10078+
dump_refs := MakeAddr(LAddr, SizeOf(integer));
1005310079

1005410080
if (AMinVersion >= 11) then
10055-
dump_refs_file := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10081+
dump_refs_file := MakeAddr(LAddr, SizeOf(PWCharT));
1005610082

10057-
malloc_stats := MakeSlot(LSlot, SizeOf(integer), dtInt);
10058-
filesystem_encoding := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10059-
filesystem_errors := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10060-
pycache_prefix := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10061-
parse_argv := MakeSlot(LSlot, SizeOf(integer), dtInt);
10083+
malloc_stats := MakeAddr(LAddr, SizeOf(integer));
10084+
filesystem_encoding := MakeAddr(LAddr, SizeOf(PWCharT));
10085+
filesystem_errors := MakeAddr(LAddr, SizeOf(PWCharT));
10086+
pycache_prefix := MakeAddr(LAddr, SizeOf(PWCharT));
10087+
parse_argv := MakeAddr(LAddr, SizeOf(integer));
1006210088

1006310089
if (AMinVersion >= 10) then
10064-
orig_argv := MakeSlot(LSlot, SizeOf(PyWideStringList), dtPointer);
10090+
orig_argv := MakeAddr(LAddr, PyWideStringListMembersSizes);
1006510091

10066-
argv := MakeSlot(LSlot, SizeOf(PyWideStringList), dtPointer);
10092+
argv := MakeAddr(LAddr, PyWideStringListMembersSizes);
1006710093

1006810094
if (AMinVersion <= 9) then
10069-
program_name := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10095+
program_name := MakeAddr(LAddr, SizeOf(PWCharT));
1007010096

10071-
xoptions := MakeSlot(LSlot, SizeOf(PyWideStringList), dtPointer);
10072-
warnoptions := MakeSlot(LSlot, SizeOf(PyWideStringList), dtPointer);
10073-
site_import := MakeSlot(LSlot, SizeOf(integer), dtInt);
10074-
bytes_warning := MakeSlot(LSlot, SizeOf(integer), dtInt);
10097+
xoptions := MakeAddr(LAddr, PyWideStringListMembersSizes);
10098+
warnoptions := MakeAddr(LAddr, PyWideStringListMembersSizes);
10099+
site_import := MakeAddr(LAddr, SizeOf(integer));
10100+
bytes_warning := MakeAddr(LAddr, SizeOf(integer));
1007510101

1007610102
if (AMinVersion >= 10) then
10077-
warn_default_encoding := MakeSlot(LSlot, SizeOf(integer), dtInt);
10078-
10079-
inspect := MakeSlot(LSlot, SizeOf(integer), dtInt);
10080-
interactive := MakeSlot(LSlot, SizeOf(integer), dtInt);
10081-
optimization_level := MakeSlot(LSlot, SizeOf(integer), dtInt);
10082-
parser_debug := MakeSlot(LSlot, SizeOf(integer), dtInt);
10083-
write_bytecode := MakeSlot(LSlot, SizeOf(integer), dtInt);
10084-
verbose := MakeSlot(LSlot, SizeOf(integer), dtInt);
10085-
quiet := MakeSlot(LSlot, SizeOf(integer), dtInt);
10086-
user_site_directory := MakeSlot(LSlot, SizeOf(integer), dtInt);
10087-
configure_c_stdio := MakeSlot(LSlot, SizeOf(integer), dtInt);
10088-
beffered_stdio := MakeSlot(LSlot, SizeOf(integer), dtInt);
10089-
stdio_encoding := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10090-
stdio_errors := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10103+
warn_default_encoding := MakeAddr(LAddr, SizeOf(integer));
10104+
10105+
inspect := MakeAddr(LAddr, SizeOf(integer));
10106+
interactive := MakeAddr(LAddr, SizeOf(integer));
10107+
optimization_level := MakeAddr(LAddr, SizeOf(integer));
10108+
parser_debug := MakeAddr(LAddr, SizeOf(integer));
10109+
write_bytecode := MakeAddr(LAddr, SizeOf(integer));
10110+
verbose := MakeAddr(LAddr, SizeOf(integer));
10111+
quiet := MakeAddr(LAddr, SizeOf(integer));
10112+
user_site_directory := MakeAddr(LAddr, SizeOf(integer));
10113+
configure_c_stdio := MakeAddr(LAddr, SizeOf(integer));
10114+
beffered_stdio := MakeAddr(LAddr, SizeOf(integer));
10115+
stdio_encoding := MakeAddr(LAddr, SizeOf(PWCharT));
10116+
stdio_errors := MakeAddr(LAddr, SizeOf(PWCharT));
1009110117

1009210118
{$IFDEF MSWINDOWS}
10093-
legacy_windows_stdio := MakeSlot(LSlot, SizeOf(integer), dtInt);
10119+
legacy_windows_stdio := MakeAddr(LAddr, SizeOf(integer));
1009410120
{$ENDIF MSWINDOWS}
1009510121

10096-
check_hash_pycs_mode := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10122+
check_hash_pycs_mode := MakeAddr(LAddr, SizeOf(PWCharT));
1009710123

1009810124
if (AMinVersion >= 11) then
10099-
use_frozen_modules := MakeSlot(LSlot, SizeOf(integer), dtInt);
10125+
use_frozen_modules := MakeAddr(LAddr, SizeOf(integer));
1010010126

1010110127
if (AMinVersion >= 11) then
10102-
safe_path := MakeSlot(LSlot, SizeOf(integer), dtInt);
10128+
safe_path := MakeAddr(LAddr, SizeOf(integer));
1010310129

1010410130
if (AMinVersion >= 12) then
10105-
int_max_str_digits := MakeSlot(LSlot, SizeOf(integer), dtInt);
10131+
int_max_str_digits := MakeAddr(LAddr, SizeOf(integer));
1010610132

1010710133
if (AMinVersion >= 13) then
10108-
cpu_count := MakeSlot(LSlot, SizeOf(integer), dtInt);
10134+
cpu_count := MakeAddr(LAddr, SizeOf(integer));
1010910135

1011010136
if (AMinVersion >= 13) and APyGILEnabled then
10111-
enable_gil := MakeSlot(LSlot, SizeOf(integer), dtInt);
10137+
enable_gil := MakeAddr(LAddr, SizeOf(integer));
1011210138

10113-
pathconfig_warnings := MakeSlot(LSlot, SizeOf(integer), dtInt);
10139+
pathconfig_warnings := MakeAddr(LAddr, SizeOf(integer));
1011410140

1011510141
if (AMinVersion >= 10) then
10116-
program_name_1 := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10142+
program_name_1 := MakeAddr(LAddr, SizeOf(PWCharT));
1011710143

10118-
pythonpath_env := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10119-
home := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10144+
pythonpath_env := MakeAddr(LAddr, SizeOf(PWCharT));
10145+
home := MakeAddr(LAddr, SizeOf(PWCharT));
1012010146

1012110147
if (AMinVersion >= 10) then
10122-
platlibdir_1 := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10148+
platlibdir_1 := MakeAddr(LAddr, SizeOf(PWCharT));
1012310149

10124-
module_search_paths_set := MakeSlot(LSlot, SizeOf(integer), dtInt);
10125-
module_search_paths := MakeSlot(LSlot, SizeOf(PyWideStringList), dtPointer);
10150+
module_search_paths_set := MakeAddr(LAddr, SizeOf(integer));
10151+
module_search_paths := MakeAddr(LAddr, PyWideStringListMembersSizes);
1012610152

1012710153
if (AMinVersion >= 11) then
10128-
stdlib_dir := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10154+
stdlib_dir := MakeAddr(LAddr, SizeOf(PWCharT));
1012910155

10130-
executable := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10131-
base_executable := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10132-
prefix := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10133-
base_prefix := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10134-
exec_prefix := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10135-
base_exec_prefix := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10156+
executable := MakeAddr(LAddr, SizeOf(PWCharT));
10157+
base_executable := MakeAddr(LAddr, SizeOf(PWCharT));
10158+
prefix := MakeAddr(LAddr, SizeOf(PWCharT));
10159+
base_prefix := MakeAddr(LAddr, SizeOf(PWCharT));
10160+
exec_prefix := MakeAddr(LAddr, SizeOf(PWCharT));
10161+
base_exec_prefix := MakeAddr(LAddr, SizeOf(PWCharT));
1013610162

1013710163
if (AMinVersion = 9) then
10138-
platlibdir := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10164+
platlibdir := MakeAddr(LAddr, SizeOf(PWCharT));
1013910165

10140-
skip_source_first_line := MakeSlot(LSlot, SizeOf(integer), dtInt);
10141-
run_command := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10142-
run_module := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10143-
run_filename := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10166+
skip_source_first_line := MakeAddr(LAddr, SizeOf(integer));
10167+
run_command := MakeAddr(LAddr, SizeOf(PWCharT));
10168+
run_module := MakeAddr(LAddr, SizeOf(PWCharT));
10169+
run_filename := MakeAddr(LAddr, SizeOf(PWCharT));
1014410170

1014510171
if (AMinVersion >= 13) then
10146-
sys_path_0 := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10172+
sys_path_0 := MakeAddr(LAddr, SizeOf(PWCharT));
1014710173

10148-
_install_importlib := MakeSlot(LSlot, SizeOf(integer), dtInt);
10149-
_init_main := MakeSlot(LSlot, SizeOf(integer), dtInt);
10174+
_install_importlib := MakeAddr(LAddr, SizeOf(integer));
10175+
_init_main := MakeAddr(LAddr, SizeOf(integer));
1015010176

1015110177
if (AMinVersion >= 9) then
10152-
_isolated_interpreter := MakeSlot(LSlot, SizeOf(integer), dtInt);
10178+
_isolated_interpreter := MakeAddr(LAddr, SizeOf(integer));
1015310179

1015410180
if (AMinVersion = 9) then
10155-
_orig_argv := MakeSlot(LSlot, SizeOf(PyWideStringList), dtPointer);
10181+
_orig_argv := MakeAddr(LAddr, PyWideStringListMembersSizes);
1015610182

1015710183
if (AMinVersion >= 11) then
10158-
_is_python_build := MakeSlot(LSlot, SizeOf(integer), dtInt);
10184+
_is_python_build := MakeAddr(LAddr, SizeOf(integer));
1015910185

1016010186
if (AMinVersion >= 13) and APyStatEnabled then
10161-
_pystats := MakeSlot(LSlot, SizeOf(integer), dtInt);
10187+
_pystats := MakeAddr(LAddr, SizeOf(integer));
1016210188

1016310189
if (AMinVersion >= 13) and APyDebugEnabled then
10164-
run_presite := MakeSlot(LSlot, SizeOf(PWCharT), dtPointer);
10190+
run_presite := MakeAddr(LAddr, SizeOf(PWCharT));
1016510191

1016610192
// Redirects
1016710193
if (AMinVersion >= 10) then begin
@@ -10170,7 +10196,7 @@ procedure PyConfig.Patch(const AMinVersion: integer;
1017010196
end;
1017110197

1017210198
Assert(
10173-
(NativeUInt(LSlot) - NativeUInt(@Self)) <= SizeOf(_container),
10199+
(NativeUInt(LAddr) - NativeUInt(@Self)) <= SizeOf(_container),
1017410200
'Insufficient memory.');
1017510201
end;
1017610202

0 commit comments

Comments
 (0)