Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-46528: Check PyMem_Malloc call for NULL #30998

Merged
merged 1 commit into from
Feb 9, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 15 additions & 8 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -8443,21 +8443,22 @@ fold_tuple_on_constants(struct compiler *c,
#define VISITED (-1)

// Replace an arbitrary run of SWAPs and NOPs with an optimal one that has the
// same effect. Return the number of instructions that were optimized.
// same effect.
static int
swaptimize(basicblock *block, int ix)
swaptimize(basicblock *block, int *ix)
{
// NOTE: "./python -m test test_patma" serves as a good, quick stress test
// for this function. Make sure to blow away cached *.pyc files first!
assert(ix < block->b_iused);
struct instr *instructions = &block->b_instr[ix];
assert(*ix < block->b_iused);
struct instr *instructions = &block->b_instr[*ix];
// Find the length of the current sequence of SWAPs and NOPs, and record the
// maximum depth of the stack manipulations:
assert(instructions[0].i_opcode == SWAP);
int depth = instructions[0].i_oparg;
int len = 0;
int more = false;
while (++len < block->b_iused - ix) {
int limit = block->b_iused - *ix;
while (++len < limit) {
int opcode = instructions[len].i_opcode;
if (opcode == SWAP) {
depth = Py_MAX(depth, instructions[len].i_oparg);
Expand All @@ -8473,6 +8474,10 @@ swaptimize(basicblock *block, int ix)
}
// Create an array with elements {0, 1, 2, ..., depth - 1}:
int *stack = PyMem_Malloc(depth * sizeof(int));
if (stack == NULL) {
PyErr_NoMemory();
return -1;
}
for (int i = 0; i < depth; i++) {
stack[i] = i;
}
Expand Down Expand Up @@ -8530,9 +8535,9 @@ swaptimize(basicblock *block, int ix)
while (0 <= current) {
instructions[current--].i_opcode = NOP;
}
// Done! Return the number of optimized instructions:
PyMem_Free(stack);
return len - 1;
*ix += len - 1;
return 0;
}

// Attempt to eliminate jumps to jumps by updating inst to jump to
Expand Down Expand Up @@ -8783,7 +8788,9 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
inst->i_opcode = NOP;
break;
}
i += swaptimize(bb, i);
if (swaptimize(bb, &i)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (swaptimize(bb, &i)) {
if (swaptimize(bb, &i) < 0) {

This is much common in the codebase.

goto error;
}
break;
default:
/* All HAS_CONST opcodes should be handled with LOAD_CONST */
Expand Down