mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 13:00:17 +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>());
|
||||
|
||||
ThreadedVM* vm = pkpy_new_tvm(true);
|
||||
_Code code;
|
||||
_Code code = nullptr;
|
||||
Timer("Compile time").run([&]{
|
||||
code = compile(vm, src.c_str(), filename);
|
||||
});
|
||||
|
@ -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&);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -9,7 +9,7 @@ enum InputResult {
|
||||
EXEC_SKIPPED = 2,
|
||||
};
|
||||
|
||||
class REPL: public PkExportedResource {
|
||||
class REPL {
|
||||
protected:
|
||||
int need_more_lines = 0;
|
||||
std::string buffer;
|
||||
|
56
src/vm.h
56
src/vm.h
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user