This commit is contained in:
blueloveTH 2024-06-02 02:55:35 +08:00
parent 2d739cae19
commit 0cc3b77017
9 changed files with 27 additions and 94 deletions

View File

@ -95,7 +95,8 @@ void add_module_cjson(VM* vm){
vm->bind_func(mod, "loads", 1, [](VM* vm, ArgsView args){
std::string_view sv;
if(is_type(args[0], vm->tp_bytes)){
sv = PK_OBJ_GET(Bytes, args[0]).sv();
const Bytes& b = PK_OBJ_GET(Bytes, args[0]);
sv = std::string_view((char*)b.data(), b.size());
}else{
sv = CAST(Str&, args[0]).sv();
}

View File

@ -65,34 +65,7 @@ struct StarWrapper{
void _gc_mark(VM*) const;
};
struct Bytes{
unsigned char* _data;
int _size;
int size() const noexcept { return _size; }
int operator[](int i) const noexcept { return (int)_data[i]; }
const unsigned char* data() const noexcept { return _data; }
bool operator==(const Bytes& rhs) const;
bool operator!=(const Bytes& rhs) const;
Str str() const noexcept { return Str((char*)_data, _size); }
std::string_view sv() const noexcept { return std::string_view((char*)_data, _size); }
Bytes() : _data(nullptr), _size(0) {}
Bytes(unsigned char* p, int size): _data(p), _size(size) {}
Bytes(const Str& str): Bytes(str.sv()) {}
operator bool() const noexcept { return _data != nullptr; }
Bytes(std::string_view sv);
Bytes(const Bytes& rhs);
Bytes(Bytes&& rhs) noexcept;
Bytes& operator=(Bytes&& rhs) noexcept;
Bytes& operator=(const Bytes& rhs) = delete;
std::pair<unsigned char*, int> detach() noexcept;
~Bytes(){ delete[] _data;}
};
using Bytes = array<unsigned char>;
struct Super{
PyVar first;

View File

@ -31,6 +31,7 @@ struct array{
_size = other._size;
for(int i=0; i<_size; i++) _data[i] = other._data[i];
}
array(T* data, int size): _data(data), _size(size) {}
array& operator=(array&& other) noexcept{
if(_data){
@ -60,6 +61,7 @@ struct array{
T* begin() const{ return _data; }
T* end() const{ return _data + _size; }
T* data() const { return _data; }
std::pair<T*, int> detach() noexcept {
std::pair<T*, int> retval(_data, _size);

View File

@ -171,7 +171,7 @@ void add_module_base64(VM* vm){
// b64encode
vm->bind_func(mod, "b64encode", 1, [](VM* vm, ArgsView args){
Bytes& b = CAST(Bytes&, args[0]);
unsigned char* p = new unsigned char[b.size() * 2];
unsigned char* p = (unsigned char*)malloc(b.size() * 2);
int size = base64_encode((const unsigned char*)b.data(), b.size(), (char*)p);
return VAR(Bytes(p, size));
});
@ -179,7 +179,7 @@ void add_module_base64(VM* vm){
// b64decode
vm->bind_func(mod, "b64decode", 1, [](VM* vm, ArgsView args){
Bytes& b = CAST(Bytes&, args[0]);
unsigned char* p = new unsigned char[b.size()];
unsigned char* p = (unsigned char*)malloc(b.size());
int size = base64_decode((const char*)b.data(), b.size(), p);
return VAR(Bytes(p, size));
});

View File

@ -382,7 +382,7 @@ __NEXT_STEP:
} DISPATCH()
case OP_BUILD_BYTES: {
const Str& s = CAST(Str&, TOP());
unsigned char* p = new unsigned char[s.size];
unsigned char* p = (unsigned char*)malloc(s.size);
memcpy(p, s.data, s.size);
TOP() = VAR(Bytes(p, s.size));
} DISPATCH()

View File

@ -73,7 +73,7 @@ void FileIO::_register(VM* vm, PyObject* mod, PyObject* type){
}else{
buffer_size = size;
}
unsigned char* buffer = new unsigned char[buffer_size];
unsigned char* buffer = (unsigned char*)malloc(buffer_size);
i64 actual_size = io_fread(buffer, 1, buffer_size, io.fp);
PK_ASSERT(actual_size <= buffer_size);
// in text mode, CR may be dropped, which may cause `actual_size < buffer_size`

View File

@ -94,7 +94,8 @@ void add_module_json(VM* vm){
vm->bind_func(mod, "loads", 1, [](VM* vm, ArgsView args) {
std::string_view sv;
if(is_type(args[0], vm->tp_bytes)){
sv = PK_OBJ_GET(Bytes, args[0]).sv();
const Bytes& b = PK_OBJ_GET(Bytes, args[0]);
sv = std::string_view((char*)b.data(), b.size());
}else{
sv = CAST(Str&, args[0]).sv();
}

View File

@ -2,50 +2,4 @@
namespace pkpy{
PyVar::PyVar(PyObject* p): PyVar(p->type, p) {}
bool Bytes::operator==(const Bytes& rhs) const{
if(_size != rhs._size) return false;
for(int i=0; i<_size; i++) if(_data[i] != rhs._data[i]) return false;
return true;
}
bool Bytes::operator!=(const Bytes& rhs) const{ return !(*this == rhs); }
Bytes::Bytes(std::string_view sv){
_data = new unsigned char[sv.size()];
_size = sv.size();
for(int i=0; i<_size; i++) _data[i] = sv[i];
}
// copy constructor
Bytes::Bytes(const Bytes& rhs){
_data = new unsigned char[rhs._size];
_size = rhs._size;
for(int i=0; i<_size; i++) _data[i] = rhs._data[i];
}
// move constructor
Bytes::Bytes(Bytes&& rhs) noexcept {
_data = rhs._data;
_size = rhs._size;
rhs._data = nullptr;
rhs._size = 0;
}
// move assignment
Bytes& Bytes::operator=(Bytes&& rhs) noexcept {
delete[] _data;
_data = rhs._data;
_size = rhs._size;
rhs._data = nullptr;
rhs._size = 0;
return *this;
}
std::pair<unsigned char*, int> Bytes::detach() noexcept {
unsigned char* p = _data;
int size = _size;
_data = nullptr;
_size = 0;
return {p, size};
}
} // namespace pkpy

View File

@ -687,9 +687,9 @@ void __init_builtins(VM* _vm) {
_vm->bind_func(VM::tp_str, "encode", 1, [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
unsigned char* buffer = new unsigned char[self.length()];
memcpy(buffer, self.data, self.length());
return VAR(Bytes(buffer, self.length()));
Bytes retval(self.length());
memcpy(retval.data(), self.data, self.length());
return VAR(std::move(retval));
});
_vm->bind_func(VM::tp_str, "join", 2, [](VM* vm, ArgsView args) {
@ -1129,13 +1129,13 @@ void __init_builtins(VM* _vm) {
// tp_bytes
_vm->bind_func(VM::tp_bytes, __new__, 2, [](VM* vm, ArgsView args){
List& list = CAST(List&, args[1]);
unsigned char* buffer = new unsigned char[list.size()];
Bytes retval(list.size());
for(int i=0; i<list.size(); i++){
i64 b = CAST(i64, list[i]);
if(b<0 || b>255) vm->ValueError("byte must be in range[0, 256)");
buffer[i] = (char)b;
retval[i] = (char)b;
}
return VAR(Bytes(buffer, list.size()));
return VAR(std::move(retval));
});
_vm->bind__getitem__(VM::tp_bytes, [](VM* vm, PyVar _0, PyVar _1) {
@ -1146,7 +1146,7 @@ void __init_builtins(VM* _vm) {
vm->parse_int_slice(s, self.size(), start, stop, step);
int guess_max_size = abs(stop - start) / abs(step) + 1;
if(guess_max_size > self.size()) guess_max_size = self.size();
unsigned char* buffer = new unsigned char[guess_max_size];
unsigned char* buffer = (unsigned char*)malloc(guess_max_size);
int j = 0; // actual size
PK_SLICE_LOOP(i, start, stop, step) buffer[j++] = self[i];
return VAR(Bytes(buffer, j));
@ -1159,10 +1159,10 @@ void __init_builtins(VM* _vm) {
_vm->bind__add__(VM::tp_bytes, [](VM* vm, PyVar _0, PyVar _1) {
const Bytes& a = _CAST(Bytes&, _0);
const Bytes& b = CAST(Bytes&, _1);
unsigned char *buffer = new unsigned char[a.size() + b.size()];
memcpy(buffer, a.data(), a.size());
memcpy(buffer + a.size(), b.data(), b.size());
return VAR(Bytes(buffer, a.size() + b.size()));
Bytes retval(a.size() + b.size());
memcpy(retval.data(), a.data(), a.size());
memcpy(retval.data() + a.size(), b.data(), b.size());
return VAR(std::move(retval));
});
_vm->bind__hash__(VM::tp_bytes, [](VM* vm, PyVar _0) {
@ -1188,13 +1188,15 @@ void __init_builtins(VM* _vm) {
_vm->bind_func(VM::tp_bytes, "decode", 1, [](VM* vm, ArgsView args) {
const Bytes& self = _CAST(Bytes&, args[0]);
// TODO: check encoding is utf-8
return VAR(Str(self.str()));
return VAR(Str(std::string_view((char*)self.data(), self.size())));
});
_vm->bind__eq__(VM::tp_bytes, [](VM* vm, PyVar _0, PyVar _1) {
if(!is_type(_1, vm->tp_bytes)) return vm->NotImplemented;
return VAR(_CAST(Bytes&, _0) == _CAST(Bytes&, _1));
const Bytes& lhs = _CAST(Bytes&, _0);
const Bytes& rhs = _CAST(Bytes&, _1);
if(lhs.size() != rhs.size()) return vm->False;
return VAR(memcmp(lhs.data(), rhs.data(), lhs.size()) == 0);
});
// tp_slice