Skip to content

Commit fa5c6fd

Browse files
committed
Make PyStackRef_CLOSE escaping.
1 parent 75b4962 commit fa5c6fd

File tree

11 files changed

+1493
-597
lines changed

11 files changed

+1493
-597
lines changed

Include/internal/pycore_uop_metadata.h

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_generated_cases.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,9 @@ def test_error_if_plain(self):
538538
frame->instr_ptr = next_instr;
539539
next_instr += 1;
540540
INSTRUCTION_STATS(OP);
541-
if (cond) goto label;
541+
if (cond) {
542+
goto label;
543+
}
542544
DISPATCH();
543545
}
544546
"""
@@ -555,7 +557,9 @@ def test_error_if_plain_with_comment(self):
555557
frame->instr_ptr = next_instr;
556558
next_instr += 1;
557559
INSTRUCTION_STATS(OP);
558-
if (cond) goto label;
560+
if (cond) {
561+
goto label;
562+
}
559563
// Comment is ok
560564
DISPATCH();
561565
}
@@ -582,7 +586,11 @@ def test_error_if_pop(self):
582586
right = stack_pointer[-1];
583587
left = stack_pointer[-2];
584588
SPAM(left, right);
585-
if (cond) goto pop_2_label;
589+
if (cond) {
590+
stack_pointer += -2;
591+
assert(WITHIN_STACK_BOUNDS());
592+
goto label;
593+
}
586594
res = 0;
587595
stack_pointer[-2] = res;
588596
stack_pointer += -1;
@@ -611,7 +619,12 @@ def test_error_if_pop_with_result(self):
611619
right = stack_pointer[-1];
612620
left = stack_pointer[-2];
613621
res = SPAM(left, right);
614-
if (cond) goto pop_2_label;
622+
if (cond) {
623+
stack_pointer[-2] = res;
624+
stack_pointer += -1;
625+
assert(WITHIN_STACK_BOUNDS());
626+
goto label;
627+
}
615628
stack_pointer[-2] = res;
616629
stack_pointer += -1;
617630
assert(WITHIN_STACK_BOUNDS());
@@ -1392,7 +1405,11 @@ def test_pop_on_error_peeks(self):
13921405
// THIRD
13931406
{
13941407
// Mark j and k as used
1395-
if (cond) goto pop_2_error;
1408+
if (cond) {
1409+
stack_pointer += -2;
1410+
assert(WITHIN_STACK_BOUNDS());
1411+
goto error;
1412+
}
13961413
}
13971414
stack_pointer += -2;
13981415
assert(WITHIN_STACK_BOUNDS());

Python/bytecodes.c

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,8 +2120,7 @@ dummy_func(
21202120
PyStackRef_CLOSE(self_st);
21212121
self_or_null = PyStackRef_NULL;
21222122
}
2123-
PyStackRef_CLOSE(class_st);
2124-
PyStackRef_CLOSE(global_super_st);
2123+
DECREF_INPUTS();
21252124

21262125
attr = PyStackRef_FromPyObjectSteal(attr_o);
21272126
}
@@ -3635,15 +3634,14 @@ dummy_func(
36353634
EXIT_IF(!PyStackRef_IsNull(null[0]));
36363635
}
36373636

3638-
op(_EXPAND_METHOD, (callable[1], null[1], unused[oparg] -- method[1], self[1], unused[oparg])) {
3637+
op(_EXPAND_METHOD, (callable[1], self_or_null[1], unused[oparg] -- callable[1], self_or_null[1], unused[oparg])) {
36393638
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
3640-
assert(PyStackRef_IsNull(null[0]));
3641-
DEAD(null);
3639+
assert(PyStackRef_IsNull(self_or_null[0]));
36423640
assert(Py_TYPE(callable_o) == &PyMethod_Type);
3643-
self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
3641+
self_or_null[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
36443642
_PyStackRef temp = callable[0];
3645-
method[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
3646-
assert(PyStackRef_FunctionCheck(method[0]));
3643+
callable[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
3644+
assert(PyStackRef_FunctionCheck(callable[0]));
36473645
PyStackRef_CLOSE(temp);
36483646
}
36493647

@@ -3704,13 +3702,13 @@ dummy_func(
37043702
EXIT_IF(Py_TYPE(PyStackRef_AsPyObjectBorrow(callable[0])) != &PyMethod_Type);
37053703
}
37063704

3707-
op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable[1], null[1], unused[oparg] -- func[1], self[1], unused[oparg])) {
3708-
DEAD(null);
3705+
op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable[1], self_or_null[1], unused[oparg] -- callable[1], self_or_null[1], unused[oparg])) {
3706+
assert(PyStackRef_IsNull(self_or_null[0]));
37093707
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
37103708
STAT_INC(CALL, hit);
3711-
self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
3709+
self_or_null[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
37123710
_PyStackRef temp = callable[0];
3713-
func[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
3711+
callable[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
37143712
PyStackRef_CLOSE(temp);
37153713
}
37163714

@@ -4135,8 +4133,9 @@ dummy_func(
41354133
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
41364134

41374135
int total_args = oparg;
4136+
_PyStackRef *arguments = args;
41384137
if (!PyStackRef_IsNull(self_or_null[0])) {
4139-
args--;
4138+
arguments--;
41404139
total_args++;
41414140
}
41424141

@@ -4147,8 +4146,8 @@ dummy_func(
41474146
EXIT_IF(meth->ml_flags != METH_O);
41484147
// CPython promises to check all non-vectorcall function calls.
41494148
EXIT_IF(tstate->c_recursion_remaining <= 0);
4150-
_PyStackRef arg_stackref = args[1];
4151-
_PyStackRef self_stackref = args[0];
4149+
_PyStackRef arg_stackref = arguments[1];
4150+
_PyStackRef self_stackref = arguments[0];
41524151
EXIT_IF(!Py_IS_TYPE(PyStackRef_AsPyObjectBorrow(self_stackref),
41534152
method->d_common.d_type));
41544153
STAT_INC(CALL, hit);
@@ -4159,11 +4158,7 @@ dummy_func(
41594158
PyStackRef_AsPyObjectBorrow(arg_stackref));
41604159
_Py_LeaveRecursiveCallTstate(tstate);
41614160
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
4162-
PyStackRef_CLOSE(self_stackref);
4163-
PyStackRef_CLOSE(arg_stackref);
4164-
DEAD(args);
4165-
DEAD(self_or_null);
4166-
PyStackRef_CLOSE(callable[0]);
4161+
DECREF_INPUTS();
41674162
ERROR_IF(res_o == NULL, error);
41684163
res = PyStackRef_FromPyObjectSteal(res_o);
41694164
}
@@ -4450,15 +4445,14 @@ dummy_func(
44504445
EXIT_IF(!PyStackRef_IsNull(null[0]));
44514446
}
44524447

4453-
op(_EXPAND_METHOD_KW, (callable[1], null[1], unused[oparg], unused -- method[1], self[1], unused[oparg], unused)) {
4448+
op(_EXPAND_METHOD_KW, (callable[1], self_or_null[1], unused[oparg], unused -- callable[1], self_or_null[1], unused[oparg], unused)) {
4449+
assert(PyStackRef_IsNull(self_or_null[0]));
44544450
_PyStackRef callable_s = callable[0];
44554451
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable_s);
4456-
4457-
assert(PyStackRef_IsNull(null[0]));
44584452
assert(Py_TYPE(callable_o) == &PyMethod_Type);
4459-
self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
4460-
method[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
4461-
assert(PyStackRef_FunctionCheck(method[0]));
4453+
self_or_null[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
4454+
callable[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
4455+
assert(PyStackRef_FunctionCheck(callable[0]));
44624456
PyStackRef_CLOSE(callable_s);
44634457
}
44644458

@@ -4564,7 +4558,8 @@ dummy_func(
45644558
}
45654559
}
45664560

4567-
op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st -- result)) {
4561+
op(_DO_CALL_FUNCTION_EX, (func_st, null, callargs_st, kwargs_st -- result)) {
4562+
(void)null;
45684563
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
45694564

45704565
// DICT_MERGE is called before this opcode if there are kwargs.
@@ -4635,8 +4630,8 @@ dummy_func(
46354630
result_o = PyObject_Call(func, callargs, kwargs);
46364631
}
46374632
PyStackRef_XCLOSE(kwargs_st);
4638-
DEAD(kwargs_st);
46394633
PyStackRef_CLOSE(callargs_st);
4634+
DEAD(null);
46404635
PyStackRef_CLOSE(func_st);
46414636
ERROR_IF(result_o == NULL, error);
46424637
result = PyStackRef_FromPyObjectSteal(result_o);
@@ -4773,12 +4768,11 @@ dummy_func(
47734768

47744769
macro(BINARY_OP) = _SPECIALIZE_BINARY_OP + unused/4 + _BINARY_OP;
47754770

4776-
pure inst(SWAP, (bottom_in, unused[oparg-2], top_in --
4777-
top_out, unused[oparg-2], bottom_out)) {
4778-
bottom_out = bottom_in;
4779-
DEAD(bottom_in);
4780-
top_out = top_in;
4781-
DEAD(top_in);
4771+
pure inst(SWAP, (bottom[1], unused[oparg-2], top[1] --
4772+
bottom[1], unused[oparg-2], top[1])) {
4773+
_PyStackRef temp = bottom[0];
4774+
bottom[0] = top[0];
4775+
top[0] = temp;
47824776
assert(oparg >= 2);
47834777
}
47844778

@@ -5138,7 +5132,8 @@ dummy_func(
51385132
EXIT_TO_TIER1();
51395133
}
51405134

5141-
tier2 op(_ERROR_POP_N, (target/2, unused[oparg] --)) {
5135+
tier2 op(_ERROR_POP_N, (target/2 --)) {
5136+
assert(oparg == 0);
51425137
frame->instr_ptr = _PyFrame_GetBytecode(frame) + target;
51435138
SYNC_SP();
51445139
GOTO_UNWIND();

0 commit comments

Comments
 (0)