mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
use new vector impl
This commit is contained in:
parent
ac82f6f33f
commit
a59592b799
@ -1,5 +1,5 @@
|
||||
SRC=$(find src/ -name "*.cpp")
|
||||
|
||||
FLAGS="-std=c++17 -O2 -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g"
|
||||
FLAGS="-std=c++17 -Og -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g"
|
||||
|
||||
clang++ $FLAGS -o main src2/main.cpp $SRC
|
||||
|
@ -70,17 +70,17 @@ struct CodeObject {
|
||||
std::shared_ptr<SourceData> src;
|
||||
Str name;
|
||||
|
||||
std::vector<Bytecode> codes;
|
||||
std::vector<LineInfo> lines;
|
||||
vector<Bytecode> codes;
|
||||
vector<LineInfo> lines;
|
||||
|
||||
small_vector_2<PyVar, 8> consts; // constants
|
||||
small_vector_2<StrName, 8> varnames; // local variables
|
||||
int nlocals; // varnames.size()
|
||||
|
||||
NameDictInt varnames_inv;
|
||||
std::vector<CodeBlock> blocks;
|
||||
vector<CodeBlock> blocks;
|
||||
NameDictInt labels;
|
||||
std::vector<FuncDecl_> func_decls;
|
||||
vector<FuncDecl_> func_decls;
|
||||
|
||||
int start_line;
|
||||
int end_line;
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <ctime>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <string_view>
|
||||
|
@ -27,11 +27,11 @@ class Compiler {
|
||||
bool unknown_global_scope; // for eval/exec() call
|
||||
// for parsing token stream
|
||||
int i = 0;
|
||||
std::vector<Token> tokens;
|
||||
vector<Token> tokens;
|
||||
|
||||
const Token& prev() const{ return tokens.at(i-1); }
|
||||
const Token& curr() const{ return tokens.at(i); }
|
||||
const Token& next() const{ return tokens.at(i+1); }
|
||||
const Token& prev() const{ return tokens[i-1]; }
|
||||
const Token& curr() const{ return tokens[i]; }
|
||||
const Token& next() const{ return tokens[i+1]; }
|
||||
const Token& err() const{
|
||||
if(i >= tokens.size()) return prev();
|
||||
return curr();
|
||||
|
@ -37,10 +37,10 @@ struct SourceData {
|
||||
CompileMode mode;
|
||||
|
||||
Str source;
|
||||
pod_vector<const char*> line_starts;
|
||||
vector<const char*> line_starts;
|
||||
|
||||
bool is_precompiled;
|
||||
std::vector<Str> _precompiled_tokens;
|
||||
vector<Str> _precompiled_tokens;
|
||||
|
||||
SourceData(std::string_view source, const Str& filename, CompileMode mode);
|
||||
SourceData(const Str& filename, CompileMode mode);
|
||||
|
@ -352,7 +352,7 @@ struct CallExpr: Expr{
|
||||
Expr_ callable;
|
||||
Expr_vector args;
|
||||
// **a will be interpreted as a special keyword argument: {"**": a}
|
||||
std::vector<std::pair<Str, Expr_>> kwargs;
|
||||
vector<std::pair<Str, Expr_>> kwargs;
|
||||
void emit_(CodeEmitContext* ctx) override;
|
||||
};
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
namespace pkpy {
|
||||
struct ManagedHeap{
|
||||
std::vector<PyObject*> _no_gc;
|
||||
std::vector<PyObject*> gen;
|
||||
vector<PyObject*> _no_gc;
|
||||
vector<PyObject*> gen;
|
||||
VM* vm;
|
||||
void (*_gc_on_delete)(VM*, PyObject*) = nullptr;
|
||||
void (*_gc_marker_ex)(VM*) = nullptr;
|
||||
|
@ -30,7 +30,7 @@ constexpr const char* kTokens[] = {
|
||||
};
|
||||
|
||||
using TokenValue = std::variant<std::monostate, i64, f64, Str>;
|
||||
const TokenIndex kTokenCount = sizeof(kTokens) / sizeof(kTokens[0]);
|
||||
const int kTokenCount = sizeof(kTokens) / sizeof(kTokens[0]);
|
||||
|
||||
constexpr TokenIndex TK(const char token[]) {
|
||||
for(int k=0; k<kTokenCount; k++){
|
||||
@ -99,7 +99,7 @@ struct Lexer {
|
||||
const char* token_start;
|
||||
const char* curr_char;
|
||||
int current_line = 1;
|
||||
std::vector<Token> nexts;
|
||||
vector<Token> nexts;
|
||||
stack_no_copy<int, small_vector_2<int, 8>> indents;
|
||||
int brackets_level = 0;
|
||||
|
||||
@ -129,7 +129,7 @@ struct Lexer {
|
||||
void SyntaxError(){ throw_err("SyntaxError", "invalid syntax"); }
|
||||
void IndentationError(Str msg){ throw_err("IndentationError", msg); }
|
||||
Lexer(VM* vm, std::shared_ptr<SourceData> src);
|
||||
std::vector<Token> run();
|
||||
vector<Token> run();
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,17 +13,11 @@ constexpr T default_invalid_value(){
|
||||
else return Discarded();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct NameDictItem{
|
||||
StrName first;
|
||||
T second;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct NameDictImpl {
|
||||
PK_ALWAYS_PASS_BY_POINTER(NameDictImpl)
|
||||
|
||||
using Item = NameDictItem<T>;
|
||||
using Item = std::pair<StrName, T>;
|
||||
static constexpr uint16_t kInitialCapacity = 16;
|
||||
static_assert(is_pod_v<T>);
|
||||
|
||||
@ -166,19 +160,21 @@ while(!_items[i].first.empty()) { \
|
||||
return val;
|
||||
}
|
||||
|
||||
pod_vector<StrName> keys() const {
|
||||
pod_vector<StrName> v;
|
||||
array<StrName> keys() const {
|
||||
array<StrName> v(_size);
|
||||
int j = 0;
|
||||
for(uint16_t i=0; i<_capacity; i++){
|
||||
if(_items[i].first.empty()) continue;
|
||||
v.push_back(_items[i].first);
|
||||
new (&v[j++]) StrName(_items[i].first);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
pod_vector<NameDictItem<T>> items() const{
|
||||
pod_vector<NameDictItem<T>> v;
|
||||
array<Item> items() const{
|
||||
array<Item> v(_size);
|
||||
int j = 0;
|
||||
apply([&](StrName key, T val){
|
||||
v.push_back(NameDictItem<T>{key, val});
|
||||
new(&v[j++]) Item(key, val);
|
||||
});
|
||||
return v;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ struct _FrameRecord{
|
||||
|
||||
struct LineProfiler{
|
||||
// filename -> records
|
||||
std::map<std::string_view, std::vector<_LineRecord>> records;
|
||||
std::map<std::string_view, vector<_LineRecord>> records;
|
||||
stack_no_copy<_FrameRecord> frames;
|
||||
std::set<FuncDecl*> functions;
|
||||
|
||||
|
@ -77,8 +77,8 @@ struct Str{
|
||||
int index(const Str& sub, int start=0) const;
|
||||
Str replace(char old, char new_) const;
|
||||
Str replace(const Str& old, const Str& new_, int count=-1) const;
|
||||
pod_vector<std::string_view> split(const Str& sep) const;
|
||||
pod_vector<std::string_view> split(char sep) const;
|
||||
vector<std::string_view> split(const Str& sep) const;
|
||||
vector<std::string_view> split(char sep) const;
|
||||
int count(const Str& sub) const;
|
||||
|
||||
/*************unicode*************/
|
||||
@ -127,15 +127,15 @@ struct StrName {
|
||||
|
||||
struct SStream{
|
||||
PK_ALWAYS_PASS_BY_POINTER(SStream)
|
||||
// pod_vector<T> is allocated by pool128 so the buffer can be moved into Str without a copy
|
||||
pod_vector<char> buffer;
|
||||
|
||||
vector<char> buffer;
|
||||
int _precision = -1;
|
||||
|
||||
bool empty() const { return buffer.empty(); }
|
||||
void setprecision(int precision) { _precision = precision; }
|
||||
|
||||
SStream(){}
|
||||
SStream(int guess_size){ buffer.reserve(guess_size); }
|
||||
SStream() {}
|
||||
SStream(int guess_size) { buffer.reserve(guess_size);}
|
||||
|
||||
Str str();
|
||||
|
||||
|
@ -35,8 +35,8 @@ struct Tuple {
|
||||
void _gc_mark(VM*) const;
|
||||
};
|
||||
|
||||
struct List: pod_vector<PyVar>{
|
||||
using pod_vector<PyVar>::pod_vector;
|
||||
struct List: public vector<PyVar>{
|
||||
using vector<PyVar>::vector;
|
||||
void _gc_mark(VM*) const;
|
||||
|
||||
Tuple to_tuple() const{
|
||||
|
@ -5,147 +5,216 @@
|
||||
|
||||
namespace pkpy{
|
||||
|
||||
struct explicit_copy_t {
|
||||
explicit explicit_copy_t() = default;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct pod_vector{
|
||||
static constexpr int SizeT = sizeof(T);
|
||||
static constexpr int N = 128 / SizeT;
|
||||
static constexpr int Growth = 2;
|
||||
|
||||
// static_assert(128 % SizeT == 0);
|
||||
static_assert(is_pod_v<T>);
|
||||
static_assert(N >= 4);
|
||||
|
||||
int _size;
|
||||
int _capacity;
|
||||
struct array{
|
||||
T* _data;
|
||||
int _size;
|
||||
|
||||
using size_type = int;
|
||||
|
||||
pod_vector(): _size(0), _capacity(N) {
|
||||
_data = (T*)pool128_alloc(_capacity * SizeT);
|
||||
}
|
||||
|
||||
// support initializer list
|
||||
pod_vector(std::initializer_list<T> il): _size(il.size()), _capacity(std::max(N, _size)) {
|
||||
_data = (T*)pool128_alloc(_capacity * SizeT);
|
||||
for(int i=0; i<_size; i++) _data[i] = *(il.begin() + i);
|
||||
}
|
||||
|
||||
pod_vector(int size): _size(size), _capacity(std::max(N, size)) {
|
||||
_data = (T*)pool128_alloc(_capacity * SizeT);
|
||||
}
|
||||
|
||||
pod_vector(const pod_vector& other): _size(other._size), _capacity(other._capacity) {
|
||||
_data = (T*)pool128_alloc(_capacity * SizeT);
|
||||
memcpy(_data, other._data, SizeT * _size);
|
||||
}
|
||||
|
||||
pod_vector(pod_vector&& other) noexcept {
|
||||
_size = other._size;
|
||||
_capacity = other._capacity;
|
||||
_data = other._data;
|
||||
array(): _data(nullptr), _size(0) {}
|
||||
array(int size): _data((T*)malloc(sizeof(T) * size)), _size(size) {}
|
||||
array(array&& other) noexcept: _data(other._data), _size(other._size) {
|
||||
other._data = nullptr;
|
||||
other._size = 0;
|
||||
}
|
||||
array(const array& other) = delete;
|
||||
array(explicit_copy_t, const array& other) {
|
||||
_data = (T*)malloc(sizeof(T) * other._size);
|
||||
_size = other._size;
|
||||
for(int i=0; i<_size; i++) _data[i] = other._data[i];
|
||||
}
|
||||
|
||||
pod_vector& operator=(pod_vector&& other) noexcept {
|
||||
if(_data!=nullptr) pool128_dealloc(_data);
|
||||
_size = other._size;
|
||||
_capacity = other._capacity;
|
||||
array& operator=(array&& other) noexcept{
|
||||
if(_data){
|
||||
std::destroy(begin(), end());
|
||||
free(_data);
|
||||
}
|
||||
_data = other._data;
|
||||
_size = other._size;
|
||||
other._data = nullptr;
|
||||
other._size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// remove copy assignment
|
||||
pod_vector& operator=(const pod_vector& other) = delete;
|
||||
array& operator=(const array& other) = delete;
|
||||
|
||||
template<typename __ValueT>
|
||||
void push_back(__ValueT&& t) {
|
||||
if (_size == _capacity) reserve(_capacity*Growth);
|
||||
_data[_size++] = std::forward<__ValueT>(t);
|
||||
T& operator[](int i) {
|
||||
PK_DEBUG_ASSERT(i>=0 && i<_size);
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void emplace_back(Args&&... args) {
|
||||
if (_size == _capacity) reserve(_capacity*Growth);
|
||||
new (&_data[_size++]) T(std::forward<Args>(args)...);
|
||||
const T& operator[](int i) const {
|
||||
PK_DEBUG_ASSERT(i>=0 && i<_size);
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
void reserve(int cap){
|
||||
if(cap <= _capacity) return;
|
||||
_capacity = cap;
|
||||
T* old_data = _data;
|
||||
_data = (T*)pool128_alloc(_capacity * SizeT);
|
||||
if(old_data != nullptr){
|
||||
memcpy(_data, old_data, SizeT * _size);
|
||||
pool128_dealloc(old_data);
|
||||
}
|
||||
}
|
||||
|
||||
void pop_back() { _size--; }
|
||||
T popx_back() { T t = std::move(_data[_size-1]); _size--; return t; }
|
||||
|
||||
void extend(const pod_vector& other){
|
||||
for(int i=0; i<other.size(); i++) push_back(other[i]);
|
||||
}
|
||||
|
||||
void extend(const T* begin, const T* end){
|
||||
for(auto it=begin; it!=end; it++) push_back(*it);
|
||||
}
|
||||
|
||||
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; }
|
||||
void clear() { _size=0; }
|
||||
|
||||
template<typename __ValueT>
|
||||
void insert(int i, __ValueT&& val){
|
||||
if (_size == _capacity) reserve(_capacity*Growth);
|
||||
for(int j=_size; j>i; j--) _data[j] = _data[j-1];
|
||||
_data[i] = std::forward<__ValueT>(val);
|
||||
_size++;
|
||||
}
|
||||
|
||||
void erase(int i){
|
||||
for(int j=i; j<_size-1; j++) _data[j] = _data[j+1];
|
||||
_size--;
|
||||
}
|
||||
|
||||
void reverse(){
|
||||
std::reverse(_data, _data+_size);
|
||||
}
|
||||
|
||||
void resize(int size){
|
||||
if(size > _capacity) reserve(size);
|
||||
_size = size;
|
||||
}
|
||||
T* begin() const{ return _data; }
|
||||
T* end() const{ return _data + _size; }
|
||||
|
||||
std::pair<T*, int> detach() noexcept {
|
||||
T* p = _data;
|
||||
int size = _size;
|
||||
std::pair<T*, int> retval(_data, _size);
|
||||
_data = nullptr;
|
||||
_size = 0;
|
||||
return {p, size};
|
||||
return retval;
|
||||
}
|
||||
|
||||
~pod_vector() {
|
||||
if(_data != nullptr) pool128_dealloc(_data);
|
||||
~array() {
|
||||
if(_data){
|
||||
std::destroy(begin(), end());
|
||||
free(_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T, typename Container=std::vector<T>>
|
||||
template<typename T>
|
||||
struct vector{
|
||||
T* _data;
|
||||
int _capacity;
|
||||
int _size;
|
||||
|
||||
using size_type = int;
|
||||
|
||||
vector(): _data(nullptr), _capacity(0), _size(0) {}
|
||||
vector(int size):
|
||||
_data((T*)malloc(sizeof(T) * size)),
|
||||
_capacity(size), _size(size) {}
|
||||
vector(vector&& other) noexcept:
|
||||
_data(other._data), _capacity(other._capacity), _size(other._size) {
|
||||
other._data = nullptr;
|
||||
other._capacity = 0;
|
||||
other._size = 0;
|
||||
}
|
||||
vector(const vector& other) = delete;
|
||||
vector(explicit_copy_t, const vector& other):
|
||||
_data((T*)malloc(sizeof(T) * other._size)),
|
||||
_capacity(other._size), _size(other._size) {
|
||||
for(int i=0; i<_size; i++) _data[i] = other._data[i];
|
||||
}
|
||||
|
||||
// allow move
|
||||
vector& operator=(vector&& other) noexcept{
|
||||
if(_data){
|
||||
std::destroy(begin(), end());
|
||||
free(_data);
|
||||
}
|
||||
new (this) vector(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
// disallow copy
|
||||
vector& operator=(const vector& other) = delete;
|
||||
|
||||
bool empty() const { return _size == 0; }
|
||||
int size() const { return _size; }
|
||||
int capacity() const { return _capacity; }
|
||||
T& back() { return _data[_size-1]; }
|
||||
|
||||
T* begin() const { return _data; }
|
||||
T* end() const { return _data + _size; }
|
||||
T* data() const { return _data; }
|
||||
|
||||
void reserve(int cap){
|
||||
if(cap < 4) cap = 4; // minimum capacity
|
||||
if(cap <= capacity()) return;
|
||||
T* new_data = (T*)malloc(sizeof(T) * cap);
|
||||
if constexpr(std::is_trivially_copyable_v<T>){
|
||||
memcpy(new_data, _data, sizeof(T) * _size);
|
||||
}else{
|
||||
for(int i=0; i<_size; i++){
|
||||
new(&new_data[i]) T(std::move(_data[i]));
|
||||
_data[i].~T();
|
||||
}
|
||||
}
|
||||
if(_data) free(_data);
|
||||
_data = new_data;
|
||||
_capacity = cap;
|
||||
}
|
||||
|
||||
void resize(int size){
|
||||
reserve(size);
|
||||
_size = size;
|
||||
}
|
||||
|
||||
void push_back(const T& t){
|
||||
if(_size == _capacity) reserve(_capacity * 2);
|
||||
new (&_data[_size++]) T(t);
|
||||
}
|
||||
|
||||
void push_back(T&& t){
|
||||
if(_size == _capacity) reserve(_capacity * 2);
|
||||
new(&_data[_size++]) T(std::move(t));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void emplace_back(Args&&... args){
|
||||
if(_size == _capacity) reserve(_capacity * 2);
|
||||
new(&_data[_size++]) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
T& operator[](int i) { return _data[i]; }
|
||||
const T& operator[](int i) const { return _data[i]; }
|
||||
|
||||
void extend(T* begin, T* end){
|
||||
int n = end - begin;
|
||||
reserve(_size + n);
|
||||
for(int i=0; i<n; i++) new(&_data[_size++]) T(begin[i]);
|
||||
}
|
||||
|
||||
void insert(int index, const T& t){
|
||||
if(_size == _capacity) reserve(_capacity * 2);
|
||||
for(int i=_size; i>index; i--) _data[i] = std::move(_data[i-1]);
|
||||
_data[index] = t;
|
||||
_size++;
|
||||
}
|
||||
|
||||
void erase(int index){
|
||||
for(int i=index; i<_size-1; i++) _data[i] = std::move(_data[i+1]);
|
||||
_size--;
|
||||
}
|
||||
|
||||
void pop_back(){
|
||||
PK_DEBUG_ASSERT(_size > 0);
|
||||
_size--;
|
||||
if constexpr(!std::is_trivially_destructible_v<T>){
|
||||
_data[_size].~T();
|
||||
}
|
||||
}
|
||||
|
||||
void clear(){
|
||||
std::destroy(begin(), end());
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
std::pair<T*, int> detach() noexcept {
|
||||
std::pair<T*, int> retval(_data, _size);
|
||||
_data = nullptr;
|
||||
_capacity = 0;
|
||||
_size = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
void swap(vector& other){
|
||||
std::swap(_data, other._data);
|
||||
std::swap(_capacity, other._capacity);
|
||||
std::swap(_size, other._size);
|
||||
}
|
||||
|
||||
~vector(){
|
||||
if(_data){
|
||||
std::destroy(begin(), end());
|
||||
free(_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Container=vector<T>>
|
||||
class stack{
|
||||
Container vec;
|
||||
public:
|
||||
@ -167,7 +236,7 @@ public:
|
||||
const Container& container() const { return vec; }
|
||||
};
|
||||
|
||||
template <typename T, typename Container=std::vector<T>>
|
||||
template <typename T, typename Container=vector<T>>
|
||||
class stack_no_copy: public stack<T, Container>{
|
||||
public:
|
||||
stack_no_copy() = default;
|
||||
|
@ -74,7 +74,7 @@ struct PyTypeInfo{
|
||||
PyTypeInfo(PyObject* obj, Type base, PyObject* mod, StrName name, bool subclass_enabled, Vt vt={}):
|
||||
obj(obj), base(base), mod(mod), name(name), subclass_enabled(subclass_enabled), vt(vt) {}
|
||||
|
||||
std::vector<StrName> annotated_fields = {};
|
||||
vector<StrName> annotated_fields = {};
|
||||
|
||||
// unary operators
|
||||
Str (*m__repr__)(VM* vm, PyVar) = nullptr;
|
||||
@ -127,8 +127,8 @@ struct PyTypeInfo{
|
||||
struct ImportContext{
|
||||
PK_ALWAYS_PASS_BY_POINTER(ImportContext)
|
||||
|
||||
std::vector<Str> pending;
|
||||
std::vector<bool> pending_is_init; // a.k.a __init__.py
|
||||
vector<Str> pending;
|
||||
vector<bool> pending_is_init; // a.k.a __init__.py
|
||||
|
||||
ImportContext() {}
|
||||
|
||||
@ -159,7 +159,7 @@ public:
|
||||
ManagedHeap heap;
|
||||
ValueStack s_data;
|
||||
CallStack callstack;
|
||||
std::vector<PyTypeInfo> _all_types;
|
||||
vector<PyTypeInfo> _all_types;
|
||||
|
||||
NameDict _modules; // loaded modules
|
||||
std::map<StrName, Str> _lazy_modules; // lazy loaded modules
|
||||
|
@ -931,7 +931,7 @@ __NEXT_STEP:
|
||||
if(_1 == StopIteration) break;
|
||||
extras.push_back(_1);
|
||||
}
|
||||
PUSH(VAR(extras));
|
||||
PUSH(VAR(std::move(extras)));
|
||||
} DISPATCH()
|
||||
/*****************************************/
|
||||
case OP_BEGIN_CLASS:{
|
||||
@ -1056,7 +1056,9 @@ __NEXT_STEP:
|
||||
Exception& _e = PK_OBJ_GET(Exception, e_obj);
|
||||
bool is_base_frame_to_be_popped = frame == base_frame;
|
||||
__pop_frame();
|
||||
if(callstack.empty()) throw _e; // propagate to the top level
|
||||
if(callstack.empty()){
|
||||
throw std::move(_e); // propagate to the top level
|
||||
}
|
||||
frame = &callstack.top();
|
||||
PUSH(e_obj);
|
||||
if(is_base_frame_to_be_popped){
|
||||
|
@ -1292,7 +1292,7 @@ __EAT_DOTS_END:
|
||||
}
|
||||
|
||||
int count = deserializer.read_count();
|
||||
std::vector<Str>& precompiled_tokens = lexer.src->_precompiled_tokens;
|
||||
vector<Str>& precompiled_tokens = lexer.src->_precompiled_tokens;
|
||||
for(int i=0; i<count; i++){
|
||||
precompiled_tokens.push_back(deserializer.read_string('\n'));
|
||||
}
|
||||
@ -1379,7 +1379,7 @@ __EAT_DOTS_END:
|
||||
PyVar e_obj = vm->call(vm->builtins->attr(type), VAR(msg));
|
||||
Exception& e = PK_OBJ_GET(Exception, e_obj);
|
||||
e.st_push(src, lineno, cursor, "");
|
||||
throw e;
|
||||
throw std::move(e);
|
||||
}
|
||||
|
||||
std::string_view TokenDeserializer::read_string(char c){
|
||||
|
@ -73,7 +73,7 @@ __NEXT_LINE:
|
||||
if(ret.size() == 0){
|
||||
vm->ValueError("empty csvfile");
|
||||
}
|
||||
List header = CAST(List&, ret[0]);
|
||||
const List& header = CAST(List&, ret[0]);
|
||||
List new_ret;
|
||||
for(int i=1; i<ret.size(); i++){
|
||||
const List& row = CAST(List&, ret[i]);
|
||||
|
@ -66,14 +66,16 @@ namespace pkpy{
|
||||
}
|
||||
|
||||
Str Exception::summary() const {
|
||||
stack<ExceptionLine> st(stacktrace);
|
||||
SStream ss;
|
||||
if(is_re) ss << "Traceback (most recent call last):\n";
|
||||
while(!st.empty()) {
|
||||
ss << st.top().snapshot() << '\n';
|
||||
st.pop();
|
||||
// while(!st.empty()) {
|
||||
// ss << st.top().snapshot() << '\n';
|
||||
// st.pop();
|
||||
// }
|
||||
const auto& container = stacktrace.container();
|
||||
for(int i=container.size()-1; i>=0; i--){
|
||||
ss << container[i].snapshot() << '\n';
|
||||
}
|
||||
// TODO: allow users to override the behavior
|
||||
if (!msg.empty()) ss << type.sv() << ": " << msg;
|
||||
else ss << type.sv();
|
||||
return ss.str();
|
||||
|
@ -3,7 +3,8 @@
|
||||
namespace pkpy{
|
||||
|
||||
int ManagedHeap::sweep(){
|
||||
std::vector<PyObject*> alive;
|
||||
vector<PyObject*> alive;
|
||||
alive.reserve(gen.size() / 2);
|
||||
for(PyObject* obj: gen){
|
||||
if(obj->gc_marked){
|
||||
obj->gc_marked = false;
|
||||
|
@ -485,7 +485,7 @@ static bool is_unicode_Lo_char(uint32_t c) {
|
||||
this->indents.push(0);
|
||||
}
|
||||
|
||||
std::vector<Token> Lexer::run() {
|
||||
vector<Token> Lexer::run() {
|
||||
PK_ASSERT(curr_char == src->source.c_str());
|
||||
while (lex_one_token());
|
||||
return std::move(nexts);
|
||||
|
@ -622,7 +622,7 @@ void __init_builtins(VM* _vm) {
|
||||
const Str& self = _CAST(Str&, args[0]);
|
||||
const Str& sep = CAST(Str&, args[1]);
|
||||
if(sep.empty()) vm->ValueError("empty separator");
|
||||
pod_vector<std::string_view> parts;
|
||||
vector<std::string_view> parts;
|
||||
if(sep.size == 1){
|
||||
parts = self.split(sep[0]);
|
||||
}else{
|
||||
@ -635,8 +635,7 @@ void __init_builtins(VM* _vm) {
|
||||
|
||||
_vm->bind(_vm->_t(VM::tp_str), "splitlines(self)", [](VM* vm, ArgsView args) {
|
||||
const Str& self = _CAST(Str&, args[0]);
|
||||
pod_vector<std::string_view> parts;
|
||||
parts = self.split('\n');
|
||||
vector<std::string_view> parts = self.split('\n');
|
||||
List ret(parts.size());
|
||||
for(int i=0; i<parts.size(); i++) ret[i] = VAR(Str(parts[i]));
|
||||
return VAR(std::move(ret));
|
||||
@ -797,7 +796,9 @@ void __init_builtins(VM* _vm) {
|
||||
});
|
||||
}
|
||||
bool reverse = CAST(bool, args[2]);
|
||||
if(reverse) self.reverse();
|
||||
if(reverse){
|
||||
std::reverse(self.begin(), self.end());
|
||||
}
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
@ -892,7 +893,9 @@ void __init_builtins(VM* _vm) {
|
||||
List& self = _CAST(List&, args[0]);
|
||||
if(args.size() == 1+0){
|
||||
if(self.empty()) vm->IndexError("pop from empty list");
|
||||
return self.popx_back();
|
||||
PyVar retval = self.back();
|
||||
self.pop_back();
|
||||
return retval;
|
||||
}
|
||||
if(args.size() == 1+1){
|
||||
i64 index = CAST(i64, args[1]);
|
||||
@ -936,7 +939,7 @@ void __init_builtins(VM* _vm) {
|
||||
int n = _CAST(int, _1);
|
||||
List result;
|
||||
result.reserve(self.size() * n);
|
||||
for(int i = 0; i < n; i++) result.extend(self);
|
||||
for(int i = 0; i < n; i++) result.extend(self.begin(), self.end());
|
||||
return VAR(std::move(result));
|
||||
});
|
||||
_vm->bind_func(VM::tp_list, "__rmul__", 2, [](VM* vm, ArgsView args) {
|
||||
@ -945,7 +948,7 @@ void __init_builtins(VM* _vm) {
|
||||
int n = _CAST(int, args[1]);
|
||||
List result;
|
||||
result.reserve(self.size() * n);
|
||||
for(int i = 0; i < n; i++) result.extend(self);
|
||||
for(int i = 0; i < n; i++) result.extend(self.begin(), self.end());
|
||||
return VAR(std::move(result));
|
||||
});
|
||||
|
||||
@ -964,7 +967,10 @@ void __init_builtins(VM* _vm) {
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
_vm->bind_func(VM::tp_list, "copy", 1, PK_LAMBDA(VAR(_CAST(List, args[0]))));
|
||||
_vm->bind_func(VM::tp_list, "copy", 1, [](VM* vm, ArgsView args){
|
||||
const List& self = _CAST(List&, args[0]);
|
||||
return VAR(List(explicit_copy_t(), self));
|
||||
});
|
||||
|
||||
#define BIND_RICH_CMP(name, op, _t, _T) \
|
||||
_vm->bind__##name##__(_vm->_t, [](VM* vm, PyVar lhs, PyVar rhs){ \
|
||||
@ -993,8 +999,8 @@ void __init_builtins(VM* _vm) {
|
||||
_vm->bind__add__(VM::tp_list, [](VM* vm, PyVar _0, PyVar _1) {
|
||||
const List& self = _CAST(List&, _0);
|
||||
const List& other = CAST(List&, _1);
|
||||
List new_list(self); // copy construct
|
||||
new_list.extend(other);
|
||||
List new_list(explicit_copy_t(), self);
|
||||
new_list.extend(other.begin(), other.end());
|
||||
return VAR(std::move(new_list));
|
||||
});
|
||||
|
||||
@ -1637,7 +1643,7 @@ void VM::__post_init_builtin_types(){
|
||||
try{
|
||||
// initialize dummy func_decl for exec/eval
|
||||
CodeObject_ dynamic_co = compile("def _(): pass", "<dynamic>", EXEC_MODE);
|
||||
__dynamic_func_decl = dynamic_co->func_decls.at(0);
|
||||
__dynamic_func_decl = dynamic_co->func_decls[0];
|
||||
// initialize builtins
|
||||
CodeObject_ code = compile(kPythonLibs_builtins, "<builtins>", EXEC_MODE);
|
||||
this->_exec(code, this->builtins);
|
||||
|
@ -40,7 +40,7 @@ void LineProfiler::_step(int callstack_size, Frame* frame){
|
||||
}
|
||||
}
|
||||
|
||||
frames.top().prev_record = &file_records.at(line);
|
||||
frames.top().prev_record = &file_records[line];
|
||||
}
|
||||
|
||||
void LineProfiler::_step_end(int callstack_size, Frame* frame, int line){
|
||||
@ -87,11 +87,11 @@ Str LineProfiler::stats(){
|
||||
int end_line = decl->code->end_line;
|
||||
if(start_line == -1 || end_line == -1) continue;
|
||||
std::string_view filename = decl->code->src->filename.sv();
|
||||
std::vector<_LineRecord>& file_records = records[filename];
|
||||
vector<_LineRecord>& file_records = records[filename];
|
||||
if(file_records.empty()) continue;
|
||||
clock_t total_time = 0;
|
||||
for(int line = start_line; line <= end_line; line++){
|
||||
total_time += file_records.at(line).time;
|
||||
total_time += file_records[line].time;
|
||||
}
|
||||
ss << "Total time: " << (f64)total_time / CLOCKS_PER_SEC << "s\n";
|
||||
ss << "File: " << filename << "\n";
|
||||
@ -99,7 +99,7 @@ Str LineProfiler::stats(){
|
||||
ss << "Line # Hits Time Per Hit % Time Line Contents\n";
|
||||
ss << "==============================================================\n";
|
||||
for(int line = start_line; line <= end_line; line++){
|
||||
const _LineRecord& record = file_records.at(line);
|
||||
const _LineRecord& record = file_records[line];
|
||||
if(!record.is_valid()) continue;
|
||||
ss << left_pad(std::to_string(line), 6);
|
||||
if(record.hits == 0){
|
||||
|
@ -190,7 +190,7 @@ struct Random{
|
||||
PyVar* data = view.begin();
|
||||
int size = view.size();
|
||||
if(size == 0) vm->IndexError("cannot choose from an empty sequence");
|
||||
pod_vector<f64> cum_weights(size);
|
||||
array<f64> cum_weights(size);
|
||||
if(args[2] == vm->None){
|
||||
for(int i = 0; i < size; i++) cum_weights[i] = i + 1;
|
||||
}else{
|
||||
|
24
src/str.cpp
24
src/str.cpp
@ -333,8 +333,8 @@ int utf8len(unsigned char c, bool suppress){
|
||||
return _byte_index_to_unicode(size);
|
||||
}
|
||||
|
||||
pod_vector<std::string_view> Str::split(const Str& sep) const{
|
||||
pod_vector<std::string_view> result;
|
||||
vector<std::string_view> Str::split(const Str& sep) const{
|
||||
vector<std::string_view> result;
|
||||
std::string_view tmp;
|
||||
int start = 0;
|
||||
while(true){
|
||||
@ -349,8 +349,8 @@ int utf8len(unsigned char c, bool suppress){
|
||||
return result;
|
||||
}
|
||||
|
||||
pod_vector<std::string_view> Str::split(char sep) const{
|
||||
pod_vector<std::string_view> result;
|
||||
vector<std::string_view> Str::split(char sep) const{
|
||||
vector<std::string_view> result;
|
||||
int i = 0;
|
||||
for(int j = 0; j < size; j++){
|
||||
if(data[j] == sep){
|
||||
@ -404,29 +404,35 @@ int utf8len(unsigned char c, bool suppress){
|
||||
}
|
||||
|
||||
Str SStream::str(){
|
||||
#if 0
|
||||
// after this call, the buffer is no longer valid
|
||||
buffer.reserve(buffer.size() + 1); // allocate one more byte for '\0'
|
||||
buffer[buffer.size()] = '\0'; // set '\0'
|
||||
return Str(buffer.detach());
|
||||
#else
|
||||
#warning "SStream::str() needs to be optimized"
|
||||
buffer.push_back('\0');
|
||||
return Str(buffer.data(), buffer.size()-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(const Str& s){
|
||||
buffer.extend(s.begin(), s.end());
|
||||
for(char c: s) buffer.push_back(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(const char* s){
|
||||
buffer.extend(s, s + strlen(s));
|
||||
while(*s) buffer.push_back(*s++);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(const std::string& s){
|
||||
buffer.extend(s.data(), s.data() + s.size());
|
||||
for(char c: s) buffer.push_back(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SStream& SStream::operator<<(std::string_view s){
|
||||
buffer.extend(s.data(), s.data() + s.size());
|
||||
for(char c: s) buffer.push_back(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -459,7 +465,7 @@ int utf8len(unsigned char c, bool suppress){
|
||||
buffer.push_back('-');
|
||||
val = -val;
|
||||
}
|
||||
char* begin = buffer.end();
|
||||
auto begin = buffer.end();
|
||||
while(val){
|
||||
buffer.push_back('0' + val % 10);
|
||||
val /= 10;
|
||||
|
12
src/vm.cpp
12
src/vm.cpp
@ -330,7 +330,7 @@ namespace pkpy{
|
||||
|
||||
PyVar VM::py_import(Str path, bool throw_err){
|
||||
if(path.empty()) vm->ValueError("empty module name");
|
||||
static auto f_join = [](const pod_vector<std::string_view>& cpnts){
|
||||
static auto f_join = [](const vector<std::string_view>& cpnts){
|
||||
SStream ss;
|
||||
for(int i=0; i<cpnts.size(); i++){
|
||||
if(i != 0) ss << ".";
|
||||
@ -346,7 +346,7 @@ namespace pkpy{
|
||||
Str curr_path = __import_context.pending.back();
|
||||
bool curr_is_init = __import_context.pending_is_init.back();
|
||||
// convert relative path to absolute path
|
||||
pod_vector<std::string_view> cpnts = curr_path.split('.');
|
||||
vector<std::string_view> cpnts = curr_path.split('.');
|
||||
int prefix = 0; // how many dots in the prefix
|
||||
for(int i=0; i<path.length(); i++){
|
||||
if(path[i] == '.') prefix++;
|
||||
@ -366,7 +366,7 @@ namespace pkpy{
|
||||
PyVar ext_mod = _modules.try_get(name);
|
||||
if(ext_mod != nullptr) return ext_mod;
|
||||
|
||||
pod_vector<std::string_view> path_cpnts = path.split('.');
|
||||
vector<std::string_view> path_cpnts = path.split('.');
|
||||
// check circular import
|
||||
if(__import_context.pending.size() > 128){
|
||||
ImportError("maximum recursion depth exceeded while importing");
|
||||
@ -769,7 +769,7 @@ Str VM::disassemble(CodeObject_ co){
|
||||
return s + std::string(n - s.length(), ' ');
|
||||
};
|
||||
|
||||
std::vector<int> jumpTargets;
|
||||
vector<int> jumpTargets;
|
||||
for(int i=0; i<co->codes.size(); i++){
|
||||
Bytecode byte = co->codes[i];
|
||||
if(byte.is_forward_jump()){
|
||||
@ -1442,7 +1442,7 @@ void VM::_error(PyVar e_obj){
|
||||
Exception& e = PK_OBJ_GET(Exception, e_obj);
|
||||
if(callstack.empty()){
|
||||
e.is_re = false;
|
||||
throw e;
|
||||
throw std::move(e);
|
||||
}
|
||||
PUSH(e_obj);
|
||||
__raise_exc();
|
||||
@ -1665,7 +1665,7 @@ void VM::__breakpoint(){
|
||||
bool show_headers = true;
|
||||
|
||||
while(true){
|
||||
std::vector<LinkedFrame*> frames;
|
||||
vector<LinkedFrame*> frames;
|
||||
LinkedFrame* lf = callstack._tail;
|
||||
while(lf != nullptr){
|
||||
frames.push_back(lf);
|
||||
|
Loading…
x
Reference in New Issue
Block a user