mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
impl small_vector
This commit is contained in:
parent
7ce783360f
commit
e69b66f0b7
@ -6,7 +6,7 @@ with open("src/opcodes.h", "rt", encoding='utf-8') as f:
|
||||
OPCODES_TEXT = f.read()
|
||||
|
||||
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"],
|
||||
["gc.h", "vm.h", "ceval.h", "expr.h", "compiler.h", "repl.h"],
|
||||
["iter.h", "cffi.h", "io.h", "_generated.h", "pocketpy.h"]
|
||||
|
16
src/common.h
16
src/common.h
@ -107,22 +107,6 @@ inline bool is_both_int(PyObject* a, PyObject* b) noexcept {
|
||||
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;
|
||||
typedef std::unique_ptr<Expr> Expr_;
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "codeobject.h"
|
||||
#include "vector.h"
|
||||
|
||||
namespace pkpy{
|
||||
|
||||
static THREAD_LOCAL uint64_t kFrameGlobalId = 0;
|
||||
|
||||
using ValueStack = small_vector<PyObject*, 6>;
|
||||
|
||||
struct Frame {
|
||||
std::vector<PyObject*> _data;
|
||||
ValueStack _data;
|
||||
int _ip = -1;
|
||||
int _next_ip = 0;
|
||||
|
||||
@ -16,7 +19,7 @@ struct Frame {
|
||||
NameDict_ _locals;
|
||||
NameDict_ _closure;
|
||||
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
|
||||
|
||||
NameDict& f_locals() noexcept { return *_locals; }
|
||||
@ -148,7 +151,7 @@ struct Frame {
|
||||
}
|
||||
|
||||
void pop_n(int n){
|
||||
_data.resize(_data.size()-n);
|
||||
_data.pop_back_n(n);
|
||||
}
|
||||
|
||||
void _mark() const {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "vector.h"
|
||||
|
||||
namespace pkpy{
|
||||
|
||||
|
112
src/vector.h
Normal file
112
src/vector.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user