mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
partially fix #351
This commit is contained in:
parent
e84f86b2de
commit
c99f0ee919
@ -495,10 +495,12 @@ 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,
|
/// You need to prepare the stack using the following format:
|
||||||
/// v2, ...` `argc` is the number of positional arguments excluding `self`. `kwargc` is the number
|
/// `callable, self/nil, arg1, arg2, ..., k1, v1, k2, v2, ...`.
|
||||||
/// of keyword arguments, i.e. the number of key-value pairs. The result will be set to
|
/// `argc` is the number of positional arguments excluding `self`.
|
||||||
/// `py_retval()`. The stack size will be reduced by `2 + argc + kwargc * 2`.
|
/// `kwargc` is the number of keyword arguments.
|
||||||
|
/// The result will be set to `py_retval()`.
|
||||||
|
/// 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.
|
||||||
|
@ -13,14 +13,6 @@ static bool stack_format_object(VM* self, c11_sv spec);
|
|||||||
#define CHECK_RETURN_FROM_EXCEPT_OR_FINALLY() \
|
#define CHECK_RETURN_FROM_EXCEPT_OR_FINALLY() \
|
||||||
if(self->is_curr_exc_handled) py_clearexc(NULL)
|
if(self->is_curr_exc_handled) py_clearexc(NULL)
|
||||||
|
|
||||||
#define CHECK_STACK_OVERFLOW() \
|
|
||||||
do { \
|
|
||||||
if(self->stack.sp > self->stack.end) { \
|
|
||||||
py_exception(tp_StackOverflowError, ""); \
|
|
||||||
goto __ERROR; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define DISPATCH() \
|
#define DISPATCH() \
|
||||||
do { \
|
do { \
|
||||||
frame->ip++; \
|
frame->ip++; \
|
||||||
@ -61,6 +53,7 @@ static bool stack_format_object(VM* self, c11_sv spec);
|
|||||||
*SECOND() = *THIRD(); \
|
*SECOND() = *THIRD(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
// Must use a DISPATCH() after vectorcall_opcall() immediately!
|
||||||
#define vectorcall_opcall(argc, kwargc) \
|
#define vectorcall_opcall(argc, kwargc) \
|
||||||
do { \
|
do { \
|
||||||
FrameResult res = VM__vectorcall(self, (argc), (kwargc), true); \
|
FrameResult res = VM__vectorcall(self, (argc), (kwargc), true); \
|
||||||
@ -93,6 +86,11 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
while(true) {
|
while(true) {
|
||||||
Bytecode byte;
|
Bytecode byte;
|
||||||
__NEXT_FRAME:
|
__NEXT_FRAME:
|
||||||
|
if(self->stack.sp > self->stack.end) {
|
||||||
|
py_exception(tp_StackOverflowError, "");
|
||||||
|
goto __ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
codes = frame->co->codes.data;
|
codes = frame->co->codes.data;
|
||||||
frame->ip++;
|
frame->ip++;
|
||||||
|
|
||||||
@ -149,39 +147,32 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
DISPATCH();
|
DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_CONST: {
|
case OP_LOAD_CONST: {
|
||||||
CHECK_STACK_OVERFLOW();
|
|
||||||
PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg));
|
PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg));
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_LOAD_NONE: {
|
case OP_LOAD_NONE: {
|
||||||
CHECK_STACK_OVERFLOW();
|
|
||||||
py_newnone(SP()++);
|
py_newnone(SP()++);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_LOAD_TRUE: {
|
case OP_LOAD_TRUE: {
|
||||||
CHECK_STACK_OVERFLOW();
|
|
||||||
py_newbool(SP()++, true);
|
py_newbool(SP()++, true);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_LOAD_FALSE: {
|
case OP_LOAD_FALSE: {
|
||||||
CHECK_STACK_OVERFLOW();
|
|
||||||
py_newbool(SP()++, false);
|
py_newbool(SP()++, false);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_SMALL_INT: {
|
case OP_LOAD_SMALL_INT: {
|
||||||
CHECK_STACK_OVERFLOW();
|
|
||||||
py_newint(SP()++, (int16_t)byte.arg);
|
py_newint(SP()++, (int16_t)byte.arg);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_ELLIPSIS: {
|
case OP_LOAD_ELLIPSIS: {
|
||||||
CHECK_STACK_OVERFLOW();
|
|
||||||
py_newellipsis(SP()++);
|
py_newellipsis(SP()++);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_LOAD_FUNCTION: {
|
case OP_LOAD_FUNCTION: {
|
||||||
CHECK_STACK_OVERFLOW();
|
|
||||||
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
||||||
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
|
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
|
||||||
Function__ctor(ud, decl, frame->module, frame->globals);
|
Function__ctor(ud, decl, frame->module, frame->globals);
|
||||||
@ -352,8 +343,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
} else {
|
} else {
|
||||||
INSERT_THIRD(); // [?, a, b]
|
INSERT_THIRD(); // [?, a, b]
|
||||||
*THIRD() = *magic; // [__getitem__, a, b]
|
*THIRD() = *magic; // [__getitem__, a, b]
|
||||||
if(!py_vectorcall(1, 0)) goto __ERROR;
|
vectorcall_opcall(1, 0);
|
||||||
PUSH(py_retval());
|
|
||||||
}
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
@ -503,8 +493,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
py_newnil(SP()++); // [complex, NULL]
|
py_newnil(SP()++); // [complex, NULL]
|
||||||
py_newint(SP()++, 0); // [complex, NULL, 0]
|
py_newint(SP()++, 0); // [complex, NULL, 0]
|
||||||
*SP()++ = tmp; // [complex, NULL, 0, x]
|
*SP()++ = tmp; // [complex, NULL, 0, x]
|
||||||
if(!py_vectorcall(2, 0)) goto __ERROR;
|
vectorcall_opcall(2, 0);
|
||||||
PUSH(py_retval());
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_BUILD_BYTES: {
|
case OP_BUILD_BYTES: {
|
||||||
@ -1079,8 +1068,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
TOP()->type);
|
TOP()->type);
|
||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
}
|
}
|
||||||
if(!py_vectorcall(0, 0)) goto __ERROR;
|
vectorcall_opcall(0, 0);
|
||||||
PUSH(py_retval());
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_WITH_EXIT: {
|
case OP_WITH_EXIT: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user