Skip to content

Commit

Permalink
Enable stack switching
Browse files Browse the repository at this point in the history
  • Loading branch information
hoodmane committed Jul 13, 2024
1 parent c37898f commit 7005855
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 65 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ src/core/libpyodide.a: \
src/core/jslib_asm.o \
src/core/python2js.o \
src/core/pyodide_pre.o \
src/core/stack_switching/pystate.o \
src/core/pyversion.o
emar rcs src/core/libpyodide.a $(filter %.o,$^)

Expand Down
63 changes: 3 additions & 60 deletions src/core/stack_switching/pystate.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "Python.h"
#include "emscripten.h"
#include "error_handling.h"
#include "internal/pycore_frame.h"
#include "missing_python.h"

// This file manages the Python stack / thread state when stack switching.
//
Expand Down Expand Up @@ -116,17 +116,14 @@ typedef struct
PyThreadState* ts;
} ThreadState;

PyThreadState *
_PyThreadState_SwapNoGIL(PyThreadState *newts);


EMSCRIPTEN_KEEPALIVE ThreadState*
captureThreadState()
{
ThreadState* res = malloc(sizeof(ThreadState));
res->as = saveAsyncioState();
PyThreadState* interp = PyThreadState_New(PyInterpreterState_Get());
res->ts = _PyThreadState_SwapNoGIL(interp);
res->ts = PyThreadState_Swap(interp);

PyObject* _asyncio_module = NULL;
PyObject* t = NULL;
Expand All @@ -143,61 +140,7 @@ EMSCRIPTEN_KEEPALIVE void
restoreThreadState(ThreadState* state)
{
restoreAsyncioState(state->as);
PyThreadState* res = _PyThreadState_SwapNoGIL(state->ts);
PyThreadState* res = PyThreadState_Swap(state->ts);
PyThreadState_Delete(res);
}

EMSCRIPTEN_KEEPALIVE int size_of_cframe = sizeof(_PyCFrame);

EMSCRIPTEN_KEEPALIVE _PyCFrame*
get_cframe()
{
PyThreadState* tstate = PyThreadState_Get();
return tstate->cframe;
}

EMSCRIPTEN_KEEPALIVE void
restore_cframe(_PyCFrame* frame)
{
PyThreadState* tstate = PyThreadState_Get();
tstate->cframe = frame;
}

EMSCRIPTEN_KEEPALIVE void
set_new_cframe(_PyCFrame* frame)
{
PyThreadState* tstate = PyThreadState_Get();
*frame = *tstate->cframe;
tstate->cframe = frame;
tstate->cframe->previous = &PyThreadState_GET()->root_cframe;
tstate->cframe->current_frame = NULL;
tstate->trash.delete_nesting = 0;
tstate->py_recursion_remaining = tstate->py_recursion_limit;
tstate->c_recursion_remaining = C_RECURSION_LIMIT;
}

EMSCRIPTEN_KEEPALIVE void
exit_cframe(_PyCFrame* frame)
{
PyThreadState* tstate = PyThreadState_Get();
_PyStackChunk* chunk = tstate->datastack_chunk;

PyObjectArenaAllocator alloc;
PyObject_GetArenaAllocator(&alloc);

tstate->cframe = frame;
tstate->datastack_chunk = NULL;
tstate->datastack_top = NULL;
tstate->datastack_limit = NULL;

if (!alloc.free) {
return;
}

while (chunk) {
_PyStackChunk* prev = chunk->previous;
chunk->previous = NULL;
alloc.free(alloc.ctx, chunk, chunk->size);
chunk = prev;
}
}
5 changes: 0 additions & 5 deletions src/core/stack_switching/suspenders.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@ import { StackState } from "./stack_state.mjs";
function save_state() {
const stackState = new StackState();
const threadState = _captureThreadState();
const origCframe = Module.origCframe;
_restore_cframe(origCframe);
return {
threadState,
stackState,
suspender: suspenderGlobal.value,
origCframe,
};
}

Expand Down Expand Up @@ -87,8 +84,6 @@ export function promisingApply(...args) {
validSuspender.value = true;
// Record the current stack position. Used in stack_state.mjs
Module.stackStop = stackSave();
// Subtle cframe shenanigans...
Module.origCframe = _get_cframe();
return promisingApplyHandler(...args);
}

Expand Down

0 comments on commit 7005855

Please sign in to comment.