mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
...
This commit is contained in:
parent
efb7fce3c1
commit
c32be30009
@ -47,6 +47,10 @@ struct CodeBlock {
|
|||||||
type(type), parent(parent), for_loop_depth(for_loop_depth), start(start), end(-1) {}
|
type(type), parent(parent), for_loop_depth(for_loop_depth), start(start), end(-1) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CodeObject;
|
||||||
|
typedef shared_ptr<CodeObject> CodeObject_;
|
||||||
|
struct FuncDecl;
|
||||||
|
using FuncDecl_ = shared_ptr<FuncDecl>;
|
||||||
|
|
||||||
struct CodeObjectSerializer{
|
struct CodeObjectSerializer{
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
@ -107,4 +111,98 @@ struct CodeObject {
|
|||||||
Str serialize(VM* vm) const;
|
Str serialize(VM* vm) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FuncDecl {
|
||||||
|
struct KwArg {
|
||||||
|
int key; // index in co->varnames
|
||||||
|
PyObject* value; // default value
|
||||||
|
};
|
||||||
|
CodeObject_ code; // code object of this function
|
||||||
|
pod_vector<int> args; // indices in co->varnames
|
||||||
|
pod_vector<KwArg> kwargs; // indices in co->varnames
|
||||||
|
int starred_arg = -1; // index in co->varnames, -1 if no *arg
|
||||||
|
int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg
|
||||||
|
bool nested = false; // whether this function is nested
|
||||||
|
|
||||||
|
Str signature; // signature of this function
|
||||||
|
Str docstring; // docstring of this function
|
||||||
|
void _gc_mark() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NativeFunc {
|
||||||
|
NativeFuncC f;
|
||||||
|
|
||||||
|
// old style argc-based call
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
// new style decl-based call
|
||||||
|
FuncDecl_ decl;
|
||||||
|
|
||||||
|
using UserData = char[32];
|
||||||
|
UserData _userdata;
|
||||||
|
bool _has_userdata;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void set_userdata(T data) {
|
||||||
|
static_assert(std::is_trivially_copyable_v<T>);
|
||||||
|
static_assert(sizeof(T) <= sizeof(UserData));
|
||||||
|
if(_has_userdata) throw std::runtime_error("userdata already set");
|
||||||
|
_has_userdata = true;
|
||||||
|
memcpy(_userdata, &data, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T get_userdata() const {
|
||||||
|
static_assert(std::is_trivially_copyable_v<T>);
|
||||||
|
static_assert(sizeof(T) <= sizeof(UserData));
|
||||||
|
#if PK_DEBUG_EXTRA_CHECK
|
||||||
|
if(!_has_userdata) throw std::runtime_error("userdata not set");
|
||||||
|
#endif
|
||||||
|
return reinterpret_cast<const T&>(_userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeFunc(NativeFuncC f, int argc, bool method);
|
||||||
|
NativeFunc(NativeFuncC f, FuncDecl_ decl);
|
||||||
|
|
||||||
|
void check_size(VM* vm, ArgsView args) const;
|
||||||
|
PyObject* call(VM* vm, ArgsView args) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Function{
|
||||||
|
FuncDecl_ decl;
|
||||||
|
PyObject* _module;
|
||||||
|
NameDict_ _closure;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Py_<Function> final: PyObject {
|
||||||
|
Function _value;
|
||||||
|
Py_(Type type, Function val): PyObject(type), _value(val) {
|
||||||
|
enable_instance_dict();
|
||||||
|
}
|
||||||
|
void _obj_gc_mark() override {
|
||||||
|
_value.decl->_gc_mark();
|
||||||
|
if(_value._module != nullptr) PK_OBJ_MARK(_value._module);
|
||||||
|
if(_value._closure != nullptr) gc_mark_namedict(*_value._closure);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Py_<NativeFunc> final: PyObject {
|
||||||
|
NativeFunc _value;
|
||||||
|
Py_(Type type, NativeFunc val): PyObject(type), _value(val) {
|
||||||
|
enable_instance_dict();
|
||||||
|
}
|
||||||
|
void _obj_gc_mark() override {
|
||||||
|
if(_value.decl != nullptr){
|
||||||
|
_value.decl->_gc_mark();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T lambda_get_userdata(PyObject** p){
|
||||||
|
if(p[-1] != PY_NULL) return PK_OBJ_GET(NativeFunc, p[-1]).get_userdata<T>();
|
||||||
|
else return PK_OBJ_GET(NativeFunc, p[-2]).get_userdata<T>();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
@ -6,9 +6,6 @@
|
|||||||
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
|
|
||||||
struct CodeObject;
|
|
||||||
typedef shared_ptr<CodeObject> CodeObject_;
|
|
||||||
|
|
||||||
struct Frame;
|
struct Frame;
|
||||||
class VM;
|
class VM;
|
||||||
|
|
||||||
@ -18,70 +15,6 @@ using NativeFuncC = std::function<PyObject*(VM*, ArgsView)>;
|
|||||||
typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
|
typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct FuncDecl {
|
|
||||||
struct KwArg {
|
|
||||||
int key; // index in co->varnames
|
|
||||||
PyObject* value; // default value
|
|
||||||
};
|
|
||||||
CodeObject_ code; // code object of this function
|
|
||||||
pod_vector<int> args; // indices in co->varnames
|
|
||||||
pod_vector<KwArg> kwargs; // indices in co->varnames
|
|
||||||
int starred_arg = -1; // index in co->varnames, -1 if no *arg
|
|
||||||
int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg
|
|
||||||
bool nested = false; // whether this function is nested
|
|
||||||
|
|
||||||
Str signature; // signature of this function
|
|
||||||
Str docstring; // docstring of this function
|
|
||||||
void _gc_mark() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
using FuncDecl_ = shared_ptr<FuncDecl>;
|
|
||||||
|
|
||||||
struct NativeFunc {
|
|
||||||
NativeFuncC f;
|
|
||||||
|
|
||||||
// old style argc-based call
|
|
||||||
int argc;
|
|
||||||
|
|
||||||
// new style decl-based call
|
|
||||||
FuncDecl_ decl;
|
|
||||||
|
|
||||||
using UserData = char[32];
|
|
||||||
UserData _userdata;
|
|
||||||
bool _has_userdata;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void set_userdata(T data) {
|
|
||||||
static_assert(std::is_trivially_copyable_v<T>);
|
|
||||||
static_assert(sizeof(T) <= sizeof(UserData));
|
|
||||||
if(_has_userdata) throw std::runtime_error("userdata already set");
|
|
||||||
_has_userdata = true;
|
|
||||||
memcpy(_userdata, &data, sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T get_userdata() const {
|
|
||||||
static_assert(std::is_trivially_copyable_v<T>);
|
|
||||||
static_assert(sizeof(T) <= sizeof(UserData));
|
|
||||||
#if PK_DEBUG_EXTRA_CHECK
|
|
||||||
if(!_has_userdata) throw std::runtime_error("userdata not set");
|
|
||||||
#endif
|
|
||||||
return reinterpret_cast<const T&>(_userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeFunc(NativeFuncC f, int argc, bool method);
|
|
||||||
NativeFunc(NativeFuncC f, FuncDecl_ decl);
|
|
||||||
|
|
||||||
void check_size(VM* vm, ArgsView args) const;
|
|
||||||
PyObject* call(VM* vm, ArgsView args) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Function{
|
|
||||||
FuncDecl_ decl;
|
|
||||||
PyObject* _module;
|
|
||||||
NameDict_ _closure;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BoundMethod {
|
struct BoundMethod {
|
||||||
PyObject* self;
|
PyObject* self;
|
||||||
PyObject* func;
|
PyObject* func;
|
||||||
@ -365,32 +298,6 @@ struct Py_<Slice> final: PyObject {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
|
||||||
struct Py_<Function> final: PyObject {
|
|
||||||
Function _value;
|
|
||||||
Py_(Type type, Function val): PyObject(type), _value(val) {
|
|
||||||
enable_instance_dict();
|
|
||||||
}
|
|
||||||
void _obj_gc_mark() override {
|
|
||||||
_value.decl->_gc_mark();
|
|
||||||
if(_value._module != nullptr) PK_OBJ_MARK(_value._module);
|
|
||||||
if(_value._closure != nullptr) gc_mark_namedict(*_value._closure);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct Py_<NativeFunc> final: PyObject {
|
|
||||||
NativeFunc _value;
|
|
||||||
Py_(Type type, NativeFunc val): PyObject(type), _value(val) {
|
|
||||||
enable_instance_dict();
|
|
||||||
}
|
|
||||||
void _obj_gc_mark() override {
|
|
||||||
if(_value.decl != nullptr){
|
|
||||||
_value.decl->_gc_mark();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Py_<Super> final: PyObject {
|
struct Py_<Super> final: PyObject {
|
||||||
Super _value;
|
Super _value;
|
||||||
@ -427,10 +334,4 @@ struct Py_<DummyModule> final: PyObject {
|
|||||||
void _obj_gc_mark() override {}
|
void _obj_gc_mark() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T lambda_get_userdata(PyObject** p){
|
|
||||||
if(p[-1] != PY_NULL) return PK_OBJ_GET(NativeFunc, p[-1]).get_userdata<T>();
|
|
||||||
else return PK_OBJ_GET(NativeFunc, p[-2]).get_userdata<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
@ -154,4 +154,18 @@ void CodeObjectSerializer::write_code(VM* vm, const CodeObject* co){
|
|||||||
buffer += END;
|
buffer += END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NativeFunc::NativeFunc(NativeFuncC f, int argc, bool method){
|
||||||
|
this->f = f;
|
||||||
|
this->argc = argc;
|
||||||
|
if(argc != -1) this->argc += (int)method;
|
||||||
|
_has_userdata = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeFunc::NativeFunc(NativeFuncC f, FuncDecl_ decl){
|
||||||
|
this->f = f;
|
||||||
|
this->argc = -1;
|
||||||
|
this->decl = decl;
|
||||||
|
_has_userdata = false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
15
src/obj.cpp
15
src/obj.cpp
@ -1,21 +1,6 @@
|
|||||||
#include "pocketpy/obj.h"
|
#include "pocketpy/obj.h"
|
||||||
|
|
||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
NativeFunc::NativeFunc(NativeFuncC f, int argc, bool method){
|
|
||||||
this->f = f;
|
|
||||||
this->argc = argc;
|
|
||||||
if(argc != -1) this->argc += (int)method;
|
|
||||||
_has_userdata = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeFunc::NativeFunc(NativeFuncC f, FuncDecl_ decl){
|
|
||||||
this->f = f;
|
|
||||||
this->argc = -1;
|
|
||||||
this->decl = decl;
|
|
||||||
_has_userdata = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject::~PyObject() {
|
PyObject::~PyObject() {
|
||||||
if(_attr == nullptr) return;
|
if(_attr == nullptr) return;
|
||||||
_attr->~NameDict();
|
_attr->~NameDict();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user