mirror of
https://github.com/pocketpy/pocketpy
synced 2026-02-04 06:30:17 +00:00
fix #456
This commit is contained in:
parent
a59f916f5b
commit
cf965a1957
@ -135,7 +135,7 @@ void FuncDecl__dtor(FuncDecl* self);
|
||||
typedef struct Function {
|
||||
FuncDecl_ decl;
|
||||
py_GlobalRef module; // maybe NULL, weak ref
|
||||
py_Ref globals; // maybe NULL, strong ref
|
||||
py_TValue globals; // maybe nil, strong ref
|
||||
NameDict* closure; // maybe NULL, strong ref
|
||||
PyObject* clazz; // weak ref; for super()
|
||||
py_CFunction cfunc; // wrapped C function; for decl-based binding
|
||||
@ -143,3 +143,8 @@ typedef struct Function {
|
||||
|
||||
void Function__ctor(Function* self, FuncDecl_ decl, py_GlobalRef module, py_Ref globals);
|
||||
void Function__dtor(Function* self);
|
||||
|
||||
|
||||
// https://github.com/pocketpy/pocketpy/issues/456
|
||||
// Function may be created from `execdyn` and return
|
||||
// Weakrefs like `.globals` and `.clazz` may invalidate
|
||||
|
||||
@ -512,7 +512,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
||||
// submit the call
|
||||
if(!fn->cfunc) {
|
||||
// python function
|
||||
VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, false));
|
||||
VM__push_frame(self, Frame__new(co, p0, fn->module, &fn->globals, argv, false));
|
||||
return opcall ? RES_CALL : VM__run_top_frame(self);
|
||||
} else {
|
||||
// decl-based binding
|
||||
@ -541,7 +541,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
||||
// submit the call
|
||||
if(!fn->cfunc) {
|
||||
// python function
|
||||
VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, false));
|
||||
VM__push_frame(self, Frame__new(co, p0, fn->module, &fn->globals, argv, false));
|
||||
return opcall ? RES_CALL : VM__run_top_frame(self);
|
||||
} else {
|
||||
// decl-based binding
|
||||
@ -557,7 +557,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
||||
// copy buffer back to stack
|
||||
self->stack.sp = argv + co->nlocals;
|
||||
memcpy(argv, self->vectorcall_buffer, co->nlocals * sizeof(py_TValue));
|
||||
py_Frame* frame = Frame__new(co, p0, fn->module, fn->globals, argv, false);
|
||||
py_Frame* frame = Frame__new(co, p0, fn->module, &fn->globals, argv, false);
|
||||
pk_newgenerator(py_retval(), frame, p0, self->stack.sp);
|
||||
self->stack.sp = p0; // reset the stack
|
||||
return RES_RETURN;
|
||||
|
||||
@ -538,7 +538,7 @@ py_GlobalRef pk_builtins__register() {
|
||||
|
||||
void function__gc_mark(void* ud, c11_vector* p_stack) {
|
||||
Function* func = ud;
|
||||
if(func->globals) pk__mark_value(func->globals);
|
||||
pk__mark_value(&func->globals);
|
||||
if(func->closure) {
|
||||
NameDict* dict = func->closure;
|
||||
for(int i = 0; i < dict->capacity; i++) {
|
||||
|
||||
@ -143,7 +143,7 @@ void Function__ctor(Function* self, FuncDecl_ decl, py_GlobalRef module, py_Ref
|
||||
PK_INCREF(decl);
|
||||
self->decl = decl;
|
||||
self->module = module;
|
||||
self->globals = globals;
|
||||
self->globals = globals != NULL ? *globals : *py_NIL();
|
||||
self->closure = NULL;
|
||||
self->clazz = NULL;
|
||||
self->cfunc = NULL;
|
||||
|
||||
17
tests/661_exec_bug.py
Normal file
17
tests/661_exec_bug.py
Normal file
@ -0,0 +1,17 @@
|
||||
# https://github.com/pocketpy/pocketpy/issues/456
|
||||
|
||||
module_code = '''
|
||||
CONSTANT = 42
|
||||
|
||||
def hello(name):
|
||||
return "Hello, " + name
|
||||
'''
|
||||
|
||||
namespace = {}
|
||||
|
||||
exec(module_code, namespace)
|
||||
|
||||
assert namespace['CONSTANT'] == 42
|
||||
assert namespace['hello']('world') == "Hello, world"
|
||||
# print("Constant:", namespace['CONSTANT'])
|
||||
# print("Function result:", namespace['hello']('world'))
|
||||
Loading…
x
Reference in New Issue
Block a user