Skip to content

Commit ffa55d2

Browse files
authored
bpo-39448: Add regen-frozen makefile target. (GH-18174)
Add the "regen-frozen" makefile target that regenerates the code for the frozen __hello__ module.
1 parent 743932d commit ffa55d2

File tree

6 files changed

+82
-21
lines changed

6 files changed

+82
-21
lines changed

Lib/ctypes/test/test_values.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ class struct_frozen(Structure):
8080
continue
8181
items.append((entry.name.decode("ascii"), entry.size))
8282

83-
expected = [("__hello__", 141),
84-
("__phello__", -141),
85-
("__phello__.spam", 141),
83+
expected = [("__hello__", 125),
84+
("__phello__", -125),
85+
("__phello__.spam", 125),
8686
]
8787
self.assertEqual(items, expected, "PyImport_FrozenModules example "
8888
"in Doc/library/ctypes.rst may be out of date")

Makefile.pre.in

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ regen-limited-abi: all
761761

762762
regen-all: regen-opcode regen-opcode-targets regen-typeslots \
763763
regen-token regen-ast regen-keyword regen-importlib clinic \
764-
regen-pegen-metaparser regen-pegen
764+
regen-pegen-metaparser regen-pegen regen-frozen
765765
@echo
766766
@echo "Note: make regen-stdlib-module-names and autoconf should be run manually"
767767

@@ -870,6 +870,11 @@ regen-opcode:
870870
$(srcdir)/Include/opcode.h.new
871871
$(UPDATE_FILE) $(srcdir)/Include/opcode.h $(srcdir)/Include/opcode.h.new
872872

873+
.PHONY: regen-frozen
874+
regen-frozen:
875+
# Regenerate code for frozen module "__hello__".
876+
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/freeze/regen_frozen.py $(srcdir)/Python/frozen_hello.h
877+
873878
.PHONY: regen-token
874879
regen-token:
875880
# Regenerate Doc/library/token-list.inc from Grammar/Tokens
@@ -974,7 +979,7 @@ Python/ceval.o: $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/ceval_gil.h \
974979
$(srcdir)/Python/condvar.h
975980

976981
Python/frozen.o: $(srcdir)/Python/importlib.h $(srcdir)/Python/importlib_external.h \
977-
$(srcdir)/Python/importlib_zipimport.h
982+
$(srcdir)/Python/importlib_zipimport.h $(srcdir)/Python/frozen_hello.h
978983

979984
# Generate DTrace probe macros, then rename them (PYTHON_ -> PyDTrace_) to
980985
# follow our naming conventions. dtrace(1) uses the output filename to generate
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add the "regen-frozen" makefile target that regenerates the code for the
2+
frozen ``__hello__`` module.

Python/frozen.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
/* Dummy frozen modules initializer */
2+
/* Frozen modules initializer */
33

44
#include "Python.h"
55
#include "importlib.h"
@@ -10,21 +10,11 @@
1010
define a single frozen module, __hello__. Loading it will print
1111
some famous words... */
1212

13-
/* To regenerate this data after the bytecode or marshal format has changed,
14-
go to ../Tools/freeze/ and freeze the flag.py file; then copy and paste
15-
the appropriate bytes from M___main__.c. */
16-
17-
static unsigned char M___hello__[] = {
18-
227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
19-
0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0,
20-
90,0,101,1,100,1,131,1,1,0,100,2,83,0,41,3,
21-
84,122,12,72,101,108,108,111,32,119,111,114,108,100,33,78,
22-
41,2,218,11,105,110,105,116,105,97,108,105,122,101,100,218,
23-
5,112,114,105,110,116,169,0,114,3,0,0,0,114,3,0,
24-
0,0,250,20,84,111,111,108,115,47,102,114,101,101,122,101,
25-
47,102,108,97,103,46,112,121,218,8,60,109,111,100,117,108,
26-
101,62,1,0,0,0,115,2,0,0,0,4,1,
27-
};
13+
/* Run "make regen-frozen" to regen the file below (e.g. after a bytecode
14+
* format change). The file is created by Tools/frozen/regen_frozen.py. The
15+
* include file defines M___hello__ as an array of bytes.
16+
*/
17+
#include "frozen_hello.h"
2818

2919
#define SIZE (int)sizeof(M___hello__)
3020

Python/frozen_hello.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* Generated with Tools/freeze/regen_frozen.py */
2+
static unsigned char M___hello__[] = {
3+
227,0,0,0,0,0,0,0,0,0,0,0,0,
4+
0,0,0,0,2,0,0,0,64,0,0,0,115,
5+
16,0,0,0,100,0,90,0,101,1,100,1,131,
6+
1,1,0,100,2,83,0,41,3,84,122,12,72,
7+
101,108,108,111,32,119,111,114,108,100,33,78,41,
8+
2,90,11,105,110,105,116,105,97,108,105,122,101,
9+
100,218,5,112,114,105,110,116,169,0,114,2,0,
10+
0,0,114,2,0,0,0,218,4,110,111,110,101,
11+
218,8,60,109,111,100,117,108,101,62,1,0,0,
12+
0,115,2,0,0,0,4,1,
13+
};

Tools/freeze/regen_frozen.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env python3
2+
import sys
3+
import os
4+
import marshal
5+
6+
7+
DIR = os.path.dirname(sys.argv[0])
8+
# source code for module to freeze
9+
FILE = os.path.join(DIR, 'flag.py')
10+
# C symbol to use for array holding frozen bytes
11+
SYMBOL = 'M___hello__'
12+
13+
14+
def get_module_code(filename):
15+
"""Compile 'filename' and return the module code as a marshalled byte
16+
string.
17+
"""
18+
with open(filename, 'r') as fp:
19+
src = fp.read()
20+
co = compile(src, 'none', 'exec')
21+
co_bytes = marshal.dumps(co)
22+
return co_bytes
23+
24+
25+
def gen_c_code(fp, co_bytes):
26+
"""Generate C code for the module code in 'co_bytes', write it to 'fp'.
27+
"""
28+
def write(*args, **kwargs):
29+
print(*args, **kwargs, file=fp)
30+
write('/* Generated with Tools/freeze/regen_frozen.py */')
31+
write('static unsigned char %s[] = {' % SYMBOL, end='')
32+
bytes_per_row = 13
33+
for i, opcode in enumerate(co_bytes):
34+
if (i % bytes_per_row) == 0:
35+
# start a new row
36+
write()
37+
write(' ', end='')
38+
write('%d,' % opcode, end='')
39+
write()
40+
write('};')
41+
42+
43+
def main():
44+
out_filename = sys.argv[1]
45+
co_bytes = get_module_code(FILE)
46+
with open(out_filename, 'w') as fp:
47+
gen_c_code(fp, co_bytes)
48+
49+
50+
if __name__ == '__main__':
51+
main()

0 commit comments

Comments
 (0)