diff --git a/build_g.sh b/build_g.sh index 314b42b6..d22c5975 100644 --- a/build_g.sh +++ b/build_g.sh @@ -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 diff --git a/include/pocketpy/codeobject.h b/include/pocketpy/codeobject.h index b4759067..d6bf1c4c 100644 --- a/include/pocketpy/codeobject.h +++ b/include/pocketpy/codeobject.h @@ -70,17 +70,17 @@ struct CodeObject { std::shared_ptr src; Str name; - std::vector codes; - std::vector lines; + vector codes; + vector lines; small_vector_2 consts; // constants small_vector_2 varnames; // local variables int nlocals; // varnames.size() NameDictInt varnames_inv; - std::vector blocks; + vector blocks; NameDictInt labels; - std::vector func_decls; + vector func_decls; int start_line; int end_line; diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h index 302f5456..5164acbf 100644 --- a/include/pocketpy/common.h +++ b/include/pocketpy/common.h @@ -5,7 +5,6 @@ #include #include -#include #include #include #include diff --git a/include/pocketpy/compiler.h b/include/pocketpy/compiler.h index ec8398d6..09ad3209 100644 --- a/include/pocketpy/compiler.h +++ b/include/pocketpy/compiler.h @@ -27,11 +27,11 @@ class Compiler { bool unknown_global_scope; // for eval/exec() call // for parsing token stream int i = 0; - std::vector tokens; + vector 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(); diff --git a/include/pocketpy/error.h b/include/pocketpy/error.h index 4127b986..bbc65495 100644 --- a/include/pocketpy/error.h +++ b/include/pocketpy/error.h @@ -37,10 +37,10 @@ struct SourceData { CompileMode mode; Str source; - pod_vector line_starts; + vector line_starts; bool is_precompiled; - std::vector _precompiled_tokens; + vector _precompiled_tokens; SourceData(std::string_view source, const Str& filename, CompileMode mode); SourceData(const Str& filename, CompileMode mode); diff --git a/include/pocketpy/expr.h b/include/pocketpy/expr.h index d85d6a47..f5d4c7ac 100644 --- a/include/pocketpy/expr.h +++ b/include/pocketpy/expr.h @@ -352,7 +352,7 @@ struct CallExpr: Expr{ Expr_ callable; Expr_vector args; // **a will be interpreted as a special keyword argument: {"**": a} - std::vector> kwargs; + vector> kwargs; void emit_(CodeEmitContext* ctx) override; }; diff --git a/include/pocketpy/gc.h b/include/pocketpy/gc.h index c69b0563..3550dde1 100644 --- a/include/pocketpy/gc.h +++ b/include/pocketpy/gc.h @@ -8,8 +8,8 @@ namespace pkpy { struct ManagedHeap{ - std::vector _no_gc; - std::vector gen; + vector _no_gc; + vector gen; VM* vm; void (*_gc_on_delete)(VM*, PyObject*) = nullptr; void (*_gc_marker_ex)(VM*) = nullptr; diff --git a/include/pocketpy/lexer.h b/include/pocketpy/lexer.h index fff1d7e3..3966409e 100644 --- a/include/pocketpy/lexer.h +++ b/include/pocketpy/lexer.h @@ -30,7 +30,7 @@ constexpr const char* kTokens[] = { }; using TokenValue = std::variant; -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 nexts; + vector nexts; stack_no_copy> 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 src); - std::vector run(); + vector run(); }; diff --git a/include/pocketpy/namedict.h b/include/pocketpy/namedict.h index 6eafc072..3f4548ad 100644 --- a/include/pocketpy/namedict.h +++ b/include/pocketpy/namedict.h @@ -13,17 +13,11 @@ constexpr T default_invalid_value(){ else return Discarded(); } -template -struct NameDictItem{ - StrName first; - T second; -}; - template struct NameDictImpl { PK_ALWAYS_PASS_BY_POINTER(NameDictImpl) - using Item = NameDictItem; + using Item = std::pair; static constexpr uint16_t kInitialCapacity = 16; static_assert(is_pod_v); @@ -166,19 +160,21 @@ while(!_items[i].first.empty()) { \ return val; } - pod_vector keys() const { - pod_vector v; + array keys() const { + array 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> items() const{ - pod_vector> v; + array items() const{ + array v(_size); + int j = 0; apply([&](StrName key, T val){ - v.push_back(NameDictItem{key, val}); + new(&v[j++]) Item(key, val); }); return v; } diff --git a/include/pocketpy/profiler.h b/include/pocketpy/profiler.h index b102a5f6..715d9948 100644 --- a/include/pocketpy/profiler.h +++ b/include/pocketpy/profiler.h @@ -22,7 +22,7 @@ struct _FrameRecord{ struct LineProfiler{ // filename -> records - std::map> records; + std::map> records; stack_no_copy<_FrameRecord> frames; std::set functions; diff --git a/include/pocketpy/str.h b/include/pocketpy/str.h index 7fa1188e..f161d0a1 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/str.h @@ -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 split(const Str& sep) const; - pod_vector split(char sep) const; + vector split(const Str& sep) const; + vector 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 is allocated by pool128 so the buffer can be moved into Str without a copy - pod_vector buffer; + + vector 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(); diff --git a/include/pocketpy/tuplelist.h b/include/pocketpy/tuplelist.h index 34b50b2b..fa6ff66c 100644 --- a/include/pocketpy/tuplelist.h +++ b/include/pocketpy/tuplelist.h @@ -35,8 +35,8 @@ struct Tuple { void _gc_mark(VM*) const; }; -struct List: pod_vector{ - using pod_vector::pod_vector; +struct List: public vector{ + using vector::vector; void _gc_mark(VM*) const; Tuple to_tuple() const{ diff --git a/include/pocketpy/vector.h b/include/pocketpy/vector.h index 160a3233..656c35bd 100644 --- a/include/pocketpy/vector.h +++ b/include/pocketpy/vector.h @@ -5,147 +5,216 @@ namespace pkpy{ +struct explicit_copy_t { + explicit explicit_copy_t() = default; +}; + template -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); - 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 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 - 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 - void emplace_back(Args&&... args) { - if (_size == _capacity) reserve(_capacity*Growth); - new (&_data[_size++]) T(std::forward(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 - 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 detach() noexcept { - T* p = _data; - int size = _size; + std::pair 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 > +template +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){ + 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 + void emplace_back(Args&&... args){ + if(_size == _capacity) reserve(_capacity * 2); + new(&_data[_size++]) T(std::forward(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; iindex; 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){ + _data[_size].~T(); + } + } + + void clear(){ + std::destroy(begin(), end()); + _size = 0; + } + + std::pair detach() noexcept { + std::pair 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 > class stack{ Container vec; public: @@ -167,7 +236,7 @@ public: const Container& container() const { return vec; } }; -template > +template > class stack_no_copy: public stack{ public: stack_no_copy() = default; diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index d87ac92b..2288c84b 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -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 annotated_fields = {}; + vector 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 pending; - std::vector pending_is_init; // a.k.a __init__.py + vector pending; + vector pending_is_init; // a.k.a __init__.py ImportContext() {} @@ -159,7 +159,7 @@ public: ManagedHeap heap; ValueStack s_data; CallStack callstack; - std::vector _all_types; + vector _all_types; NameDict _modules; // loaded modules std::map _lazy_modules; // lazy loaded modules diff --git a/src/ceval.cpp b/src/ceval.cpp index 7b9b2f55..1e8b1234 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -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){ diff --git a/src/compiler.cpp b/src/compiler.cpp index 4f963ca3..9b8263e1 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -1292,7 +1292,7 @@ __EAT_DOTS_END: } int count = deserializer.read_count(); - std::vector& precompiled_tokens = lexer.src->_precompiled_tokens; + vector& precompiled_tokens = lexer.src->_precompiled_tokens; for(int i=0; icall(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){ diff --git a/src/csv.cpp b/src/csv.cpp index e6c054bb..4aa68f62 100644 --- a/src/csv.cpp +++ b/src/csv.cpp @@ -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 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(); diff --git a/src/gc.cpp b/src/gc.cpp index aaa2a3c3..ec8daa23 100644 --- a/src/gc.cpp +++ b/src/gc.cpp @@ -3,7 +3,8 @@ namespace pkpy{ int ManagedHeap::sweep(){ - std::vector alive; + vector alive; + alive.reserve(gen.size() / 2); for(PyObject* obj: gen){ if(obj->gc_marked){ obj->gc_marked = false; diff --git a/src/lexer.cpp b/src/lexer.cpp index 5b45d2d1..8b711659 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -485,7 +485,7 @@ static bool is_unicode_Lo_char(uint32_t c) { this->indents.push(0); } - std::vector Lexer::run() { + vector Lexer::run() { PK_ASSERT(curr_char == src->source.c_str()); while (lex_one_token()); return std::move(nexts); diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 6c751b6c..1c347371 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -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 parts; + vector 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 parts; - parts = self.split('\n'); + vector parts = self.split('\n'); List ret(parts.size()); for(int i=0; iNone; }); @@ -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,11 +967,14 @@ 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){ \ - if(!is_type(rhs, vm->_t)) return vm->NotImplemented; \ + _vm->bind__##name##__(_vm->_t, [](VM* vm, PyVar lhs, PyVar rhs){ \ + if(!is_type(rhs, vm->_t)) return vm->NotImplemented; \ auto& a = _CAST(_T&, lhs); \ auto& b = _CAST(_T&, rhs); \ for(int i=0; ibind__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", "", 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, "", EXEC_MODE); this->_exec(code, this->builtins); diff --git a/src/profiler.cpp b/src/profiler.cpp index 75dd1021..af73b8c2 100644 --- a/src/profiler.cpp +++ b/src/profiler.cpp @@ -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){ diff --git a/src/random.cpp b/src/random.cpp index 21350b62..71a28701 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -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 cum_weights(size); + array cum_weights(size); if(args[2] == vm->None){ for(int i = 0; i < size; i++) cum_weights[i] = i + 1; }else{ diff --git a/src/str.cpp b/src/str.cpp index 8b31ded6..c135223f 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -333,8 +333,8 @@ int utf8len(unsigned char c, bool suppress){ return _byte_index_to_unicode(size); } - pod_vector Str::split(const Str& sep) const{ - pod_vector result; + vector Str::split(const Str& sep) const{ + vector 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 Str::split(char sep) const{ - pod_vector result; + vector Str::split(char sep) const{ + vector 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; diff --git a/src/vm.cpp b/src/vm.cpp index df5b2935..b81ee0de 100644 --- a/src/vm.cpp +++ b/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& cpnts){ + static auto f_join = [](const vector& cpnts){ SStream ss; for(int i=0; i cpnts = curr_path.split('.'); + vector cpnts = curr_path.split('.'); int prefix = 0; // how many dots in the prefix for(int i=0; i path_cpnts = path.split('.'); + vector 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 jumpTargets; + vector jumpTargets; for(int i=0; icodes.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 frames; + vector frames; LinkedFrame* lf = callstack._tail; while(lf != nullptr){ frames.push_back(lf);