summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-11-23 09:53:24 (GMT)
committerGitHub <noreply@github.com>2021-11-23 09:53:24 (GMT)
commit135cabd328504e1648d17242b42b675cdbd0193b (patch)
tree4efa5418b1816ba02c206678ecfa4e2d8e8d8f14 /Python/compile.c
parentd82f2caf942fa8b94e797a2f116ee54ec303c2df (diff)
downloadcpython-135cabd328504e1648d17242b42b675cdbd0193b.zip
cpython-135cabd328504e1648d17242b42b675cdbd0193b.tar.gz
cpython-135cabd328504e1648d17242b42b675cdbd0193b.tar.bz2
bpo-44525: Copy free variables in bytecode to allow calls to inner functions to be specialized (GH-29595)
* Make internal APIs that take PyFrameConstructor take a PyFunctionObject instead. * Add reference to function to frame, borrow references to builtins and globals. * Add COPY_FREE_VARS instruction to allow specialization of calls to inner functions.
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 40bd1fd..87de7ba 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1171,6 +1171,7 @@ stack_effect(int opcode, int oparg, int jump)
/* Closures */
case MAKE_CELL:
+ case COPY_FREE_VARS:
return 0;
case LOAD_CLOSURE:
return 1;
@@ -7611,7 +7612,7 @@ insert_instruction(basicblock *block, int pos, struct instr *instr) {
static int
insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
- int *fixed)
+ int *fixed, int nfreevars)
{
int flags = compute_code_flags(c);
@@ -7684,6 +7685,22 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock,
}
}
+ if (nfreevars) {
+ struct instr copy_frees = {
+ .i_opcode = COPY_FREE_VARS,
+ .i_oparg = nfreevars,
+ .i_lineno = -1,
+ .i_col_offset = -1,
+ .i_end_lineno = -1,
+ .i_end_col_offset = -1,
+ .i_target = NULL,
+ };
+ if (insert_instruction(entryblock, 0, &copy_frees) < 0) {
+ return -1;
+ }
+
+ }
+
return 0;
}
@@ -7818,7 +7835,7 @@ assemble(struct compiler *c, int addNone)
}
// This must be called before fix_cell_offsets().
- if (insert_prefix_instructions(c, entryblock, cellfixedoffsets)) {
+ if (insert_prefix_instructions(c, entryblock, cellfixedoffsets, nfreevars)) {
goto error;
}