impl small_vector

This commit is contained in:
blueloveTH 2023-04-06 14:51:18 +08:00
parent 7ce783360f
commit e69b66f0b7
5 changed files with 120 additions and 20 deletions

View File

@ -6,7 +6,7 @@ with open("src/opcodes.h", "rt", encoding='utf-8') as f:
OPCODES_TEXT = f.read() OPCODES_TEXT = f.read()
pipeline = [ pipeline = [
["common.h", "memory.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "lexer.h"], ["common.h", "vector.h", "memory.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "lexer.h"],
["obj.h", "codeobject.h", "frame.h"], ["obj.h", "codeobject.h", "frame.h"],
["gc.h", "vm.h", "ceval.h", "expr.h", "compiler.h", "repl.h"], ["gc.h", "vm.h", "ceval.h", "expr.h", "compiler.h", "repl.h"],
["iter.h", "cffi.h", "io.h", "_generated.h", "pocketpy.h"] ["iter.h", "cffi.h", "io.h", "_generated.h", "pocketpy.h"]

View File

@ -107,22 +107,6 @@ inline bool is_both_int(PyObject* a, PyObject* b) noexcept {
return is_int(a) && is_int(b); return is_int(a) && is_int(b);
} }
template <typename T>
class stack{
std::vector<T> vec;
public:
void push(const T& t){ vec.push_back(t); }
void push(T&& t){ vec.push_back(std::move(t)); }
void pop(){ vec.pop_back(); }
void clear(){ vec.clear(); }
bool empty() const { return vec.empty(); }
size_t size() const { return vec.size(); }
T& top(){ return vec.back(); }
const T& top() const { return vec.back(); }
T popx(){ T t = std::move(vec.back()); vec.pop_back(); return t; }
const std::vector<T>& data() const { return vec; }
};
struct Expr; struct Expr;
typedef std::unique_ptr<Expr> Expr_; typedef std::unique_ptr<Expr> Expr_;

View File

@ -1,13 +1,16 @@
#pragma once #pragma once
#include "codeobject.h" #include "codeobject.h"
#include "vector.h"
namespace pkpy{ namespace pkpy{
static THREAD_LOCAL uint64_t kFrameGlobalId = 0; static THREAD_LOCAL uint64_t kFrameGlobalId = 0;
using ValueStack = small_vector<PyObject*, 6>;
struct Frame { struct Frame {
std::vector<PyObject*> _data; ValueStack _data;
int _ip = -1; int _ip = -1;
int _next_ip = 0; int _next_ip = 0;
@ -16,7 +19,7 @@ struct Frame {
NameDict_ _locals; NameDict_ _locals;
NameDict_ _closure; NameDict_ _closure;
const uint64_t id; const uint64_t id;
std::vector<std::pair<int, std::vector<PyObject*>>> s_try_block; std::vector<std::pair<int, ValueStack>> s_try_block;
const NameDict* names[5]; // name resolution array, zero terminated const NameDict* names[5]; // name resolution array, zero terminated
NameDict& f_locals() noexcept { return *_locals; } NameDict& f_locals() noexcept { return *_locals; }
@ -148,7 +151,7 @@ struct Frame {
} }
void pop_n(int n){ void pop_n(int n){
_data.resize(_data.size()-n); _data.pop_back_n(n);
} }
void _mark() const { void _mark() const {

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "common.h" #include "common.h"
#include "vector.h"
namespace pkpy{ namespace pkpy{

112
src/vector.h Normal file
View File

@ -0,0 +1,112 @@
#pragma once
#include "common.h"
namespace pkpy{
template<typename T, int N>
struct small_vector{
int _size;
int _capacity;
T* _data;
T _buffer[N];
small_vector(): _size(0), _capacity(N) {
static_assert(std::is_pod_v<T>);
_data = _buffer;
}
small_vector(const small_vector& other): _size(other._size), _capacity(other._capacity) {
if(other.is_small()){
_data = _buffer;
memcpy(_buffer, other._buffer, sizeof(T) * _size);
} else {
_data = (T*)malloc(sizeof(T) * _capacity);
memcpy(_data, other._data, sizeof(T) * _size);
}
}
small_vector(small_vector&& other) noexcept {
_size = other._size;
_capacity = other._capacity;
if(other.is_small()){
_data = _buffer;
memcpy(_buffer, other._buffer, sizeof(T) * _size);
} else {
_data = other._data;
other._data = other._buffer;
}
}
small_vector& operator=(small_vector&& other) noexcept {
if (!is_small()) free(_data);
_size = other._size;
_capacity = other._capacity;
if(other.is_small()){
_data = _buffer;
memcpy(_buffer, other._buffer, sizeof(T) * _size);
} else {
_data = other._data;
other._data = other._buffer;
}
return *this;
}
template<typename __ValueT>
void push_back(__ValueT&& t) {
if (_size == _capacity) {
_capacity *= 2;
if (is_small()) {
_data = (T*)malloc(sizeof(T) * _capacity);
memcpy(_data, _buffer, sizeof(T) * _size);
} else {
_data = (T*)realloc(_data, sizeof(T) * _capacity);
}
}
_data[_size++] = std::forward<__ValueT>(t);
}
void pop_back() { _size--; }
T& operator[](int index) { return _data[index]; }
const T& operator[](int index) const { return _data[index]; }
T* begin() { return _data; }
T* end() { return _data + _size; }
const T* begin() const { return _data; }
const T* end() const { return _data + _size; }
T& back() { return _data[_size - 1]; }
const T& back() const { return _data[_size - 1]; }
bool empty() const { return _size == 0; }
int size() const { return _size; }
T* data() { return _data; }
const T* data() const { return _data; }
bool is_small() const { return _data == _buffer; }
void pop_back_n(int n) { _size -= n; }
~small_vector() {
if (!is_small()) free(_data);
}
};
template <typename T, typename Container=std::vector<T>>
class stack{
Container vec;
public:
void push(const T& t){ vec.push_back(t); }
void push(T&& t){ vec.push_back(std::move(t)); }
void pop(){ vec.pop_back(); }
void clear(){ vec.clear(); }
bool empty() const { return vec.empty(); }
size_t size() const { return vec.size(); }
T& top(){ return vec.back(); }
const T& top() const { return vec.back(); }
T popx(){ T t = std::move(vec.back()); vec.pop_back(); return t; }
const Container& data() const { return vec; }
};
template <typename T, int N=8>
using small_stack = stack<T, small_vector<T, N>>;
} // namespace pkpy