GH-135379: Remove types from stack items in code generator. (GH-135384)
* Make casts explicit in the instruction definitions
This commit is contained in:
parent
49d72365cd
commit
c87b5b2cb6
@ -264,6 +264,32 @@ PyStackRef_IsNullOrInt(_PyStackRef ref);
|
|||||||
|
|
||||||
static const _PyStackRef PyStackRef_ERROR = { .bits = Py_TAG_INVALID };
|
static const _PyStackRef PyStackRef_ERROR = { .bits = Py_TAG_INVALID };
|
||||||
|
|
||||||
|
/* Wrap a pointer in a stack ref.
|
||||||
|
* The resulting stack reference is not safe and should only be used
|
||||||
|
* in the interpreter to pass values from one uop to another.
|
||||||
|
* The GC should never see one of these stack refs. */
|
||||||
|
static inline _PyStackRef
|
||||||
|
PyStackRef_Wrap(void *ptr)
|
||||||
|
{
|
||||||
|
assert(ptr != NULL);
|
||||||
|
#ifdef Py_DEBUG
|
||||||
|
return (_PyStackRef){ .bits = ((uintptr_t)ptr) | Py_TAG_INVALID };
|
||||||
|
#else
|
||||||
|
return (_PyStackRef){ .bits = (uintptr_t)ptr };
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
PyStackRef_Unwrap(_PyStackRef ref)
|
||||||
|
{
|
||||||
|
#ifdef Py_DEBUG
|
||||||
|
assert ((ref.bits & Py_TAG_BITS) == Py_TAG_INVALID);
|
||||||
|
return (void *)(ref.bits & ~Py_TAG_BITS);
|
||||||
|
#else
|
||||||
|
return (void *)(ref.bits);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
PyStackRef_IsError(_PyStackRef ref)
|
PyStackRef_IsError(_PyStackRef ref)
|
||||||
{
|
{
|
||||||
|
@ -56,14 +56,14 @@ class TestEffects(unittest.TestCase):
|
|||||||
def test_effect_sizes(self):
|
def test_effect_sizes(self):
|
||||||
stack = Stack()
|
stack = Stack()
|
||||||
inputs = [
|
inputs = [
|
||||||
x := StackItem("x", None, "1"),
|
x := StackItem("x", "1"),
|
||||||
y := StackItem("y", None, "oparg"),
|
y := StackItem("y", "oparg"),
|
||||||
z := StackItem("z", None, "oparg*2"),
|
z := StackItem("z", "oparg*2"),
|
||||||
]
|
]
|
||||||
outputs = [
|
outputs = [
|
||||||
StackItem("x", None, "1"),
|
StackItem("x", "1"),
|
||||||
StackItem("b", None, "oparg*4"),
|
StackItem("b", "oparg*4"),
|
||||||
StackItem("c", None, "1"),
|
StackItem("c", "1"),
|
||||||
]
|
]
|
||||||
null = CWriter.null()
|
null = CWriter.null()
|
||||||
stack.pop(z, null)
|
stack.pop(z, null)
|
||||||
@ -1103,32 +1103,6 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
self.run_cases_test(input, output)
|
self.run_cases_test(input, output)
|
||||||
|
|
||||||
def test_pointer_to_stackref(self):
|
|
||||||
input = """
|
|
||||||
inst(OP, (arg: _PyStackRef * -- out)) {
|
|
||||||
out = *arg;
|
|
||||||
DEAD(arg);
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
output = """
|
|
||||||
TARGET(OP) {
|
|
||||||
#if Py_TAIL_CALL_INTERP
|
|
||||||
int opcode = OP;
|
|
||||||
(void)(opcode);
|
|
||||||
#endif
|
|
||||||
frame->instr_ptr = next_instr;
|
|
||||||
next_instr += 1;
|
|
||||||
INSTRUCTION_STATS(OP);
|
|
||||||
_PyStackRef *arg;
|
|
||||||
_PyStackRef out;
|
|
||||||
arg = (_PyStackRef *)stack_pointer[-1].bits;
|
|
||||||
out = *arg;
|
|
||||||
stack_pointer[-1] = out;
|
|
||||||
DISPATCH();
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
self.run_cases_test(input, output)
|
|
||||||
|
|
||||||
def test_unused_cached_value(self):
|
def test_unused_cached_value(self):
|
||||||
input = """
|
input = """
|
||||||
op(FIRST, (arg1 -- out)) {
|
op(FIRST, (arg1 -- out)) {
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
The cases generator no longer accepts type annotations on stack items.
|
||||||
|
Conversions to non-default types are now done explictly in bytecodes.c and
|
||||||
|
optimizer_bytecodes.c. This will simplify code generation for top-of-stack
|
||||||
|
caching and other future features.
|
@ -985,12 +985,13 @@ dummy_func(
|
|||||||
STAT_INC(BINARY_OP, hit);
|
STAT_INC(BINARY_OP, hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame: _PyInterpreterFrame* )) {
|
op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) {
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame);
|
_PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame);
|
||||||
new_frame->localsplus[0] = container;
|
pushed_frame->localsplus[0] = container;
|
||||||
new_frame->localsplus[1] = sub;
|
pushed_frame->localsplus[1] = sub;
|
||||||
INPUTS_DEAD();
|
INPUTS_DEAD();
|
||||||
frame->return_offset = INSTRUCTION_SIZE;
|
frame->return_offset = INSTRUCTION_SIZE;
|
||||||
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro(BINARY_OP_SUBSCR_GETITEM) =
|
macro(BINARY_OP_SUBSCR_GETITEM) =
|
||||||
@ -1296,20 +1297,21 @@ dummy_func(
|
|||||||
|
|
||||||
macro(SEND) = _SPECIALIZE_SEND + _SEND;
|
macro(SEND) = _SPECIALIZE_SEND + _SEND;
|
||||||
|
|
||||||
op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame: _PyInterpreterFrame *)) {
|
op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) {
|
||||||
PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver);
|
PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver);
|
||||||
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type);
|
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type);
|
||||||
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING);
|
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING);
|
||||||
STAT_INC(SEND, hit);
|
STAT_INC(SEND, hit);
|
||||||
gen_frame = &gen->gi_iframe;
|
_PyInterpreterFrame *pushed_frame = &gen->gi_iframe;
|
||||||
_PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v));
|
_PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v));
|
||||||
DEAD(v);
|
DEAD(v);
|
||||||
gen->gi_frame_state = FRAME_EXECUTING;
|
gen->gi_frame_state = FRAME_EXECUTING;
|
||||||
gen->gi_exc_state.previous_item = tstate->exc_info;
|
gen->gi_exc_state.previous_item = tstate->exc_info;
|
||||||
tstate->exc_info = &gen->gi_exc_state;
|
tstate->exc_info = &gen->gi_exc_state;
|
||||||
assert(INSTRUCTION_SIZE + oparg <= UINT16_MAX);
|
assert(INSTRUCTION_SIZE + oparg <= UINT16_MAX);
|
||||||
frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg);
|
frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg);
|
||||||
gen_frame->previous = frame;
|
pushed_frame->previous = frame;
|
||||||
|
gen_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro(SEND_GEN) =
|
macro(SEND_GEN) =
|
||||||
@ -2463,7 +2465,7 @@ dummy_func(
|
|||||||
_LOAD_ATTR_CLASS +
|
_LOAD_ATTR_CLASS +
|
||||||
_PUSH_NULL_CONDITIONAL;
|
_PUSH_NULL_CONDITIONAL;
|
||||||
|
|
||||||
op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _PyInterpreterFrame *)) {
|
op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame)) {
|
||||||
assert((oparg & 1) == 0);
|
assert((oparg & 1) == 0);
|
||||||
assert(Py_IS_TYPE(fget, &PyFunction_Type));
|
assert(Py_IS_TYPE(fget, &PyFunction_Type));
|
||||||
PyFunctionObject *f = (PyFunctionObject *)fget;
|
PyFunctionObject *f = (PyFunctionObject *)fget;
|
||||||
@ -2473,9 +2475,10 @@ dummy_func(
|
|||||||
DEOPT_IF(code->co_argcount != 1);
|
DEOPT_IF(code->co_argcount != 1);
|
||||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize));
|
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize));
|
||||||
STAT_INC(LOAD_ATTR, hit);
|
STAT_INC(LOAD_ATTR, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame);
|
||||||
new_frame->localsplus[0] = owner;
|
pushed_frame->localsplus[0] = owner;
|
||||||
DEAD(owner);
|
DEAD(owner);
|
||||||
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro(LOAD_ATTR_PROPERTY) =
|
macro(LOAD_ATTR_PROPERTY) =
|
||||||
@ -3344,7 +3347,7 @@ dummy_func(
|
|||||||
_ITER_JUMP_RANGE +
|
_ITER_JUMP_RANGE +
|
||||||
_ITER_NEXT_RANGE;
|
_ITER_NEXT_RANGE;
|
||||||
|
|
||||||
op(_FOR_ITER_GEN_FRAME, (iter, null -- iter, null, gen_frame: _PyInterpreterFrame*)) {
|
op(_FOR_ITER_GEN_FRAME, (iter, null -- iter, null, gen_frame)) {
|
||||||
PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter);
|
PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter);
|
||||||
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type);
|
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type);
|
||||||
#ifdef Py_GIL_DISABLED
|
#ifdef Py_GIL_DISABLED
|
||||||
@ -3356,14 +3359,15 @@ dummy_func(
|
|||||||
#endif
|
#endif
|
||||||
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING);
|
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING);
|
||||||
STAT_INC(FOR_ITER, hit);
|
STAT_INC(FOR_ITER, hit);
|
||||||
gen_frame = &gen->gi_iframe;
|
_PyInterpreterFrame *pushed_frame = &gen->gi_iframe;
|
||||||
_PyFrame_StackPush(gen_frame, PyStackRef_None);
|
_PyFrame_StackPush(pushed_frame, PyStackRef_None);
|
||||||
gen->gi_frame_state = FRAME_EXECUTING;
|
gen->gi_frame_state = FRAME_EXECUTING;
|
||||||
gen->gi_exc_state.previous_item = tstate->exc_info;
|
gen->gi_exc_state.previous_item = tstate->exc_info;
|
||||||
tstate->exc_info = &gen->gi_exc_state;
|
tstate->exc_info = &gen->gi_exc_state;
|
||||||
gen_frame->previous = frame;
|
pushed_frame->previous = frame;
|
||||||
// oparg is the return offset from the next instruction.
|
// oparg is the return offset from the next instruction.
|
||||||
frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg);
|
frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg);
|
||||||
|
gen_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro(FOR_ITER_GEN) =
|
macro(FOR_ITER_GEN) =
|
||||||
@ -3715,7 +3719,7 @@ dummy_func(
|
|||||||
macro(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC;
|
macro(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC;
|
||||||
macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC;
|
macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC;
|
||||||
|
|
||||||
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) {
|
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame)) {
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||||
|
|
||||||
// oparg counts all of the args, but *not* self:
|
// oparg counts all of the args, but *not* self:
|
||||||
@ -3737,7 +3741,7 @@ dummy_func(
|
|||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
ERROR_NO_POP();
|
ERROR_NO_POP();
|
||||||
}
|
}
|
||||||
new_frame = temp;
|
new_frame = PyStackRef_Wrap(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, unused, unused[oparg] -- callable, unused, unused[oparg])) {
|
op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, unused, unused[oparg] -- callable, unused, unused[oparg])) {
|
||||||
@ -3874,27 +3878,26 @@ dummy_func(
|
|||||||
DEOPT_IF(tstate->py_recursion_remaining <= 1);
|
DEOPT_IF(tstate->py_recursion_remaining <= 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
replicate(5) pure op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) {
|
replicate(5) pure op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame)) {
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
INPUTS_DEAD();
|
INPUTS_DEAD();
|
||||||
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_PUSH_FRAME, (new_frame: _PyInterpreterFrame* -- )) {
|
op(_PUSH_FRAME, (new_frame -- )) {
|
||||||
// Write it out explicitly because it's subtly different.
|
|
||||||
// Eventually this should be the only occurrence of this code.
|
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
DEAD(new_frame);
|
DEAD(new_frame);
|
||||||
SYNC_SP();
|
SYNC_SP();
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -4046,7 +4049,7 @@ dummy_func(
|
|||||||
PyStackRef_CLOSE(temp);
|
PyStackRef_CLOSE(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame: _PyInterpreterFrame *)) {
|
op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame)) {
|
||||||
_PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked(
|
_PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked(
|
||||||
tstate, (PyCodeObject *)&_Py_InitCleanup, 1, frame);
|
tstate, (PyCodeObject *)&_Py_InitCleanup, 1, frame);
|
||||||
assert(_PyFrame_GetBytecode(shim)[0].op.code == EXIT_INIT_CHECK);
|
assert(_PyFrame_GetBytecode(shim)[0].op.code == EXIT_INIT_CHECK);
|
||||||
@ -4063,12 +4066,12 @@ dummy_func(
|
|||||||
_PyEval_FrameClearAndPop(tstate, shim);
|
_PyEval_FrameClearAndPop(tstate, shim);
|
||||||
ERROR_NO_POP();
|
ERROR_NO_POP();
|
||||||
}
|
}
|
||||||
init_frame = temp;
|
|
||||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||||
/* Account for pushing the extra frame.
|
/* Account for pushing the extra frame.
|
||||||
* We don't check recursion depth here,
|
* We don't check recursion depth here,
|
||||||
* as it will be checked after start_frame */
|
* as it will be checked after start_frame */
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
|
init_frame = PyStackRef_Wrap(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro(CALL_ALLOC_AND_ENTER_INIT) =
|
macro(CALL_ALLOC_AND_ENTER_INIT) =
|
||||||
@ -4594,7 +4597,7 @@ dummy_func(
|
|||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame: _PyInterpreterFrame*)) {
|
op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame)) {
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||||
|
|
||||||
// oparg counts all of the args, but *not* self:
|
// oparg counts all of the args, but *not* self:
|
||||||
@ -4621,7 +4624,7 @@ dummy_func(
|
|||||||
DEAD(callable);
|
DEAD(callable);
|
||||||
SYNC_SP();
|
SYNC_SP();
|
||||||
ERROR_IF(temp == NULL);
|
ERROR_IF(temp == NULL);
|
||||||
new_frame = temp;
|
new_frame = PyStackRef_Wrap(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_CHECK_FUNCTION_VERSION_KW, (func_version/2, callable, unused, unused[oparg], unused -- callable, unused, unused[oparg], unused)) {
|
op(_CHECK_FUNCTION_VERSION_KW, (func_version/2, callable, unused, unused[oparg], unused -- callable, unused, unused[oparg], unused)) {
|
||||||
|
134
Python/executor_cases.c.h
generated
134
Python/executor_cases.c.h
generated
@ -1551,15 +1551,16 @@
|
|||||||
_PyStackRef getitem;
|
_PyStackRef getitem;
|
||||||
_PyStackRef sub;
|
_PyStackRef sub;
|
||||||
_PyStackRef container;
|
_PyStackRef container;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
getitem = stack_pointer[-1];
|
getitem = stack_pointer[-1];
|
||||||
sub = stack_pointer[-2];
|
sub = stack_pointer[-2];
|
||||||
container = stack_pointer[-3];
|
container = stack_pointer[-3];
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame);
|
_PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame);
|
||||||
new_frame->localsplus[0] = container;
|
pushed_frame->localsplus[0] = container;
|
||||||
new_frame->localsplus[1] = sub;
|
pushed_frame->localsplus[1] = sub;
|
||||||
frame->return_offset = 6 ;
|
frame->return_offset = 6 ;
|
||||||
stack_pointer[-3].bits = (uintptr_t)new_frame;
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-3] = new_frame;
|
||||||
stack_pointer += -2;
|
stack_pointer += -2;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -1907,7 +1908,7 @@
|
|||||||
case _SEND_GEN_FRAME: {
|
case _SEND_GEN_FRAME: {
|
||||||
_PyStackRef v;
|
_PyStackRef v;
|
||||||
_PyStackRef receiver;
|
_PyStackRef receiver;
|
||||||
_PyInterpreterFrame *gen_frame;
|
_PyStackRef gen_frame;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
v = stack_pointer[-1];
|
v = stack_pointer[-1];
|
||||||
receiver = stack_pointer[-2];
|
receiver = stack_pointer[-2];
|
||||||
@ -1921,15 +1922,16 @@
|
|||||||
JUMP_TO_JUMP_TARGET();
|
JUMP_TO_JUMP_TARGET();
|
||||||
}
|
}
|
||||||
STAT_INC(SEND, hit);
|
STAT_INC(SEND, hit);
|
||||||
gen_frame = &gen->gi_iframe;
|
_PyInterpreterFrame *pushed_frame = &gen->gi_iframe;
|
||||||
_PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v));
|
_PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v));
|
||||||
gen->gi_frame_state = FRAME_EXECUTING;
|
gen->gi_frame_state = FRAME_EXECUTING;
|
||||||
gen->gi_exc_state.previous_item = tstate->exc_info;
|
gen->gi_exc_state.previous_item = tstate->exc_info;
|
||||||
tstate->exc_info = &gen->gi_exc_state;
|
tstate->exc_info = &gen->gi_exc_state;
|
||||||
assert( 2 + oparg <= UINT16_MAX);
|
assert( 2 + oparg <= UINT16_MAX);
|
||||||
frame->return_offset = (uint16_t)( 2 + oparg);
|
frame->return_offset = (uint16_t)( 2 + oparg);
|
||||||
gen_frame->previous = frame;
|
pushed_frame->previous = frame;
|
||||||
stack_pointer[-1].bits = (uintptr_t)gen_frame;
|
gen_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-1] = gen_frame;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3471,7 +3473,7 @@
|
|||||||
|
|
||||||
case _LOAD_ATTR_PROPERTY_FRAME: {
|
case _LOAD_ATTR_PROPERTY_FRAME: {
|
||||||
_PyStackRef owner;
|
_PyStackRef owner;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
owner = stack_pointer[-1];
|
owner = stack_pointer[-1];
|
||||||
PyObject *fget = (PyObject *)CURRENT_OPERAND0();
|
PyObject *fget = (PyObject *)CURRENT_OPERAND0();
|
||||||
@ -3496,9 +3498,10 @@
|
|||||||
JUMP_TO_JUMP_TARGET();
|
JUMP_TO_JUMP_TARGET();
|
||||||
}
|
}
|
||||||
STAT_INC(LOAD_ATTR, hit);
|
STAT_INC(LOAD_ATTR, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame);
|
||||||
new_frame->localsplus[0] = owner;
|
pushed_frame->localsplus[0] = owner;
|
||||||
stack_pointer[-1].bits = (uintptr_t)new_frame;
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-1] = new_frame;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4467,7 +4470,7 @@
|
|||||||
|
|
||||||
case _FOR_ITER_GEN_FRAME: {
|
case _FOR_ITER_GEN_FRAME: {
|
||||||
_PyStackRef iter;
|
_PyStackRef iter;
|
||||||
_PyInterpreterFrame *gen_frame;
|
_PyStackRef gen_frame;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
iter = stack_pointer[-2];
|
iter = stack_pointer[-2];
|
||||||
PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter);
|
PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter);
|
||||||
@ -4487,14 +4490,15 @@
|
|||||||
JUMP_TO_JUMP_TARGET();
|
JUMP_TO_JUMP_TARGET();
|
||||||
}
|
}
|
||||||
STAT_INC(FOR_ITER, hit);
|
STAT_INC(FOR_ITER, hit);
|
||||||
gen_frame = &gen->gi_iframe;
|
_PyInterpreterFrame *pushed_frame = &gen->gi_iframe;
|
||||||
_PyFrame_StackPush(gen_frame, PyStackRef_None);
|
_PyFrame_StackPush(pushed_frame, PyStackRef_None);
|
||||||
gen->gi_frame_state = FRAME_EXECUTING;
|
gen->gi_frame_state = FRAME_EXECUTING;
|
||||||
gen->gi_exc_state.previous_item = tstate->exc_info;
|
gen->gi_exc_state.previous_item = tstate->exc_info;
|
||||||
tstate->exc_info = &gen->gi_exc_state;
|
tstate->exc_info = &gen->gi_exc_state;
|
||||||
gen_frame->previous = frame;
|
pushed_frame->previous = frame;
|
||||||
frame->return_offset = (uint16_t)( 2 + oparg);
|
frame->return_offset = (uint16_t)( 2 + oparg);
|
||||||
stack_pointer[0].bits = (uintptr_t)gen_frame;
|
gen_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[0] = gen_frame;
|
||||||
stack_pointer += 1;
|
stack_pointer += 1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -4775,7 +4779,7 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
self_or_null = stack_pointer[-1 - oparg];
|
self_or_null = stack_pointer[-1 - oparg];
|
||||||
@ -4800,8 +4804,8 @@
|
|||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
JUMP_TO_ERROR();
|
JUMP_TO_ERROR();
|
||||||
}
|
}
|
||||||
new_frame = temp;
|
new_frame = PyStackRef_Wrap(temp);
|
||||||
stack_pointer[0].bits = (uintptr_t)new_frame;
|
stack_pointer[0] = new_frame;
|
||||||
stack_pointer += 1;
|
stack_pointer += 1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -5067,7 +5071,7 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = 0;
|
oparg = 0;
|
||||||
assert(oparg == CURRENT_OPARG());
|
assert(oparg == CURRENT_OPARG());
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
@ -5075,13 +5079,14 @@
|
|||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame;
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-2 - oparg] = new_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -5091,7 +5096,7 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = 1;
|
oparg = 1;
|
||||||
assert(oparg == CURRENT_OPARG());
|
assert(oparg == CURRENT_OPARG());
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
@ -5099,13 +5104,14 @@
|
|||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame;
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-2 - oparg] = new_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -5115,7 +5121,7 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = 2;
|
oparg = 2;
|
||||||
assert(oparg == CURRENT_OPARG());
|
assert(oparg == CURRENT_OPARG());
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
@ -5123,13 +5129,14 @@
|
|||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame;
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-2 - oparg] = new_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -5139,7 +5146,7 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = 3;
|
oparg = 3;
|
||||||
assert(oparg == CURRENT_OPARG());
|
assert(oparg == CURRENT_OPARG());
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
@ -5147,13 +5154,14 @@
|
|||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame;
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-2 - oparg] = new_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -5163,7 +5171,7 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = 4;
|
oparg = 4;
|
||||||
assert(oparg == CURRENT_OPARG());
|
assert(oparg == CURRENT_OPARG());
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
@ -5171,13 +5179,14 @@
|
|||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame;
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-2 - oparg] = new_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -5187,34 +5196,35 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
self_or_null = stack_pointer[-1 - oparg];
|
self_or_null = stack_pointer[-1 - oparg];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame;
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
|
stack_pointer[-2 - oparg] = new_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case _PUSH_FRAME: {
|
case _PUSH_FRAME: {
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
new_frame = (_PyInterpreterFrame *)stack_pointer[-1].bits;
|
new_frame = stack_pointer[-1];
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
stack_pointer += -1;
|
stack_pointer += -1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -5429,7 +5439,7 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self;
|
_PyStackRef self;
|
||||||
_PyStackRef init;
|
_PyStackRef init;
|
||||||
_PyInterpreterFrame *init_frame;
|
_PyStackRef init_frame;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
self = stack_pointer[-1 - oparg];
|
self = stack_pointer[-1 - oparg];
|
||||||
@ -5453,10 +5463,10 @@
|
|||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
JUMP_TO_ERROR();
|
JUMP_TO_ERROR();
|
||||||
}
|
}
|
||||||
init_frame = temp;
|
|
||||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
stack_pointer[0].bits = (uintptr_t)init_frame;
|
init_frame = PyStackRef_Wrap(temp);
|
||||||
|
stack_pointer[0] = init_frame;
|
||||||
stack_pointer += 1;
|
stack_pointer += 1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -6309,7 +6319,7 @@
|
|||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
kwnames = stack_pointer[-1];
|
kwnames = stack_pointer[-1];
|
||||||
args = &stack_pointer[-1 - oparg];
|
args = &stack_pointer[-1 - oparg];
|
||||||
@ -6343,8 +6353,8 @@
|
|||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
JUMP_TO_ERROR();
|
JUMP_TO_ERROR();
|
||||||
}
|
}
|
||||||
new_frame = temp;
|
new_frame = PyStackRef_Wrap(temp);
|
||||||
stack_pointer[0].bits = (uintptr_t)new_frame;
|
stack_pointer[0] = new_frame;
|
||||||
stack_pointer += 1;
|
stack_pointer += 1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
|
122
Python/generated_cases.c.h
generated
122
Python/generated_cases.c.h
generated
@ -604,7 +604,7 @@
|
|||||||
_PyStackRef container;
|
_PyStackRef container;
|
||||||
_PyStackRef getitem;
|
_PyStackRef getitem;
|
||||||
_PyStackRef sub;
|
_PyStackRef sub;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 5 cache entries */
|
/* Skip 5 cache entries */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -650,19 +650,20 @@
|
|||||||
// _BINARY_OP_SUBSCR_INIT_CALL
|
// _BINARY_OP_SUBSCR_INIT_CALL
|
||||||
{
|
{
|
||||||
sub = stack_pointer[-1];
|
sub = stack_pointer[-1];
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame);
|
_PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame);
|
||||||
new_frame->localsplus[0] = container;
|
pushed_frame->localsplus[0] = container;
|
||||||
new_frame->localsplus[1] = sub;
|
pushed_frame->localsplus[1] = sub;
|
||||||
frame->return_offset = 6 ;
|
frame->return_offset = 6 ;
|
||||||
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
stack_pointer += -2;
|
stack_pointer += -2;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -1708,8 +1709,8 @@
|
|||||||
_PyStackRef init;
|
_PyStackRef init;
|
||||||
_PyStackRef self;
|
_PyStackRef self;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyInterpreterFrame *init_frame;
|
_PyStackRef init_frame;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -1792,17 +1793,17 @@
|
|||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
init_frame = temp;
|
|
||||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
|
init_frame = PyStackRef_Wrap(temp);
|
||||||
}
|
}
|
||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
new_frame = init_frame;
|
new_frame = init_frame;
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -1828,7 +1829,7 @@
|
|||||||
_PyStackRef null;
|
_PyStackRef null;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -1921,12 +1922,13 @@
|
|||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
// _SAVE_RETURN_OFFSET
|
// _SAVE_RETURN_OFFSET
|
||||||
{
|
{
|
||||||
@ -1940,11 +1942,11 @@
|
|||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -1970,7 +1972,7 @@
|
|||||||
_PyStackRef null;
|
_PyStackRef null;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -2056,7 +2058,7 @@
|
|||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
new_frame = temp;
|
new_frame = PyStackRef_Wrap(temp);
|
||||||
}
|
}
|
||||||
// _SAVE_RETURN_OFFSET
|
// _SAVE_RETURN_OFFSET
|
||||||
{
|
{
|
||||||
@ -2070,9 +2072,9 @@
|
|||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -3040,7 +3042,7 @@
|
|||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef kwnames;
|
_PyStackRef kwnames;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -3127,7 +3129,7 @@
|
|||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
new_frame = temp;
|
new_frame = PyStackRef_Wrap(temp);
|
||||||
}
|
}
|
||||||
// _SAVE_RETURN_OFFSET
|
// _SAVE_RETURN_OFFSET
|
||||||
{
|
{
|
||||||
@ -3141,9 +3143,9 @@
|
|||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -3304,7 +3306,7 @@
|
|||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef kwnames;
|
_PyStackRef kwnames;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -3364,7 +3366,7 @@
|
|||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
new_frame = temp;
|
new_frame = PyStackRef_Wrap(temp);
|
||||||
}
|
}
|
||||||
// _SAVE_RETURN_OFFSET
|
// _SAVE_RETURN_OFFSET
|
||||||
{
|
{
|
||||||
@ -3378,9 +3380,9 @@
|
|||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -4163,7 +4165,7 @@
|
|||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -4227,12 +4229,13 @@
|
|||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
int has_self = !PyStackRef_IsNull(self_or_null);
|
int has_self = !PyStackRef_IsNull(self_or_null);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame);
|
||||||
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self;
|
_PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self;
|
||||||
new_frame->localsplus[0] = self_or_null;
|
pushed_frame->localsplus[0] = self_or_null;
|
||||||
for (int i = 0; i < oparg; i++) {
|
for (int i = 0; i < oparg; i++) {
|
||||||
first_non_self_local[i] = args[i];
|
first_non_self_local[i] = args[i];
|
||||||
}
|
}
|
||||||
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
// _SAVE_RETURN_OFFSET
|
// _SAVE_RETURN_OFFSET
|
||||||
{
|
{
|
||||||
@ -4246,11 +4249,11 @@
|
|||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -4275,7 +4278,7 @@
|
|||||||
_PyStackRef callable;
|
_PyStackRef callable;
|
||||||
_PyStackRef self_or_null;
|
_PyStackRef self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -4334,7 +4337,7 @@
|
|||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
new_frame = temp;
|
new_frame = PyStackRef_Wrap(temp);
|
||||||
}
|
}
|
||||||
// _SAVE_RETURN_OFFSET
|
// _SAVE_RETURN_OFFSET
|
||||||
{
|
{
|
||||||
@ -4348,9 +4351,9 @@
|
|||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -5785,8 +5788,8 @@
|
|||||||
INSTRUCTION_STATS(FOR_ITER_GEN);
|
INSTRUCTION_STATS(FOR_ITER_GEN);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size");
|
||||||
_PyStackRef iter;
|
_PyStackRef iter;
|
||||||
_PyInterpreterFrame *gen_frame;
|
_PyStackRef gen_frame;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -5818,21 +5821,22 @@
|
|||||||
JUMP_TO_PREDICTED(FOR_ITER);
|
JUMP_TO_PREDICTED(FOR_ITER);
|
||||||
}
|
}
|
||||||
STAT_INC(FOR_ITER, hit);
|
STAT_INC(FOR_ITER, hit);
|
||||||
gen_frame = &gen->gi_iframe;
|
_PyInterpreterFrame *pushed_frame = &gen->gi_iframe;
|
||||||
_PyFrame_StackPush(gen_frame, PyStackRef_None);
|
_PyFrame_StackPush(pushed_frame, PyStackRef_None);
|
||||||
gen->gi_frame_state = FRAME_EXECUTING;
|
gen->gi_frame_state = FRAME_EXECUTING;
|
||||||
gen->gi_exc_state.previous_item = tstate->exc_info;
|
gen->gi_exc_state.previous_item = tstate->exc_info;
|
||||||
tstate->exc_info = &gen->gi_exc_state;
|
tstate->exc_info = &gen->gi_exc_state;
|
||||||
gen_frame->previous = frame;
|
pushed_frame->previous = frame;
|
||||||
frame->return_offset = (uint16_t)( 2 + oparg);
|
frame->return_offset = (uint16_t)( 2 + oparg);
|
||||||
|
gen_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
new_frame = gen_frame;
|
new_frame = gen_frame;
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -8650,7 +8654,7 @@
|
|||||||
INSTRUCTION_STATS(LOAD_ATTR_PROPERTY);
|
INSTRUCTION_STATS(LOAD_ATTR_PROPERTY);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
|
||||||
_PyStackRef owner;
|
_PyStackRef owner;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -8701,8 +8705,9 @@
|
|||||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||||
}
|
}
|
||||||
STAT_INC(LOAD_ATTR, hit);
|
STAT_INC(LOAD_ATTR, hit);
|
||||||
new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame);
|
_PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame);
|
||||||
new_frame->localsplus[0] = owner;
|
pushed_frame->localsplus[0] = owner;
|
||||||
|
new_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
// _SAVE_RETURN_OFFSET
|
// _SAVE_RETURN_OFFSET
|
||||||
{
|
{
|
||||||
@ -8716,11 +8721,11 @@
|
|||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
stack_pointer += -1;
|
stack_pointer += -1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
@ -10661,8 +10666,8 @@
|
|||||||
static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size");
|
||||||
_PyStackRef receiver;
|
_PyStackRef receiver;
|
||||||
_PyStackRef v;
|
_PyStackRef v;
|
||||||
_PyInterpreterFrame *gen_frame;
|
_PyStackRef gen_frame;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyStackRef new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// _CHECK_PEP_523
|
// _CHECK_PEP_523
|
||||||
{
|
{
|
||||||
@ -10688,24 +10693,25 @@
|
|||||||
JUMP_TO_PREDICTED(SEND);
|
JUMP_TO_PREDICTED(SEND);
|
||||||
}
|
}
|
||||||
STAT_INC(SEND, hit);
|
STAT_INC(SEND, hit);
|
||||||
gen_frame = &gen->gi_iframe;
|
_PyInterpreterFrame *pushed_frame = &gen->gi_iframe;
|
||||||
_PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v));
|
_PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v));
|
||||||
gen->gi_frame_state = FRAME_EXECUTING;
|
gen->gi_frame_state = FRAME_EXECUTING;
|
||||||
gen->gi_exc_state.previous_item = tstate->exc_info;
|
gen->gi_exc_state.previous_item = tstate->exc_info;
|
||||||
tstate->exc_info = &gen->gi_exc_state;
|
tstate->exc_info = &gen->gi_exc_state;
|
||||||
assert( 2 + oparg <= UINT16_MAX);
|
assert( 2 + oparg <= UINT16_MAX);
|
||||||
frame->return_offset = (uint16_t)( 2 + oparg);
|
frame->return_offset = (uint16_t)( 2 + oparg);
|
||||||
gen_frame->previous = frame;
|
pushed_frame->previous = frame;
|
||||||
|
gen_frame = PyStackRef_Wrap(pushed_frame);
|
||||||
}
|
}
|
||||||
// _PUSH_FRAME
|
// _PUSH_FRAME
|
||||||
{
|
{
|
||||||
new_frame = gen_frame;
|
new_frame = gen_frame;
|
||||||
assert(tstate->interp->eval_frame == NULL);
|
assert(tstate->interp->eval_frame == NULL);
|
||||||
_PyInterpreterFrame *temp = new_frame;
|
_PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame);
|
||||||
stack_pointer += -1;
|
stack_pointer += -1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
|
assert(temp->previous == frame || temp->previous->previous == frame);
|
||||||
CALL_STAT_INC(inlined_py_calls);
|
CALL_STAT_INC(inlined_py_calls);
|
||||||
frame = tstate->current_frame = temp;
|
frame = tstate->current_frame = temp;
|
||||||
tstate->py_recursion_remaining--;
|
tstate->py_recursion_remaining--;
|
||||||
|
@ -373,7 +373,7 @@ dummy_func(void) {
|
|||||||
GETLOCAL(this_instr->operand0) = res;
|
GETLOCAL(this_instr->operand0) = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame: _Py_UOpsAbstractFrame *)) {
|
op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) {
|
||||||
new_frame = NULL;
|
new_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
}
|
}
|
||||||
@ -697,7 +697,7 @@ dummy_func(void) {
|
|||||||
self = owner;
|
self = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _Py_UOpsAbstractFrame *)) {
|
op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame)) {
|
||||||
(void)fget;
|
(void)fget;
|
||||||
new_frame = NULL;
|
new_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
@ -735,7 +735,7 @@ dummy_func(void) {
|
|||||||
sym_set_type(callable, &PyMethod_Type);
|
sym_set_type(callable, &PyMethod_Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame: _Py_UOpsAbstractFrame *)) {
|
op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame)) {
|
||||||
int argcount = oparg;
|
int argcount = oparg;
|
||||||
|
|
||||||
PyCodeObject *co = NULL;
|
PyCodeObject *co = NULL;
|
||||||
@ -756,10 +756,9 @@ dummy_func(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
|
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
|
||||||
new_frame = frame_new(ctx, co, 0, args, argcount);
|
new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, args, argcount);
|
||||||
} else {
|
} else {
|
||||||
new_frame = frame_new(ctx, co, 0, NULL, 0);
|
new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,7 +768,7 @@ dummy_func(void) {
|
|||||||
self_or_null = sym_new_not_null(ctx);
|
self_or_null = sym_new_not_null(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _Py_UOpsAbstractFrame *)) {
|
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame)) {
|
||||||
PyCodeObject *co = NULL;
|
PyCodeObject *co = NULL;
|
||||||
assert((this_instr + 2)->opcode == _PUSH_FRAME);
|
assert((this_instr + 2)->opcode == _PUSH_FRAME);
|
||||||
co = get_code_with_logging((this_instr + 2));
|
co = get_code_with_logging((this_instr + 2));
|
||||||
@ -778,10 +777,10 @@ dummy_func(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_frame = frame_new(ctx, co, 0, NULL, 0);
|
new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame: _Py_UOpsAbstractFrame *)) {
|
op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame)) {
|
||||||
new_frame = NULL;
|
new_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
}
|
}
|
||||||
@ -793,7 +792,7 @@ dummy_func(void) {
|
|||||||
self_or_null = sym_new_not_null(ctx);
|
self_or_null = sym_new_not_null(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame: _Py_UOpsAbstractFrame *)) {
|
op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame)) {
|
||||||
init_frame = NULL;
|
init_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
}
|
}
|
||||||
@ -860,13 +859,13 @@ dummy_func(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_FOR_ITER_GEN_FRAME, (unused, unused -- unused, unused, gen_frame: _Py_UOpsAbstractFrame*)) {
|
op(_FOR_ITER_GEN_FRAME, (unused, unused -- unused, unused, gen_frame)) {
|
||||||
gen_frame = NULL;
|
gen_frame = NULL;
|
||||||
/* We are about to hit the end of the trace */
|
/* We are about to hit the end of the trace */
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_SEND_GEN_FRAME, (unused, unused -- unused, gen_frame: _Py_UOpsAbstractFrame *)) {
|
op(_SEND_GEN_FRAME, (unused, unused -- unused, gen_frame)) {
|
||||||
gen_frame = NULL;
|
gen_frame = NULL;
|
||||||
// We are about to hit the end of the trace:
|
// We are about to hit the end of the trace:
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
@ -884,12 +883,12 @@ dummy_func(void) {
|
|||||||
Py_UNREACHABLE();
|
Py_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- )) {
|
op(_PUSH_FRAME, (new_frame -- )) {
|
||||||
SYNC_SP();
|
SYNC_SP();
|
||||||
ctx->frame->stack_pointer = stack_pointer;
|
ctx->frame->stack_pointer = stack_pointer;
|
||||||
ctx->frame = new_frame;
|
ctx->frame = (_Py_UOpsAbstractFrame *)new_frame;
|
||||||
ctx->curr_frame_depth++;
|
ctx->curr_frame_depth++;
|
||||||
stack_pointer = new_frame->stack_pointer;
|
stack_pointer = ctx->frame->stack_pointer;
|
||||||
co = get_code(this_instr);
|
co = get_code(this_instr);
|
||||||
if (co == NULL) {
|
if (co == NULL) {
|
||||||
// should be about to _EXIT_TRACE anyway
|
// should be about to _EXIT_TRACE anyway
|
||||||
|
46
Python/optimizer_cases.c.h
generated
46
Python/optimizer_cases.c.h
generated
@ -715,10 +715,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
case _BINARY_OP_SUBSCR_INIT_CALL: {
|
case _BINARY_OP_SUBSCR_INIT_CALL: {
|
||||||
_Py_UOpsAbstractFrame *new_frame;
|
JitOptSymbol *new_frame;
|
||||||
new_frame = NULL;
|
new_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
stack_pointer[-3] = (JitOptSymbol *)new_frame;
|
stack_pointer[-3] = new_frame;
|
||||||
stack_pointer += -2;
|
stack_pointer += -2;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -829,10 +829,10 @@
|
|||||||
/* _SEND is not a viable micro-op for tier 2 */
|
/* _SEND is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _SEND_GEN_FRAME: {
|
case _SEND_GEN_FRAME: {
|
||||||
_Py_UOpsAbstractFrame *gen_frame;
|
JitOptSymbol *gen_frame;
|
||||||
gen_frame = NULL;
|
gen_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
stack_pointer[-1] = (JitOptSymbol *)gen_frame;
|
stack_pointer[-1] = gen_frame;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1323,12 +1323,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
case _LOAD_ATTR_PROPERTY_FRAME: {
|
case _LOAD_ATTR_PROPERTY_FRAME: {
|
||||||
_Py_UOpsAbstractFrame *new_frame;
|
JitOptSymbol *new_frame;
|
||||||
PyObject *fget = (PyObject *)this_instr->operand0;
|
PyObject *fget = (PyObject *)this_instr->operand0;
|
||||||
(void)fget;
|
(void)fget;
|
||||||
new_frame = NULL;
|
new_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
stack_pointer[-1] = (JitOptSymbol *)new_frame;
|
stack_pointer[-1] = new_frame;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1685,10 +1685,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
case _FOR_ITER_GEN_FRAME: {
|
case _FOR_ITER_GEN_FRAME: {
|
||||||
_Py_UOpsAbstractFrame *gen_frame;
|
JitOptSymbol *gen_frame;
|
||||||
gen_frame = NULL;
|
gen_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
stack_pointer[0] = (JitOptSymbol *)gen_frame;
|
stack_pointer[0] = gen_frame;
|
||||||
stack_pointer += 1;
|
stack_pointer += 1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -1857,7 +1857,7 @@
|
|||||||
/* _MONITOR_CALL is not a viable micro-op for tier 2 */
|
/* _MONITOR_CALL is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _PY_FRAME_GENERAL: {
|
case _PY_FRAME_GENERAL: {
|
||||||
_Py_UOpsAbstractFrame *new_frame;
|
JitOptSymbol *new_frame;
|
||||||
PyCodeObject *co = NULL;
|
PyCodeObject *co = NULL;
|
||||||
assert((this_instr + 2)->opcode == _PUSH_FRAME);
|
assert((this_instr + 2)->opcode == _PUSH_FRAME);
|
||||||
co = get_code_with_logging((this_instr + 2));
|
co = get_code_with_logging((this_instr + 2));
|
||||||
@ -1865,8 +1865,8 @@
|
|||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
new_frame = frame_new(ctx, co, 0, NULL, 0);
|
new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0);
|
||||||
stack_pointer[-2 - oparg] = (JitOptSymbol *)new_frame;
|
stack_pointer[-2 - oparg] = new_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -1970,7 +1970,7 @@
|
|||||||
case _INIT_CALL_PY_EXACT_ARGS: {
|
case _INIT_CALL_PY_EXACT_ARGS: {
|
||||||
JitOptSymbol **args;
|
JitOptSymbol **args;
|
||||||
JitOptSymbol *self_or_null;
|
JitOptSymbol *self_or_null;
|
||||||
_Py_UOpsAbstractFrame *new_frame;
|
JitOptSymbol *new_frame;
|
||||||
args = &stack_pointer[-oparg];
|
args = &stack_pointer[-oparg];
|
||||||
self_or_null = stack_pointer[-1 - oparg];
|
self_or_null = stack_pointer[-1 - oparg];
|
||||||
int argcount = oparg;
|
int argcount = oparg;
|
||||||
@ -1988,25 +1988,25 @@
|
|||||||
argcount++;
|
argcount++;
|
||||||
}
|
}
|
||||||
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
|
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
|
||||||
new_frame = frame_new(ctx, co, 0, args, argcount);
|
new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, args, argcount);
|
||||||
} else {
|
} else {
|
||||||
new_frame = frame_new(ctx, co, 0, NULL, 0);
|
new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = (JitOptSymbol *)new_frame;
|
stack_pointer[-2 - oparg] = new_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case _PUSH_FRAME: {
|
case _PUSH_FRAME: {
|
||||||
_Py_UOpsAbstractFrame *new_frame;
|
JitOptSymbol *new_frame;
|
||||||
new_frame = (_Py_UOpsAbstractFrame *)stack_pointer[-1];
|
new_frame = stack_pointer[-1];
|
||||||
stack_pointer += -1;
|
stack_pointer += -1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
ctx->frame->stack_pointer = stack_pointer;
|
ctx->frame->stack_pointer = stack_pointer;
|
||||||
ctx->frame = new_frame;
|
ctx->frame = (_Py_UOpsAbstractFrame *)new_frame;
|
||||||
ctx->curr_frame_depth++;
|
ctx->curr_frame_depth++;
|
||||||
stack_pointer = new_frame->stack_pointer;
|
stack_pointer = ctx->frame->stack_pointer;
|
||||||
co = get_code(this_instr);
|
co = get_code(this_instr);
|
||||||
if (co == NULL) {
|
if (co == NULL) {
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
@ -2159,10 +2159,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
case _CREATE_INIT_FRAME: {
|
case _CREATE_INIT_FRAME: {
|
||||||
_Py_UOpsAbstractFrame *init_frame;
|
JitOptSymbol *init_frame;
|
||||||
init_frame = NULL;
|
init_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
stack_pointer[-2 - oparg] = (JitOptSymbol *)init_frame;
|
stack_pointer[-2 - oparg] = init_frame;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
@ -2326,10 +2326,10 @@
|
|||||||
/* _DO_CALL_KW is not a viable micro-op for tier 2 */
|
/* _DO_CALL_KW is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _PY_FRAME_KW: {
|
case _PY_FRAME_KW: {
|
||||||
_Py_UOpsAbstractFrame *new_frame;
|
JitOptSymbol *new_frame;
|
||||||
new_frame = NULL;
|
new_frame = NULL;
|
||||||
ctx->done = true;
|
ctx->done = true;
|
||||||
stack_pointer[-3 - oparg] = (JitOptSymbol *)new_frame;
|
stack_pointer[-3 - oparg] = new_frame;
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
|
@ -135,15 +135,13 @@ class Flush:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class StackItem:
|
class StackItem:
|
||||||
name: str
|
name: str
|
||||||
type: str | None
|
|
||||||
size: str
|
size: str
|
||||||
peek: bool = False
|
peek: bool = False
|
||||||
used: bool = False
|
used: bool = False
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
size = f"[{self.size}]" if self.size else ""
|
size = f"[{self.size}]" if self.size else ""
|
||||||
type = "" if self.type is None else f"{self.type} "
|
return f"{self.name}{size} {self.peek}"
|
||||||
return f"{type}{self.name}{size} {self.peek}"
|
|
||||||
|
|
||||||
def is_array(self) -> bool:
|
def is_array(self) -> bool:
|
||||||
return self.size != ""
|
return self.size != ""
|
||||||
@ -345,7 +343,7 @@ def override_error(
|
|||||||
def convert_stack_item(
|
def convert_stack_item(
|
||||||
item: parser.StackEffect, replace_op_arg_1: str | None
|
item: parser.StackEffect, replace_op_arg_1: str | None
|
||||||
) -> StackItem:
|
) -> StackItem:
|
||||||
return StackItem(item.name, item.type, item.size)
|
return StackItem(item.name, item.size)
|
||||||
|
|
||||||
def check_unused(stack: list[StackItem], input_names: dict[str, lexer.Token]) -> None:
|
def check_unused(stack: list[StackItem], input_names: dict[str, lexer.Token]) -> None:
|
||||||
"Unused items cannot be on the stack above used, non-peek items"
|
"Unused items cannot be on the stack above used, non-peek items"
|
||||||
@ -683,6 +681,8 @@ NON_ESCAPING_FUNCTIONS = (
|
|||||||
"PyStackRef_IsNullOrInt",
|
"PyStackRef_IsNullOrInt",
|
||||||
"PyStackRef_IsError",
|
"PyStackRef_IsError",
|
||||||
"PyStackRef_IsValid",
|
"PyStackRef_IsValid",
|
||||||
|
"PyStackRef_Wrap",
|
||||||
|
"PyStackRef_Unwrap",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -811,7 +811,7 @@ def stack_effect_only_peeks(instr: parser.InstDef) -> bool:
|
|||||||
if len(stack_inputs) == 0:
|
if len(stack_inputs) == 0:
|
||||||
return False
|
return False
|
||||||
return all(
|
return all(
|
||||||
(s.name == other.name and s.type == other.type and s.size == other.size)
|
(s.name == other.name and s.size == other.size)
|
||||||
for s, other in zip(stack_inputs, instr.outputs)
|
for s, other in zip(stack_inputs, instr.outputs)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,9 +56,7 @@ def root_relative_path(filename: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def type_and_null(var: StackItem) -> tuple[str, str]:
|
def type_and_null(var: StackItem) -> tuple[str, str]:
|
||||||
if var.type:
|
if var.is_array():
|
||||||
return var.type, "NULL"
|
|
||||||
elif var.is_array():
|
|
||||||
return "_PyStackRef *", "NULL"
|
return "_PyStackRef *", "NULL"
|
||||||
else:
|
else:
|
||||||
return "_PyStackRef", "PyStackRef_NULL"
|
return "_PyStackRef", "PyStackRef_NULL"
|
||||||
|
@ -73,8 +73,6 @@ def validate_uop(override: Uop, uop: Uop) -> None:
|
|||||||
def type_name(var: StackItem) -> str:
|
def type_name(var: StackItem) -> str:
|
||||||
if var.is_array():
|
if var.is_array():
|
||||||
return "JitOptSymbol **"
|
return "JitOptSymbol **"
|
||||||
if var.type:
|
|
||||||
return var.type
|
|
||||||
return "JitOptSymbol *"
|
return "JitOptSymbol *"
|
||||||
|
|
||||||
|
|
||||||
@ -230,7 +228,7 @@ def generate_abstract_interpreter(
|
|||||||
declare_variables(override, out, skip_inputs=False)
|
declare_variables(override, out, skip_inputs=False)
|
||||||
else:
|
else:
|
||||||
declare_variables(uop, out, skip_inputs=True)
|
declare_variables(uop, out, skip_inputs=True)
|
||||||
stack = Stack(extract_bits=False, cast_type="JitOptSymbol *")
|
stack = Stack()
|
||||||
write_uop(override, uop, out, stack, debug, skip_inputs=(override is None))
|
write_uop(override, uop, out, stack, debug, skip_inputs=(override is None))
|
||||||
out.start_line()
|
out.start_line()
|
||||||
out.emit("break;\n")
|
out.emit("break;\n")
|
||||||
|
@ -247,12 +247,11 @@ class SimpleStmt(Stmt):
|
|||||||
@dataclass
|
@dataclass
|
||||||
class StackEffect(Node):
|
class StackEffect(Node):
|
||||||
name: str = field(compare=False) # __eq__ only uses type, cond, size
|
name: str = field(compare=False) # __eq__ only uses type, cond, size
|
||||||
type: str = "" # Optional `:type`
|
|
||||||
size: str = "" # Optional `[size]`
|
size: str = "" # Optional `[size]`
|
||||||
# Note: size cannot be combined with type or cond
|
# Note: size cannot be combined with type or cond
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
items = [self.name, self.type, self.size]
|
items = [self.name, self.size]
|
||||||
while items and items[-1] == "":
|
while items and items[-1] == "":
|
||||||
del items[-1]
|
del items[-1]
|
||||||
return f"StackEffect({', '.join(repr(item) for item in items)})"
|
return f"StackEffect({', '.join(repr(item) for item in items)})"
|
||||||
@ -463,20 +462,13 @@ class Parser(PLexer):
|
|||||||
# IDENTIFIER [':' IDENTIFIER [TIMES]] ['if' '(' expression ')']
|
# IDENTIFIER [':' IDENTIFIER [TIMES]] ['if' '(' expression ')']
|
||||||
# | IDENTIFIER '[' expression ']'
|
# | IDENTIFIER '[' expression ']'
|
||||||
if tkn := self.expect(lx.IDENTIFIER):
|
if tkn := self.expect(lx.IDENTIFIER):
|
||||||
type_text = ""
|
|
||||||
if self.expect(lx.COLON):
|
|
||||||
type_text = self.require(lx.IDENTIFIER).text.strip()
|
|
||||||
if self.expect(lx.TIMES):
|
|
||||||
type_text += " *"
|
|
||||||
size_text = ""
|
size_text = ""
|
||||||
if self.expect(lx.LBRACKET):
|
if self.expect(lx.LBRACKET):
|
||||||
if type_text:
|
|
||||||
raise self.make_syntax_error("Unexpected [")
|
|
||||||
if not (size := self.expression()):
|
if not (size := self.expression()):
|
||||||
raise self.make_syntax_error("Expected expression")
|
raise self.make_syntax_error("Expected expression")
|
||||||
self.require(lx.RBRACKET)
|
self.require(lx.RBRACKET)
|
||||||
size_text = size.text.strip()
|
size_text = size.text.strip()
|
||||||
return StackEffect(tkn.text, type_text, size_text)
|
return StackEffect(tkn.text, size_text)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@contextual
|
@contextual
|
||||||
|
@ -168,7 +168,7 @@ class Local:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def register(name: str) -> "Local":
|
def register(name: str) -> "Local":
|
||||||
item = StackItem(name, None, "", False, True)
|
item = StackItem(name, "", False, True)
|
||||||
return Local(item, None, True)
|
return Local(item, None, True)
|
||||||
|
|
||||||
def kill(self) -> None:
|
def kill(self) -> None:
|
||||||
@ -216,13 +216,11 @@ def array_or_scalar(var: StackItem | Local) -> str:
|
|||||||
return "array" if var.is_array() else "scalar"
|
return "array" if var.is_array() else "scalar"
|
||||||
|
|
||||||
class Stack:
|
class Stack:
|
||||||
def __init__(self, extract_bits: bool=True, cast_type: str = "uintptr_t") -> None:
|
def __init__(self) -> None:
|
||||||
self.base_offset = PointerOffset.zero()
|
self.base_offset = PointerOffset.zero()
|
||||||
self.physical_sp = PointerOffset.zero()
|
self.physical_sp = PointerOffset.zero()
|
||||||
self.logical_sp = PointerOffset.zero()
|
self.logical_sp = PointerOffset.zero()
|
||||||
self.variables: list[Local] = []
|
self.variables: list[Local] = []
|
||||||
self.extract_bits = extract_bits
|
|
||||||
self.cast_type = cast_type
|
|
||||||
|
|
||||||
def drop(self, var: StackItem, check_liveness: bool) -> None:
|
def drop(self, var: StackItem, check_liveness: bool) -> None:
|
||||||
self.logical_sp = self.logical_sp.pop(var)
|
self.logical_sp = self.logical_sp.pop(var)
|
||||||
@ -268,10 +266,8 @@ class Stack:
|
|||||||
self.base_offset = self.logical_sp
|
self.base_offset = self.logical_sp
|
||||||
if var.name in UNUSED or not var.used:
|
if var.name in UNUSED or not var.used:
|
||||||
return Local.unused(var, self.base_offset)
|
return Local.unused(var, self.base_offset)
|
||||||
cast = f"({var.type})" if (not indirect and var.type) else ""
|
|
||||||
bits = ".bits" if cast and self.extract_bits else ""
|
|
||||||
c_offset = (self.base_offset - self.physical_sp).to_c()
|
c_offset = (self.base_offset - self.physical_sp).to_c()
|
||||||
assign = f"{var.name} = {cast}{indirect}stack_pointer[{c_offset}]{bits};\n"
|
assign = f"{var.name} = {indirect}stack_pointer[{c_offset}];\n"
|
||||||
out.emit(assign)
|
out.emit(assign)
|
||||||
self._print(out)
|
self._print(out)
|
||||||
return Local.from_memory(var, self.base_offset)
|
return Local.from_memory(var, self.base_offset)
|
||||||
@ -292,12 +288,8 @@ class Stack:
|
|||||||
out: CWriter,
|
out: CWriter,
|
||||||
var: StackItem,
|
var: StackItem,
|
||||||
stack_offset: PointerOffset,
|
stack_offset: PointerOffset,
|
||||||
cast_type: str,
|
|
||||||
extract_bits: bool,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
cast = f"({cast_type})" if var.type else ""
|
out.emit(f"stack_pointer[{stack_offset.to_c()}] = {var.name};\n")
|
||||||
bits = ".bits" if cast and extract_bits else ""
|
|
||||||
out.emit(f"stack_pointer[{stack_offset.to_c()}]{bits} = {cast}{var.name};\n")
|
|
||||||
|
|
||||||
def _save_physical_sp(self, out: CWriter) -> None:
|
def _save_physical_sp(self, out: CWriter) -> None:
|
||||||
if self.physical_sp != self.logical_sp:
|
if self.physical_sp != self.logical_sp:
|
||||||
@ -320,7 +312,7 @@ class Stack:
|
|||||||
self._print(out)
|
self._print(out)
|
||||||
var.memory_offset = var_offset
|
var.memory_offset = var_offset
|
||||||
stack_offset = var_offset - self.physical_sp
|
stack_offset = var_offset - self.physical_sp
|
||||||
Stack._do_emit(out, var.item, stack_offset, self.cast_type, self.extract_bits)
|
Stack._do_emit(out, var.item, stack_offset)
|
||||||
self._print(out)
|
self._print(out)
|
||||||
var_offset = var_offset.push(var.item)
|
var_offset = var_offset.push(var.item)
|
||||||
|
|
||||||
@ -350,7 +342,7 @@ class Stack:
|
|||||||
out.emit(self.as_comment() + "\n")
|
out.emit(self.as_comment() + "\n")
|
||||||
|
|
||||||
def copy(self) -> "Stack":
|
def copy(self) -> "Stack":
|
||||||
other = Stack(self.extract_bits, self.cast_type)
|
other = Stack()
|
||||||
other.base_offset = self.base_offset
|
other.base_offset = self.base_offset
|
||||||
other.physical_sp = self.physical_sp
|
other.physical_sp = self.physical_sp
|
||||||
other.logical_sp = self.logical_sp
|
other.logical_sp = self.logical_sp
|
||||||
|
Loading…
x
Reference in New Issue
Block a user