This commit is contained in:
blueloveTH 2022-12-02 01:56:05 +08:00
parent 6fafe4aa6b
commit 5f4d47721a
6 changed files with 64 additions and 52 deletions

View File

@ -94,7 +94,7 @@ int main(int argc, char** argv){
std::string src((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
ThreadedVM* vm = pkpy_new_tvm(true);
_Code code;
_Code code = nullptr;
Timer("Compile time").run([&]{
code = compile(vm, src.c_str(), filename);
});

View File

@ -5,13 +5,12 @@
typedef int64_t _Int;
typedef double _Float;
#define PK_VERSION "0.4.0"
#define PK_VERSION "0.4.5"
class CodeObject;
class BasePointer;
class VM;
class Frame;
class PkExportedResource {};
typedef std::shared_ptr<const BasePointer> _Pointer;
typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);

View File

@ -630,9 +630,33 @@ void __addModuleSys(VM* vm){
vm->setAttr(mod, "version", vm->PyStr(PK_VERSION));
}
class _PkExported;
static std::vector<_PkExported*> _pkLookupTable;
class _PkExported{
public:
virtual ~_PkExported() = default;
virtual void* get() = 0;
};
template<typename T>
class PkExported : public _PkExported{
T* _ptr;
public:
template<typename... Args>
PkExported(Args&&... args) : _ptr(new T(std::forward<Args>(args)...)){
_pkLookupTable.push_back(this);
}
~PkExported() override { delete _ptr; }
void* get() override { return _ptr; }
operator T*() { return _ptr; }
};
#define pkpy_allocate(T, ...) *(new PkExported<T>(__VA_ARGS__))
extern "C" {
struct PyObjectDump: public PkExportedResource{
struct PyObjectDump {
const char* type; // "int", "str", "float" ...
const char* json; // json representation
@ -647,7 +671,7 @@ extern "C" {
}
};
struct PyOutputDump: public PkExportedResource{
struct PyOutputDump {
const char* _stdout;
const char* _stderr;
@ -663,8 +687,13 @@ extern "C" {
};
__EXPORT
void pkpy_delete(PkExportedResource* p){
delete p;
void pkpy_delete(void* p){
for(int i = 0; i < _pkLookupTable.size(); i++){
if(_pkLookupTable[i]->get() == p){
delete _pkLookupTable[i];
_pkLookupTable.erase(_pkLookupTable.begin() + i);
}
}
}
__EXPORT
@ -686,7 +715,7 @@ extern "C" {
PyObjectDump* pkpy_get_global(VM* vm, const char* name){
auto it = vm->_main->attribs.find(name);
if(it == vm->_main->attribs.end()) return nullptr;
return new PyObjectDump(
return pkpy_allocate(PyObjectDump,
it->second->getTypeName().c_str(),
vm->PyStr_AS_C(vm->asJson(it->second)).c_str()
);
@ -698,7 +727,7 @@ extern "C" {
if(code == nullptr) return nullptr;
PyVarOrNull ret = vm->exec(code);
if(ret == nullptr) return nullptr;
return new PyObjectDump(
return pkpy_allocate(PyObjectDump,
ret->getTypeName(),
vm->PyStr_AS_C(vm->asJson(ret))
);
@ -706,7 +735,7 @@ extern "C" {
__EXPORT
REPL* pkpy_new_repl(VM* vm){
return new REPL(vm);
return pkpy_allocate(REPL, vm);
}
__EXPORT
@ -736,14 +765,14 @@ extern "C" {
__EXPORT
VM* pkpy_new_vm(bool use_stdio){
VM* vm = new VM(use_stdio);
VM* vm = pkpy_allocate(VM, use_stdio);
__vm_init(vm);
return vm;
}
__EXPORT
ThreadedVM* pkpy_new_tvm(bool use_stdio){
ThreadedVM* vm = new ThreadedVM(use_stdio);
ThreadedVM* vm = pkpy_allocate(ThreadedVM, use_stdio);
__vm_init(vm);
return vm;
}
@ -754,7 +783,7 @@ extern "C" {
_StrStream* s_out = dynamic_cast<_StrStream*>(vm->_stdout);
_StrStream* s_err = dynamic_cast<_StrStream*>(vm->_stderr);
if(s_out == nullptr || s_err == nullptr) return nullptr;
PyOutputDump* dump = new PyOutputDump(s_out->str(), s_err->str());
PyOutputDump* dump = pkpy_allocate(PyOutputDump, s_out->str(), s_err->str());
s_out->str("");
s_err->str("");
return dump;
@ -774,7 +803,7 @@ extern "C" {
PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){
std::optional<_Str> s = vm->readSharedStr();
if(!s.has_value()) return nullptr;
return new PyObjectDump("str"_c, s.value());
return pkpy_allocate(PyObjectDump, "str"_c, s.value());
}
__EXPORT

View File

@ -52,7 +52,7 @@ struct IndexPointer : BasePointer {
struct CompoundPointer : BasePointer {
const std::vector<_Pointer> pointers;
CompoundPointer(std::vector<_Pointer> pointers) : pointers(pointers) {}
CompoundPointer(const std::vector<_Pointer>& pointers) : pointers(pointers) {}
CompoundPointer(std::vector<_Pointer>&& pointers) : pointers(pointers) {}
PyVar get(VM* vm, Frame* frame) const;

View File

@ -9,7 +9,7 @@ enum InputResult {
EXEC_SKIPPED = 2,
};
class REPL: public PkExportedResource {
class REPL {
protected:
int need_more_lines = 0;
std::string buffer;

View File

@ -19,32 +19,11 @@
__DEF_PY(type, ctype, ptype) \
__DEF_PY_AS_C(type, ctype, ptype)
#define __DEF_PY_POOL(name, ctype, ptype, max_size) \
std::vector<PyObject*> _pool##name; \
PyVar Py##name(ctype _native) { \
PyObject* _raw = nullptr; \
if(_pool##name.size() > 0) { \
_raw = _pool##name.back(); \
_raw->_native = std::move(_native); \
_pool##name.pop_back(); \
}else{ \
__checkType(ptype, _tp_type); \
_raw = new PyObject(std::move(_native));\
_raw->setType(ptype); \
} \
return PyVar(_raw, [this](PyObject* p){ \
if(_pool##name.size() < max_size){ \
_pool##name.push_back(p); \
}else{ \
delete p; \
} \
}); \
}
typedef void(*PrintFn)(const VM*, const char*);
class VM: public PkExportedResource{
class VM {
std::atomic<bool> _stopFlag = false;
std::vector<PyVar> _smallIntegers; // [-5, 256]
protected:
std::deque< std::unique_ptr<Frame> > callstack;
PyVarDict _modules; // loaded modules
@ -100,11 +79,11 @@ protected:
} break;
case OP_STORE_PTR: {
PyVar obj = frame->popValue(this);
const _Pointer& p = PyPointer_AS_C(frame->__pop());
const _Pointer p = PyPointer_AS_C(frame->__pop());
p->set(this, frame, std::move(obj));
} break;
case OP_DELETE_PTR: {
const _Pointer& p = PyPointer_AS_C(frame->__pop());
const _Pointer p = PyPointer_AS_C(frame->__pop());
p->del(this, frame);
} break;
case OP_BUILD_SMART_TUPLE:
@ -170,7 +149,7 @@ protected:
case OP_RETURN_VALUE: return frame->popValue(this);
case OP_PRINT_EXPR:
{
const PyVar& expr = frame->topValue(this);
const PyVar expr = frame->topValue(this);
if(expr == None) break;
*_stdout << PyStr_AS_C(asRepr(expr)) << '\n';
} break;
@ -228,7 +207,7 @@ protected:
case OP_UNARY_REF:
{
// _pointer to pointer
const _Pointer& p = PyPointer_AS_C(frame->__pop());
const _Pointer p = PyPointer_AS_C(frame->__pop());
_Pointer up = std::make_shared<UserPointer>(p, frame->id);
frame->push(newObject(_tp_user_pointer, std::move(up)));
} break;
@ -317,13 +296,13 @@ protected:
} break;
case OP_JUMP_IF_FALSE_OR_POP:
{
const PyVar& expr = frame->topValue(this);
const PyVar expr = frame->topValue(this);
if(asBool(expr)==False) frame->jump(byte.arg);
else frame->popValue(this);
} break;
case OP_JUMP_IF_TRUE_OR_POP:
{
const PyVar& expr = frame->topValue(this);
const PyVar expr = frame->topValue(this);
if(asBool(expr)==True) frame->jump(byte.arg);
else frame->popValue(this);
} break;
@ -407,6 +386,9 @@ public:
this->_stderr = new _StrStream();
}
initializeBuiltinClasses();
_smallIntegers.reserve(300);
for(_Int i=-5; i<=256; i++) _smallIntegers.push_back(newObject(_tp_int, i));
}
void keyboardInterrupt(){
@ -784,18 +766,20 @@ public:
PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer;
PyVar _tp_user_pointer, _tp_super;
__DEF_PY_POOL(Int, _Int, _tp_int, 256);
__DEF_PY_AS_C(Int, _Int, _tp_int)
__DEF_PY_POOL(Float, _Float, _tp_float, 256);
__DEF_PY_AS_C(Float, _Float, _tp_float)
__DEF_PY_POOL(Pointer, _Pointer, _tp_pointer, 256)
__DEF_PY(Pointer, _Pointer, _tp_pointer)
inline _Pointer& PyPointer_AS_C(const PyVar& obj)
{
if(!obj->isType(_tp_pointer)) typeError("expected an l-value");
return std::get<_Pointer>(obj->_native);
}
__DEF_PY_AS_C(Int, _Int, _tp_int)
inline PyVar PyInt(_Int value) {
if(value >= -5 && value <= 256) return _smallIntegers[value + 5];
return newObject(_tp_int, value);
}
DEF_NATIVE(Float, _Float, _tp_float)
DEF_NATIVE(Str, _Str, _tp_str)
DEF_NATIVE(List, PyVarList, _tp_list)
DEF_NATIVE(Tuple, PyVarList, _tp_tuple)
@ -1116,7 +1100,7 @@ class ThreadedVM : public VM {
void __deleteThread(){
if(_thread != nullptr){
if(_state == THREAD_RUNNING || _state == THREAD_SUSPENDED){
UNREACHABLE();
keyboardInterrupt();
}
_thread->join();
delete _thread;