mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
plan to implement tracefunc
This commit is contained in:
parent
7b4994ee35
commit
19d0cfd4fd
@ -1,10 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
#define PK_VERSION "2.0.6"
|
#define PK_VERSION "2.0.7"
|
||||||
#define PK_VERSION_MAJOR 2
|
#define PK_VERSION_MAJOR 2
|
||||||
#define PK_VERSION_MINOR 0
|
#define PK_VERSION_MINOR 0
|
||||||
#define PK_VERSION_PATCH 6
|
#define PK_VERSION_PATCH 7
|
||||||
|
|
||||||
/*************** feature settings ***************/
|
/*************** feature settings ***************/
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ typedef struct VM {
|
|||||||
|
|
||||||
py_TValue last_retval;
|
py_TValue last_retval;
|
||||||
py_TValue curr_exception;
|
py_TValue curr_exception;
|
||||||
volatile bool is_signal_interrupted;
|
|
||||||
bool is_curr_exc_handled; // handled by try-except block but not cleared yet
|
bool is_curr_exc_handled; // handled by try-except block but not cleared yet
|
||||||
|
|
||||||
py_TValue reg[8]; // users' registers
|
py_TValue reg[8]; // users' registers
|
||||||
|
@ -34,6 +34,33 @@ typedef struct c11_sv {
|
|||||||
int size;
|
int size;
|
||||||
} c11_sv;
|
} c11_sv;
|
||||||
|
|
||||||
|
// An enum for tracing events.
|
||||||
|
enum py_TraceEvent {
|
||||||
|
TraceEvent_Line,
|
||||||
|
TraceEvent_Call,
|
||||||
|
TraceEvent_Return,
|
||||||
|
TraceEvent_Exception,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A struct contains the arguments of the tracing event.
|
||||||
|
union py_TraceEventArg {
|
||||||
|
struct {
|
||||||
|
int _;
|
||||||
|
} line;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int _;
|
||||||
|
} call;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int _;
|
||||||
|
} return_;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int _;
|
||||||
|
} exception;
|
||||||
|
};
|
||||||
|
|
||||||
/// A struct contains the callbacks of the VM.
|
/// A struct contains the callbacks of the VM.
|
||||||
typedef struct py_Callbacks {
|
typedef struct py_Callbacks {
|
||||||
/// Used by `__import__` to load source code of a module.
|
/// Used by `__import__` to load source code of a module.
|
||||||
@ -42,6 +69,8 @@ typedef struct py_Callbacks {
|
|||||||
void (*print)(const char*);
|
void (*print)(const char*);
|
||||||
/// Used by `input` to get a character.
|
/// Used by `input` to get a character.
|
||||||
int (*getchar)();
|
int (*getchar)();
|
||||||
|
/// C-style `sys.settrace` function.
|
||||||
|
void (*tracefunc)(enum py_TraceEvent, union py_TraceEventArg);
|
||||||
} py_Callbacks;
|
} py_Callbacks;
|
||||||
|
|
||||||
#define PY_RAISE
|
#define PY_RAISE
|
||||||
@ -89,8 +118,6 @@ PK_API void py_resetvm();
|
|||||||
PK_API void* py_getvmctx();
|
PK_API void* py_getvmctx();
|
||||||
/// Set the current VM context. This is used for user-defined data.
|
/// Set the current VM context. This is used for user-defined data.
|
||||||
PK_API void py_setvmctx(void* ctx);
|
PK_API void py_setvmctx(void* ctx);
|
||||||
/// Interrupt the current VM and raise a `KeyboardInterrupt` exception.
|
|
||||||
PK_API void py_interrupt();
|
|
||||||
/// Set `sys.argv`. Used for storing command-line arguments.
|
/// Set `sys.argv`. Used for storing command-line arguments.
|
||||||
PK_API void py_sys_setargv(int argc, char** argv);
|
PK_API void py_sys_setargv(int argc, char** argv);
|
||||||
/// Setup the callbacks for the current VM.
|
/// Setup the callbacks for the current VM.
|
||||||
@ -219,10 +246,7 @@ PK_API c11_sv py_name2sv(py_Name);
|
|||||||
/// @param base base type.
|
/// @param base base type.
|
||||||
/// @param module module where the type is defined. Use `NULL` for built-in types.
|
/// @param module module where the type is defined. Use `NULL` for built-in types.
|
||||||
/// @param dtor destructor function. Use `NULL` if not needed.
|
/// @param dtor destructor function. Use `NULL` if not needed.
|
||||||
PK_API py_Type py_newtype(const char* name,
|
PK_API py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, py_Dtor dtor);
|
||||||
py_Type base,
|
|
||||||
const py_GlobalRef module,
|
|
||||||
py_Dtor dtor);
|
|
||||||
|
|
||||||
/// Create a new object.
|
/// Create a new object.
|
||||||
/// @param out output reference.
|
/// @param out output reference.
|
||||||
@ -478,11 +502,10 @@ PK_API py_StackRef py_pushtmp();
|
|||||||
/// If return false: `[self] -> [self]` (no change).
|
/// If return false: `[self] -> [self]` (no change).
|
||||||
PK_API bool py_pushmethod(py_Name name);
|
PK_API bool py_pushmethod(py_Name name);
|
||||||
/// Call a callable object via pocketpy's calling convention.
|
/// Call a callable object via pocketpy's calling convention.
|
||||||
/// You need to prepare the stack using this form: `callable, self/nil, arg1, arg2, ..., k1, v1, k2, v2, ...`
|
/// You need to prepare the stack using this form: `callable, self/nil, arg1, arg2, ..., k1, v1, k2,
|
||||||
/// `argc` is the number of positional arguments excluding `self`.
|
/// v2, ...` `argc` is the number of positional arguments excluding `self`. `kwargc` is the number
|
||||||
/// `kwargc` is the number of keyword arguments, i.e. the number of key-value pairs.
|
/// of keyword arguments, i.e. the number of key-value pairs. The result will be set to
|
||||||
/// The result will be set to `py_retval()`.
|
/// `py_retval()`. The stack size will be reduced by `2 + argc + kwargc * 2`.
|
||||||
/// The stack size will be reduced by `2 + argc + kwargc * 2`.
|
|
||||||
PK_API bool py_vectorcall(uint16_t argc, uint16_t kwargc) PY_RAISE PY_RETURN;
|
PK_API bool py_vectorcall(uint16_t argc, uint16_t kwargc) PY_RAISE PY_RETURN;
|
||||||
/// Evaluate an expression and push the result to the stack.
|
/// Evaluate an expression and push the result to the stack.
|
||||||
/// This function is used for testing.
|
/// This function is used for testing.
|
||||||
@ -536,7 +559,9 @@ PK_API void py_clearexc(py_StackRef p0);
|
|||||||
#define AttributeError(self, n) \
|
#define AttributeError(self, n) \
|
||||||
py_exception(tp_AttributeError, "'%t' object has no attribute '%n'", (self)->type, (n))
|
py_exception(tp_AttributeError, "'%t' object has no attribute '%n'", (self)->type, (n))
|
||||||
#define UnboundLocalError(n) \
|
#define UnboundLocalError(n) \
|
||||||
py_exception(tp_UnboundLocalError, "cannot access local variable '%n' where it is not associated with a value", (n))
|
py_exception(tp_UnboundLocalError, \
|
||||||
|
"cannot access local variable '%n' where it is not associated with a value", \
|
||||||
|
(n))
|
||||||
|
|
||||||
PK_API bool StopIteration() PY_RAISE;
|
PK_API bool StopIteration() PY_RAISE;
|
||||||
PK_API bool KeyError(py_Ref key) PY_RAISE;
|
PK_API bool KeyError(py_Ref key) PY_RAISE;
|
||||||
@ -672,15 +697,15 @@ PK_API int py_replinput(char* buf, int max_size);
|
|||||||
/// %t: py_Type
|
/// %t: py_Type
|
||||||
/// %n: py_Name
|
/// %n: py_Name
|
||||||
|
|
||||||
enum py_MagicNames {
|
enum py_MagicName {
|
||||||
py_MagicNames__NULL, // 0 is reserved
|
py_MagicName__NULL, // 0 is reserved
|
||||||
|
|
||||||
#define MAGIC_METHOD(x) x,
|
#define MAGIC_METHOD(x) x,
|
||||||
#include "pocketpy/xmacros/magics.h"
|
#include "pocketpy/xmacros/magics.h"
|
||||||
#undef MAGIC_METHOD
|
#undef MAGIC_METHOD
|
||||||
};
|
};
|
||||||
|
|
||||||
enum py_PredefinedTypes {
|
enum py_PredefinedType {
|
||||||
tp_nil = 0,
|
tp_nil = 0,
|
||||||
tp_object = 1,
|
tp_object = 1,
|
||||||
tp_type, // py_Type
|
tp_type, // py_Type
|
||||||
|
@ -97,18 +97,16 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
frame->ip++;
|
frame->ip++;
|
||||||
|
|
||||||
__NEXT_STEP:
|
__NEXT_STEP:
|
||||||
|
if(self->callbacks.tracefunc) {
|
||||||
|
// TODO: implement tracing mechanism
|
||||||
|
}
|
||||||
|
|
||||||
byte = codes[frame->ip];
|
byte = codes[frame->ip];
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
pk_print_stack(self, frame, byte);
|
pk_print_stack(self, frame, byte);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(self->is_signal_interrupted) {
|
|
||||||
self->is_signal_interrupted = false;
|
|
||||||
py_exception(tp_KeyboardInterrupt, "");
|
|
||||||
goto __ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch((Opcode)byte.op) {
|
switch((Opcode)byte.op) {
|
||||||
case OP_NO_OP: DISPATCH();
|
case OP_NO_OP: DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
|
@ -68,10 +68,10 @@ void VM__ctor(VM* self) {
|
|||||||
self->callbacks.importfile = pk_default_importfile;
|
self->callbacks.importfile = pk_default_importfile;
|
||||||
self->callbacks.print = pk_default_print;
|
self->callbacks.print = pk_default_print;
|
||||||
self->callbacks.getchar = getchar;
|
self->callbacks.getchar = getchar;
|
||||||
|
self->callbacks.tracefunc = NULL;
|
||||||
|
|
||||||
self->last_retval = *py_NIL();
|
self->last_retval = *py_NIL();
|
||||||
self->curr_exception = *py_NIL();
|
self->curr_exception = *py_NIL();
|
||||||
self->is_signal_interrupted = false;
|
|
||||||
self->is_curr_exc_handled = false;
|
self->is_curr_exc_handled = false;
|
||||||
|
|
||||||
self->ctx = NULL;
|
self->ctx = NULL;
|
||||||
|
@ -90,8 +90,6 @@ void* py_getvmctx() { return pk_current_vm->ctx; }
|
|||||||
|
|
||||||
void py_setvmctx(void* ctx) { pk_current_vm->ctx = ctx; }
|
void py_setvmctx(void* ctx) { pk_current_vm->ctx = ctx; }
|
||||||
|
|
||||||
void py_interrupt() { pk_current_vm->is_signal_interrupted = true; }
|
|
||||||
|
|
||||||
void py_sys_setargv(int argc, char** argv) {
|
void py_sys_setargv(int argc, char** argv) {
|
||||||
py_GlobalRef sys = py_getmodule("sys");
|
py_GlobalRef sys = py_getmodule("sys");
|
||||||
py_Ref argv_list = py_getdict(sys, py_name("argv"));
|
py_Ref argv_list = py_getdict(sys, py_name("argv"));
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "pocketpy.h"
|
#include "pocketpy.h"
|
||||||
|
|
||||||
|
#define py_interrupt()
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user