mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
...
This commit is contained in:
parent
fae084ed44
commit
c9926cdcea
@ -1,5 +1,5 @@
|
||||
clang++ -pg -O2 -std=c++17 -fno-rtti -stdlib=libc++ -Wall -o pocketpy src/main.cpp
|
||||
time ./pocketpy benchmarks/fib.py
|
||||
time ./pocketpy benchmarks/sort.py
|
||||
mv benchmarks/gmon.out .
|
||||
gprof pocketpy gmon.out > gprof.txt
|
||||
rm gmon.out
|
||||
|
15
src/ceval.h
15
src/ceval.h
@ -13,6 +13,7 @@ inline PyObject* VM::_run_top_frame(){
|
||||
|
||||
// shared registers
|
||||
PyObject *_0, *_1, *_2;
|
||||
const PyTypeInfo* _ti;
|
||||
StrName _name;
|
||||
|
||||
while(true){
|
||||
@ -146,7 +147,12 @@ __NEXT_STEP:;
|
||||
TARGET(LOAD_SUBSCR)
|
||||
_1 = POPX(); // b
|
||||
_0 = TOP(); // a
|
||||
TOP() = call_method(_0, __getitem__, _1);
|
||||
_ti = _inst_type_info(_0);
|
||||
if(_ti->m__getitem__){
|
||||
TOP() = _ti->m__getitem__(this, _0, _1);
|
||||
}else{
|
||||
TOP() = call_method(_0, __getitem__, _1);
|
||||
}
|
||||
DISPATCH();
|
||||
TARGET(STORE_FAST)
|
||||
frame->_locals[byte.arg] = POPX();
|
||||
@ -174,7 +180,12 @@ __NEXT_STEP:;
|
||||
_2 = POPX(); // b
|
||||
_1 = POPX(); // a
|
||||
_0 = POPX(); // val
|
||||
call_method(_1, __setitem__, _2, _0);
|
||||
_ti = _inst_type_info(_1);
|
||||
if(_ti->m__setitem__){
|
||||
_ti->m__setitem__(this, _1, _2, _0);
|
||||
}else{
|
||||
call_method(_1, __setitem__, _2, _0);
|
||||
}
|
||||
DISPATCH();
|
||||
TARGET(DELETE_FAST)
|
||||
_0 = frame->_locals[byte.arg];
|
||||
|
@ -551,29 +551,13 @@ inline void init_builtins(VM* _vm) {
|
||||
});
|
||||
|
||||
_vm->bind_method<1>("list", "__getitem__", [](VM* vm, ArgsView args) {
|
||||
const List& self = _CAST(List&, args[0]);
|
||||
|
||||
if(is_type(args[1], vm->tp_slice)){
|
||||
const Slice& s = _CAST(Slice&, args[1]);
|
||||
int start, stop, step;
|
||||
vm->parse_int_slice(s, self.size(), start, stop, step);
|
||||
List new_list;
|
||||
for(int i=start; step>0?i<stop:i>stop; i+=step) new_list.push_back(self[i]);
|
||||
return VAR(std::move(new_list));
|
||||
}
|
||||
|
||||
int index = CAST(int, args[1]);
|
||||
index = vm->normalized_index(index, self.size());
|
||||
return self[index];
|
||||
return PyArrayGetItem<List>(vm, args[0], args[1]);
|
||||
});
|
||||
|
||||
_vm->bind_method<2>("list", "__setitem__", [](VM* vm, ArgsView args) {
|
||||
List& self = _CAST(List&, args[0]);
|
||||
int index = CAST(int, args[1]);
|
||||
index = vm->normalized_index(index, self.size());
|
||||
self[index] = args[2];
|
||||
return vm->None;
|
||||
return PyListSetItem(vm, args[0], args[1], args[2]);
|
||||
});
|
||||
_vm->_type_info("list")->m__getitem__ = PyArrayGetItem<List>;
|
||||
_vm->_type_info("list")->m__setitem__ = PyListSetItem;
|
||||
|
||||
_vm->bind_method<1>("list", "__delitem__", [](VM* vm, ArgsView args) {
|
||||
List& self = _CAST(List&, args[0]);
|
||||
@ -594,21 +578,9 @@ inline void init_builtins(VM* _vm) {
|
||||
});
|
||||
|
||||
_vm->bind_method<1>("tuple", "__getitem__", [](VM* vm, ArgsView args) {
|
||||
const Tuple& self = _CAST(Tuple&, args[0]);
|
||||
|
||||
if(is_type(args[1], vm->tp_slice)){
|
||||
const Slice& s = _CAST(Slice&, args[1]);
|
||||
int start, stop, step;
|
||||
vm->parse_int_slice(s, self.size(), start, stop, step);
|
||||
List new_list;
|
||||
for(int i=start; step>0?i<stop:i>stop; i+=step) new_list.push_back(self[i]);
|
||||
return VAR(Tuple(std::move(new_list)));
|
||||
}
|
||||
|
||||
int index = CAST(int, args[1]);
|
||||
index = vm->normalized_index(index, self.size());
|
||||
return self[index];
|
||||
return PyArrayGetItem<Tuple>(vm, args[0], args[1]);
|
||||
});
|
||||
_vm->_type_info("tuple")->m__getitem__ = PyArrayGetItem<Tuple>;
|
||||
|
||||
_vm->bind_method<0>("tuple", "__len__", [](VM* vm, ArgsView args) {
|
||||
const Tuple& self = _CAST(Tuple&, args[0]);
|
||||
|
49
src/vm.h
49
src/vm.h
@ -65,6 +65,9 @@ struct PyTypeInfo{
|
||||
Type base;
|
||||
Str name;
|
||||
bool subclass_enabled;
|
||||
// cached special methods
|
||||
PyObject* (*m__getitem__)(VM* vm, PyObject*, PyObject*) = nullptr;
|
||||
PyObject* (*m__setitem__)(VM* vm, PyObject*, PyObject*, PyObject*) = nullptr;
|
||||
};
|
||||
|
||||
struct FrameId{
|
||||
@ -265,6 +268,21 @@ public:
|
||||
return obj;
|
||||
}
|
||||
|
||||
PyTypeInfo* _type_info(const Str& type){
|
||||
PyObject* obj = builtins->attr().try_get(type);
|
||||
if(obj == nullptr){
|
||||
for(auto& t: _all_types) if(t.name == type) return &t;
|
||||
FATAL_ERROR();
|
||||
}
|
||||
return &_all_types[OBJ_GET(Type, obj)];
|
||||
}
|
||||
|
||||
const PyTypeInfo* _inst_type_info(PyObject* obj){
|
||||
if(is_int(obj)) return &_all_types[tp_int];
|
||||
if(is_float(obj)) return &_all_types[tp_float];
|
||||
return &_all_types[obj->type];
|
||||
}
|
||||
|
||||
template<int ARGC>
|
||||
void bind_func(Str type, Str name, NativeFuncC fn) {
|
||||
bind_func<ARGC>(_find_type(type), name, fn);
|
||||
@ -370,7 +388,7 @@ public:
|
||||
PyObject* _t(PyObject* obj){
|
||||
if(is_int(obj)) return _t(tp_int);
|
||||
if(is_float(obj)) return _t(tp_float);
|
||||
return _all_types[OBJ_GET(Type, _t(obj->type)).index].obj;
|
||||
return _all_types[obj->type].obj;
|
||||
}
|
||||
|
||||
~VM() {
|
||||
@ -1216,4 +1234,33 @@ inline Str obj_type_name(VM *vm, Type type){
|
||||
#undef PY_VAR_INT
|
||||
#undef PY_VAR_FLOAT
|
||||
|
||||
/***************************************************/
|
||||
|
||||
template<typename T>
|
||||
PyObject* PyArrayGetItem(VM* vm, PyObject* obj, PyObject* index){
|
||||
static_assert(std::is_same_v<T, List> || std::is_same_v<T, Tuple>);
|
||||
const T& self = _CAST(T&, obj);
|
||||
|
||||
if(is_type(index, vm->tp_slice)){
|
||||
const Slice& s = _CAST(Slice&, index);
|
||||
int start, stop, step;
|
||||
vm->parse_int_slice(s, self.size(), start, stop, step);
|
||||
List new_list;
|
||||
for(int i=start; step>0?i<stop:i>stop; i+=step) new_list.push_back(self[i]);
|
||||
return VAR(T(std::move(new_list)));
|
||||
}
|
||||
|
||||
int i = CAST(int, index);
|
||||
i = vm->normalized_index(i, self.size());
|
||||
return self[i];
|
||||
}
|
||||
|
||||
inline PyObject* PyListSetItem(VM* vm, PyObject* obj, PyObject* index, PyObject* value){
|
||||
List& self = _CAST(List&, obj);
|
||||
int i = CAST(int, index);
|
||||
i = vm->normalized_index(i, self.size());
|
||||
self[i] = value;
|
||||
return vm->None;
|
||||
}
|
||||
|
||||
} // namespace pkpy
|
Loading…
x
Reference in New Issue
Block a user