mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
1a4b88829c
commit
8f97e9419f
@ -324,6 +324,8 @@ bool py_callmethod(py_Ref self, py_Name, int argc, py_Ref argv);
|
|||||||
/// The result will be set to `py_retval()`.
|
/// The result will be set to `py_retval()`.
|
||||||
/// The stack remains unchanged after the operation.
|
/// The stack remains unchanged after the operation.
|
||||||
bool py_callmagic(py_Name name, int argc, py_Ref argv);
|
bool py_callmagic(py_Name name, int argc, py_Ref argv);
|
||||||
|
/// Call a `py_CFunction` in a safe way.
|
||||||
|
bool py_callcfunc(py_StackRef p0, py_CFunction cfunc, int argc, py_Ref argv);
|
||||||
|
|
||||||
bool py_str(py_Ref val);
|
bool py_str(py_Ref val);
|
||||||
#define py_repr(val) py_callmagic(__repr__, 1, val)
|
#define py_repr(val) py_callmagic(__repr__, 1, val)
|
||||||
|
@ -267,10 +267,8 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
py_Ref magic = py_tpfindmagic(SECOND()->type, __getitem__);
|
py_Ref magic = py_tpfindmagic(SECOND()->type, __getitem__);
|
||||||
if(magic) {
|
if(magic) {
|
||||||
if(magic->type == tp_nativefunc) {
|
if(magic->type == tp_nativefunc) {
|
||||||
py_TValue* next_sp = TOP();
|
py_TValue* p0 = TOP();
|
||||||
bool ok = magic->_cfunc(2, SECOND());
|
if(!py_callcfunc(p0, magic->_cfunc, 2, SECOND())) goto __ERROR;
|
||||||
if(!ok) goto __ERROR;
|
|
||||||
SP() = next_sp;
|
|
||||||
*TOP() = self->last_retval;
|
*TOP() = self->last_retval;
|
||||||
} else {
|
} else {
|
||||||
INSERT_THIRD(); // [?, a, b]
|
INSERT_THIRD(); // [?, a, b]
|
||||||
@ -321,10 +319,8 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
if(magic) {
|
if(magic) {
|
||||||
PUSH(THIRD()); // [val, a, b, val]
|
PUSH(THIRD()); // [val, a, b, val]
|
||||||
if(magic->type == tp_nativefunc) {
|
if(magic->type == tp_nativefunc) {
|
||||||
py_TValue* next_sp = FOURTH();
|
py_TValue* p0 = FOURTH();
|
||||||
bool ok = magic->_cfunc(3, THIRD());
|
if(!py_callcfunc(p0, magic->_cfunc, 3, THIRD())) goto __ERROR;
|
||||||
if(!ok) goto __ERROR;
|
|
||||||
SP() = next_sp;
|
|
||||||
} else {
|
} else {
|
||||||
*FOURTH() = *magic; // [__selitem__, a, b, val]
|
*FOURTH() = *magic; // [__selitem__, a, b, val]
|
||||||
if(!py_vectorcall(2, 0)) goto __ERROR;
|
if(!py_vectorcall(2, 0)) goto __ERROR;
|
||||||
@ -391,10 +387,8 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
py_Ref magic = py_tpfindmagic(SECOND()->type, __delitem__);
|
py_Ref magic = py_tpfindmagic(SECOND()->type, __delitem__);
|
||||||
if(magic) {
|
if(magic) {
|
||||||
if(magic->type == tp_nativefunc) {
|
if(magic->type == tp_nativefunc) {
|
||||||
py_TValue* next_sp = SECOND();
|
py_TValue* p0 = SECOND();
|
||||||
bool ok = magic->_cfunc(2, SECOND());
|
if(!py_callcfunc(p0, magic->_cfunc, 2, SECOND())) goto __ERROR;
|
||||||
if(!ok) goto __ERROR;
|
|
||||||
SP() = next_sp;
|
|
||||||
} else {
|
} else {
|
||||||
INSERT_THIRD(); // [?, a, b]
|
INSERT_THIRD(); // [?, a, b]
|
||||||
*THIRD() = *magic; // [__delitem__, a, b]
|
*THIRD() = *magic; // [__delitem__, a, b]
|
||||||
@ -533,10 +527,8 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
py_Ref magic = py_tpfindmagic(SECOND()->type, __contains__);
|
py_Ref magic = py_tpfindmagic(SECOND()->type, __contains__);
|
||||||
if(magic) {
|
if(magic) {
|
||||||
if(magic->type == tp_nativefunc) {
|
if(magic->type == tp_nativefunc) {
|
||||||
py_TValue* next_sp = TOP();
|
py_TValue* p0 = TOP();
|
||||||
bool ok = magic->_cfunc(2, SECOND());
|
if(!py_callcfunc(p0, magic->_cfunc, 2, SECOND())) goto __ERROR;
|
||||||
if(!ok) goto __ERROR;
|
|
||||||
SP() = next_sp;
|
|
||||||
*TOP() = self->last_retval;
|
*TOP() = self->last_retval;
|
||||||
} else {
|
} else {
|
||||||
INSERT_THIRD(); // [?, b, a]
|
INSERT_THIRD(); // [?, b, a]
|
||||||
|
@ -391,8 +391,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
|
|||||||
pk_VM__push_frame(self, Frame__new(co, fn->module, p0, p0, argv, co));
|
pk_VM__push_frame(self, Frame__new(co, fn->module, p0, p0, argv, co));
|
||||||
return opcall ? RES_CALL : pk_VM__run_top_frame(self);
|
return opcall ? RES_CALL : pk_VM__run_top_frame(self);
|
||||||
} else {
|
} else {
|
||||||
bool ok = fn->cfunc(co->nlocals, argv);
|
bool ok = py_callcfunc(p0, fn->cfunc, co->nlocals, argv);
|
||||||
self->stack.sp = p0;
|
|
||||||
return ok ? RES_RETURN : RES_ERROR;
|
return ok ? RES_RETURN : RES_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,32 +430,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(p0->type == tp_nativefunc) {
|
if(p0->type == tp_nativefunc) {
|
||||||
// const auto& f = PK_OBJ_GET(NativeFunc, callable);
|
if(!py_callcfunc(p0, p0->_cfunc, p1 - argv, argv)) return RES_ERROR;
|
||||||
// PyVar ret;
|
|
||||||
// if(f.decl != nullptr) {
|
|
||||||
// int co_nlocals = f.decl->code->nlocals;
|
|
||||||
// prepare_py_call(__vectorcall_buffer, args, kwargs, f.decl);
|
|
||||||
// // copy buffer back to stack
|
|
||||||
// s_data.reset(_base + co_nlocals);
|
|
||||||
// for(int j = 0; j < co_nlocals; j++)
|
|
||||||
// _base[j] = __vectorcall_buffer[j];
|
|
||||||
// ret = f.call(vm, ArgsView(s_data._sp - co_nlocals, s_data._sp));
|
|
||||||
// } else {
|
|
||||||
// if(f.argc != -1) {
|
|
||||||
// if(KWARGC != 0)
|
|
||||||
// TypeError(
|
|
||||||
// "old-style native_func does not accept keyword arguments. If you want to
|
|
||||||
// skip this check, specify `argc` to -1");
|
|
||||||
// if(args.size() != f.argc) {
|
|
||||||
// vm->TypeError(_S("expected ", f.argc, " arguments, got ", args.size()));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ret = f.call(this, args);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// `argc` passed to _cfunc must include self if exists
|
|
||||||
if(!p0->_cfunc(p1 - argv, argv)) return RES_ERROR;
|
|
||||||
self->stack.sp = p0;
|
|
||||||
return RES_RETURN;
|
return RES_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +178,27 @@ static bool _py_builtins__sum(int argc, py_Ref argv) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool _py_builtins__print(int argc, py_Ref argv) {
|
||||||
|
int length;
|
||||||
|
py_TValue* args = pk_arrayview(argv, &length);
|
||||||
|
assert(args != NULL);
|
||||||
|
c11_sv sep = py_tosv(py_arg(1));
|
||||||
|
c11_sv end = py_tosv(py_arg(2));
|
||||||
|
c11_sbuf buf;
|
||||||
|
c11_sbuf__ctor(&buf);
|
||||||
|
for(int i = 0; i < length; i++) {
|
||||||
|
if(i > 0) c11_sbuf__write_sv(&buf, sep);
|
||||||
|
if(!py_str(&args[i])) return false;
|
||||||
|
c11_sbuf__write_sv(&buf, py_tosv(py_retval()));
|
||||||
|
}
|
||||||
|
c11_sbuf__write_sv(&buf, end);
|
||||||
|
c11_string* res = c11_sbuf__submit(&buf);
|
||||||
|
pk_current_vm->_stdout("%s", res->data);
|
||||||
|
c11_string__delete(res);
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
py_TValue pk_builtins__register() {
|
py_TValue pk_builtins__register() {
|
||||||
py_Ref builtins = py_newmodule("builtins", NULL);
|
py_Ref builtins = py_newmodule("builtins", NULL);
|
||||||
py_bindnativefunc(builtins, "repr", _py_builtins__repr);
|
py_bindnativefunc(builtins, "repr", _py_builtins__repr);
|
||||||
@ -191,6 +212,7 @@ py_TValue pk_builtins__register() {
|
|||||||
py_bindnativefunc(builtins, "abs", _py_builtins__abs);
|
py_bindnativefunc(builtins, "abs", _py_builtins__abs);
|
||||||
py_bindnativefunc(builtins, "sum", _py_builtins__sum);
|
py_bindnativefunc(builtins, "sum", _py_builtins__sum);
|
||||||
|
|
||||||
|
py_bind(builtins, "print(*args, sep=' ', end='\\n')", _py_builtins__print);
|
||||||
py_bind(builtins, "sorted(iterable, key=None, reverse=False)", _py_builtins__sorted);
|
py_bind(builtins, "sorted(iterable, key=None, reverse=False)", _py_builtins__sorted);
|
||||||
return *builtins;
|
return *builtins;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,6 @@ static bool _py_dict__delitem__(int argc, py_Ref argv) {
|
|||||||
PY_CHECK_ARGC(2);
|
PY_CHECK_ARGC(2);
|
||||||
Dict* self = py_touserdata(argv);
|
Dict* self = py_touserdata(argv);
|
||||||
if(!Dict__pop(self, py_arg(1))) return false;
|
if(!Dict__pop(self, py_arg(1))) return false;
|
||||||
py_newnone(py_retval());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +174,7 @@ static bool _py_list__delitem__(int argc, py_Ref argv) {
|
|||||||
int index = py_toint(py_arg(1));
|
int index = py_toint(py_arg(1));
|
||||||
if(!pk__normalize_index(&index, self->count)) return false;
|
if(!pk__normalize_index(&index, self->count)) return false;
|
||||||
c11_vector__erase(py_TValue, self, index);
|
c11_vector__erase(py_TValue, self, index);
|
||||||
|
py_newnone(py_retval());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ void py_bindnativefunc(py_Ref obj, const char* name, py_CFunction f) {
|
|||||||
|
|
||||||
void py_bind(py_Ref obj, const char* sig, py_CFunction f) {
|
void py_bind(py_Ref obj, const char* sig, py_CFunction f) {
|
||||||
py_TValue tmp;
|
py_TValue tmp;
|
||||||
do{
|
do {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
snprintf(buffer, sizeof(buffer), "def %s: pass", sig);
|
snprintf(buffer, sizeof(buffer), "def %s: pass", sig);
|
||||||
// fn(a, b, *c, d=1) -> None
|
// fn(a, b, *c, d=1) -> None
|
||||||
@ -82,7 +82,7 @@ void py_bind(py_Ref obj, const char* sig, py_CFunction f) {
|
|||||||
ud->cfunc = f;
|
ud->cfunc = f;
|
||||||
CodeObject__dtor(&code);
|
CodeObject__dtor(&code);
|
||||||
PK_DECREF(source);
|
PK_DECREF(source);
|
||||||
}while(0);
|
} while(0);
|
||||||
Function* ud = py_touserdata(&tmp);
|
Function* ud = py_touserdata(&tmp);
|
||||||
py_Name name = py_name(ud->decl->code.name->data);
|
py_Name name = py_name(ud->decl->code.name->data);
|
||||||
py_setdict(obj, name, &tmp);
|
py_setdict(obj, name, &tmp);
|
||||||
|
@ -203,7 +203,8 @@ bool py_exec2(const char* source, const char* filename, enum py_CompileMode mode
|
|||||||
|
|
||||||
bool py_call(py_Ref f, int argc, py_Ref argv) {
|
bool py_call(py_Ref f, int argc, py_Ref argv) {
|
||||||
if(f->type == tp_nativefunc) {
|
if(f->type == tp_nativefunc) {
|
||||||
return f->_cfunc(argc, argv);
|
py_TValue* p0 = pk_current_vm->stack.sp;
|
||||||
|
return py_callcfunc(p0, f->_cfunc, argc, argv);
|
||||||
} else {
|
} else {
|
||||||
py_push(f);
|
py_push(f);
|
||||||
py_pushnil();
|
py_pushnil();
|
||||||
@ -311,6 +312,12 @@ bool py_callmagic(py_Name name, int argc, py_Ref argv) {
|
|||||||
return py_call(tmp, argc, argv);
|
return py_call(tmp, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool py_callcfunc(py_StackRef p0, py_CFunction cfunc, int argc, py_Ref argv) {
|
||||||
|
bool ok = cfunc(argc, argv);
|
||||||
|
pk_current_vm->stack.sp = p0;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
bool StopIteration() {
|
bool StopIteration() {
|
||||||
pk_VM* vm = pk_current_vm;
|
pk_VM* vm = pk_current_vm;
|
||||||
assert(!vm->is_stopiteration); // flag is already set
|
assert(!vm->is_stopiteration); // flag is already set
|
||||||
|
Loading…
x
Reference in New Issue
Block a user