This commit is contained in:
blueloveTH 2025-11-02 14:45:29 +08:00
parent 10ce995780
commit 96505249d6
3 changed files with 21 additions and 8 deletions

View File

@ -56,3 +56,7 @@ Mark a function that can raise an exception on failure.
### `PY_RETURN` macro ### `PY_RETURN` macro
Mark a function that can store a value in `py_retval()` on success. Mark a function that can store a value in `py_retval()` on success.
### `PY_MAYBENULL` macro
Mark a variable or callback function that may be `NULL`.

View File

@ -49,6 +49,7 @@ typedef struct c11_sv {
#define PY_RAISE #define PY_RAISE
#define PY_RETURN #define PY_RETURN
#define PY_MAYBENULL
/// A generic reference to a python object. /// A generic reference to a python object.
typedef py_TValue* py_Ref; typedef py_TValue* py_Ref;
@ -79,7 +80,7 @@ typedef struct py_Callbacks {
/// Used by `__import__` to load a source module. /// Used by `__import__` to load a source module.
char* (*importfile)(const char*); char* (*importfile)(const char*);
/// Called before `importfile` to lazy-import a C module. /// Called before `importfile` to lazy-import a C module.
py_GlobalRef (*lazyimport)(const char*); PY_MAYBENULL py_GlobalRef (*lazyimport)(const char*);
/// Used by `print` to output a string. /// Used by `print` to output a string.
void (*print)(const char*); void (*print)(const char*);
/// Flush the output buffer of `print`. /// Flush the output buffer of `print`.
@ -87,7 +88,9 @@ typedef struct py_Callbacks {
/// Used by `input` to get a character. /// Used by `input` to get a character.
int (*getchr)(); int (*getchr)();
/// Used by `gc.collect()` to mark extra objects for garbage collection. /// Used by `gc.collect()` to mark extra objects for garbage collection.
void (*gc_mark)(void (*f)(py_Ref val, void* ctx), void* ctx); PY_MAYBENULL void (*gc_mark)(void (*f)(py_Ref val, void* ctx), void* ctx);
/// Used by `PRINT_EXPR` bytecode.
PY_MAYBENULL bool (*displayhook)(py_Ref val) PY_RAISE;
} py_Callbacks; } py_Callbacks;
/// A struct contains the application-level callbacks. /// A struct contains the application-level callbacks.

View File

@ -152,15 +152,21 @@ __NEXT_STEP:
*THIRD() = tmp; *THIRD() = tmp;
DISPATCH(); DISPATCH();
} }
case OP_PRINT_EXPR: case OP_PRINT_EXPR: {
if(self->callbacks.displayhook) {
bool ok = self->callbacks.displayhook(TOP());
if(!ok) goto __ERROR;
} else {
if(TOP()->type != tp_NoneType) { if(TOP()->type != tp_NoneType) {
bool ok = py_repr(TOP()); bool ok = py_repr(TOP());
if(!ok) goto __ERROR; if(!ok) goto __ERROR;
self->callbacks.print(py_tostr(&self->last_retval)); self->callbacks.print(py_tostr(&self->last_retval));
self->callbacks.print("\n"); self->callbacks.print("\n");
} }
}
POP(); POP();
DISPATCH(); DISPATCH();
}
/*****************************************/ /*****************************************/
case OP_LOAD_CONST: { case OP_LOAD_CONST: {
PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg)); PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg));