some optimize

This commit is contained in:
blueloveTH 2023-02-24 18:11:33 +08:00
parent 44d6a6d5dd
commit 1ea7c151a3
4 changed files with 42 additions and 38 deletions

View File

@ -247,7 +247,7 @@ PyVar VM::run_frame(Frame* frame){
frame->push(std::move(iter));
} continue;
case OP_FOR_ITER: {
auto& it = PyIter_AS_C(frame->top());
BaseIter* it = PyIter_AS_C(frame->top());
PyVar obj = it->next();
if(obj != nullptr){
PyRef_AS_C(it->loop_var)->set(this, frame, std::move(obj));

View File

@ -48,25 +48,17 @@ public:
}
};
class Generator: public BaseIter {
std::unique_ptr<Frame> frame;
int state; // 0,1,2
public:
Generator(VM* vm, std::unique_ptr<Frame>&& frame)
: BaseIter(vm, nullptr), frame(std::move(frame)), state(0) {}
PyVar next() {
if(state == 2) return nullptr;
vm->callstack.push(std::move(frame));
PyVar ret = vm->_exec();
if(ret == vm->_py_op_yield){
frame = std::move(vm->callstack.top());
vm->callstack.pop();
state = 1;
return frame->pop_value(vm);
}else{
state = 2;
return nullptr;
}
PyVar Generator::next(){
if(state == 2) return nullptr;
vm->callstack.push(std::move(frame));
PyVar ret = vm->_exec();
if(ret == vm->_py_op_yield){
frame = std::move(vm->callstack.top());
vm->callstack.pop();
state = 1;
return frame->pop_value(vm);
}else{
state = 2;
return nullptr;
}
};
}

View File

@ -169,7 +169,7 @@ void init_builtins(VM* _vm) {
});
_vm->bind_method<0>("range", "__iter__", CPP_LAMBDA(
vm->PyIter(pkpy::make_shared<BaseIter, RangeIter>(vm, args[0]))
vm->PyIter(RangeIter(vm, args[0]))
));
_vm->bind_method<0>("NoneType", "__repr__", CPP_LAMBDA(vm->PyStr("None")));
@ -303,10 +303,7 @@ void init_builtins(VM* _vm) {
});
_vm->bind_method<0>("str", "__str__", CPP_LAMBDA(args[0]));
_vm->bind_method<0>("str", "__iter__", CPP_LAMBDA(
vm->PyIter(pkpy::make_shared<BaseIter, StringIter>(vm, args[0]))
));
_vm->bind_method<0>("str", "__iter__", CPP_LAMBDA(vm->PyIter(StringIter(vm, args[0]))));
_vm->bind_method<0>("str", "__repr__", [](VM* vm, pkpy::Args& args) {
const Str& _self = vm->PyStr_AS_C(args[0]);
@ -447,7 +444,7 @@ void init_builtins(VM* _vm) {
});
_vm->bind_method<0>("list", "__iter__", [](VM* vm, pkpy::Args& args) {
return vm->PyIter(pkpy::make_shared<BaseIter, ArrayIter<pkpy::List>>(vm, args[0]));
return vm->PyIter(ArrayIter<pkpy::List>(vm, args[0]));
});
_vm->bind_method<1>("list", "__getitem__", [](VM* vm, pkpy::Args& args) {
@ -489,7 +486,7 @@ void init_builtins(VM* _vm) {
});
_vm->bind_method<0>("tuple", "__iter__", [](VM* vm, pkpy::Args& args) {
return vm->PyIter(pkpy::make_shared<BaseIter, ArrayIter<pkpy::Args>>(vm, args[0]));
return vm->PyIter(ArrayIter<pkpy::Args>(vm, args[0]));
});
_vm->bind_method<1>("tuple", "__getitem__", [](VM* vm, pkpy::Args& args) {

View File

@ -11,7 +11,15 @@
inline PyVar Py##type(const ctype& value) { return new_object(ptype, value);} \
inline PyVar Py##type(ctype&& value) { return new_object(ptype, std::move(value));}
class Generator;
class Generator: public BaseIter {
std::unique_ptr<Frame> frame;
int state; // 0,1,2
public:
Generator(VM* vm, std::unique_ptr<Frame>&& frame)
: BaseIter(vm, nullptr), frame(std::move(frame)), state(0) {}
PyVar next();
};
class VM {
public:
@ -192,10 +200,7 @@ public:
}
const PyVar& _module = fn._module != nullptr ? fn._module : top_frame()->_module;
auto _frame = _new_frame(fn.code, _module, locals, fn._closure);
if(fn.code->is_generator){
return PyIter(pkpy::make_shared<BaseIter, Generator>(
this, std::move(_frame)));
}
if(fn.code->is_generator) return PyIter(Generator(this, std::move(_frame)));
callstack.push(std::move(_frame));
if(opCall) return _py_op_call;
return _exec();
@ -204,7 +209,6 @@ public:
return None;
}
// repl mode is only for setting `frame->id` to 0
PyVarOrNull exec(Str source, Str filename, CompileMode mode, PyVar _module=nullptr){
if(_module == nullptr) _module = _main;
@ -523,7 +527,7 @@ public:
template<typename P>
inline PyVarRef PyRef(P&& value) {
static_assert(std::is_base_of<BaseRef, std::remove_reference_t<P>>::value, "P should derive from BaseRef");
static_assert(std::is_base_of_v<BaseRef, RAW(P)>);
return new_object(tp_ref, std::forward<P>(value));
}
@ -533,6 +537,18 @@ public:
return static_cast<const BaseRef*>(obj->value());
}
template<typename P>
inline PyVar PyIter(P&& value) {
static_assert(std::is_base_of_v<BaseIter, RAW(P)>);
return new_object(tp_native_iterator, std::forward<P>(value));
}
inline BaseIter* PyIter_AS_C(const PyVar& obj)
{
check_type(obj, tp_native_iterator);
return static_cast<BaseIter*>(obj->value());
}
inline const Str& PyStr_AS_C(const PyVar& obj) {
check_type(obj, tp_str);
return OBJ_GET(Str, obj);
@ -587,7 +603,6 @@ public:
DEF_NATIVE(Tuple, pkpy::Tuple, tp_tuple)
DEF_NATIVE(Function, pkpy::Function, tp_function)
DEF_NATIVE(NativeFunc, pkpy::NativeFunc, tp_native_function)
DEF_NATIVE(Iter, pkpy::shared_ptr<BaseIter>, tp_native_iterator)
DEF_NATIVE(BoundMethod, pkpy::BoundMethod, tp_bound_method)
DEF_NATIVE(Range, pkpy::Range, tp_range)
DEF_NATIVE(Slice, pkpy::Slice, tp_slice)
@ -860,7 +875,7 @@ PyVar TupleRef::get(VM* vm, Frame* frame) const{
void TupleRef::set(VM* vm, Frame* frame, PyVar val) const{
val = vm->asIter(val);
pkpy::shared_ptr<BaseIter> iter = vm->PyIter_AS_C(val);
BaseIter* iter = vm->PyIter_AS_C(val);
for(int i=0; i<objs.size(); i++){
PyVarOrNull x;
if(is_type(objs[i], vm->tp_star_wrapper)){