From 27ad4a047da23ede8f9b01c8cad4ffcd0df43905 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 26 Feb 2023 01:38:20 +0800 Subject: [PATCH] up Update cffi.h --- src/cffi.h | 157 +++++++++++++++++++++++++-------------------------- src/parser.h | 2 +- 2 files changed, 77 insertions(+), 82 deletions(-) diff --git a/src/cffi.h b/src/cffi.h index 90248e19..3aec4b50 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -5,22 +5,51 @@ struct CType{ PY_CLASS(c, type) - Str name; - int size; - CType(const Str& name, int size) : name(name), size(size) {} + const char* name; // must be a literal + int size; + constexpr CType(const char name[], int size) : name(name), size(size) {} static void _register(VM* vm, PyVar mod, PyVar type){ vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED()); + + vm->bind_method<0>(type, "__repr__", [](VM* vm, pkpy::Args& args) { + CType& self = vm->py_cast(args[0]); + StrStream ss; + ss << ""; + return vm->PyStr(ss.str()); + }); } }; +constexpr CType kCTypes[] = { + CType("int8", 1), CType("int16", 2), CType("int32", 4), CType("int64", 8), + CType("uint8", 1), CType("uint16", 2), CType("uint32", 4), CType("uint64", 8), + CType("float32", 4), CType("float64", 8), CType("bool8", 1), CType("void", 0), +}; + +const int kCTypeCount = sizeof(kCTypes) / sizeof(CType); + +constexpr int ctype(const char name[]){ + for(int k=0; kbind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED()); @@ -28,78 +57,47 @@ struct Pointer{ vm->bind_method<0>(type, "__repr__", [](VM* vm, pkpy::Args& args) { Pointer& self = vm->py_cast(args[0]); StrStream ss; - ss << "<" << self.ctype.name << "* at " << std::hex << self.ptr << ">"; + ss << "<" << self._ctype.name << "* at " << std::hex << self.ptr << ">"; return vm->PyStr(ss.str()); }); - vm->bind_method<1>(type, "cast", [](VM* vm, pkpy::Args& args) { - Pointer& self = vm->py_cast(args[0]); - CType& ctype = vm->py_cast(args[1]); - return vm->new_object(self.ptr, ctype); - }); - vm->bind_method<1>(type, "__getitem__", [](VM* vm, pkpy::Args& args) { Pointer& self = vm->py_cast(args[0]); i64 index = vm->PyInt_AS_C(args[1]); - if(self.ctype.name == "char"){ - return vm->PyInt(((char*)self.ptr)[index]); - }else if(self.ctype.name == "int8"){ - return vm->PyInt(((int8_t*)self.ptr)[index]); - }else if(self.ctype.name == "int16"){ - return vm->PyInt(((int16_t*)self.ptr)[index]); - }else if(self.ctype.name == "int32"){ - return vm->PyInt(((int*)self.ptr)[index]); - }else if(self.ctype.name == "int64"){ - return vm->PyInt(((int64_t*)self.ptr)[index]); - }else if(self.ctype.name == "uint8"){ - return vm->PyInt(((uint8_t*)self.ptr)[index]); - }else if(self.ctype.name == "uint16"){ - return vm->PyInt(((uint16_t*)self.ptr)[index]); - }else if(self.ctype.name == "uint32"){ - return vm->PyInt(((uint32_t*)self.ptr)[index]); - }else if(self.ctype.name == "uint64"){ - return vm->PyInt(((uint64_t*)self.ptr)[index]); - }else if(self.ctype.name == "float"){ - return vm->PyFloat(((float*)self.ptr)[index]); - }else if(self.ctype.name == "double"){ - return vm->PyFloat(((double*)self.ptr)[index]); - }else if(self.ctype.name == "bool"){ - return vm->PyBool(((bool*)self.ptr)[index]); - }else{ - vm->TypeError("unsupported type"); - return vm->None; + switch(ctype(self._ctype.name)){ // TODO: optimize + case ctype("int8"): return vm->PyInt(((int8_t*)self.ptr)[index]); + case ctype("int16"): return vm->PyInt(((int16_t*)self.ptr)[index]); + case ctype("int32"): return vm->PyInt(((int32_t*)self.ptr)[index]); + case ctype("int64"): return vm->PyInt(((int64_t*)self.ptr)[index]); + case ctype("uint8"): return vm->PyInt(((uint8_t*)self.ptr)[index]); + case ctype("uint16"): return vm->PyInt(((uint16_t*)self.ptr)[index]); + case ctype("uint32"): return vm->PyInt(((uint32_t*)self.ptr)[index]); + case ctype("uint64"): return vm->PyInt(((uint64_t*)self.ptr)[index]); + case ctype("float32"): return vm->PyFloat(((float*)self.ptr)[index]); + case ctype("float64"): return vm->PyFloat(((double*)self.ptr)[index]); + case ctype("bool8"): return vm->PyBool(((bool*)self.ptr)[index]); + case ctype("void"): vm->TypeError("cannot index void*"); + default: vm->TypeError("unsupported type"); } + return vm->None; }); vm->bind_method<2>(type, "__setitem__", [](VM* vm, pkpy::Args& args) { Pointer& self = vm->py_cast(args[0]); i64 index = vm->PyInt_AS_C(args[1]); - if(self.ctype.name == "char"){ - ((char*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "int8"){ - ((int8_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "int16"){ - ((int16_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "int32"){ - ((int*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "int64"){ - ((int64_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "uint8"){ - ((uint8_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "uint16"){ - ((uint16_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "uint32"){ - ((uint32_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "uint64"){ - ((uint64_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); - }else if(self.ctype.name == "float"){ - ((float*)self.ptr)[index] = vm->PyFloat_AS_C(args[2]); - }else if(self.ctype.name == "double"){ - ((double*)self.ptr)[index] = vm->PyFloat_AS_C(args[2]); - }else if(self.ctype.name == "bool"){ - ((bool*)self.ptr)[index] = vm->PyBool_AS_C(args[2]); - }else{ - vm->TypeError("unsupported type"); + switch(ctype(self._ctype.name)){ // TODO: optimize + case ctype("int8"): ((int8_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); break; + case ctype("int16"): ((int16_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); break; + case ctype("int32"): ((int32_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); break; + case ctype("int64"): ((int64_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); break; + case ctype("uint8"): ((uint8_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); break; + case ctype("uint16"): ((uint16_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); break; + case ctype("uint32"): ((uint32_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); break; + case ctype("uint64"): ((uint64_t*)self.ptr)[index] = vm->PyInt_AS_C(args[2]); break; + case ctype("float32"): ((float*)self.ptr)[index] = vm->PyFloat_AS_C(args[2]); break; + case ctype("float64"): ((double*)self.ptr)[index] = vm->PyFloat_AS_C(args[2]); break; + case ctype("bool8"): ((bool*)self.ptr)[index] = vm->PyBool_AS_C(args[2]); break; + case ctype("void"): vm->TypeError("cannot index void*"); } return vm->None; }); @@ -114,24 +112,21 @@ struct Pointer{ void add_module_c(VM* vm){ PyVar mod = vm->new_module("c"); PyVar ptr_t = vm->register_class(mod); - PyVar ctype_t = vm->register_class(mod); + vm->register_class(mod); - vm->setattr(mod, "char", vm->new_object("char", 1)); - vm->setattr(mod, "int8", vm->new_object("int8", 1)); - vm->setattr(mod, "int16", vm->new_object("int16", 2)); - vm->setattr(mod, "int32", vm->new_object("int32", 4)); - vm->setattr(mod, "int64", vm->new_object("int64", 8)); - vm->setattr(mod, "uint8", vm->new_object("uint8", 1)); - vm->setattr(mod, "uint16", vm->new_object("uint16", 2)); - vm->setattr(mod, "uint32", vm->new_object("uint32", 4)); - vm->setattr(mod, "uint64", vm->new_object("uint64", 8)); - vm->setattr(mod, "float", vm->new_object("float", 4)); - vm->setattr(mod, "double", vm->new_object("double", 8)); - vm->setattr(mod, "bool", vm->new_object("bool", 1)); + for(int i=0; isetattr(mod, kCTypes[i].name, vm->new_object(kCTypes[i])); + } vm->bind_func<1>(mod, "malloc", [](VM* vm, pkpy::Args& args) { i64 size = vm->PyInt_AS_C(args[0]); - return vm->new_object(malloc(size), CType("char", 1)); + return vm->new_object(malloc(size), ctype_t("void")); + }); + + vm->bind_func<2>(mod, "cast", [](VM* vm, pkpy::Args& args) { + Pointer& self = vm->py_cast(args[0]); + CType& ctype = vm->py_cast(args[1]); + return vm->new_object(self.ptr, ctype); }); vm->bind_func<1>(mod, "free", [](VM* vm, pkpy::Args& args) { @@ -164,10 +159,10 @@ void add_module_c(VM* vm){ vm->bind_func<1>(mod, "strdup", [ptr_t](VM* vm, pkpy::Args& args) { if(is_type(args[0], vm->tp_str)){ const Str& s = vm->PyStr_AS_C(args[0]); - return vm->new_object(strdup(s.c_str()), CType("char", 1)); + return vm->new_object(strdup(s.c_str()), ctype_t("char")); }else if(is_type(args[0], OBJ_GET(Type, ptr_t))){ Pointer& p = vm->py_cast(args[0]); - return vm->new_object(strdup(p.cast()), CType("char", 1)); + return vm->new_object(strdup(p.cast()), ctype_t("char")); }else{ vm->TypeError("strdup() argument must be 'str' or 'c.ptr'"); return vm->None; diff --git a/src/parser.h b/src/parser.h index cb50cfff..b7e2f20b 100644 --- a/src/parser.h +++ b/src/parser.h @@ -24,7 +24,7 @@ constexpr const char* kTokens[] = { const TokenIndex kTokenCount = sizeof(kTokens) / sizeof(kTokens[0]); -constexpr TokenIndex TK(const char* const token) { +constexpr TokenIndex TK(const char token[]) { for(int k=0; k