some tidy

This commit is contained in:
blueloveTH 2024-06-26 01:02:45 +08:00
parent 0871b627ed
commit 5bdbec273e
10 changed files with 311 additions and 180 deletions

View File

@ -64,7 +64,6 @@ typedef struct pk_VM {
PyVar last_retval;
// registers
PyVar reg[8];
PyVar sysreg[8];
PyObject* __curr_class;
PyObject* __cached_object_new;

View File

@ -1,12 +1,9 @@
#pragma once
#include "stdint.h"
#include "stdbool.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
/************* Public Types *************/
typedef struct PyObject PyObject;
typedef struct PyVar PyVar;
typedef struct pk_VM pk_VM;
@ -27,38 +24,28 @@ typedef enum BindType {
BindType_CLASSMETHOD,
} BindType;
extern pk_VM* pk_current_vm;
/************* Global VMs *************/
void py_initialize();
// void py_switch_vm(const char* name);
void py_finalize();
int py_exec_simple(const char*);
int py_eval_simple(const char*, py_Ref);
int py_exec(const char*);
int py_eval(const char*);
/* py_error */
py_Error* py_getlasterror();
void py_Error__print(py_Error*);
int py_eq(const py_Ref, const py_Ref);
int py_le(const py_Ref, const py_Ref);
int py_hash(const py_Ref, int64_t* out);
/* py_var */
/************* Values Creation *************/
void py_newint(py_Ref, int64_t);
void py_newfloat(py_Ref, double);
void py_newbool(py_Ref, bool);
void py_newstr(py_Ref, const char*);
void py_newstrn(py_Ref, const char*, int);
// void py_newfstr(py_Ref, const char*, ...);
void py_newbytes(py_Ref, const uint8_t*, int);
// void py_newbytes(py_Ref, const uint8_t*, int);
void py_newnone(py_Ref);
void py_newnull(py_Ref);
void py_newtuple(py_Ref, int);
// void py_newlist(py_Ref);
// new style decl-based function
void py_newfunction(py_Ref, py_CFunction, const char* sig, BindType bt);
@ -67,48 +54,55 @@ void py_newfunction2(py_Ref, py_CFunction, const char* sig, BindType bt, const c
void py_newnativefunc(py_Ref, py_CFunction, int argc, BindType bt);
void py_newnativefunc2(py_Ref, py_CFunction, int argc, BindType bt, const char* docstring, const py_Ref userdata);
py_Ref py_newmodule(const char* name, const char* package);
py_Ref py_getmodule(const char* name);
const py_Ref py_import(const char* name);
#define py_isnull(self) ((self)->type == 0)
/// Sets the name of the object to the given value.
void py_setdict(py_Ref self, py_Name name, const py_Ref val);
/// Returns a reference to the name of the object.
/************* References *************/
py_Ref py_getdict(const py_Ref self, py_Name name);
void py_setdict(py_Ref self, py_Name name, const py_Ref val);
/// Sets the i-th slot of the object to the given value.
void py_setslot(py_Ref self, int i, const py_Ref val);
/// Returns a reference to the i-th slot of the object.
py_Ref py_getslot(const py_Ref self, int i);
void py_setslot(py_Ref self, int i, const py_Ref val);
/// Equivalent to `self.name = val`.
/// Returns 0 | err
int py_setattr(py_Ref self, py_Name name, const py_Ref val);
// int py_getattr(const py_Ref self, py_Name name, py_Ref out);
// int py_setattr(py_Ref self, py_Name name, const py_Ref val);
/// Equivalent to `self.name`.
/// Returns 0 | err
int py_getattr(const py_Ref self, py_Name name, py_Ref out);
/// Copies src to dst.
void py_copyref(const py_Ref src, py_Ref dst);
/************* Stack Operations *************/
py_Ref py_gettop();
void py_settop(const py_Ref);
py_Ref py_getsecond();
void py_setsecond(const py_Ref);
/// Returns a reference to the i-th object from the top of the stack.
/// i should be negative, e.g. (-1) means TOS.
py_Ref py_stack(int i);
/// Returns a reference to the i-th register.
py_Ref py_reg(int i);
/// Returns a reference to the i-th system register.
py_Ref py_sysreg(int i);
py_Ref py_peek(int i);
/// Prepares a push and returns an uninitialized reference.
py_Ref py_push();
/// Pops an object from the stack.
void py_pop();
void py_shrink(int n);
/// Pushes the object to the stack.
void py_pushref(const py_Ref src);
/// Pops the object from the stack.
void py_copyref(const py_Ref src, py_Ref dst);
/// Get a temporary variable from the stack and returns the reference to it.
py_Ref py_pushtmp();
/// Free n temporary variable.
void py_poptmp(int n);
/************* Modules *************/
py_Ref py_newmodule(const char* name, const char* package);
py_Ref py_getmodule(const char* name);
void py_import(const char* name, py_Ref out);
/************* Errors *************/
py_Error* py_getlasterror();
void py_Error__print(py_Error*);
int py_eq(const py_Ref, const py_Ref);
int py_le(const py_Ref, const py_Ref);
int py_hash(const py_Ref, int64_t* out);
#define py_isnull(self) ((self)->type == 0)
/* tuple */

View File

@ -106,19 +106,19 @@ void pk_VM__ctor(pk_VM* self){
ValueStack__ctor(&self->stack);
self->True = (PyVar){.type=tp_bool, .is_ptr=true, .extra=1,
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 1),
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 0),
};
self->False = (PyVar){.type=tp_bool, .is_ptr=true, .extra=0,
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 1),
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 0),
};
self->None = (PyVar){.type=tp_none_type, .is_ptr=true,
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_none_type, 0, 1),
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_none_type, 0, 0),
};
self->NotImplemented = (PyVar){.type=tp_not_implemented_type, .is_ptr=true,
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_not_implemented_type, 0, 1),
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_not_implemented_type, 0, 0),
};
self->Ellipsis = (PyVar){.type=tp_ellipsis, .is_ptr=true,
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_ellipsis, 0, 1),
._obj=pk_ManagedHeap__gcnew(&self->heap, tp_ellipsis, 0, 0),
};
/* Init Builtin Types */

View File

@ -5,135 +5,13 @@
#include <assert.h>
#include <stdlib.h>
pk_VM* pk_current_vm;
static pk_VM pk_default_vm;
void py_initialize(){
Pools_initialize();
pk_StrName__initialize();
pk_current_vm = &pk_default_vm;
pk_VM__ctor(&pk_default_vm);
}
int py_exec_simple(const char* source){
CodeObject* co = NULL;
pk_VM* vm = pk_current_vm;
Frame* frame = Frame__new(
co,
&vm->main,
NULL,
vm->stack.sp,
vm->stack.sp,
co
);
pk_VM__push_frame(vm, frame);
pk_FrameResult res = pk_VM__run_top_frame(vm);
if(res == RES_ERROR) return vm->last_error->type;
if(res == RES_RETURN) return 0; // vm->last_retval;
assert(0); // unreachable
}
py_Ref py_getmodule(const char *name){
pk_VM* vm = pk_current_vm;
return pk_NameDict__try_get(&vm->modules, py_name(name));
}
py_Ref py_newmodule(const char *name, const char *package){
pk_ManagedHeap* heap = &pk_current_vm->heap;
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_module, -1, 0);
py_Ref r0 = py_sysreg(0);
py_Ref r1 = py_sysreg(1);
*r0 = PyVar__fromobj(obj);
py_newstr(r1, name);
py_setdict(r0, __name__, r1);
package = package ? package : "";
py_newstr(r1, package);
py_setdict(r0, __package__, r1);
// convert to fullname
if(package[0] != '\0'){
// package.name
char buf[256];
snprintf(buf, sizeof(buf), "%s.%s", package, name);
name = buf;
}
py_newstr(r1, name);
py_setdict(r0, __path__, r1);
// we do not allow override in order to avoid memory leak
// it is because Module objects are not garbage collected
bool exists = pk_NameDict__contains(&pk_current_vm->modules, py_name(name));
if(exists) abort();
pk_NameDict__set(&pk_current_vm->modules, py_name(name), *r0);
return py_getmodule(name);
}
py_Error* py_getlasterror(){
return pk_current_vm->last_error;
}
void py_Error__print(py_Error* self){
abort();
}
py_Ref py_reg(int i){
assert(i >= 0 && i < 8);
return &pk_current_vm->reg[i];
}
py_Ref py_sysreg(int i){
assert(i >= 0 && i < 8);
return &pk_current_vm->sysreg[i];
}
py_Ref py_stack(int i){
assert(i < 0);
return &pk_current_vm->stack.sp[i];
}
void py_finalize(){
pk_VM__dtor(&pk_default_vm);
pk_current_vm = NULL;
pk_StrName__finalize();
Pools_finalize();
}
void py_setdict(py_Ref self, py_Name name, const py_Ref val){
pk_NameDict__set(
PyObject__dict(self->_obj),
name,
*val
);
}
void py_newint(py_Ref self, int64_t val){
self->type = tp_int;
self->is_ptr = false;
self->_i64 = val;
}
void py_newfloat(py_Ref self, double val){
self->type = tp_float;
self->is_ptr = false;
self->_f64 = val;
}
void py_newbool(py_Ref self, bool val){
pk_VM* vm = pk_current_vm;
*self = val ? vm->True : vm->False;
}
void py_newstr(py_Ref self, const char* val){
pk_VM* vm = pk_current_vm;
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_str, 0, sizeof(py_Str));
py_Str__ctor((py_Str*)PyObject__value(obj), val);
self->type = tp_str;
self->is_ptr = true;
self->_obj = obj;
}

15
src/public/error.c Normal file
View File

@ -0,0 +1,15 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h"
py_Error* py_getlasterror(){
return pk_current_vm->last_error;
}
void py_Error__print(py_Error* self){
abort();
}

48
src/public/modules.c Normal file
View File

@ -0,0 +1,48 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h"
py_Ref py_getmodule(const char *name){
pk_VM* vm = pk_current_vm;
return pk_NameDict__try_get(&vm->modules, py_name(name));
}
py_Ref py_newmodule(const char *name, const char *package){
pk_ManagedHeap* heap = &pk_current_vm->heap;
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_module, -1, 0);
py_Ref r0 = py_pushtmp();
py_Ref r1 = py_pushtmp();
*r0 = PyVar__fromobj(obj);
py_newstr(r1, name);
py_setdict(r0, __name__, r1);
package = package ? package : "";
py_newstr(r1, package);
py_setdict(r0, __package__, r1);
// convert to fullname
if(package[0] != '\0'){
// package.name
char buf[256];
snprintf(buf, sizeof(buf), "%s.%s", package, name);
name = buf;
}
py_newstr(r1, name);
py_setdict(r0, __path__, r1);
// we do not allow override in order to avoid memory leak
// it is because Module objects are not garbage collected
bool exists = pk_NameDict__contains(&pk_current_vm->modules, py_name(name));
if(exists) abort();
pk_NameDict__set(&pk_current_vm->modules, py_name(name), *r0);
py_poptmp(2);
return py_getmodule(name);
}

84
src/public/stackops.c Normal file
View File

@ -0,0 +1,84 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h"
py_Ref py_getdict(const py_Ref self, py_Name name){
assert(self && self->is_ptr);
return pk_NameDict__try_get(PyObject__dict(self->_obj), name);
}
void py_setdict(py_Ref self, py_Name name, const py_Ref val){
assert(self && self->is_ptr);
pk_NameDict__set(PyObject__dict(self->_obj), name, *val);
}
py_Ref py_getslot(const py_Ref self, int i){
assert(self && self->is_ptr);
assert(i >= 0 && i < self->_obj->slots);
return PyObject__slots(self->_obj) + i;
}
void py_setslot(py_Ref self, int i, const py_Ref val){
assert(self && self->is_ptr);
assert(i >= 0 && i < self->_obj->slots);
PyObject__slots(self->_obj)[i] = *val;
}
void py_copyref(const py_Ref src, py_Ref dst){
*dst = *src;
}
/* Stack References */
py_Ref py_gettop(){
return pk_current_vm->stack.sp - 1;
}
void py_settop(const py_Ref val){
pk_current_vm->stack.sp[-1] = *val;
}
py_Ref py_getsecond(){
return pk_current_vm->stack.sp - 2;
}
void py_setsecond(const py_Ref val){
pk_current_vm->stack.sp[-2] = *val;
}
py_Ref py_peek(int i){
assert(i < 0);
return pk_current_vm->stack.sp + i;
}
py_Ref py_push(){
pk_VM* vm = pk_current_vm;
py_Ref top = vm->stack.sp;
vm->stack.sp++;
return top;
}
void py_pop(){
pk_VM* vm = pk_current_vm;
vm->stack.sp--;
}
void py_shrink(int n){
pk_VM* vm = pk_current_vm;
vm->stack.sp -= n;
}
void py_pushref(const py_Ref src){
*py_push() = *src;
}
py_Ref py_pushtmp(){
py_Ref r = py_push();
py_newnull(r);
return r;
}
void py_poptmp(int n){
py_shrink(n);
}

73
src/public/values.c Normal file
View File

@ -0,0 +1,73 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h"
void py_newint(py_Ref self, int64_t val){
self->type = tp_int;
self->is_ptr = false;
self->_i64 = val;
}
void py_newfloat(py_Ref self, double val){
self->type = tp_float;
self->is_ptr = false;
self->_f64 = val;
}
void py_newbool(py_Ref self, bool val){
pk_VM* vm = pk_current_vm;
*self = val ? vm->True : vm->False;
}
void py_newstr(py_Ref self, const char* data){
pk_ManagedHeap* heap = &pk_current_vm->heap;
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str));
py_Str__ctor((py_Str*)PyObject__value(obj), data);
self->type = tp_str;
self->is_ptr = true;
self->_obj = obj;
}
void py_newstrn(py_Ref self, const char* data, int size){
pk_ManagedHeap* heap = &pk_current_vm->heap;
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str));
py_Str__ctor2((py_Str*)PyObject__value(obj), data, size);
self->type = tp_str;
self->is_ptr = true;
self->_obj = obj;
}
void py_newnone(py_Ref self){
pk_VM* vm = pk_current_vm;
*self = vm->None;
}
void py_newnull(py_Ref self){
self->type = 0;
}
void py_newtuple(py_Ref self, int n){
pk_VM* vm = pk_current_vm;
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_tuple, n, 0);
self->type = tp_tuple;
self->is_ptr = true;
self->_obj = obj;
}
void py_newfunction(py_Ref self, py_CFunction f, const char* sig, BindType bt){
py_newfunction2(self, f, sig, bt, NULL, NULL);
}
void py_newfunction2(py_Ref self, py_CFunction f, const char *sig, BindType bt, const char *docstring, const py_Ref userdata){
}
void py_newnativefunc(py_Ref self, py_CFunction f, int argc, BindType bt){
py_newnativefunc2(self, f, argc, bt, NULL, NULL);
}
void py_newnativefunc2(py_Ref self, py_CFunction f, int argc, BindType bt, const char *docstring, const py_Ref userdata){
}

40
src/public/vm.c Normal file
View File

@ -0,0 +1,40 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h"
pk_VM* pk_current_vm;
static pk_VM pk_default_vm;
void py_initialize(){
Pools_initialize();
pk_StrName__initialize();
pk_current_vm = &pk_default_vm;
pk_VM__ctor(&pk_default_vm);
}
void py_finalize(){
pk_VM__dtor(&pk_default_vm);
pk_current_vm = NULL;
pk_StrName__finalize();
Pools_finalize();
}
int py_exec(const char* source){
CodeObject* co = NULL;
pk_VM* vm = pk_current_vm;
Frame* frame = Frame__new(
co,
&vm->main,
NULL,
vm->stack.sp,
vm->stack.sp,
co
);
pk_VM__push_frame(vm, frame);
pk_FrameResult res = pk_VM__run_top_frame(vm);
if(res == RES_ERROR) return vm->last_error->type;
if(res == RES_RETURN) return 0; // vm->last_retval;
assert(0); // unreachable
}

View File

@ -1,7 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "pocketpy.h"
#include "pocketpy/pocketpy.h"
char* read_file(const char* path) {
FILE* file = fopen(path, "r");
@ -28,7 +28,7 @@ int main(int argc, char** argv) {
char* source = read_file(argv[1]);
py_initialize();
if(py_exec_simple(source)){
if(py_exec(source)){
py_Error* err = py_getlasterror();
py_Error__print(err);
}