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)); frame->push(std::move(iter));
} continue; } continue;
case OP_FOR_ITER: { case OP_FOR_ITER: {
auto& it = PyIter_AS_C(frame->top()); BaseIter* it = PyIter_AS_C(frame->top());
PyVar obj = it->next(); PyVar obj = it->next();
if(obj != nullptr){ if(obj != nullptr){
PyRef_AS_C(it->loop_var)->set(this, frame, std::move(obj)); PyRef_AS_C(it->loop_var)->set(this, frame, std::move(obj));

View File

@ -48,25 +48,17 @@ public:
} }
}; };
class Generator: public BaseIter { PyVar Generator::next(){
std::unique_ptr<Frame> frame; if(state == 2) return nullptr;
int state; // 0,1,2 vm->callstack.push(std::move(frame));
public: PyVar ret = vm->_exec();
Generator(VM* vm, std::unique_ptr<Frame>&& frame) if(ret == vm->_py_op_yield){
: BaseIter(vm, nullptr), frame(std::move(frame)), state(0) {} frame = std::move(vm->callstack.top());
vm->callstack.pop();
PyVar next() { state = 1;
if(state == 2) return nullptr; return frame->pop_value(vm);
vm->callstack.push(std::move(frame)); }else{
PyVar ret = vm->_exec(); state = 2;
if(ret == vm->_py_op_yield){ return nullptr;
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->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"))); _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", "__str__", CPP_LAMBDA(args[0]));
_vm->bind_method<0>("str", "__iter__", CPP_LAMBDA(vm->PyIter(StringIter(vm, 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", "__repr__", [](VM* vm, pkpy::Args& args) { _vm->bind_method<0>("str", "__repr__", [](VM* vm, pkpy::Args& args) {
const Str& _self = vm->PyStr_AS_C(args[0]); 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) { _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) { _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) { _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) { _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(const ctype& value) { return new_object(ptype, value);} \
inline PyVar Py##type(ctype&& value) { return new_object(ptype, std::move(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 { class VM {
public: public:
@ -192,10 +200,7 @@ public:
} }
const PyVar& _module = fn._module != nullptr ? fn._module : top_frame()->_module; const PyVar& _module = fn._module != nullptr ? fn._module : top_frame()->_module;
auto _frame = _new_frame(fn.code, _module, locals, fn._closure); auto _frame = _new_frame(fn.code, _module, locals, fn._closure);
if(fn.code->is_generator){ if(fn.code->is_generator) return PyIter(Generator(this, std::move(_frame)));
return PyIter(pkpy::make_shared<BaseIter, Generator>(
this, std::move(_frame)));
}
callstack.push(std::move(_frame)); callstack.push(std::move(_frame));
if(opCall) return _py_op_call; if(opCall) return _py_op_call;
return _exec(); return _exec();
@ -204,7 +209,6 @@ public:
return None; return None;
} }
// repl mode is only for setting `frame->id` to 0 // repl mode is only for setting `frame->id` to 0
PyVarOrNull exec(Str source, Str filename, CompileMode mode, PyVar _module=nullptr){ PyVarOrNull exec(Str source, Str filename, CompileMode mode, PyVar _module=nullptr){
if(_module == nullptr) _module = _main; if(_module == nullptr) _module = _main;
@ -523,7 +527,7 @@ public:
template<typename P> template<typename P>
inline PyVarRef PyRef(P&& value) { 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)); return new_object(tp_ref, std::forward<P>(value));
} }
@ -533,6 +537,18 @@ public:
return static_cast<const BaseRef*>(obj->value()); 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) { inline const Str& PyStr_AS_C(const PyVar& obj) {
check_type(obj, tp_str); check_type(obj, tp_str);
return OBJ_GET(Str, obj); return OBJ_GET(Str, obj);
@ -587,7 +603,6 @@ public:
DEF_NATIVE(Tuple, pkpy::Tuple, tp_tuple) DEF_NATIVE(Tuple, pkpy::Tuple, tp_tuple)
DEF_NATIVE(Function, pkpy::Function, tp_function) DEF_NATIVE(Function, pkpy::Function, tp_function)
DEF_NATIVE(NativeFunc, pkpy::NativeFunc, tp_native_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(BoundMethod, pkpy::BoundMethod, tp_bound_method)
DEF_NATIVE(Range, pkpy::Range, tp_range) DEF_NATIVE(Range, pkpy::Range, tp_range)
DEF_NATIVE(Slice, pkpy::Slice, tp_slice) 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{ void TupleRef::set(VM* vm, Frame* frame, PyVar val) const{
val = vm->asIter(val); 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++){ for(int i=0; i<objs.size(); i++){
PyVarOrNull x; PyVarOrNull x;
if(is_type(objs[i], vm->tp_star_wrapper)){ if(is_type(objs[i], vm->tp_star_wrapper)){