mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 21:10:19 +00:00
some fix
This commit is contained in:
parent
6fafe4aa6b
commit
5f4d47721a
@ -94,7 +94,7 @@ int main(int argc, char** argv){
|
|||||||
std::string src((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
std::string src((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
ThreadedVM* vm = pkpy_new_tvm(true);
|
ThreadedVM* vm = pkpy_new_tvm(true);
|
||||||
_Code code;
|
_Code code = nullptr;
|
||||||
Timer("Compile time").run([&]{
|
Timer("Compile time").run([&]{
|
||||||
code = compile(vm, src.c_str(), filename);
|
code = compile(vm, src.c_str(), filename);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,13 +5,12 @@
|
|||||||
typedef int64_t _Int;
|
typedef int64_t _Int;
|
||||||
typedef double _Float;
|
typedef double _Float;
|
||||||
|
|
||||||
#define PK_VERSION "0.4.0"
|
#define PK_VERSION "0.4.5"
|
||||||
|
|
||||||
class CodeObject;
|
class CodeObject;
|
||||||
class BasePointer;
|
class BasePointer;
|
||||||
class VM;
|
class VM;
|
||||||
class Frame;
|
class Frame;
|
||||||
class PkExportedResource {};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<const BasePointer> _Pointer;
|
typedef std::shared_ptr<const BasePointer> _Pointer;
|
||||||
typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);
|
typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);
|
||||||
|
|||||||
@ -630,9 +630,33 @@ void __addModuleSys(VM* vm){
|
|||||||
vm->setAttr(mod, "version", vm->PyStr(PK_VERSION));
|
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" {
|
extern "C" {
|
||||||
struct PyObjectDump: public PkExportedResource{
|
struct PyObjectDump {
|
||||||
const char* type; // "int", "str", "float" ...
|
const char* type; // "int", "str", "float" ...
|
||||||
const char* json; // json representation
|
const char* json; // json representation
|
||||||
|
|
||||||
@ -647,7 +671,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PyOutputDump: public PkExportedResource{
|
struct PyOutputDump {
|
||||||
const char* _stdout;
|
const char* _stdout;
|
||||||
const char* _stderr;
|
const char* _stderr;
|
||||||
|
|
||||||
@ -663,8 +687,13 @@ extern "C" {
|
|||||||
};
|
};
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
void pkpy_delete(PkExportedResource* p){
|
void pkpy_delete(void* p){
|
||||||
delete p;
|
for(int i = 0; i < _pkLookupTable.size(); i++){
|
||||||
|
if(_pkLookupTable[i]->get() == p){
|
||||||
|
delete _pkLookupTable[i];
|
||||||
|
_pkLookupTable.erase(_pkLookupTable.begin() + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
@ -686,7 +715,7 @@ extern "C" {
|
|||||||
PyObjectDump* pkpy_get_global(VM* vm, const char* name){
|
PyObjectDump* pkpy_get_global(VM* vm, const char* name){
|
||||||
auto it = vm->_main->attribs.find(name);
|
auto it = vm->_main->attribs.find(name);
|
||||||
if(it == vm->_main->attribs.end()) return nullptr;
|
if(it == vm->_main->attribs.end()) return nullptr;
|
||||||
return new PyObjectDump(
|
return pkpy_allocate(PyObjectDump,
|
||||||
it->second->getTypeName().c_str(),
|
it->second->getTypeName().c_str(),
|
||||||
vm->PyStr_AS_C(vm->asJson(it->second)).c_str()
|
vm->PyStr_AS_C(vm->asJson(it->second)).c_str()
|
||||||
);
|
);
|
||||||
@ -698,7 +727,7 @@ extern "C" {
|
|||||||
if(code == nullptr) return nullptr;
|
if(code == nullptr) return nullptr;
|
||||||
PyVarOrNull ret = vm->exec(code);
|
PyVarOrNull ret = vm->exec(code);
|
||||||
if(ret == nullptr) return nullptr;
|
if(ret == nullptr) return nullptr;
|
||||||
return new PyObjectDump(
|
return pkpy_allocate(PyObjectDump,
|
||||||
ret->getTypeName(),
|
ret->getTypeName(),
|
||||||
vm->PyStr_AS_C(vm->asJson(ret))
|
vm->PyStr_AS_C(vm->asJson(ret))
|
||||||
);
|
);
|
||||||
@ -706,7 +735,7 @@ extern "C" {
|
|||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
REPL* pkpy_new_repl(VM* vm){
|
REPL* pkpy_new_repl(VM* vm){
|
||||||
return new REPL(vm);
|
return pkpy_allocate(REPL, vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
@ -736,14 +765,14 @@ extern "C" {
|
|||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
VM* pkpy_new_vm(bool use_stdio){
|
VM* pkpy_new_vm(bool use_stdio){
|
||||||
VM* vm = new VM(use_stdio);
|
VM* vm = pkpy_allocate(VM, use_stdio);
|
||||||
__vm_init(vm);
|
__vm_init(vm);
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
ThreadedVM* pkpy_new_tvm(bool use_stdio){
|
ThreadedVM* pkpy_new_tvm(bool use_stdio){
|
||||||
ThreadedVM* vm = new ThreadedVM(use_stdio);
|
ThreadedVM* vm = pkpy_allocate(ThreadedVM, use_stdio);
|
||||||
__vm_init(vm);
|
__vm_init(vm);
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
@ -754,7 +783,7 @@ extern "C" {
|
|||||||
_StrStream* s_out = dynamic_cast<_StrStream*>(vm->_stdout);
|
_StrStream* s_out = dynamic_cast<_StrStream*>(vm->_stdout);
|
||||||
_StrStream* s_err = dynamic_cast<_StrStream*>(vm->_stderr);
|
_StrStream* s_err = dynamic_cast<_StrStream*>(vm->_stderr);
|
||||||
if(s_out == nullptr || s_err == nullptr) return nullptr;
|
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_out->str("");
|
||||||
s_err->str("");
|
s_err->str("");
|
||||||
return dump;
|
return dump;
|
||||||
@ -774,7 +803,7 @@ extern "C" {
|
|||||||
PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){
|
PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){
|
||||||
std::optional<_Str> s = vm->readSharedStr();
|
std::optional<_Str> s = vm->readSharedStr();
|
||||||
if(!s.has_value()) return nullptr;
|
if(!s.has_value()) return nullptr;
|
||||||
return new PyObjectDump("str"_c, s.value());
|
return pkpy_allocate(PyObjectDump, "str"_c, s.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
|
|||||||
@ -52,7 +52,7 @@ struct IndexPointer : BasePointer {
|
|||||||
|
|
||||||
struct CompoundPointer : BasePointer {
|
struct CompoundPointer : BasePointer {
|
||||||
const std::vector<_Pointer> pointers;
|
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) {}
|
CompoundPointer(std::vector<_Pointer>&& pointers) : pointers(pointers) {}
|
||||||
|
|
||||||
PyVar get(VM* vm, Frame* frame) const;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
|
|||||||
@ -9,7 +9,7 @@ enum InputResult {
|
|||||||
EXEC_SKIPPED = 2,
|
EXEC_SKIPPED = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
class REPL: public PkExportedResource {
|
class REPL {
|
||||||
protected:
|
protected:
|
||||||
int need_more_lines = 0;
|
int need_more_lines = 0;
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|||||||
56
src/vm.h
56
src/vm.h
@ -19,32 +19,11 @@
|
|||||||
__DEF_PY(type, ctype, ptype) \
|
__DEF_PY(type, ctype, ptype) \
|
||||||
__DEF_PY_AS_C(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*);
|
typedef void(*PrintFn)(const VM*, const char*);
|
||||||
|
|
||||||
class VM: public PkExportedResource{
|
class VM {
|
||||||
std::atomic<bool> _stopFlag = false;
|
std::atomic<bool> _stopFlag = false;
|
||||||
|
std::vector<PyVar> _smallIntegers; // [-5, 256]
|
||||||
protected:
|
protected:
|
||||||
std::deque< std::unique_ptr<Frame> > callstack;
|
std::deque< std::unique_ptr<Frame> > callstack;
|
||||||
PyVarDict _modules; // loaded modules
|
PyVarDict _modules; // loaded modules
|
||||||
@ -100,11 +79,11 @@ protected:
|
|||||||
} break;
|
} break;
|
||||||
case OP_STORE_PTR: {
|
case OP_STORE_PTR: {
|
||||||
PyVar obj = frame->popValue(this);
|
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));
|
p->set(this, frame, std::move(obj));
|
||||||
} break;
|
} break;
|
||||||
case OP_DELETE_PTR: {
|
case OP_DELETE_PTR: {
|
||||||
const _Pointer& p = PyPointer_AS_C(frame->__pop());
|
const _Pointer p = PyPointer_AS_C(frame->__pop());
|
||||||
p->del(this, frame);
|
p->del(this, frame);
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_SMART_TUPLE:
|
case OP_BUILD_SMART_TUPLE:
|
||||||
@ -170,7 +149,7 @@ protected:
|
|||||||
case OP_RETURN_VALUE: return frame->popValue(this);
|
case OP_RETURN_VALUE: return frame->popValue(this);
|
||||||
case OP_PRINT_EXPR:
|
case OP_PRINT_EXPR:
|
||||||
{
|
{
|
||||||
const PyVar& expr = frame->topValue(this);
|
const PyVar expr = frame->topValue(this);
|
||||||
if(expr == None) break;
|
if(expr == None) break;
|
||||||
*_stdout << PyStr_AS_C(asRepr(expr)) << '\n';
|
*_stdout << PyStr_AS_C(asRepr(expr)) << '\n';
|
||||||
} break;
|
} break;
|
||||||
@ -228,7 +207,7 @@ protected:
|
|||||||
case OP_UNARY_REF:
|
case OP_UNARY_REF:
|
||||||
{
|
{
|
||||||
// _pointer to pointer
|
// _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);
|
_Pointer up = std::make_shared<UserPointer>(p, frame->id);
|
||||||
frame->push(newObject(_tp_user_pointer, std::move(up)));
|
frame->push(newObject(_tp_user_pointer, std::move(up)));
|
||||||
} break;
|
} break;
|
||||||
@ -317,13 +296,13 @@ protected:
|
|||||||
} break;
|
} break;
|
||||||
case OP_JUMP_IF_FALSE_OR_POP:
|
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);
|
if(asBool(expr)==False) frame->jump(byte.arg);
|
||||||
else frame->popValue(this);
|
else frame->popValue(this);
|
||||||
} break;
|
} break;
|
||||||
case OP_JUMP_IF_TRUE_OR_POP:
|
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);
|
if(asBool(expr)==True) frame->jump(byte.arg);
|
||||||
else frame->popValue(this);
|
else frame->popValue(this);
|
||||||
} break;
|
} break;
|
||||||
@ -407,6 +386,9 @@ public:
|
|||||||
this->_stderr = new _StrStream();
|
this->_stderr = new _StrStream();
|
||||||
}
|
}
|
||||||
initializeBuiltinClasses();
|
initializeBuiltinClasses();
|
||||||
|
|
||||||
|
_smallIntegers.reserve(300);
|
||||||
|
for(_Int i=-5; i<=256; i++) _smallIntegers.push_back(newObject(_tp_int, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboardInterrupt(){
|
void keyboardInterrupt(){
|
||||||
@ -784,18 +766,20 @@ public:
|
|||||||
PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer;
|
PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer;
|
||||||
PyVar _tp_user_pointer, _tp_super;
|
PyVar _tp_user_pointer, _tp_super;
|
||||||
|
|
||||||
__DEF_PY_POOL(Int, _Int, _tp_int, 256);
|
__DEF_PY(Pointer, _Pointer, _tp_pointer)
|
||||||
__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)
|
|
||||||
|
|
||||||
inline _Pointer& PyPointer_AS_C(const PyVar& obj)
|
inline _Pointer& PyPointer_AS_C(const PyVar& obj)
|
||||||
{
|
{
|
||||||
if(!obj->isType(_tp_pointer)) typeError("expected an l-value");
|
if(!obj->isType(_tp_pointer)) typeError("expected an l-value");
|
||||||
return std::get<_Pointer>(obj->_native);
|
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(Str, _Str, _tp_str)
|
||||||
DEF_NATIVE(List, PyVarList, _tp_list)
|
DEF_NATIVE(List, PyVarList, _tp_list)
|
||||||
DEF_NATIVE(Tuple, PyVarList, _tp_tuple)
|
DEF_NATIVE(Tuple, PyVarList, _tp_tuple)
|
||||||
@ -1116,7 +1100,7 @@ class ThreadedVM : public VM {
|
|||||||
void __deleteThread(){
|
void __deleteThread(){
|
||||||
if(_thread != nullptr){
|
if(_thread != nullptr){
|
||||||
if(_state == THREAD_RUNNING || _state == THREAD_SUSPENDED){
|
if(_state == THREAD_RUNNING || _state == THREAD_SUSPENDED){
|
||||||
UNREACHABLE();
|
keyboardInterrupt();
|
||||||
}
|
}
|
||||||
_thread->join();
|
_thread->join();
|
||||||
delete _thread;
|
delete _thread;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user