#define STACK_LEVEL() ((int)(stack_pointer - ctx->frame->stack))
#define STACK_SIZE() ((int)(ctx->frame->stack_len))
+#define CURRENT_FRAME_IS_INIT_SHIM() (ctx->frame->code == ((PyCodeObject *)&_Py_InitCleanup))
+
#define WITHIN_STACK_BOUNDS() \
- (STACK_LEVEL() >= 0 && STACK_LEVEL() <= STACK_SIZE())
+ (CURRENT_FRAME_IS_INIT_SHIM() || (STACK_LEVEL() >= 0 && STACK_LEVEL() <= STACK_SIZE()))
#define GETLOCAL(idx) ((ctx->frame->locals[idx]))
ctx->frame = frame;
_PyUOpInstruction *this_instr = NULL;
+ JitOptRef *stack_pointer = ctx->frame->stack_pointer;
+
for (int i = 0; !ctx->done; i++) {
assert(i < trace_len);
this_instr = &trace[i];
int oparg = this_instr->oparg;
opcode = this_instr->opcode;
- JitOptRef *stack_pointer = ctx->frame->stack_pointer;
+
+ if (!CURRENT_FRAME_IS_INIT_SHIM()) {
+ stack_pointer = ctx->frame->stack_pointer;
+ }
#ifdef Py_DEBUG
if (get_lltrace() >= 3) {
Py_UNREACHABLE();
}
assert(ctx->frame != NULL);
- DPRINTF(3, " stack_level %d\n", STACK_LEVEL());
- ctx->frame->stack_pointer = stack_pointer;
- assert(STACK_LEVEL() >= 0);
+ if (!CURRENT_FRAME_IS_INIT_SHIM()) {
+ DPRINTF(3, " stack_level %d\n", STACK_LEVEL());
+ ctx->frame->stack_pointer = stack_pointer;
+ assert(STACK_LEVEL() >= 0);
+ }
}
if (ctx->out_of_space) {
DPRINTF(3, "\n");
}
op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame)) {
- init_frame = PyJitRef_NULL;
- ctx->done = true;
+ _Py_UOpsAbstractFrame *old_frame = ctx->frame;
+ _Py_UOpsAbstractFrame *shim = frame_new(ctx, (PyCodeObject *)&_Py_InitCleanup, 0, NULL, 0);
+ if (shim == NULL) {
+ break;
+ }
+ /* Push self onto stack of shim */
+ shim->stack[0] = self;
+ shim->stack_pointer++;
+ assert((int)(shim->stack_pointer - shim->stack) == 1);
+ ctx->frame = shim;
+ ctx->curr_frame_depth++;
+ assert((this_instr + 1)->opcode == _PUSH_FRAME);
+ PyCodeObject *co = get_code_with_logging((this_instr + 1));
+ init_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, args-1, oparg+1));
}
op(_RETURN_VALUE, (retval -- res)) {
op(_PUSH_FRAME, (new_frame -- )) {
SYNC_SP();
- ctx->frame->stack_pointer = stack_pointer;
+ if (!CURRENT_FRAME_IS_INIT_SHIM()) {
+ ctx->frame->stack_pointer = stack_pointer;
+ }
ctx->frame = (_Py_UOpsAbstractFrame *)PyJitRef_Unwrap(new_frame);
ctx->curr_frame_depth++;
stack_pointer = ctx->frame->stack_pointer;
new_frame = stack_pointer[-1];
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
- ctx->frame->stack_pointer = stack_pointer;
+ if (!CURRENT_FRAME_IS_INIT_SHIM()) {
+ ctx->frame->stack_pointer = stack_pointer;
+ }
ctx->frame = (_Py_UOpsAbstractFrame *)PyJitRef_Unwrap(new_frame);
ctx->curr_frame_depth++;
stack_pointer = ctx->frame->stack_pointer;
}
case _CREATE_INIT_FRAME: {
+ JitOptRef *args;
+ JitOptRef self;
JitOptRef init_frame;
- init_frame = PyJitRef_NULL;
- ctx->done = true;
+ args = &stack_pointer[-oparg];
+ self = stack_pointer[-1 - oparg];
+ _Py_UOpsAbstractFrame *old_frame = ctx->frame;
+ _Py_UOpsAbstractFrame *shim = frame_new(ctx, (PyCodeObject *)&_Py_InitCleanup, 0, NULL, 0);
+ if (shim == NULL) {
+ break;
+ }
+ shim->stack[0] = self;
+ shim->stack_pointer++;
+ assert((int)(shim->stack_pointer - shim->stack) == 1);
+ ctx->frame = shim;
+ ctx->curr_frame_depth++;
+ assert((this_instr + 1)->opcode == _PUSH_FRAME);
+ PyCodeObject *co = get_code_with_logging((this_instr + 1));
+ init_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, args-1, oparg+1));
stack_pointer[-2 - oparg] = init_frame;
stack_pointer += -1 - oparg;
assert(WITHIN_STACK_BOUNDS());
return NULL;
}
_Py_UOpsAbstractFrame *frame = &ctx->frames[ctx->curr_frame_depth];
-
frame->code = co;
frame->stack_len = co->co_stacksize;
frame->locals_len = co->co_nlocalsplus;